diff options
263 files changed, 89483 insertions, 2778 deletions
diff --git a/TI_OMAP4_Kernel_Release_Notes_L24.x.txt b/TI_OMAP4_Kernel_Release_Notes_L24.x.txt new file mode 100755 index 000000000000..9e71822cdebc --- /dev/null +++ b/TI_OMAP4_Kernel_Release_Notes_L24.x.txt @@ -0,0 +1,480 @@ +8 April 2010 + + +1. Introduction +---------------- +This document accompanies OMAP(TM) Software Release L24.5 for Linux 2.6.33-rc2 +on OMAP4430 SDP. The document specifies: + - Instructions for unpacking the release + - New features and features the release supports + - Planned future features + - Postponed features + + +2. Release Summary +------------------ +This is a release of the Linux Baseport for OMAP4430. It supports the +OMAP4 Wakeup SDP board. The kernel is based on Linux-omap version 2.6.33-rc2 +from open source. U-boot is based on open-source version 1.1.4. + +The u-boot source can be obtained via GIT from: + http://dev.omapzoom.org/?p=bootloader/u-boot.git;a=shortlog;h=refs/heads/omap4_dev + +The x-loader source can be obtained via GIT from: + http://dev.omapzoom.org/?p=bootloader/x-loader.git;a=shortlog;h=refs/heads/omap4_dev + +The kernel source can be obtained via GIT from: + http://dev.omapzoom.org/?p=integration/kernel-omap4.git;a=shortlog;h=refs/heads/L24.5 + +Components that are supported in the release: + X-loader, U-Boot, OS Kernel (SMP), Phoenix power IC, UART, GP Timer, GPIO, Watchdog, + Neon, I2C, MMC/SD/eMMC (with ADMA support), Ethernet, RTC, + SDMA (including descriptor loading), Keypad, Touch screen, McSPI, McBSP, Mentor USB, + Phoenix General Purpose ADC, Battery Charging, Power Management Frameworks, + Audio (Phoenix Audio IC, ABE, AESS), + Display driver (TAAL based), Basic display (DSS2 migration, FB dev), Tiler memory manager. + WLAN support + + +3. Instructions +---------------- + +3.1 Board setup + +Please refer to the OMAP4430 SDP guide for instructions on setting up the OMAP4 +board. + +3.2 Compiling Images + +3.2.1 Compiling U-boot + +Set the environment variable PATH such that cross compile binaries point to the +needed tool chain. Refer to section 5 for tool chain information. + +To select the default configuration for U-Boot type: + # make CROSS_COMPILE=arm-none-linux-gnueabi- omap4430sdp_config + +To build the U-Boot image type: + # make CROSS_COMPILE=arm-none-linux-gnueabi- + + +3.2.2 Compiling X-loader (for booting from external/removable MMC) + +Set the environment variable PATH such that cross compile binaries point to the +needed tool chain. Refer to section 5 for tool chain information. + +U-boot needs to be placed in a directory parallel to x-loader and compiled first. +E.g.: + [DIR] omap4 + +-- u-boot + +-- x-loader + +To select the default configuration for X-loader type: + # make CROSS_COMPILE=arm-none-linux-gnueabi- omap4430sdp_config + +To build the X-loader image type: + # make CROSS_COMPILE=arm-none-linux-gnueabi- + # make ift CROSS_COMPILE=arm-none-linux-gnueabi- + +The above step will create a MLO image, which can be copied into the +MMC card for booting via MMC. + +3.2.3 Compiling X-loader (for booting from eMMC) + +Follow same steps as above to create an MLO image. A configuration header needs +to be added at the begining of this MLO to create an image 'x-load.ch.bin' that +can be written to the eMMC for eMMC-booting. Please contact your TI +representative for obtaining the configuration header. + +3.2.4 Compiling the Kernel + +Set the environment variable PATH such that cross-compile binaries point to the +needed tool chain. Refer to section 5 for tool chain information. + +The default configuration file for OMAP 4430 is present at +arch/arm/configs/omap_4430sdp_defconfig. + +To work with the default configuration file, run following commands: + # make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- + omap_4430sdp_defconfig + +Build kernel with: + # make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- uImage + +NOTE: The above steps will create arch/arm/boot/uImage in the kernel directory + which is the binary used for booting. + +3.3 Flashing and Booting + +3.3.1 Booting from removable MMC + +Use the MLO (ref: section 3.2.2) and u-boot.bin (ref: section 3.2.1) binaries +and follow the instructions at http://elinux.org/BeagleBoard#MMC.2FSD_boot +to boot the board from removable MMC. + +Set the board switch settings as follows to boot the board from removable MMC: + S9 - 1-off, 2-on, 3-on, 4-on + S8 - 1-off, 2-on, 3-off, 4-on, 5-on, 6-on, 7-on, 8-on + +3.3.2 Flashing and booting from eMMC + +Follow the instructions below to save x-loader and u-boot binaries to eMMC and +subsequently boot from eMMC. + +Get the x-loader and u-boot binaries (that you want to flash to eMMC) into RAM +using one of the following options. + +Option 1: +Use a debugger or OMAPFlasher tool to download x-loader (with configuration +header, e.g. x-load.ch.bin) as well as u-boot.bin into +SDRAM and run u-boot from SDRAM. + +Option 2: +Boot via a removable MMC card following the instructions in section 3.3.1, but +additionally keep the x-load.ch.bin that you want to flash to eMMC in the same +removable MMC card. After booting from removable MMC, copy the x-load.ch.bin +and u-boot.bin from the MMC to RAM using the following commands: +OMAP44XX SDP # mmcinit 0 +OMAP44XX SDP # fatload mmc 0 [Ram Address X] x-load.ch.bin +OMAP44XX SDP # fatload mmc 0 [Ram Address Y] u-boot.bin + +Once the x-loader and u-boot binaries are in RAM, use the following commands +to copy them to eMMC. + +1) Erase all EMMC contents +OMAP44XX SDP # mmcinit 1 +OMAP44XX SDP # mmc 1 erase 0x0 0x800000 +2) Flash x-loader +OMAP44XX SDP # mmc 1 erase 0x100 [size of x-loader in hex] +OMAP44XX SDP # mmc 1 write [Ram Address X] 0x100 [size of x-loader in hex] +Note: Ram address X is address where x-loader is downloaded in RAM using either the +debugger, OMAPFlasher or removable MMC. +3) Flash u-boot.bin +OMAP44XX SDP # mmc 1 erase 0x400 [size] +OMAP44XX SDP # mmc 1 write [Ram Address Y] 0x400 [size] +Note: Ram address Y is address where u-boot is downloaded in RAM using either the +debugger, OMAPFlasher or removable MMC. + +Set the board switch settings as follows to boot the board from eMMC: + S9 - 1-off, 2-on, 3-on, 4-on + S8 - 1-on, 2-on, 3-on, 4-on, 5-on, 6-off, 7-on, 8-on + +3.3.3 Using Filesystem from eMMC + +Use fdisk to create an ext2 partition (/dev/mmcblk0p2) in eMMC leaving 2MB of space +at the top. + +Use the following commands to flash the filesystem to eMMC partition +1) Bootup with a known good kernel and filesystem from RAM +2) Use a filesystem which has USB Gadget filestorage module g_filestorage.ko +3) Connect the usb cable from the board to the PC +4) Load the USB filestorage gadget module as: +insmod g_filestorage.ko file=/dev/mmcblk0p2 stall=0 removable=1 +5) When the USB drive enumerates on the Linux PC, mount the drive +6) Add ext2 filesystem to the mounted drive +7) sync and then mount the drive. +8) Add the following in bootargs "root=/dev/mmcblk0p2 rw rootdelay=1" to be able +to use the eMMC based FS as rootfs. + +3.3.4 Bootargs + +Since UART3 is used as the console on OMAP4 Wakeup board, you need to set +'console=ttyS2,115200n8' in the bootargs + +While using a filesystem from MMC or eMMC, you may use params such as: +'root=/dev/mmcblk0p2 rw rootdelay=1'. The rootdelay is required because +removable cards may take a few seconds to be detected. + +While using a filesystem via NFS, you may use params such as: +'root=/dev/nfs rw nfsroot=<serverip>:<mount-partition>,nolock' + +Refer to section 3.4.2 for display related bootargs options + +For detailed list and explaination of the various boot parameters, please refer +http://www.kernel.org/pub/linux/kernel/people/gregkh/lkn/lkn_pdf/ch09.pdf + + +3.4 Using FB and V4L2 Display driver + +3.4.1 To enable secondary display + +Please use following set of commands after kernel bootup for setting +secondary display ON. + +1) Enable secondary display (display1) + echo "1" > /sys/devices/platform/omapdss/display1/enabled +2) Disable overlay1 + echo "0" > /sys/devices/platform/omapdss/overlay1/enabled +3) Attach secondary display as a manager for overlay1 + echo "2lcd" > /sys/devices/platform/omapdss/overlay1/manager +4) Enable overlay1 + echo "1" > /sys/devices/platform/omapdss/overlay1/enabled + +3.4.2 Display specific bootargs options + +3.4.2.1 Using 1 FB and 3 V4L2 devices +Add the following in bootargs "omapfb.numfb=1" + +3.4.2.2 Using 2 FB and 2 V4L2 devices (default option in L24.2 onwards) +Add the following in bootargs "omapfb.numfb=2" + +3.4.2.3 Enabling DSS DEBUG prints +Add the following in bootargs "omapdss.debug=1" + +3.4.3 Pico DLP support + +OMAP4 device supports a pico DLP and secondary LCD output on the secondary +LCD manager (with the name of '2lcd'). The configuration of the display +happens in a non-conventional way. + +3.4.3.1 For building kernel image with Pico DLP support: + In menuconfig following "pico DLP" option needs to be set + Device drivers -> + Graphics support -> + OMAP 2/3 Diaplay subsystem support -> + omap 2/3 display drivers -> + <*> pico DLP +3.4.3.2 After bootup: + +To configure output to either pico DLP or secondary LCD, set the overlay's +manager to the secondary LCD manager: + +echo "0" > /sys/devices/platform/omapdss/overlay0/enabled +echo "2lcd" > /sys/devices/platform/omapdss/overlay0/manager +echo "1" > /sys/devices/platform/omapdss/overlay0/enabled + +3.4.3.3 Then enable the correct display to chose pico DLP or secondary LCD (default +is secondary LCD). Assuming display1 is secondary LCD, and display3 is +pico DLP: + +echo "0" > /sys/devices/platform/omapdss/display1/enabled +# set the secondary manager to pico DLP +echo "pico_DLP" > /sys/devices/platform/omapdss/manager2/display -- This will set secondary manager to pico. +echo "1" > /sys/devices/platform/omapdss/display3/enabled + +3.4.3.4 Now to switch back to secondary +echo "0" > /sys/devices/platform/omapdss/display3/enabled +echo "2lcd" > /sys/devices/platform/omapdss/manager2/display +echo "1" > /sys/devices/platform/omapdss/display1/enabled + +3.5 Enabling Power Management Features + +All PM features are disabled in the default OMAP4 kernel configuration +(omap_4430sdp_defconfig). +All clocks are still kept enabled on bootloader. + +To test PM features please use omap4_pm_defconfig. Note that PM features +on OMAP4430 ES1.0 can only be verified on a EMU device. The EMU device needs +the x-loader signed with the right PPA release. + +omap4_pm_defconfig does not enable Tick suppression. To do so enable these +options manually. + +Enable the following options in menuconfig + Kernel Features ---> Use local timer interrupts + Kernel Features ---> Tickless System + Kernel Features ---> High Resolution Timer support + +omap4_pm_defconfig has VFP support disabled due to a know issue with enabling +FPU on ES1. Please do not enable VFP support. + +3.5.1 CPU Hotplug + +To hotplug out CPU1 use the following command + +echo 0 > /sys/devices/system/cpu/cpu1/online + +To bring back CPU1 online use the following command + +echo 1 > /sys/devices/system/cpu/cpu1/online + +Note that CPU0 cannot be offlined due to hardware limitation. +Currenlty CPU1 transitions to CSWR state when offlined. This can +only be verified using OBS signals. + +3.5.2 CPUIdle + +To test cpuidle, it's necessary that CPU1 is hotplugged out. +Use the below command to hotplug out CPU1 +echo 0 > /sys/devices/system/cpu/cpu1/online + +Once CPU1 is hotplugged out, OBS signals can be used to +verify MPU/CPU0/CPU1 transtitions. + +Currently only sleep state of MPU CSWR is supported. + +3.5.3 System Suspend + +To test system suspend, use the following command + +echo mem > /sys/power/state + +Use OBS signals to verify MPU/CPU0/CPU1 transitions. + +Currently only sleep state of MPU CSWR is supported. + +Please use a ramdisk inorder to test system suspend feature + +3.6 Using Audio Driver + +Include the asound.conf file in /etc directory in your FS. It maps the different +audio devices + +Usage: +aplay -D mm file.wav +aplay -D tones file.wav +aplay -D vx file.wav +aplay -D hd_audio file.wav + + + +4. Features +----------- + +4.1 New Features + +- Power Management Frameworks + - Clock framework + - Clockdomain framework + - Powerdomain framework + - Regulator framework + - CPUidle with support upto MPU CSWR + - System wide suspend with support upto MPU CSWR + - CPU1 hotplug with support upto CPU1 CSWR +NOTE: + - All PM features are disabled in the default OMAP4 kernel configuration. + - All clocks are still kept enabled on bootloader. + - These features can only be validated on EMU devices with omap4_pm_defconfig + +- Audio + - Audio Playback to Phoenix Earphone + - Audio Playback using Tones port + - ALSA controls for ABE mixers + - Add McPDM power management support + +4.2 Supported Features + +- Boot-loader: + X-loader with MMC/eMMC/SD support + U-boot with USB, MMC/eMMC/SD and Ethernet support + +- OS Kernel + OS Kernel (SMP) + Phoenix power IC, + UART, + GP Timer, + GPIO, + Watchdog, + NEON, + I2C, + MMC/SD/eMMC (with ADMA support), + Ethernet, + RTC, + SDMA (including descriptor loading), + Keypad, + Touch screen, + McSPI, + McBSP, + Mentor USB, + Phoenix General Purpose ADC, + Battery Charging. + +- Audio + Audio playback to Phoenix Hand-free, Head set output devices. + HDMI audio playback + Audio record through Phoenix analog MIC input. + Simultaneous audio playback and capture. + +- Video + Display driver + - FBdev and V4L2 API support + - Primary and Secondary DSI and HDMI displays + - Simultaneous rendering on all 3 displays + Tiler memory manager. + +- WLAN + +4.3 Postponed Features + +None + +4.4 Future Planned Features + +Refer to Program schedule. + +4.5 Defects Fixed in This Release + +OMAPS00214290 MUSB Tx throughput degrades with Poky FS accessed over NFS. +OMAPS00216452 Fastboot devices are not detected if USB cable is connected after boot up +OMAPS00214706 Adapt DPI to support CHANNEL LCD2 along with CHANNEL LCD in OMAP4 +OMAPS00216009 Call to display->update call is missing in function pan display +OMAPS00215432 CONFIG_PANEL_4430SDP_TAAL lacks config dependency +OMAPS00215230 1680 *1050 resolution DVI monitor gives SYNC LOST +OMAPS00213860 DQUE ioctl() takes ~40-50ms although buffer is available. +OMAPS00213905 Dsi framedone timeout seen when switching from HDMI to primary display +OMAPS00213910 tearing effect seen with alternate frames being colored +OMAPS00213912 DSI lcd display does refresh at 40fps instead of 60fps +OMAPS00214176 Remove the mux configuration for dsi1, dsi2, hdmi +OMAPS00214175 Move GPIO and twl config to board file for dsi1, dsi2, hdmi +OMAPS00216009 Call to display->update call is missing in function omapfb_pan_display +OMAPS00212907 ALSA Record + +Known Issues: +OMAPS00216391 With tearing effect patch , frame drops from 60fps to 30fps +OMAPS00216592 There is no way available for dynamically setting/resetting dithering bit +OMAPS00213907 With omapfb.numfb=1 in bootargs , the rest of pipelines are not given to v4l2 +OMAPS00214116 Visible tearing during the execution of a 3D app with flipping enabled. +OMAPS00215432 CONFIG_PANEL_4430SDP_TAAL lacks config dependency on DSS_DSI +OMAPS00216002 DSS function default_wait_vsync doesn't distinguish between primary and secondary LCD panels +OMAPS00216444 Provide KConfig options for DSI2, Sec Taal panel, and all DSI specific knobs +OMAPS00216589 VGA Rotation on LCD does not work +OMAPS00216585 V4L2 Rotation ioctls rotate 90 degrees when set to 270 degress and vice versa +OMAPS00216582 streaming test case gives issue when multiple buffers are used in the videobuf queu + +4.6 Open Defects + +OMAPS00214020 ethernet doesn't get configured with L24.4 kernel +OMAPS00214519 After boot SATO image and Calibrate Touchscreen, if the screen is touched X-server crashes. +OMAPS00215651 MUSB driver in host mode has problems with unaligned DMA +OMAPS00215668 MUSB driver in device mode has problems with unaligned DMA. +OMAPS00216393 DMA testcases should declare set_test_passed(1) only during rmmod + + +4.7 Open Change Requests + +None + +4.8 Rejected Defects + +None + +4.9 Postponed Defects + +None + +4.10 Limitations + +1) At u-boot level saveenv command doesn't work. +2) MAC address reading from ethernet EEPROM is not supported. + + +5. Tool Chain +------------- +The toolchain used to build the code can be obtained from CodeSourcery at the +following URL: + http://www.codesourcery.com/sgpp/lite/arm/portal/release858 + +The tool chain version is Sourcery G++ Lite 2009q1-203 for ARM GNU/Linux. + +The tool chain requires glibc 2.3.0 or higher to compile the source code on +the host machine. + + +-------------------------------------------------------------------------------- + +OMAP(TM) is a Trademark of Texas Instruments Incorporated +Innovator(TM) is a Trademark of Texas Instruments Incorporated +Code Composer Studio(TM) is a Trademark of Texas Instruments Incorporated +DSP/BIOS(TM) is a Trademark of Texas Instruments Incorporated + +All other trademarks are the property of the respective owner. diff --git a/arch/arm/configs/omap4_pm_defconfig b/arch/arm/configs/omap4_pm_defconfig index 32975a35d6c7..0e323ca1060f 100644 --- a/arch/arm/configs/omap4_pm_defconfig +++ b/arch/arm/configs/omap4_pm_defconfig @@ -835,6 +835,7 @@ CONFIG_REGULATOR_TWL4030=y # CONFIG_VGASTATE is not set # CONFIG_VIDEO_OUTPUT_CONTROL is not set # CONFIG_FB is not set +# CONFIG_OMAP2_DSS is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # @@ -999,6 +1000,9 @@ CONFIG_RTC_DRV_TWL4030=y # TI VLYNQ # # CONFIG_STAGING is not set +CONFIG_DMM_OMAP=y +CONFIG_TILER_OMAP=y +# CONFIG_Sys_Link is not set # # File systems diff --git a/arch/arm/configs/omap_4430sdp_defconfig b/arch/arm/configs/omap_4430sdp_defconfig index 6610f9b51861..11d04492a6ae 100644 --- a/arch/arm/configs/omap_4430sdp_defconfig +++ b/arch/arm/configs/omap_4430sdp_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.32 -# Sun Dec 6 23:37:45 2009 +# Linux kernel version: 2.6.33-rc2 +# Fri Apr 9 12:18:37 2010 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -22,6 +22,7 @@ CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y @@ -36,14 +37,18 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set # # RCU Subsystem # CONFIG_TREE_RCU=y # CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set # CONFIG_RCU_TRACE is not set CONFIG_RCU_FANOUT=32 # CONFIG_RCU_FANOUT_EXACT is not set @@ -127,14 +132,41 @@ CONFIG_LBDAF=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +CONFIG_MUTEX_SPIN_ON_OWNER=y # CONFIG_FREEZER is not set # @@ -163,6 +195,7 @@ CONFIG_MMU=y # CONFIG_ARCH_IXP2000 is not set # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_DOVE is not set # CONFIG_ARCH_KIRKWOOD is not set # CONFIG_ARCH_LOKI is not set # CONFIG_ARCH_MV78XX0 is not set @@ -185,6 +218,7 @@ CONFIG_MMU=y # CONFIG_ARCH_DAVINCI is not set CONFIG_ARCH_OMAP=y # CONFIG_ARCH_BCMRING is not set +# CONFIG_ARCH_U8500 is not set # # TI OMAP Implementations @@ -200,7 +234,8 @@ CONFIG_ARCH_OMAP4=y # CONFIG_OMAP_RESET_CLOCKS is not set # CONFIG_OMAP_MUX is not set CONFIG_OMAP_MCBSP=y -# CONFIG_OMAP_MBOX_FWK is not set +CONFIG_OMAP_MBOX_FWK=y +CONFIG_OMAP_IOMMU=y # CONFIG_OMAP_MPU_TIMER is not set CONFIG_OMAP_32K_TIMER=y CONFIG_OMAP_32K_TIMER_HZ=128 @@ -215,6 +250,8 @@ CONFIG_OMAP_PM_NOOP=y # # OMAP Board Type # +# CONFIG_WIFI_CONTROL_FUNC is not set +# CONFIG_TIWLAN_SDIO is not set CONFIG_MACH_OMAP_4430SDP=y # @@ -232,6 +269,7 @@ CONFIG_CPU_TLB_V7=y CONFIG_CPU_HAS_ASID=y CONFIG_CPU_CP15=y CONFIG_CPU_CP15_MMU=y +# CONFIG_CPU_USE_DOMAINS is not set # # Processor Features @@ -244,13 +282,16 @@ CONFIG_CPU_CP15_MMU=y CONFIG_HAS_TLS_REG=y CONFIG_OUTER_CACHE=y CONFIG_CACHE_L2X0=y +CONFIG_CACHE_PL310=y CONFIG_ARM_L1_CACHE_SHIFT=5 +CONFIG_ARCH_HAS_BARRIERS=y # CONFIG_ARM_ERRATA_430973 is not set # CONFIG_ARM_ERRATA_458693 is not set # CONFIG_ARM_ERRATA_460075 is not set CONFIG_PL310_ERRATA_588369=y CONFIG_ARM_GIC=y -CONFIG_UNOFFICIAL_USER_DMA_API=y +CONFIG_COMMON_CLKDEV=y + # # Bus support # @@ -294,13 +335,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_PHYS_ADDR_T_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 CONFIG_VIRT_TO_BUS=y -CONFIG_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y # CONFIG_KSM is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 # CONFIG_LEDS is not set CONFIG_ALIGNMENT_TRAP=y # CONFIG_UACCESS_WITH_MEMCPY is not set +CONFIG_UNOFFICIAL_USER_DMA_API=y # # Boot options @@ -352,27 +392,76 @@ CONFIG_PACKET=y CONFIG_PACKET_MMAP=y CONFIG_UNIX=y CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set CONFIG_NET_KEY=y +# CONFIG_NET_KEY_MIGRATE is not set CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set CONFIG_IP_FIB_HASH=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_IP_PNP_RARP=y +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_XFRM_MODE_BEET=y CONFIG_INET_LRO=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set # CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing # +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set # CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set # # Device Drivers @@ -389,17 +478,24 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_DEBUG_DRIVER is not set # CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set # CONFIG_MTD is not set # CONFIG_PARPORT is not set CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# +# CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=16384 # CONFIG_BLK_DEV_XIP is not set # CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set # CONFIG_MG_DISK is not set # CONFIG_MISC_DEVICES is not set CONFIG_HAVE_IDE=y @@ -415,12 +511,48 @@ CONFIG_HAVE_IDE=y # CONFIG_ATA is not set # CONFIG_MD is not set CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_PHYLIB is not set CONFIG_NET_ETHERNET=y CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMC911X is not set +# CONFIG_SMSC911X is not set +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set CONFIG_KS8851=y +# CONFIG_KS8851_MLL is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set # CONFIG_WLAN is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set # CONFIG_PHONE is not set # @@ -429,6 +561,7 @@ CONFIG_KS8851=y CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set # CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set # # Userland interfaces @@ -442,12 +575,46 @@ CONFIG_INPUT_EVDEV=y # Input Device Drivers # CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set CONFIG_KEYBOARD_ATKBD=y +# CONFIG_QT2160 is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set CONFIG_KEYBOARD_OMAP=y +# CONFIG_KEYBOARD_TWL4030 is not set +# CONFIG_KEYBOARD_XTKBD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TABLET is not set CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879_I2C is not set +# CONFIG_TOUCHSCREEN_AD7879_SPI is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_W90X900 is not set CONFIG_TOUCHSCREEN_SYNTM12XX=y # CONFIG_INPUT_MISC is not set @@ -457,6 +624,8 @@ CONFIG_TOUCHSCREEN_SYNTM12XX=y CONFIG_SERIO=y CONFIG_SERIO_SERPORT=y CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set # CONFIG_GAMEPORT is not set # @@ -486,8 +655,10 @@ CONFIG_SERIAL_8250_RSA=y # # Non-8250 serial port support # +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_OMAP is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set @@ -499,6 +670,7 @@ CONFIG_HW_RANDOM=y # CONFIG_TCG_TPM is not set CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_HELPER_AUTO=y @@ -514,9 +686,46 @@ CONFIG_I2C_HELPER_AUTO=y # CONFIG_I2C_OCORES is not set CONFIG_I2C_OMAP=y # CONFIG_I2C_SIMTEC is not set -CONFIG_SPI_OMAP24XX=y -CONFIG_SPI_MASTER=y + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set +CONFIG_SPI_OMAP24XX=y +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set + # # PPS support # @@ -533,6 +742,10 @@ CONFIG_GPIOLIB=y # # I2C GPIO expanders: # +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_TWL4030 is not set # # PCI GPIO expanders: @@ -541,16 +754,33 @@ CONFIG_GPIOLIB=y # # SPI GPIO expanders: # +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set # # AC97 GPIO expanders: # # CONFIG_W1 is not set CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_BATTERY_DS2760 is not set +# CONFIG_BATTERY_DS2782 is not set +CONFIG_TWL6030_BCI_BATTERY=y +# CONFIG_BATTERY_BQ27x00 is not set +# CONFIG_BATTERY_MAX17040 is not set # CONFIG_HWMON is not set # CONFIG_THERMAL is not set CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set CONFIG_OMAP_WATCHDOG=y +# CONFIG_TWL4030_WATCHDOG is not set CONFIG_SSB_POSSIBLE=y # @@ -566,12 +796,38 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_ASIC3 is not set # CONFIG_HTC_EGPIO is not set # CONFIG_HTC_PASIC3 is not set +# CONFIG_TPS65010 is not set CONFIG_TWL4030_CORE=y +# CONFIG_TWL4030_POWER is not set +# CONFIG_TWL4030_CODEC is not set +CONFIG_TWL6030_GPADC=y # CONFIG_MFD_TMIO is not set # CONFIG_MFD_T7L66XB is not set # CONFIG_MFD_TC6387XB is not set # CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MFD_88PM8607 is not set +# CONFIG_AB4500_CORE is not set CONFIG_REGULATOR=y +# CONFIG_REGULATOR_DEBUG is not set +# CONFIG_REGULATOR_FIXED_VOLTAGE is not set +# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set +# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set +# CONFIG_REGULATOR_BQ24022 is not set +# CONFIG_REGULATOR_MAX1586 is not set +# CONFIG_REGULATOR_MAX8660 is not set +CONFIG_REGULATOR_TWL4030=y +# CONFIG_REGULATOR_LP3971 is not set +# CONFIG_REGULATOR_TPS65023 is not set +# CONFIG_REGULATOR_TPS6507X is not set CONFIG_MEDIA_SUPPORT=y # @@ -581,11 +837,14 @@ CONFIG_VIDEO_DEV=y CONFIG_VIDEO_V4L2_COMMON=y # CONFIG_VIDEO_ALLOW_V4L1 is not set CONFIG_VIDEO_V4L1_COMPAT=y +# CONFIG_DVB_CORE is not set CONFIG_VIDEO_MEDIA=y # # Multimedia drivers # +CONFIG_IR_CORE=y +CONFIG_VIDEO_IR=y # CONFIG_MEDIA_ATTACH is not set CONFIG_MEDIA_TUNER=y # CONFIG_MEDIA_TUNER_CUSTOMISE is not set @@ -605,20 +864,20 @@ CONFIG_VIDEO_CAPTURE_DRIVERS=y # CONFIG_VIDEO_ADV_DEBUG is not set # CONFIG_VIDEO_FIXED_MINOR_RANGES is not set CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +CONFIG_VIDEO_IR_I2C=y # CONFIG_VIDEO_VIVI is not set # CONFIG_VIDEO_SAA5246A is not set # CONFIG_VIDEO_SAA5249 is not set -CONFIG_VIDEO_OMAP3=y -CONFIG_VIDEO_OMAP_VIDEOLIB=y -CONFIG_VIDEO_OMAP_VIDEOOUT=y -CONFIG_NTSC_M=y -# CONFIG_PAL_BDGHI is not set +CONFIG_VIDEO_OMAP3_OUT=y # CONFIG_SOC_CAMERA is not set CONFIG_RADIO_ADAPTERS=y +# CONFIG_I2C_SI4713 is not set +# CONFIG_RADIO_SI4713 is not set +# CONFIG_RADIO_SI470X is not set # CONFIG_RADIO_TEA5764 is not set +# CONFIG_RADIO_TEF6862 is not set # CONFIG_DAB is not set - # # Graphics support # @@ -690,6 +949,9 @@ CONFIG_BACKLIGHT_GENERIC=y # # Display device support # +# CONFIG_DISPLAY_SUPPORT is not set + +# # Console display driver support # # CONFIG_VGA_CONSOLE is not set @@ -712,7 +974,42 @@ CONFIG_LOGO=y CONFIG_LOGO_LINUX_MONO=y CONFIG_LOGO_LINUX_VGA16=y CONFIG_LOGO_LINUX_CLUT224=y -# CONFIG_SOUND is not set +CONFIG_SOUND=y +# CONFIG_SOUND_OSS_CORE is not set +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_JACK=y +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_DRIVERS=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set +CONFIG_SND_ARM=y +CONFIG_SND_SPI=y +CONFIG_SND_SOC=y +CONFIG_SND_OMAP_SOC=y +CONFIG_OMAP_MCPDM=y +CONFIG_SND_OMAP_SOC_ABE=y +CONFIG_SND_OMAP_SOC_SDP4430=y +CONFIG_SND_OMAP_SOC_HDMI=y +CONFIG_SND_SOC_I2C_AND_SPI=y +# CONFIG_SND_SOC_ALL_CODECS is not set +CONFIG_SND_SOC_ABE_TWL6040=y +# CONFIG_SOUND_PRIME is not set # CONFIG_HID_SUPPORT is not set CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y @@ -783,6 +1080,7 @@ CONFIG_USB_G_SERIAL=m CONFIG_USB_OTG_UTILS=y # CONFIG_USB_GPIO_VBUS is not set # CONFIG_USB_ULPI is not set +# CONFIG_TWL4030_USB is not set CONFIG_NOP_USB_XCEIV=y CONFIG_MMC=y # CONFIG_MMC_DEBUG is not set @@ -802,6 +1100,8 @@ CONFIG_MMC_BLOCK_BOUNCE=y # CONFIG_MMC_SDHCI is not set # CONFIG_MMC_OMAP is not set CONFIG_MMC_OMAP_HS=y +# CONFIG_MMC_AT91 is not set +# CONFIG_MMC_ATMELMCI is not set # CONFIG_MMC_SPI is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set @@ -810,9 +1110,7 @@ CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_DMADEVICES is not set -# CONFIG_AUXDISPLAY is not set -# CONFIG_UIO is not set +# CONFIG_RTC_DEBUG is not set # # RTC interfaces @@ -820,21 +1118,79 @@ CONFIG_RTC_HCTOSYS_DEVICE="rtc0" CONFIG_RTC_INTF_SYSFS=y CONFIG_RTC_INTF_PROC=y CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +CONFIG_RTC_DRV_TWL4030=y +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set # -# I2C TWL drivers +# SPI RTC drivers # -CONFIG_RTC_DRV_TWL4030=y -CONFIG_REGULATOR_TWL4030=y -CONFIG_TWL6030_GPADC=y -CONFIG_TWL6030_BCI_BATTERY=y +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set # # TI VLYNQ # # CONFIG_STAGING is not set -CONFIG_dmm_tiler=y -CONFIG_DMM_TILER=y +CONFIG_DMM_OMAP=y +CONFIG_TILER_OMAP=y +CONFIG_Sys_Link=y +CONFIG_SYSLINK_PROC=y +CONFIG_SYSLINK_PROC4430=y +CONFIG_MPU_BRIDGE_NOTIFY=y +CONFIG_NOTIFY_DUCATI=y +CONFIG_MPU_SYSLINK_IPC=y +CONFIG_SYSLINK_USE_SYSMGR=y +CONFIG_OMAP_IOMMU_DEBUG_MODULE=y # # File systems @@ -852,6 +1208,7 @@ CONFIG_JBD=y CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set # CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set # CONFIG_BTRFS_FS is not set # CONFIG_NILFS2_FS is not set CONFIG_FILE_LOCKING=y @@ -860,6 +1217,7 @@ CONFIG_DNOTIFY=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y CONFIG_QUOTA=y +# CONFIG_QUOTA_NETLINK_INTERFACE is not set CONFIG_PRINT_QUOTA_WARNING=y CONFIG_QUOTA_TREE=y # CONFIG_QFMT_V1 is not set @@ -924,7 +1282,9 @@ CONFIG_NFS_FS=y CONFIG_NFS_V3=y CONFIG_NFS_V3_ACL=y CONFIG_NFS_V4=y +# CONFIG_NFS_V4_1 is not set CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_NFS_ACL_SUPPORT=y @@ -932,6 +1292,12 @@ CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y CONFIG_SUNRPC_GSS=y CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set # # Partition Types @@ -994,6 +1360,7 @@ CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_KOI8_R is not set # CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set +# CONFIG_DLM is not set # # Kernel hacking @@ -1048,13 +1415,11 @@ CONFIG_FRAME_POINTER=y # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # CONFIG_FAULT_INJECTION is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set # CONFIG_PAGE_POISONING is not set CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_TRACING_SUPPORT=y # CONFIG_FTRACE is not set -# CONFIG_BRANCH_PROFILE_NONE is not set -# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set -# CONFIG_PROFILE_ALL_BRANCHES is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -1063,6 +1428,7 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_DEBUG_ERRORS is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUG_LL is not set +# CONFIG_OC_ETM is not set # # Security options @@ -1070,7 +1436,11 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # @@ -1187,3 +1557,4 @@ CONFIG_DECOMPRESS_GZIP=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/arm/configs/omap_4430simulator_defconfig b/arch/arm/configs/omap_4430simulator_defconfig new file mode 100644 index 000000000000..6274bb1c53e0 --- /dev/null +++ b/arch/arm/configs/omap_4430simulator_defconfig @@ -0,0 +1,1017 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.31-rc9 +# Thu Oct 1 15:58:54 2009 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_GROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set +# CONFIG_CGROUPS is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +# CONFIG_ELF_CORE is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y + +# +# Performance Counters +# +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_COMPAT_BRK=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_CLK=y + +# +# GCOV-based kernel profiling +# +# CONFIG_SLOW_WORK is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" +# CONFIG_FREEZER is not set + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_STMP3XXX is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_DAVINCI is not set +CONFIG_ARCH_OMAP=y + +# +# TI OMAP Implementations +# +# CONFIG_ARCH_OMAP1 is not set +# CONFIG_ARCH_OMAP2 is not set +# CONFIG_ARCH_OMAP3 is not set +CONFIG_ARCH_OMAP4=y + +# +# OMAP Feature Selections +# +# CONFIG_OMAP_RESET_CLOCKS is not set +CONFIG_OMAP_MUX=y +CONFIG_OMAP_MCBSP=y +CONFIG_OMAP_MBOX_FWK=y +# CONFIG_OMAP_MPU_TIMER is not set +CONFIG_OMAP_32K_TIMER=y +CONFIG_OMAP_32K_TIMER_HZ=128 +CONFIG_OMAP_DM_TIMER=y +CONFIG_OMAP_LL_DEBUG_UART1=y +# CONFIG_OMAP_LL_DEBUG_UART2 is not set +# CONFIG_OMAP_LL_DEBUG_UART3 is not set + +# +# OMAP Board Type +# +CONFIG_MACH_OMAP_4430SDP=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_32v6K=y +CONFIG_CPU_V7=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_PABRT_IFAR=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +# CONFIG_ARM_THUMBEE is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_HAS_TLS_REG=y +# CONFIG_ARM_ERRATA_430973 is not set +# CONFIG_ARM_ERRATA_458693 is not set +# CONFIG_ARM_ERRATA_460075 is not set +CONFIG_ARM_ERRATA_484863=y + +CONFIG_ARM_GIC=y +# CONFIG_OMAP_L2_EVENT_DEBUG is not set +CONFIG_OMAP4_SUDO_ROMCODE=y +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_SMP=y +CONFIG_HAVE_ARM_SCU=y +CONFIG_HAVE_ARM_TWD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_NR_CPUS=2 +# CONFIG_LOCAL_TIMERS is not set +# CONFIG_HOTPLUG_CPU is not set +# CONFIG_PREEMPT is not set +CONFIG_HZ=128 +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_HIGHMEM is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="root=/dev/ram0 rw mem=128M console=ttyS0,115200n8 initrd=0x81600000,20M ramdisk_size=20480 loglevel=1" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Power Management +# +# CONFIG_CPU_FREQ is not set +# CONFIG_CPU_IDLE is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_HAVE_AOUT=y +CONFIG_BINFMT_AOUT=y +CONFIG_BINFMT_MISC=y + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_NET=y + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_MTD is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=16384 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_MG_DISK is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_OMAP=y +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=32 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_DETECT_IRQ=y +CONFIG_SERIAL_8250_RSA=y + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_SPI=y +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y + +# CONFIG_DEBUG_GPIO is not set +# CONFIG_GPIO_SYSFS is not set + +# +# Memory mapped GPIO expanders: +# + +# +# I2C GPIO expanders: +# +CONFIG_I2C_OMAP=y +CONFIG_SPI_OMAP24XX=y +CONFIG_SPI_MASTER=y +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_THERMAL_HWMON is not set +CONFIG_WATCHDOG=y +CONFIG_OMAP_WATCHDOG=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set +CONFIG_SSB_POSSIBLE=y + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_MEDIA_SUPPORT is not set +CONFIG_TWL6030_CORE=y + +# +# Multimedia devices +# + +# +# Multimedia core support +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# +CONFIG_DAB=y + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_SOUND is not set +# CONFIG_HID_SUPPORT is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +CONFIG_USB_DEBUG=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +CONFIG_USB_MON=y +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_EHCI_HCD=m +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +CONFIG_USB_EHCI_OMAP=y +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HWA_HCD is not set +CONFIG_USB_MUSB_HDRC=y +CONFIG_USB_MUSB_SOC=y + +# +# OMAP 44xx high speed USB support +# +# CONFIG_USB_MUSB_HOST is not set +CONFIG_USB_MUSB_PERIPHERAL=y +# CONFIG_USB_MUSB_OTG is not set +CONFIG_USB_GADGET_MUSB_HDRC=y +CONFIG_MUSB_PIO_ONLY=y +CONFIG_USB_MUSB_DEBUG=y + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set + +# +# USB port drivers +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_VST is not set +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C_HSOTG is not set +# CONFIG_USB_GADGET_IMX is not set +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LANGWELL is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +CONFIG_USB_ZERO=m +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_GADGETFS is not set +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set + +# +# OTG and related infrastructure +# +CONFIG_USB_OTG_UTILS=y +# CONFIG_USB_GPIO_VBUS is not set +CONFIG_NOP_USB_XCEIV=y +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_OMAP is not set +CONFIG_MMC_OMAP_HS=y +# CONFIG_MMC_SPI is not set +# CONFIG_MEMSTICK is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_TWL=y +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +CONFIG_REGULATOR=y +# CONFIG_REGULATOR_DEBUG is not set +CONFIG_REGULATOR_TWL=y +# CONFIG_UIO is not set +# CONFIG_STAGING is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +# CONFIG_EXT3_FS_XATTR is not set +# CONFIG_EXT4_FS is not set +CONFIG_JBD=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +CONFIG_FILE_LOCKING=y +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_BTRFS_FS is not set +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +# CONFIG_INOTIFY is not set +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +# CONFIG_MISC_FILESYSTEMS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +CONFIG_FRAME_POINTER=y +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_ARM_UNWIND is not set +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_LL is not set +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_FIPS is not set +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=m +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=y +# CONFIG_CRC16 is not set +CONFIG_CRC_T10DIF=y +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=y +CONFIG_ZLIB_INFLATE=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index bfdc55202163..2b37bf90866d 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h @@ -399,6 +399,10 @@ static inline void __flush_icache_all(void) #ifdef CONFIG_ARM_ERRATA_411920 extern void v6_icache_inval_all(void); v6_icache_inval_all(); +#elif defined(CONFIG_SMP) && __LINUX_ARM_ARCH__ >= 7 + asm("mcr p15, 0, %0, c7, c1, 0 @ invalidate I-cache inner shareable\n" + : + : "r" (0)); #else asm("mcr p15, 0, %0, c7, c5, 0 @ invalidate I-cache\n" : diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index 85634c5ff183..11397687f42c 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h @@ -310,13 +310,8 @@ static inline pte_t pte_mkspecial(pte_t pte) { return pte; } /* * Mark the prot value as uncacheable and unbufferable. */ -#if __LINUX_ARM_ARCH__ >= 7 -#define pgprot_noncached(prot) \ - __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE) -#else #define pgprot_noncached(prot) \ __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED) -#endif #define pgprot_writecombine(prot) \ __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE) #if __LINUX_ARM_ARCH__ >= 7 diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h index c2f1605de359..a57ec73da99b 100644 --- a/arch/arm/include/asm/tlbflush.h +++ b/arch/arm/include/asm/tlbflush.h @@ -46,6 +46,9 @@ #define TLB_V7_UIS_FULL (1 << 20) #define TLB_V7_UIS_ASID (1 << 21) +/* Inner Shareable BTB operation (ARMv7 MP extensions) */ +#define TLB_V7_IS_BTB (1 << 22) + #define TLB_L2CLEAN_FR (1 << 29) /* Feroceon */ #define TLB_DCLEAN (1 << 30) #define TLB_WB (1 << 31) @@ -183,7 +186,7 @@ #endif #ifdef CONFIG_SMP -#define v7wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BTB | \ +#define v7wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_V7_IS_BTB | \ TLB_V7_UIS_FULL | TLB_V7_UIS_PAGE | TLB_V7_UIS_ASID) #else #define v7wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BTB | \ @@ -339,6 +342,12 @@ static inline void local_flush_tlb_all(void) dsb(); isb(); } + if (tlb_flag(TLB_V7_IS_BTB)) { + /* flush the branch target cache */ + asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc"); + dsb(); + isb(); + } } static inline void local_flush_tlb_mm(struct mm_struct *mm) @@ -376,6 +385,12 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm) asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); dsb(); } + if (tlb_flag(TLB_V7_IS_BTB)) { + /* flush the branch target cache */ + asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc"); + dsb(); + isb(); + } } static inline void @@ -416,6 +431,12 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); dsb(); } + if (tlb_flag(TLB_V7_IS_BTB)) { + /* flush the branch target cache */ + asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc"); + dsb(); + isb(); + } } static inline void local_flush_tlb_kernel_page(unsigned long kaddr) @@ -454,6 +475,12 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr) dsb(); isb(); } + if (tlb_flag(TLB_V7_IS_BTB)) { + /* flush the branch target cache */ + asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc"); + dsb(); + isb(); + } } /* diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index d43a5b17dcdf..2a42d220dcc5 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -219,9 +219,6 @@ void __ref cpu_die(void) { unsigned int cpu = smp_processor_id(); - /* FIXME: BUG: scheduling while atomic: swapper/0/0x00000002 */ - preempt_enable(); - local_irq_disable(); idle_task_exit(); @@ -229,6 +226,7 @@ void __ref cpu_die(void) * actual CPU shutdown procedure is at least platform (if not * CPU) specific */ + preempt_enable_no_resched(); platform_cpu_die(cpu); /* diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 10eafa70a909..cb446cb35468 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -81,6 +81,32 @@ config MACH_OMAP3EVM bool "OMAP 3530 EVM board" depends on ARCH_OMAP3 && ARCH_OMAP34XX +config WIFI_CONTROL_FUNC + bool "Enable WiFi control function abstraction" + depends on MACH_OMAP_4430SDP + select WIRELESS_EXT + select WEXT_CORE + select WEXT_PROC + select WEXT_PRIV + default Y + help + Enables Power/Reset/Carddetect function abstraction +config TIWLAN_SDIO + bool "TI WLAN Enhanced SDIO Contoller support" + depends on MMC_OMAP || MMC_OMAP_MODULE || MMC_OMAP_HS || MMC_OMAP_HS_MODULE + help + Say Y here if you want to be able to use TI's WLAN device using the + SDIO interface. If unsure, say N. +config TIWLAN_MMC_CONTROLLER + int "MMC Controller number that TI WLAN chip is connected to" + range 1 5 + depends on TIWLAN_SDIO + default "5" + help + Choose the number of the MMC controller that TI WLAN chip is + connected to. TI WLAN has SDIO host controller that will control + this MMC port. + config MACH_OMAP3517EVM bool "OMAP3517/ AM3517 EVM board" depends on ARCH_OMAP3 && ARCH_OMAP34XX diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 3f0efe25a839..ee6f5ce08b40 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -22,6 +22,9 @@ obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o obj-$(CONFIG_LOCAL_TIMERS) += timer-mpu.o obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o +obj-$(CONFIG_ARCH_OMAP4) += omap44xx-smc.o + +AFLAGS_omap44xx-smc.o :=-Wa,-march=armv7-a # Functions loaded to SRAM obj-$(CONFIG_ARCH_OMAP2420) += sram242x.o @@ -46,8 +49,7 @@ endif # PRCM obj-$(CONFIG_ARCH_OMAP2) += cm.o obj-$(CONFIG_ARCH_OMAP3) += cm.o -obj-$(CONFIG_ARCH_OMAP4) += cm4xxx.o voltage.o opp4xxx.o \ - cpuidle44xx.o pm44xx.o sleep44xx.o +obj-$(CONFIG_ARCH_OMAP4) += cm4xxx.o voltage.o opp4xxx.o cpuidle44xx.o pm44xx.o # Clock framework obj-$(CONFIG_ARCH_OMAP2) += clock2xxx.o clock2xxx_data.o @@ -64,7 +66,7 @@ mailbox_mach-objs := mailbox.o iommu-y += iommu2.o iommu-$(CONFIG_ARCH_OMAP3) += omap3-iommu.o - +iommu-$(CONFIG_ARCH_OMAP4) += omap4-iommu.o obj-$(CONFIG_OMAP_IOMMU) += $(iommu-y) i2c-omap-$(CONFIG_I2C_OMAP) := i2c.o @@ -112,6 +114,7 @@ obj-$(CONFIG_MACH_OMAP3_TOUCHBOOK) += board-omap3touchbook.o \ mmc-twl4030.o obj-$(CONFIG_MACH_OMAP_4430SDP) += board-4430sdp.o \ mmc-twl4030.o +obj-$(CONFIG_TIWLAN_SDIO) += board-4430sdp-wifi.o obj-$(CONFIG_MACH_OMAP3517EVM) += board-am3517evm.o diff --git a/arch/arm/mach-omap2/board-4430sdp-wifi.c b/arch/arm/mach-omap2/board-4430sdp-wifi.c new file mode 100755 index 000000000000..b13e9fc3767a --- /dev/null +++ b/arch/arm/mach-omap2/board-4430sdp-wifi.c @@ -0,0 +1,138 @@ +/* + * Board support file for containing WiFi specific details for OMAP4430 SDP. + * + * Copyright (C) 2009 Texas Instruments + * + * Author: Pradeep Gurumath <pradeepgurumath@ti.com> + * + * Based on mach-omap2/board-3430sdp.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. + */ + +/* linux/arch/arm/mach-omap2/board-4430sdp-wifi.c +*/ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/mmc/host.h> +#include <linux/mmc/sdio_ids.h> +#include <linux/err.h> + +#include <asm/gpio.h> +#include <asm/io.h> +#include <plat/wifi_tiwlan.h> + +#define SDP4430_WIFI_PMENA_GPIO 54 +#define SDP4430_WIFI_IRQ_GPIO 53 + +static int sdp4430_wifi_cd; /* WIFI virtual 'card detect' status */ +static void (*wifi_status_cb)(int card_present, void *dev_id); +static void *wifi_status_cb_devid; + +int omap_wifi_status_register(void (*callback)(int card_present, + void *dev_id), void *dev_id) +{ + if (wifi_status_cb) + return -EAGAIN; + wifi_status_cb = callback; + + wifi_status_cb_devid = dev_id; + + return 0; +} + +int omap_wifi_status(int irq) +{ + return sdp4430_wifi_cd; +} + +int sdp4430_wifi_set_carddetect(int val) +{ + printk(KERN_WARNING"%s: %d\n", __func__, val); + sdp4430_wifi_cd = val; + if (wifi_status_cb) + wifi_status_cb(val, wifi_status_cb_devid); + else + printk(KERN_WARNING "%s: Nobody to notify\n", __func__); + return 0; +} +#ifndef CONFIG_WIFI_CONTROL_FUNC +EXPORT_SYMBOL(sdp4430_wifi_set_carddetect); +#endif + +static int sdp4430_wifi_power_state; + +int sdp4430_wifi_power(int on) +{ + printk(KERN_WARNING"%s: %d\n", __func__, on); + gpio_set_value(SDP4430_WIFI_PMENA_GPIO, on); + sdp4430_wifi_power_state = on; + return 0; +} +#ifndef CONFIG_WIFI_CONTROL_FUNC +EXPORT_SYMBOL(sdp4430_wifi_power); +#endif + +static int sdp4430_wifi_reset_state; +int sdp4430_wifi_reset(int on) +{ + printk(KERN_WARNING"%s: %d\n", __func__, on); + sdp4430_wifi_reset_state = on; + return 0; +} +#ifndef CONFIG_WIFI_CONTROL_FUNC +EXPORT_SYMBOL(sdp4430_wifi_reset); +#endif + +struct wifi_platform_data sdp4430_wifi_control = { + .set_power = sdp4430_wifi_power, + .set_reset = sdp4430_wifi_reset, + .set_carddetect = sdp4430_wifi_set_carddetect, +}; + +#ifdef CONFIG_WIFI_CONTROL_FUNC +static struct resource sdp4430_wifi_resources[] = { + [0] = { + .name = "device_wifi_irq", + .start = OMAP_GPIO_IRQ(SDP4430_WIFI_IRQ_GPIO), + .end = OMAP_GPIO_IRQ(SDP4430_WIFI_IRQ_GPIO), + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, + }, +}; + +static struct platform_device sdp4430_wifi_device = { + .name = "device_wifi", + .id = 1, + .num_resources = ARRAY_SIZE(sdp4430_wifi_resources), + .resource = sdp4430_wifi_resources, + .dev = { + .platform_data = &sdp4430_wifi_control, + }, +}; +#endif + +static int __init sdp4430_wifi_init(void) +{ + int ret; + + printk(KERN_WARNING"%s: start\n", __func__); + ret = gpio_request(SDP4430_WIFI_IRQ_GPIO, "wifi_irq"); + if (ret < 0) { + printk(KERN_ERR "%s: can't reserve GPIO: %d\n", __func__, + SDP4430_WIFI_IRQ_GPIO); + goto out; + } + gpio_direction_input(SDP4430_WIFI_IRQ_GPIO); +#ifdef CONFIG_WIFI_CONTROL_FUNC + ret = platform_device_register(&sdp4430_wifi_device); +#endif +out: + return ret; +} + +device_initcall(sdp4430_wifi_init); diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index e4cb21cfd05b..f27705bff190 100755 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -47,8 +47,6 @@ #include <plat/omap_device.h> #include <plat/omap_hwmod.h> -static int ts_gpio; - #define OMAP4_KBDOCP_BASE 0x4A31C000 static int omap_keymap[] = { @@ -191,12 +189,14 @@ static struct tm12xx_ts_platform_data tm12xx_platform_data[] = { /* End Synaptic Touchscreen TM-01217 */ -static struct omap2_mcspi_device_config tsc2046_mcspi_config = { +static __attribute__ ((unused)) struct + omap2_mcspi_device_config tsc2046_mcspi_config = { .turbo_mode = 0, .single_channel = 1, /* 0: slave, 1: master */ }; -static struct omap2_mcspi_device_config dummy1_mcspi_config = { +static __attribute__ ((unused)) struct + omap2_mcspi_device_config dummy1_mcspi_config = { .turbo_mode = 0, .single_channel = 1, /* 0: slave, 1: master */ }; @@ -487,7 +487,8 @@ static struct platform_device *sdp4430_devices[] __initdata = { &omap_kp_device, }; -static struct omap_uart_config sdp4430_uart_config __initdata = { +static __attribute__ ((unused)) struct + omap_uart_config sdp4430_uart_config __initdata = { .enabled_uarts = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3), }; @@ -559,6 +560,13 @@ static int __init sdp4430_mmc_init(void) /* TODO: Fix Hard Coding */ mmc[0].gpio_cd = 384 ; +#ifdef CONFIG_TIWLAN_SDIO + /* The controller that is connected to the 128x device + should have the card detect gpio disabled. This is + achieved by initializing it with a negative value */ + mmc[CONFIG_TIWLAN_MMC_CONTROLLER - 1].gpio_cd = -EINVAL; +#endif + twl4030_mmc_init(mmc); /* link regulators to MMC adapters ... we "know" the * regulators will be set up only *after* we return. @@ -574,22 +582,15 @@ static int __init sdp4430_mmc_init(void) #ifdef CONFIG_CACHE_L2X0 static int __init omap_l2_cache_init(void) { + extern void omap_smc1(u32 fn, u32 arg); void __iomem *l2cache_base; /* Static mapping, never released */ l2cache_base = ioremap(OMAP44XX_L2CACHE_BASE, SZ_4K); BUG_ON(!l2cache_base); - /* Enable L2 Cache using secure api - * Save/Restore relevant registers - */ - __asm__ __volatile__( - "stmfd r13!, {r0-r12, r14}\n" - "mov r0, #1\n" - "ldr r12, =0x102\n" - "dsb\n" - "smc\n" - "ldmfd r13!, {r0-r12, r14}"); + /* Enable PL310 L2 Cache controller */ + omap_smc1(0x102, 0x1); /* 32KB way size, 16-way associativity, * parity disabled @@ -679,7 +680,7 @@ static struct regulator_init_data sdp4430_vmmc = { | REGULATOR_CHANGE_STATUS, }, .num_consumer_supplies = 5, - .consumer_supplies = &sdp4430_vmmc_supply, + .consumer_supplies = sdp4430_vmmc_supply, }; static struct regulator_init_data sdp4430_vpp = { @@ -785,6 +786,19 @@ static struct regulator_init_data sdp4430_vusb = { }, }; +static struct twl4030_codec_data twl6040_codec = { +#ifdef CONFIG_OMAP4_AUDIO_PWRON + .audpwron_gpio = 127, + .naudint_irq = INT_44XX_SYS_NIRQ2, +#else + /* provide GPIO number above the valid value + * to mean there is no GPIO connected, + * likewise do not provide any valid IRQ number */ + .audpwron_gpio = 1024, + .naudint_irq = 0, +#endif +}; + static struct twl4030_madc_platform_data sdp4430_gpadc_data = { .irq_line = 1, }; @@ -809,6 +823,9 @@ static struct twl4030_platform_data sdp4430_twldata = { .vaux3 = &sdp4430_vaux3, .madc = &sdp4430_gpadc_data, .bci = &sdp4430_bci_data, + + /* children */ + .codec = &twl6040_codec, }; static struct pico_platform_data picodlp_platform_data[] = { @@ -853,6 +870,7 @@ static int __init omap4_i2c_init(void) ARRAY_SIZE(sdp4430_i2c_2_boardinfo)); omap_register_i2c_bus(3, 400, sdp4430_i2c_3_boardinfo, ARRAY_SIZE(sdp4430_i2c_3_boardinfo)); + omap_register_i2c_bus(4, 400, 0, 0); return 0; } @@ -895,6 +913,37 @@ static void omap_ethernet_init(void) gpio_direction_input(34); } +#ifdef CONFIG_TIWLAN_SDIO +static void pad_config(unsigned long pad_addr, u32 andmask, u32 ormask) +{ + int val; + u32 *addr; + + addr = (u32 *) ioremap(pad_addr, 4); + if (!addr) { + printk(KERN_ERR"OMAP_pad_config: ioremap failed with addr %lx\n", + pad_addr); + return; + } + + val = __raw_readl(addr); + val &= andmask; + val |= ormask; + __raw_writel(val, addr); + + iounmap(addr); +} + +void wlan_1283_config() +{ + pad_config(0x4A100078, 0xFFECFFFF, 0x00030000); + pad_config(0x4A10007C, 0xFFFFFFEF, 0x0000000B); + if (gpio_request(54, NULL) != 0) + printk(KERN_ERR "GPIO 54 request failed\n"); + gpio_direction_output(54, 0); + return ; +} +#endif static void __init omap_4430sdp_init(void) { omap4_i2c_init(); @@ -902,6 +951,10 @@ static void __init omap_4430sdp_init(void) omap_serial_init(); /* OMAP4 SDP uses internal transceiver so register nop transceiver */ sdp4430_mmc_init(); + +#ifdef CONFIG_TIWLAN_SDIO + wlan_1283_config(); +#endif usb_nop_xceiv_register(); usb_musb_init(&musb_board_data); omap_ethernet_init(); diff --git a/arch/arm/mach-omap2/cm.c b/arch/arm/mach-omap2/cm.c index 58e4a1c557d8..2d83565d2be2 100644 --- a/arch/arm/mach-omap2/cm.c +++ b/arch/arm/mach-omap2/cm.c @@ -27,9 +27,6 @@ #include "cm-regbits-24xx.h" #include "cm-regbits-34xx.h" -/* MAX_MODULE_READY_TIME: max milliseconds for module to leave idle */ -#define MAX_MODULE_READY_TIME 20000 - static const u8 cm_idlest_offs[] = { CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3 }; diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h index 4e4ac8ccd7f5..99be5cf4c4d7 100644 --- a/arch/arm/mach-omap2/cm.h +++ b/arch/arm/mach-omap2/cm.h @@ -112,7 +112,7 @@ extern u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx); extern int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift); -extern int omap4_cm_wait_module_ready(u32 prcm_mod, u8 prcm_dev_offs); +extern int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg); static inline u32 cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx) { @@ -139,5 +139,7 @@ static inline u32 cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) /* CM_IDLEST_GFX */ #define OMAP_ST_GFX (1 << 0) +/* MAX_MODULE_READY_TIME: max milliseconds for module to leave idle */ +#define MAX_MODULE_READY_TIME 20000 #endif diff --git a/arch/arm/mach-omap2/cm4xxx.c b/arch/arm/mach-omap2/cm4xxx.c index 4af76bb1003a..b101091e95d6 100644 --- a/arch/arm/mach-omap2/cm4xxx.c +++ b/arch/arm/mach-omap2/cm4xxx.c @@ -21,35 +21,41 @@ #include <asm/atomic.h> -#include "cm.h" - -/* XXX move this to cm.h */ -/* MAX_MODULE_READY_TIME: max milliseconds for module to leave idle */ -#define MAX_MODULE_READY_TIME 20000 +#include <plat/common.h> -/* - * OMAP4_PRCM_CM_CLKCTRL_IDLEST_MASK: isolates the IDLEST field in the - * CM_CLKCTRL register. - */ -#define OMAP4_PRCM_CM_CLKCTRL_IDLEST_MASK (0x2 << 16) - -/* - * OMAP4 prcm_mod u32 fields contain packed data: the CM ID in bit 16 and - * the PRCM module offset address (from the CM module base) in bits 15-0. - */ -#define OMAP4_PRCM_MOD_CM_ID_SHIFT 16 -#define OMAP4_PRCM_MOD_OFFS_MASK 0xffff +#include "cm.h" +#include "cm-regbits-44xx.h" /** - * omap4_cm_wait_idlest_ready - wait for a module to leave idle or standby - * @prcm_mod: PRCM module offset (XXX example) - * @prcm_dev_offs: PRCM device offset (e.g. MCASP XXX example) + * omap4_cm_wait_module_ready - wait for a module to be in 'func' state + * @clkctrl_reg: CLKCTRL module address + * + * Wait for the module IDLEST to be functional. If the idle state is in any + * the non functional state (trans, idle or disabled), module and thus the + * sysconfig cannot be accessed and will probably lead to an "imprecise + * external abort" + * + * Module idle state: + * 0x0 func: Module is fully functional, including OCP + * 0x1 trans: Module is performing transition: wakeup, or sleep, or sleep + * abortion + * 0x2 idle: Module is in Idle mode (only OCP part). It is functional if + * using separate functional clock + * 0x3 disabled: Module is disabled and cannot be accessed * - * XXX document + * TODO: Need to handle module accessible in idle state */ -int omap4_cm_wait_idlest_ready(u32 prcm_mod, u8 prcm_dev_offs) +int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg) { - /* FIXME: Add clock manager related code */ - return 0; + int i = 0; + + if (!clkctrl_reg) + return 0; + + omap_test_timeout(((__raw_readl(clkctrl_reg) & + OMAP4430_IDLEST_MASK) == 0), + MAX_MODULE_READY_TIME, i); + + return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; } diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c index 0d1bddff4d20..8a9adcd24eb4 100644 --- a/arch/arm/mach-omap2/cpuidle44xx.c +++ b/arch/arm/mach-omap2/cpuidle44xx.c @@ -27,10 +27,10 @@ #define OMAP4_STATE_C2 1 /* C2 - CPU0 CSWR + CPU1 OFF + MPU CSWR + Core active */ #define OMAP4_STATE_C3 2 /* C3 - CPU0 CSWR + CPU1 OFF + MPU CSWR + Core CSWR */ -extern int (*_omap_sram_idle)(void); - #define wfi() \ { \ + isb(); \ + wmb(); \ __asm__ __volatile__ ("wfi"); \ } @@ -77,7 +77,7 @@ static int omap4_enter_idle(struct cpuidle_device *dev, { struct omap4_processor_cx *cx = cpuidle_get_statedata(state); struct timespec ts_preidle, ts_postidle, ts_idle; - u32 scu_pwr_st; + u32 scu_pwr_st, cpu1_state; /* Used to keep track of the total time in idle */ getnstimeofday(&ts_preidle); @@ -88,8 +88,10 @@ static int omap4_enter_idle(struct cpuidle_device *dev, goto return_sleep_time; } - /* Do only a wfi as long as any other core is active */ - if (num_online_cpus() > 1) { + /* Make sure cpu1 is offlined before cpu0 idle's */ + cpu1_state = pwrdm_read_pwrst(cpu1_pd); + /* Do only a wfi as long as CPU1 is not in RET/OFF */ + if (cpu1_state > PWRDM_POWER_RET) { wfi(); goto return_sleep_time; } @@ -111,10 +113,7 @@ static int omap4_enter_idle(struct cpuidle_device *dev, } pwrdm_set_next_pwrst(core_pd, cx->core_state); - if (_omap_sram_idle) - _omap_sram_idle(); - else - wfi(); + wfi(); if (cx->core_state < PWRDM_POWER_ON) { omap2_gpio_resume_after_retention(); diff --git a/arch/arm/mach-omap2/dmtimers.c b/arch/arm/mach-omap2/dmtimers.c index e5f8db1cbf1b..509b8cb37802 100644 --- a/arch/arm/mach-omap2/dmtimers.c +++ b/arch/arm/mach-omap2/dmtimers.c @@ -248,6 +248,12 @@ void __init omap2_dm_timer_early_init(void) pdata = kzalloc(sizeof(struct omap_dm_timer_plat_info), GFP_KERNEL); + if (!pdata) { + WARN("gptimer%d :Memory allocation failed\n" + , i+1); + return; + } + pdata->omap_dm_clk_enable = omap2_dm_timer_enable; pdata->omap_dm_clk_disable = omap2_dm_timer_disable; pdata->omap_dm_set_source_clk = omap2_dm_timer_set_clk; @@ -397,6 +403,12 @@ fail: pdata = kzalloc(sizeof(struct omap_dm_timer_plat_info), GFP_KERNEL); + if (!pdata) { + WARN("gptimer%d :Memory allocation failed\n" + , i+1); + return; + } + pdata->omap_dm_clk_enable = omap2_dm_timer_enable; pdata->omap_dm_clk_disable = omap2_dm_timer_disable; pdata->omap_dm_set_source_clk = omap2_dm_timer_set_clk; diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c index 826861e88ea7..7dc8e0ce92c5 100644 --- a/arch/arm/mach-omap2/gpio.c +++ b/arch/arm/mach-omap2/gpio.c @@ -66,8 +66,6 @@ static inline struct gpio_bank *get_gpio_bank(int gpio) { if (cpu_is_omap24xx() || cpu_is_omap34xx() || cpu_is_omap44xx()) return &gpio_bank[gpio >> 5]; - BUG(); - return -EINVAL; } static inline int get_gpio_index(int gpio) @@ -172,7 +170,12 @@ static int _get_gpio_dataout(struct gpio_bank *bank, int gpio) return -EINVAL; reg = bank->base; - reg += OMAP24XX_GPIO_DATAOUT; + if (cpu_is_omap24xx() || cpu_is_omap34xx()) + reg += OMAP24XX_GPIO_DATAOUT; + else if (cpu_is_omap44xx()) + reg += OMAP4_GPIO_DATAOUT; + else + return -EINVAL; return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0; } @@ -514,11 +517,21 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset) _set_gpio_triggering(bank, offset, IRQ_TYPE_NONE); if (!bank->mod_usage) { + void __iomem *reg = bank->base; u32 ctrl; - ctrl = __raw_readl(bank->base + OMAP24XX_GPIO_CTRL); + + if (cpu_is_omap24xx() || cpu_is_omap34xx()) + reg += OMAP24XX_GPIO_CTRL; + else if (cpu_is_omap44xx()) + reg += OMAP4_GPIO_CTRL; + else { + spin_unlock_irqrestore(&bank->lock, flags); + return -EINVAL; + } + ctrl = __raw_readl(reg); ctrl &= 0xFFFFFFFE; /* Module is enabled, clocks are not gated */ - __raw_writel(ctrl, bank->base + OMAP24XX_GPIO_CTRL); + __raw_writel(ctrl, reg); } bank->mod_usage |= 1 << offset; @@ -534,18 +547,34 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) spin_lock_irqsave(&bank->lock, flags); { - /* Disable wake-up during idle for dynamic tick */ - void __iomem *reg = bank->base + OMAP24XX_GPIO_CLEARWKUENA; - __raw_writel(1 << offset, reg); + if (cpu_is_omap24xx() || cpu_is_omap34xx()) { + /* Disable wake-up during idle for dynamic tick */ + void __iomem *reg = bank->base + + OMAP24XX_GPIO_CLEARWKUENA; + __raw_writel(1 << offset, reg); + } else if (cpu_is_omap44xx()) { + /* Disable wake-up during idle for dynamic tick */ + void __iomem *reg = bank->base + OMAP4_GPIO_IRQWAKEN0; + __raw_writel(1 << offset, reg); + } else { + spin_lock_irqsave(&bank->lock, flags); + return -EINVAL; + } } bank->mod_usage &= ~(1 << offset); if (!bank->mod_usage) { + void __iomem *reg = bank->base; u32 ctrl; - ctrl = __raw_readl(bank->base + OMAP24XX_GPIO_CTRL); + + if (cpu_is_omap24xx() || cpu_is_omap34xx()) + reg += OMAP24XX_GPIO_CTRL; + else if (cpu_is_omap44xx()) + reg += OMAP4_GPIO_CTRL; + ctrl = __raw_readl(reg); /* Module is disabled, clocks are gated */ ctrl |= 1; - __raw_writel(ctrl, bank->base + OMAP24XX_GPIO_CTRL); + __raw_writel(ctrl, reg); } _reset_gpio(bank, bank->chip.base + offset); @@ -699,7 +728,12 @@ static int gpio_is_input(struct gpio_bank *bank, int mask) { void __iomem *reg = bank->base; - reg += OMAP24XX_GPIO_OE; + if (cpu_is_omap24xx() || cpu_is_omap34xx()) + reg += OMAP24XX_GPIO_OE; + else if (cpu_is_omap44xx()) + reg += OMAP4_GPIO_OE; + else + return -EINVAL; return __raw_readl(reg) & mask; } @@ -882,7 +916,7 @@ void omap2_gpio_prepare_for_retention(void) bank->saved_risingdetect = l2; l1 &= ~bank->enabled_non_wakeup_gpios; l2 &= ~bank->enabled_non_wakeup_gpios; - if (cpu_is_omap24xx()) { + if (cpu_is_omap24xx() || cpu_is_omap34xx()) { __raw_writel(l1, bank->base + OMAP24XX_GPIO_FALLINGDETECT); __raw_writel(l2, bank->base + @@ -1065,12 +1099,14 @@ void omap_gpio_restore_context(void) static int __devexit omap_gpio_remove(struct platform_device *pdev) { - struct omap_gpio_platform_data *pdata = pdev->dev.platform_data; + struct omap_gpio_platform_data *pdata; struct gpio_bank *bank; int id; - if (!pdev || !pdata) - return 0; + if (!pdev || !pdev->dev.platform_data) + return -EINVAL; + + pdata = pdev->dev.platform_data; id = pdev->id; if (id > gpio_bank_count) @@ -1086,16 +1122,17 @@ static int __devexit omap_gpio_remove(struct platform_device *pdev) static int __devinit omap_gpio_probe(struct platform_device *pdev) { static int show_rev_once; - struct omap_gpio_platform_data *pdata = pdev->dev.platform_data; + struct omap_gpio_platform_data *pdata; struct gpio_bank *bank; int id, i; - if (!pdev || !pdata) { + if (!pdev || !pdev->dev.platform_data) { pr_err("GPIO device initialize without" "platform data\n"); return -EINVAL; } + pdata = pdev->dev.platform_data; gpio_bank_count = OMAP_NR_GPIOS; #ifdef CONFIG_ARCH_OMAP2 if (cpu_is_omap242x()) @@ -1103,7 +1140,7 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) #endif id = pdev->id; - if (id > gpio_bank_count) { + if (id >= gpio_bank_count) { pr_err("Invalid GPIO device id (%d)\n", id); return -EINVAL; } @@ -1232,6 +1269,11 @@ void __init omap_gpio_early_init(void) pdata = kzalloc(sizeof(struct omap_gpio_platform_data), GFP_KERNEL); + if (!pdata) { + WARN("Memory allocation failed gpio%d \n", i + 1); + return; + } + pdata->base = oh->_rt_va; pdata->irq = oh->mpu_irqs[0].irq; pdata->virtual_irq_start = IH_GPIO_BASE + 32 * i; @@ -1272,11 +1314,16 @@ int __init omap_init_gpio(void) oh = omap_hwmod_lookup(oh_name); if (!oh) { pr_err("Could not look up %s\n", oh_name); + i++; continue; } pdata = kzalloc(sizeof(struct omap_gpio_platform_data), GFP_KERNEL); + if (!pdata) { + WARN("Memory allocation failed gpio%d \n", i + 1); + return; + } pdata->base = oh->_rt_va; pdata->irq = oh->mpu_irqs[0].irq; pdata->virtual_irq_start = IH_GPIO_BASE + 32 * i; diff --git a/arch/arm/mach-omap2/i2c.c b/arch/arm/mach-omap2/i2c.c index 1e456219d326..844342bfcdfc 100644 --- a/arch/arm/mach-omap2/i2c.c +++ b/arch/arm/mach-omap2/i2c.c @@ -43,8 +43,10 @@ int __init omap2_i2c_nr_ports(void) if (cpu_is_omap24xx()) ports = 2; - else if (cpu_is_omap34xx() || cpu_is_omap44xx()) + else if (cpu_is_omap34xx()) ports = 3; + else if (cpu_is_omap44xx()) + ports = 4; return ports; } diff --git a/arch/arm/mach-omap2/include/mach/dmm.h b/arch/arm/mach-omap2/include/mach/dmm.h index 2ad6c325ee5b..a3adddbf9fd6 100644 --- a/arch/arm/mach-omap2/include/mach/dmm.h +++ b/arch/arm/mach-omap2/include/mach/dmm.h @@ -113,4 +113,16 @@ u32 dmm_get_page(void); */ void dmm_free_page(u32 page_addr); +/** + * Request a set of pages from the DMM free page stack. + * @return a pointer to a list of physical page addresses. + */ +u32 *dmm_get_pages(s32 n); + +/** + * Return a set of used pages to the DMM free page stack. + * @param list a pointer to a list of physical page addresses. + */ +void dmm_free_pages(u32 *list); + #endif diff --git a/arch/arm/mach-omap2/include/mach/tiler.h b/arch/arm/mach-omap2/include/mach/tiler.h index b8adf1439b6f..b8adf1439b6f 100755..100644 --- a/arch/arm/mach-omap2/include/mach/tiler.h +++ b/arch/arm/mach-omap2/include/mach/tiler.h diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 47f68a41ab84..8a1b61208e5a 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -280,7 +280,7 @@ void __init omap2_map_common_io(void) * -EINVAL if the dpll3_m2_ck cannot be found, 0 if called on OMAP2, * or passes along the return value of clk_set_rate(). */ -static int __init _omap2_init_reprogram_sdrc(void) +static int __attribute__ ((unused)) __init _omap2_init_reprogram_sdrc(void) { struct clk *dpll3_m2_ck; int v = -EINVAL; diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c index 6f4b7cc8f4d1..2735bd769890 100644 --- a/arch/arm/mach-omap2/iommu2.c +++ b/arch/arm/mach-omap2/iommu2.c @@ -146,6 +146,8 @@ static u32 omap2_iommu_fault_isr(struct iommu *obj, u32 *ra) printk("\n"); iommu_write_reg(obj, stat, MMU_IRQSTATUS); + /* Disable MMU to stop continuous generation of MMU faults */ + omap2_iommu_disable(obj); return stat; } @@ -183,7 +185,7 @@ static struct cr_regs *omap2_alloc_cr(struct iommu *obj, struct iotlb_entry *e) if (!cr) return ERR_PTR(-ENOMEM); - cr->cam = (e->da & MMU_CAM_VATAG_MASK) | e->prsvd | e->pgsz; + cr->cam = (e->da & MMU_CAM_VATAG_MASK) | e->prsvd | e->pgsz | e->valid; cr->ram = e->pa | e->endian | e->elsz | e->mixed; return cr; @@ -211,7 +213,8 @@ static ssize_t omap2_dump_cr(struct iommu *obj, struct cr_regs *cr, char *buf) char *p = buf; /* FIXME: Need more detail analysis of cam/ram */ - p += sprintf(p, "%08x %08x\n", cr->cam, cr->ram); + p += sprintf(p, "%08x %08x %01x\n", cr->cam, cr->ram, + (cr->cam & MMU_CAM_P) ? 1 : 0); return p - buf; } diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c index 281ab6342448..55ea58e74f94 100644..100755 --- a/arch/arm/mach-omap2/mailbox.c +++ b/arch/arm/mach-omap2/mailbox.c @@ -40,6 +40,10 @@ #define AUTOIDLE (1 << 0) #define SOFTRESET (1 << 1) #define SMARTIDLE (2 << 3) +#define OMAP4_SOFTRESET (1 << 0) +#define OMAP4_SMARTIDLE (2 << 2) +#define OMAP4_NOIDLE (1 << 2) + /* SYSSTATUS: register bit definition */ #define RESETDONE (1 << 0) @@ -91,32 +95,54 @@ static int omap2_mbox_startup(struct omap_mbox *mbox) u32 l; unsigned long timeout; - mbox_ick_handle = clk_get(NULL, "mailboxes_ick"); - if (IS_ERR(mbox_ick_handle)) { - printk(KERN_ERR "Could not get mailboxes_ick: %d\n", - PTR_ERR(mbox_ick_handle)); - return PTR_ERR(mbox_ick_handle); + if (!cpu_is_omap44xx()) { + mbox_ick_handle = clk_get(NULL, "mailboxes_ick"); + if (IS_ERR(mbox_ick_handle)) { + printk(KERN_ERR "Could not get mailboxes_ick: %ld\n", + PTR_ERR(mbox_ick_handle)); + return PTR_ERR(mbox_ick_handle); + } + clk_enable(mbox_ick_handle); } - clk_enable(mbox_ick_handle); - - mbox_write_reg(SOFTRESET, MAILBOX_SYSCONFIG); - timeout = jiffies + msecs_to_jiffies(20); - do { - l = mbox_read_reg(MAILBOX_SYSSTATUS); - if (l & RESETDONE) - break; - } while (!time_after(jiffies, timeout)); - - if (!(l & RESETDONE)) { - pr_err("Can't take mmu out of reset\n"); - return -ENODEV; + + if (cpu_is_omap44xx()) { + mbox_write_reg(OMAP4_SOFTRESET, MAILBOX_SYSCONFIG); + timeout = jiffies + msecs_to_jiffies(20); + do { + l = mbox_read_reg(MAILBOX_SYSCONFIG); + if (!(l & OMAP4_SOFTRESET)) + break; + } while (!time_after(jiffies, timeout)); + + if (l & OMAP4_SOFTRESET) { + pr_err("Can't take mailbox out of reset\n"); + return -ENODEV; + } + } else { + mbox_write_reg(SOFTRESET, MAILBOX_SYSCONFIG); + timeout = jiffies + msecs_to_jiffies(20); + do { + l = mbox_read_reg(MAILBOX_SYSSTATUS); + if (l & RESETDONE) + break; + } while (!time_after(jiffies, timeout)); + + if (!(l & RESETDONE)) { + pr_err("Can't take mailbox out of reset\n"); + return -ENODEV; + } } l = mbox_read_reg(MAILBOX_REVISION); pr_info("omap mailbox rev %d.%d\n", (l & 0xf0) >> 4, (l & 0x0f)); - l = SMARTIDLE | AUTOIDLE; - mbox_write_reg(l, MAILBOX_SYSCONFIG); + if (cpu_is_omap44xx()) { + l = OMAP4_NOIDLE; /* TODO: Change to SMARTIDLE */ + mbox_write_reg(l, MAILBOX_SYSCONFIG); + } else { + l = SMARTIDLE | AUTOIDLE; + mbox_write_reg(l, MAILBOX_SYSCONFIG); + } omap2_mbox_enable_irq(mbox, IRQ_RX); @@ -125,9 +151,11 @@ static int omap2_mbox_startup(struct omap_mbox *mbox) static void omap2_mbox_shutdown(struct omap_mbox *mbox) { - clk_disable(mbox_ick_handle); - clk_put(mbox_ick_handle); - mbox_ick_handle = NULL; + if (!cpu_is_omap44xx()) { + clk_disable(mbox_ick_handle); + clk_put(mbox_ick_handle); + mbox_ick_handle = NULL; + } } /* Mailbox FIFO handle functions */ @@ -419,8 +447,10 @@ static int __devinit omap2_mbox_probe(struct platform_device *pdev) #endif return 0; +#if defined(CONFIG_ARCH_OMAP2420) /* IVA */ err_iva1: omap_mbox_unregister(&mbox_dsp_info); +#endif err_dsp: iounmap(mbox_base); diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c index baa451733850..524bb7dc9769 100644 --- a/arch/arm/mach-omap2/mcbsp.c +++ b/arch/arm/mach-omap2/mcbsp.c @@ -15,6 +15,7 @@ #include <linux/clk.h> #include <linux/err.h> #include <linux/io.h> +#include <linux/delay.h> #include <linux/platform_device.h> #include <mach/irqs.h> @@ -22,6 +23,21 @@ #include <plat/mux.h> #include <plat/cpu.h> #include <plat/mcbsp.h> +#include <plat/dma.h> + +#define OMAP_MCBSP_READ(base, reg) \ + omap_mcbsp_read(base, OMAP_MCBSP_REG_##reg) +#define OMAP_MCBSP_WRITE(base, reg, val) \ + omap_mcbsp_write(base, OMAP_MCBSP_REG_##reg, val) + +struct omap_mcbsp_reg_cfg mcbsp_cfg = {0}; + +struct mcbsp_internal_clk { + struct clk clk; + struct clk **childs; + int n_childs; +}; + static void omap2_mcbsp2_mux_setup(void) { @@ -209,8 +225,830 @@ static struct omap_mcbsp_platform_data omap44xx_mcbsp_pdata[] = { }; #define OMAP44XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap44xx_mcbsp_pdata) +static void omap2_mcbsp_free(unsigned int id) +{ + struct omap_mcbsp *mcbsp = mcbsp_ptr[id]; + + if (!cpu_is_omap2420()) { + if (mcbsp->dma_rx_lch != -1) { + omap_free_dma_chain(mcbsp->dma_rx_lch); + mcbsp->dma_rx_lch = -1; + } + + if (mcbsp->dma_tx_lch != -1) { + omap_free_dma_chain(mcbsp->dma_tx_lch); + mcbsp->dma_tx_lch = -1; + } + } + return; +} +void omap2_mcbsp_config(unsigned int id, + const struct omap_mcbsp_reg_cfg *config) +{ + struct omap_mcbsp *mcbsp; + void __iomem *io_base; + mcbsp = id_to_mcbsp_ptr(id); + io_base = mcbsp->io_base; + OMAP_MCBSP_WRITE(io_base, XCCR, config->xccr); + OMAP_MCBSP_WRITE(io_base, RCCR, config->rccr); +} + +static void omap2_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data) +{ + struct omap_mcbsp *mcbsp_dma_rx = data; + void __iomem *io_base; + io_base = mcbsp_dma_rx->io_base; + + + + /* If we are at the last transfer, Shut down the reciever */ + if ((mcbsp_dma_rx->auto_reset & OMAP_MCBSP_AUTO_RRST) + && (omap_dma_chain_status(mcbsp_dma_rx->dma_rx_lch) == + OMAP_DMA_CHAIN_INACTIVE)) + OMAP_MCBSP_WRITE(io_base, SPCR1, + OMAP_MCBSP_READ(io_base, SPCR1) & (~RRST)); + + if (mcbsp_dma_rx->rx_callback != NULL) + mcbsp_dma_rx->rx_callback(ch_status, mcbsp_dma_rx->rx_cb_arg); + +} + +static void omap2_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data) +{ + struct omap_mcbsp *mcbsp_dma_tx = data; + void __iomem *io_base; + io_base = mcbsp_dma_tx->io_base; + + /* If we are at the last transfer, Shut down the Transmitter */ + if ((mcbsp_dma_tx->auto_reset & OMAP_MCBSP_AUTO_XRST) + && (omap_dma_chain_status(mcbsp_dma_tx->dma_tx_lch) == + OMAP_DMA_CHAIN_INACTIVE)) + OMAP_MCBSP_WRITE(io_base, SPCR2, + OMAP_MCBSP_READ(io_base, SPCR2) & (~XRST)); + + if (mcbsp_dma_tx->tx_callback != NULL) + mcbsp_dma_tx->tx_callback(ch_status, mcbsp_dma_tx->tx_cb_arg); +} + +/* + * Enable/Disable the sample rate generator + * id : McBSP interface ID + * state : Enable/Disable + */ +void omap2_mcbsp_set_srg_fsg(unsigned int id, u8 state) +{ + struct omap_mcbsp *mcbsp = mcbsp_ptr[id]; + void __iomem *io_base; + + io_base = mcbsp->io_base; + + if (state == OMAP_MCBSP_DISABLE_FSG_SRG) { + OMAP_MCBSP_WRITE(io_base, SPCR2, + OMAP_MCBSP_READ(io_base, SPCR2) & (~GRST)); + OMAP_MCBSP_WRITE(io_base, SPCR2, + OMAP_MCBSP_READ(io_base, SPCR2) & (~FRST)); + } else { + OMAP_MCBSP_WRITE(io_base, SPCR2, + OMAP_MCBSP_READ(io_base, SPCR2) | GRST); + OMAP_MCBSP_WRITE(io_base, SPCR2, + OMAP_MCBSP_READ(io_base, SPCR2) | FRST); + } + return; +} + +/* + * Stop transmitting data on a McBSP interface + * id : McBSP interface ID + */ +int omap2_mcbsp_stop_datatx(unsigned int id) +{ + struct omap_mcbsp *mcbsp = mcbsp_ptr[id]; + void __iomem *io_base; + + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); + return -ENODEV; + } + + io_base = mcbsp->io_base; + + if (mcbsp->dma_tx_lch != -1) { + if (omap_stop_dma_chain_transfers(mcbsp->dma_tx_lch) != 0) + return -EINVAL; + } + mcbsp->tx_dma_chain_state = 0; + OMAP_MCBSP_WRITE(io_base, SPCR2, + OMAP_MCBSP_READ(io_base, SPCR2) & (~XRST)); + + if (!mcbsp->rx_dma_chain_state) + omap2_mcbsp_set_srg_fsg(id, OMAP_MCBSP_DISABLE_FSG_SRG); + + return 0; +} +EXPORT_SYMBOL(omap2_mcbsp_stop_datatx); + +/* + * Stop receving data on a McBSP interface + * id : McBSP interface ID + */ +int omap2_mcbsp_stop_datarx(u32 id) +{ + struct omap_mcbsp *mcbsp = mcbsp_ptr[id]; + void __iomem *io_base; + + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); + return -ENODEV; + } + + io_base = mcbsp->io_base; + + if (mcbsp->dma_rx_lch != -1) { + if (omap_stop_dma_chain_transfers(mcbsp->dma_rx_lch) != 0) + return -EINVAL; + } + OMAP_MCBSP_WRITE(io_base, SPCR1, + OMAP_MCBSP_READ(io_base, SPCR1) & (~RRST)); + + mcbsp->rx_dma_chain_state = 0; + if (!mcbsp->tx_dma_chain_state) + omap2_mcbsp_set_srg_fsg(id, OMAP_MCBSP_DISABLE_FSG_SRG); + + return 0; +} +EXPORT_SYMBOL(omap2_mcbsp_stop_datarx); + +/* + * Get the element index and frame index of transmitter + * id : McBSP interface ID + * ei : element index + * fi : frame index + */ +int omap2_mcbsp_transmitter_index(int id, int *ei, int *fi) +{ + struct omap_mcbsp *mcbsp = mcbsp_ptr[id]; + int eix = 0, fix = 0; + + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); + return -ENODEV; + } + + if ((!ei) || (!fi)) { + printk(KERN_ERR "OMAP_McBSP: Invalid ei and fi params \n"); + goto txinx_err; + } + + if (mcbsp->dma_tx_lch == -1) { + printk(KERN_ERR "OMAP_McBSP: Transmitter not started\n"); + goto txinx_err; + } + + if (omap_get_dma_chain_index + (mcbsp->dma_tx_lch, &eix, &fix) != 0) { + printk(KERN_ERR "OMAP_McBSP: Getting chain index failed\n"); + goto txinx_err; + } + + *ei = eix; + *fi = fix; + + return 0; + +txinx_err: + return -EINVAL; +} +EXPORT_SYMBOL(omap2_mcbsp_transmitter_index); +/* + * Get the element index and frame index of receiver + * id : McBSP interface ID + * ei : element index + * fi : frame index + */ +int omap2_mcbsp_receiver_index(int id, int *ei, int *fi) +{ + struct omap_mcbsp *mcbsp = mcbsp_ptr[id]; + int eix = 0, fix = 0; + + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); + return -ENODEV; + } + + if ((!ei) || (!fi)) { + printk(KERN_ERR "OMAP_McBSP: Invalid ei and fi params x\n"); + goto rxinx_err; + } + + /* Check if chain exists */ + if (mcbsp->dma_rx_lch == -1) { + printk(KERN_ERR "OMAP_McBSP: Receiver not started\n"); + goto rxinx_err; + } + + /* Get dma_chain_index */ + if (omap_get_dma_chain_index + (mcbsp->dma_rx_lch, &eix, &fix) != 0) { + printk(KERN_ERR "OMAP_McBSP: Getting chain index failed\n"); + goto rxinx_err; + } + + *ei = eix; + *fi = fix; + return 0; + +rxinx_err: + return -EINVAL; +} +EXPORT_SYMBOL(omap2_mcbsp_receiver_index); + +/* + * Basic Reset Transmitter + * id : McBSP interface number + * state : Disable (0)/ Enable (1) the transmitter + */ +int omap2_mcbsp_set_xrst(unsigned int id, u8 state) +{ + struct omap_mcbsp *mcbsp = mcbsp_ptr[id]; + void __iomem *io_base; + + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); + return -ENODEV; + } + io_base = mcbsp->io_base; + + if (state == OMAP_MCBSP_XRST_DISABLE) + OMAP_MCBSP_WRITE(io_base, SPCR2, + OMAP_MCBSP_READ(io_base, SPCR2) & (~XRST)); + else + OMAP_MCBSP_WRITE(io_base, SPCR2, + OMAP_MCBSP_READ(io_base, SPCR2) | XRST); + udelay(10); + + return 0; +} +EXPORT_SYMBOL(omap2_mcbsp_set_xrst); + +/* + * Reset Receiver + * id : McBSP interface number + * state : Disable (0)/ Enable (1) the receiver + */ +int omap2_mcbsp_set_rrst(unsigned int id, u8 state) +{ + struct omap_mcbsp *mcbsp = mcbsp_ptr[id]; + void __iomem *io_base; + + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); + return -ENODEV; + } + io_base = mcbsp->io_base; + + if (state == OMAP_MCBSP_RRST_DISABLE) + OMAP_MCBSP_WRITE(io_base, SPCR1, + OMAP_MCBSP_READ(io_base, SPCR1) & (~RRST)); + else + OMAP_MCBSP_WRITE(io_base, SPCR1, + OMAP_MCBSP_READ(io_base, SPCR1) | RRST); + udelay(10); + return 0; +} +EXPORT_SYMBOL(omap2_mcbsp_set_rrst); + +/* + * Configure the receiver parameters + * id : McBSP Interface ID + * rp : DMA Receive parameters + */ +int omap2_mcbsp_dma_recv_params(unsigned int id, + struct omap_mcbsp_dma_transfer_params *rp) +{ + struct omap_mcbsp *mcbsp; + void __iomem *io_base; + int err, chain_id = -1; + struct omap_dma_channel_params rx_params; + u32 dt = 0; + + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); + return -ENODEV; + } + + mcbsp = id_to_mcbsp_ptr(id); + io_base = mcbsp->io_base; + dt = rp->word_length1; + + if (dt == OMAP_MCBSP_WORD_8) + rx_params.data_type = OMAP_DMA_DATA_TYPE_S8; + else if (dt == OMAP_MCBSP_WORD_16) + rx_params.data_type = OMAP_DMA_DATA_TYPE_S16; + else if (dt == OMAP_MCBSP_WORD_32) + rx_params.data_type = OMAP_DMA_DATA_TYPE_S32; + else + return -EINVAL; + + rx_params.read_prio = DMA_CH_PRIO_HIGH; + rx_params.write_prio = DMA_CH_PRIO_HIGH; + rx_params.sync_mode = OMAP_DMA_SYNC_ELEMENT; + rx_params.src_fi = 0; + rx_params.trigger = mcbsp->dma_rx_sync; + rx_params.src_or_dst_synch = 0x01; + rx_params.src_amode = OMAP_DMA_AMODE_CONSTANT; + rx_params.src_ei = 0x0; + /* Indexing is always in bytes - so multiply with dt */ + + dt = (rx_params.data_type == OMAP_DMA_DATA_TYPE_S8) ? 1 : + (rx_params.data_type == OMAP_DMA_DATA_TYPE_S16) ? 2 : 4; + + /* SKIP_FIRST and SKIP_SECOND- skip alternate data in 24 bit mono */ + if (rp->skip_alt == OMAP_MCBSP_SKIP_SECOND) { + rx_params.dst_amode = OMAP_DMA_AMODE_DOUBLE_IDX; + rx_params.dst_ei = (1); + rx_params.dst_fi = (1) + ((-1) * dt); + } else if (rp->skip_alt == OMAP_MCBSP_SKIP_FIRST) { + rx_params.dst_amode = OMAP_DMA_AMODE_DOUBLE_IDX; + rx_params.dst_ei = 1 + (-2) * dt; + rx_params.dst_fi = 1 + (2) * dt; + } else { + rx_params.dst_amode = OMAP_DMA_AMODE_POST_INC; + rx_params.dst_ei = 0; + rx_params.dst_fi = 0; + } + + mcbsp->rxskip_alt = rp->skip_alt; + mcbsp->auto_reset &= ~OMAP_MCBSP_AUTO_RRST; + mcbsp->auto_reset |= (rp->auto_reset & OMAP_MCBSP_AUTO_RRST); + + mcbsp->rx_word_length = rx_params.data_type << 0x1; + if (rx_params.data_type == 0) + mcbsp->rx_word_length = 1; + + mcbsp->rx_callback = rp->callback; + /* request for a chain of dma channels for data reception */ + if (mcbsp->dma_rx_lch == -1) { + err = omap_request_dma_chain(id, "McBSP RX", + omap2_mcbsp_rx_dma_callback, &chain_id, + 2, OMAP_DMA_DYNAMIC_CHAIN, rx_params); + if (err < 0) { + printk(KERN_ERR "Receive path configuration failed \n"); + return -EINVAL; + } + mcbsp->dma_rx_lch = chain_id; + mcbsp->rx_dma_chain_state = 0; + } else { + /* DMA params already set, modify the same!! */ + err = omap_modify_dma_chain_params(mcbsp->dma_rx_lch, + rx_params); + if (err < 0) + return -EINVAL; + } + + return 0; +} +EXPORT_SYMBOL(omap2_mcbsp_dma_recv_params); + +/* + * Configure the transmitter parameters + * id : McBSP Interface ID + * tp : DMA Transfer parameters + */ + +int omap2_mcbsp_dma_trans_params(unsigned int id, + struct omap_mcbsp_dma_transfer_params *tp) +{ + struct omap_mcbsp *mcbsp; + + struct omap_dma_channel_params tx_params; + int err = 0, chain_id = -1; + void __iomem *io_base; + u32 dt = 0; + + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); + return -ENODEV; + } + + mcbsp = id_to_mcbsp_ptr(id); + io_base = mcbsp->io_base; + + dt = tp->word_length1; + if ((dt != OMAP_MCBSP_WORD_8) && (dt != OMAP_MCBSP_WORD_16) + && (dt != OMAP_MCBSP_WORD_32)) + return -EINVAL; + if (dt == OMAP_MCBSP_WORD_8) + tx_params.data_type = OMAP_DMA_DATA_TYPE_S8; + else if (dt == OMAP_MCBSP_WORD_16) + tx_params.data_type = OMAP_DMA_DATA_TYPE_S16; + else if (dt == OMAP_MCBSP_WORD_32) + tx_params.data_type = OMAP_DMA_DATA_TYPE_S32; + else + return -EINVAL; + + tx_params.read_prio = DMA_CH_PRIO_HIGH; + tx_params.write_prio = DMA_CH_PRIO_HIGH; + tx_params.sync_mode = OMAP_DMA_SYNC_ELEMENT; + tx_params.dst_fi = 0; + tx_params.trigger = mcbsp->dma_tx_sync; + tx_params.src_or_dst_synch = 0; + tx_params.dst_amode = OMAP_DMA_AMODE_CONSTANT; + tx_params.dst_ei = 0; + /* Indexing is always in bytes - so multiply with dt */ + mcbsp->tx_word_length = tx_params.data_type << 0x1; + + if (tx_params.data_type == 0) + mcbsp->tx_word_length = 1; + dt = mcbsp->tx_word_length; + + /* SKIP_FIRST and SKIP_SECOND- skip alternate data in 24 bit mono */ + if (tp->skip_alt == OMAP_MCBSP_SKIP_SECOND) { + tx_params.src_amode = OMAP_DMA_AMODE_DOUBLE_IDX; + tx_params.src_ei = (1); + tx_params.src_fi = (1) + ((-1) * dt); + } else if (tp->skip_alt == OMAP_MCBSP_SKIP_FIRST) { + tx_params.src_amode = OMAP_DMA_AMODE_DOUBLE_IDX; + tx_params.src_ei = 1 + (-2) * dt; + tx_params.src_fi = 1 + (2) * dt; + } else { + tx_params.src_amode = OMAP_DMA_AMODE_POST_INC; + tx_params.src_ei = 0; + tx_params.src_fi = 0; + } + + mcbsp->txskip_alt = tp->skip_alt; + mcbsp->auto_reset &= ~OMAP_MCBSP_AUTO_XRST; + mcbsp->auto_reset |= + (tp->auto_reset & OMAP_MCBSP_AUTO_XRST); + mcbsp->tx_callback = tp->callback; + + /* Based on Rjust we can do double indexing DMA params configuration */ + if (mcbsp->dma_tx_lch == -1) { + err = omap_request_dma_chain(id, "McBSP TX", + omap2_mcbsp_tx_dma_callback, &chain_id, + 2, OMAP_DMA_DYNAMIC_CHAIN, tx_params); + if (err < 0) { + printk(KERN_ERR + "Transmit path configuration failed \n"); + return -EINVAL; + } + mcbsp->tx_dma_chain_state = 0; + mcbsp->dma_tx_lch = chain_id; + } else { + /* DMA params already set, modify the same!! */ + err = omap_modify_dma_chain_params(mcbsp->dma_tx_lch, + tx_params); + if (err < 0) + return -EINVAL; + } + + return 0; +} +EXPORT_SYMBOL(omap2_mcbsp_dma_trans_params); + +/* + * Start receving data on a McBSP interface + * id : McBSP interface ID + * cbdata : User data to be returned with callback + * buf_start_addr : The destination address [physical address] + * buf_size : Buffer size +*/ + +int omap2_mcbsp_receive_data(unsigned int id, void *cbdata, + dma_addr_t buf_start_addr, u32 buf_size) +{ + struct omap_mcbsp *mcbsp; + void __iomem *io_base; + int enable_rx = 0; + int e_count = 0; + int f_count = 0; + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); + return -ENODEV; + } + + mcbsp = id_to_mcbsp_ptr(id); + + io_base = mcbsp->io_base; + mcbsp->rx_cb_arg = cbdata; + + /* Auto RRST handling logic - disable the Reciever before 1st dma */ + if ((mcbsp->auto_reset & OMAP_MCBSP_AUTO_RRST) && + (omap_dma_chain_status(mcbsp->dma_rx_lch) + == OMAP_DMA_CHAIN_INACTIVE)) { + OMAP_MCBSP_WRITE(io_base, SPCR1, + OMAP_MCBSP_READ(io_base, SPCR1) & (~RRST)); + enable_rx = 1; + } + + /* + * for skip_first and second, we need to set e_count =2, + * and f_count = number of frames = number of elements/e_count + */ + e_count = (buf_size / mcbsp->rx_word_length); + + if (mcbsp->rxskip_alt != OMAP_MCBSP_SKIP_NONE) { + /* + * since the number of frames = total number of elements/element + * count, However, with double indexing for data transfers, + * double the number of elements need to be transmitted + */ + f_count = e_count; + e_count = 2; + } else { + f_count = 1; + } + /* + * If the DMA is to be configured to skip the first byte, we need + * to jump backwards, so we need to move one chunk forward and + * ask dma if we dont want the client driver knowing abt this. + */ + if (mcbsp->rxskip_alt == OMAP_MCBSP_SKIP_FIRST) + buf_start_addr += mcbsp->rx_word_length; + + if (omap_dma_chain_a_transfer(mcbsp->dma_rx_lch, + mcbsp->phys_base + OMAP_MCBSP_REG_DRR, buf_start_addr, + e_count, f_count, mcbsp) < 0) { + printk(KERN_ERR " Buffer chaining failed \n"); + return -EINVAL; + } + if (mcbsp->rx_dma_chain_state == 0) { + if (omap_start_dma_chain_transfers(mcbsp->dma_rx_lch) < 0) + return -EINVAL; + mcbsp->rx_dma_chain_state = 1; + } + /* Auto RRST handling logic - Enable the Reciever after 1st dma */ + if (enable_rx && + (omap_dma_chain_status(mcbsp->dma_rx_lch) + == OMAP_DMA_CHAIN_ACTIVE)) + OMAP_MCBSP_WRITE(io_base, SPCR1, + OMAP_MCBSP_READ(io_base, SPCR1) | RRST); + + return 0; +} +EXPORT_SYMBOL(omap2_mcbsp_receive_data); + +/* + * Start transmitting data through a McBSP interface + * id : McBSP interface ID + * cbdata : User data to be returned with callback + * buf_start_addr : The source address [This should be physical address] + * buf_size : Buffer size + */ +int omap2_mcbsp_send_data(unsigned int id, void *cbdata, + dma_addr_t buf_start_addr, u32 buf_size) +{ + struct omap_mcbsp *mcbsp; + void __iomem *io_base; + u8 enable_tx = 0; + int e_count = 0; + int f_count = 0; + + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); + return -ENODEV; + } + mcbsp = id_to_mcbsp_ptr(id); + + io_base = mcbsp->io_base; + + mcbsp->tx_cb_arg = cbdata; + + /* Auto RRST handling logic - disable the Reciever before 1st dma */ + if ((mcbsp->auto_reset & OMAP_MCBSP_AUTO_XRST) && + (omap_dma_chain_status(mcbsp->dma_tx_lch) + == OMAP_DMA_CHAIN_INACTIVE)) { + OMAP_MCBSP_WRITE(io_base, SPCR2, + OMAP_MCBSP_READ(io_base, SPCR2) & (~XRST)); + enable_tx = 1; + } + /* + * for skip_first and second, we need to set e_count =2, and + * f_count = number of frames = number of elements/e_count + */ + e_count = (buf_size / mcbsp->tx_word_length); + if (mcbsp->txskip_alt != OMAP_MCBSP_SKIP_NONE) { + /* + * number of frames = total number of elements/element count, + * However, with double indexing for data transfers, double I + * the number of elements need to be transmitted + */ + f_count = e_count; + e_count = 2; + } else { + f_count = 1; + } + + /* + * If the DMA is to be configured to skip the first byte, we need + * to jump backwards, so we need to move one chunk forward and ask + * dma if we dont want the client driver knowing abt this. + */ + if (mcbsp->txskip_alt == OMAP_MCBSP_SKIP_FIRST) + buf_start_addr += mcbsp->tx_word_length; + + if (omap_dma_chain_a_transfer(mcbsp->dma_tx_lch, + buf_start_addr, mcbsp->phys_base + OMAP_MCBSP_REG_DXR, + e_count, f_count, mcbsp) < 0) + return -EINVAL; + + if (mcbsp->tx_dma_chain_state == 0) { + if (omap_start_dma_chain_transfers(mcbsp->dma_tx_lch) < 0) + return -EINVAL; + mcbsp->tx_dma_chain_state = 1; + } + + /* Auto XRST handling logic - Enable the Reciever after 1st dma */ + if (enable_tx && + (omap_dma_chain_status(mcbsp->dma_tx_lch) + == OMAP_DMA_CHAIN_ACTIVE)) + OMAP_MCBSP_WRITE(io_base, SPCR2, + OMAP_MCBSP_READ(io_base, SPCR2) | XRST); + + return 0; +} +EXPORT_SYMBOL(omap2_mcbsp_send_data); + +void omap2_mcbsp_set_recv_param(struct omap_mcbsp_reg_cfg *mcbsp_cfg, + struct omap_mcbsp_cfg_param *rp) +{ + mcbsp_cfg->spcr1 = RJUST(rp->justification); + mcbsp_cfg->rcr2 = RCOMPAND(rp->reverse_compand) | + RDATDLY(rp->data_delay); + if (rp->phase == OMAP_MCBSP_FRAME_SINGLEPHASE) + mcbsp_cfg->rcr2 = mcbsp_cfg->rcr2 & ~(RPHASE); + else + mcbsp_cfg->rcr2 = mcbsp_cfg->rcr2 | (RPHASE) | + RWDLEN2(rp->word_length2) | RFRLEN2(rp->frame_length2); + mcbsp_cfg->rcr1 = RWDLEN1(rp->word_length1) | + RFRLEN1(rp->frame_length1); + if (rp->fsync_src == OMAP_MCBSP_RXFSYNC_INTERNAL) + mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 | FSRM; + if (rp->clk_mode == OMAP_MCBSP_CLKRXSRC_INTERNAL) + mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 | CLKRM; + if (rp->clk_polarity == OMAP_MCBSP_CLKR_POLARITY_RISING) + mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 | CLKRP; + if (rp->fs_polarity == OMAP_MCBSP_FS_ACTIVE_LOW) + mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 | FSRP; + return; +} + +/* + * Set McBSP transmit parameters + * id : McBSP interface ID + * mcbsp_cfg : McBSP register configuration + * tp : McBSP transmit parameters + */ + +void omap2_mcbsp_set_trans_param(struct omap_mcbsp_reg_cfg *mcbsp_cfg, + struct omap_mcbsp_cfg_param *tp) +{ + mcbsp_cfg->xcr2 = XCOMPAND(tp->reverse_compand) | + XDATDLY(tp->data_delay); + if (tp->phase == OMAP_MCBSP_FRAME_SINGLEPHASE) + mcbsp_cfg->xcr2 = mcbsp_cfg->xcr2 & ~(XPHASE); + else + mcbsp_cfg->xcr2 = mcbsp_cfg->xcr2 | (XPHASE) | + RWDLEN2(tp->word_length2) | RFRLEN2(tp->frame_length2); + mcbsp_cfg->xcr1 = XWDLEN1(tp->word_length1) | + XFRLEN1(tp->frame_length1); + if (tp->fs_polarity == OMAP_MCBSP_FS_ACTIVE_LOW) + mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 | FSXP; + if (tp->fsync_src == OMAP_MCBSP_TXFSYNC_INTERNAL) + mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 | FSXM; + if (tp->clk_mode == OMAP_MCBSP_CLKTXSRC_INTERNAL) + mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 | CLKXM; + if (tp->clk_polarity == OMAP_MCBSP_CLKX_POLARITY_FALLING) + mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 | CLKXP; + return; +} + + /* + * Set McBSP SRG configuration + * id : McBSP interface ID + * mcbsp_cfg : McBSP register configuration + * interface_mode : Master/Slave + * param : McBSP SRG and FSG configuration + */ + +void omap2_mcbsp_set_srg_cfg_param(unsigned int id, int interface_mode, + struct omap_mcbsp_reg_cfg *mcbsp_cfg, + struct omap_mcbsp_srg_fsg_cfg *param) +{ + struct omap_mcbsp *mcbsp = mcbsp_ptr[id]; + void __iomem *io_base; + u32 clk_rate, clkgdv; + io_base = mcbsp->io_base; + + mcbsp->interface_mode = interface_mode; + mcbsp_cfg->srgr1 = FWID(param->pulse_width); + + if (interface_mode == OMAP_MCBSP_MASTER) { + clk_rate = clk_get_rate(mcbsp->fclk); + clkgdv = clk_rate / (param->sample_rate * + (param->bits_per_sample - 1)); + if (clkgdv > 0xFF ) + clkgdv = 0xFF; + mcbsp_cfg->srgr1 = mcbsp_cfg->srgr1 | CLKGDV(clkgdv); + } + if (param->dlb) + mcbsp_cfg->spcr1 = mcbsp_cfg->spcr1 & ~(ALB); + + if (param->sync_mode == OMAP_MCBSP_SRG_FREERUNNING) + mcbsp_cfg->spcr2 = mcbsp_cfg->spcr2 | FREE; + mcbsp_cfg->srgr2 = FPER(param->period)|(param->fsgm? FSGM : 0); + + switch (param->srg_src) { + + case OMAP_MCBSP_SRGCLKSRC_CLKS: + mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 & ~(SCLKME); + mcbsp_cfg->srgr2 = mcbsp_cfg->srgr2 & ~(CLKSM); + /* + * McBSP master operation at low voltage is only possible if + * CLKSP=0 In Master mode, if client driver tries to configiure + * input clock polarity as falling edge, we force it to Rising + */ + + if ((param->polarity == OMAP_MCBSP_CLKS_POLARITY_RISING) || + (interface_mode == OMAP_MCBSP_MASTER)) + mcbsp_cfg->srgr2 = mcbsp_cfg->srgr2 & ~(CLKSP); + else + mcbsp_cfg->srgr2 = mcbsp_cfg->srgr2 | (CLKSP); + break; + + + case OMAP_MCBSP_SRGCLKSRC_FCLK: + mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 & ~(SCLKME); + mcbsp_cfg->srgr2 = mcbsp_cfg->srgr2 | (CLKSM); + + break; + + case OMAP_MCBSP_SRGCLKSRC_CLKR: + mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 | (SCLKME); + mcbsp_cfg->srgr2 = mcbsp_cfg->srgr2 & ~(CLKSM); + if (param->polarity == OMAP_MCBSP_CLKR_POLARITY_FALLING) + mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 & ~(CLKRP); + else + mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 | (CLKRP); + + break; + + case OMAP_MCBSP_SRGCLKSRC_CLKX: + mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 | (SCLKME); + mcbsp_cfg->srgr2 = mcbsp_cfg->srgr2 | (CLKSM); + + if (param->polarity == OMAP_MCBSP_CLKX_POLARITY_RISING) + mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 & ~(CLKXP); + else + mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 | (CLKXP); + break; + + } + if (param->sync_mode == OMAP_MCBSP_SRG_FREERUNNING) + mcbsp_cfg->srgr2 = mcbsp_cfg->srgr2 & ~(GSYNC); + else if (param->sync_mode == OMAP_MCBSP_SRG_RUNNING) + mcbsp_cfg->srgr2 = mcbsp_cfg->srgr2 | (GSYNC); + + mcbsp_cfg->xccr = OMAP_MCBSP_READ(io_base, XCCR); + if (param->dlb) + mcbsp_cfg->xccr = mcbsp_cfg->xccr | (DILB); + mcbsp_cfg->rccr = OMAP_MCBSP_READ(io_base, RCCR); + + return; + } + +/* + * configure the McBSP registers + * id : McBSP interface ID + * interface_mode : Master/Slave + * rp : McBSP recv parameters + * tp : McBSP transmit parameters + * param : McBSP SRG and FSG configuration + */ +void omap2_mcbsp_params_cfg(unsigned int id, int interface_mode, + struct omap_mcbsp_cfg_param *rp, + struct omap_mcbsp_cfg_param *tp, + struct omap_mcbsp_srg_fsg_cfg *param) +{ + if (rp) + omap2_mcbsp_set_recv_param(&mcbsp_cfg, rp); + if (tp) + omap2_mcbsp_set_trans_param(&mcbsp_cfg, tp); + if (param) + omap2_mcbsp_set_srg_cfg_param(id, + interface_mode, &mcbsp_cfg, param); + omap_mcbsp_config(id, &mcbsp_cfg); + + return; +} +EXPORT_SYMBOL(omap2_mcbsp_params_cfg); + + static int __init omap2_mcbsp_init(void) { + + + if (cpu_is_omap2420()) omap_mcbsp_count = OMAP2420_MCBSP_PDATA_SZ; if (cpu_is_omap2430()) diff --git a/arch/arm/mach-omap2/mmc-twl4030.c b/arch/arm/mach-omap2/mmc-twl4030.c index cc27a6bbfafd..334bce573842 100644 --- a/arch/arm/mach-omap2/mmc-twl4030.c +++ b/arch/arm/mach-omap2/mmc-twl4030.c @@ -25,6 +25,11 @@ #include <plat/mmc.h> #include <plat/board.h> +#ifdef CONFIG_TIWLAN_SDIO +#include <linux/mmc/sdio_ids.h> +#include <linux/mmc/sdio_func.h> +#endif + #include "mmc-twl4030.h" #include <linux/i2c/twl.h> @@ -40,11 +45,6 @@ static u16 control_mmc1; /* Hack : Phoenix registers*/ #define PHOENIX_CFG_INPUT_PUPD3 0xF2 -#define MMC_GRP 0x68 -#define MMC_TRANS 0x69 -#define MMC_STATE 0x6a -#define MMC_VOLTAGE 0x6b - static struct twl_mmc_controller { struct omap_mmc_platform_data *mmc; @@ -62,39 +62,36 @@ static struct twl_mmc_controller { static int twl_mmc_card_detect(int irq) { unsigned i; - if (!cpu_is_omap44xx()) { - for (i = 0; i < ARRAY_SIZE(hsmmc); i++) { - struct omap_mmc_platform_data *mmc; + u8 read_reg = 0; + unsigned res; - mmc = hsmmc[i].mmc; - if (!mmc) - continue; - if (irq != mmc->slots[0].card_detect_irq) - continue; + for (i = 0; i < ARRAY_SIZE(hsmmc); i++) { + struct omap_mmc_platform_data *mmc; - /* NOTE: assumes card detect signal is active-low */ - return !gpio_get_value_cansleep - (mmc->slots[0].switch_pin); - } - return -ENOSYS; - } else { - /* BIT0 of REG_SIMCTRL - * 0 - Card not present - * 1 - Card present - */ - u8 read_reg; - unsigned res; + mmc = hsmmc[i].mmc; + if (!mmc) + continue; + if (irq != mmc->slots[0].card_detect_irq) + continue; - res = twl_i2c_read_u8(TWL4030_MODULE_INTBR, - &read_reg, PHOENIX_MMC_CTRL); - if (res < 0) { - printk(KERN_ERR"%s: i2c_read fail at %x \n", - __func__, PHOENIX_MMC_CTRL); - return -1; + /* NOTE: assumes card detect signal is active-low */ + if (!cpu_is_omap44xx()) { + return !gpio_get_value_cansleep + (mmc->slots[0].switch_pin); } else { - return read_reg & 0x1; + /* BIT0 of REG_MMC_CTRL + * 0 - Card not present + * 1 - Card present + */ + if (mmc->slots[0].nonremovable) + return 1; + res = twl_i2c_read_u8(TWL4030_MODULE_INTBR, + &read_reg, PHOENIX_MMC_CTRL); + if (res >= 0) + return read_reg & 0x1; } } + return -ENOSYS; } static int twl_mmc_get_ro(struct device *dev, int slot) @@ -121,7 +118,6 @@ static int twl_mmc_late_init(struct device *dev) struct omap_mmc_platform_data *mmc = dev->platform_data; int ret = 0; int i; - u8 regs; /* MMC/SD/SDIO doesn't require a card detect switch */ if (!cpu_is_omap44xx()) { @@ -189,19 +185,6 @@ static int twl_mmc_late_init(struct device *dev) } /* Configure Phoenix for MMC1 Card detect */ if (i == 0) { - regs = 0x01; - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, - regs, MMC_GRP); - regs = 0x03; - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, - regs, MMC_TRANS); - regs = 0x21; - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, - regs, MMC_STATE); - regs = 0x15; - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, - regs, MMC_VOLTAGE); - msleep(200); twl_i2c_write_u8(TWL4030_MODULE_INTBR, 0x04, PHOENIX_MMC_CTRL); twl_i2c_write_u8(TWL4030_MODULE_INTBR, @@ -278,7 +261,6 @@ static int twl_mmc1_set_power(struct device *dev, int slot, int power_on, int ret = 0; struct twl_mmc_controller *c = &hsmmc[0]; struct omap_mmc_platform_data *mmc = dev->platform_data; - u8 regs; /* * Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the @@ -324,40 +306,7 @@ static int twl_mmc1_set_power(struct device *dev, int slot, int power_on, OMAP4_MMC1_PWRDWNZ); } omap_ctrl_writel(reg, control_pbias_offset); - - /* Hack need to fix it */ - if ((vdd == 0x12) || (vdd == 0x7)) { - regs = 0x01; - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, - regs, MMC_GRP); - regs = 0x03; - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, - regs, MMC_TRANS); - regs = 0x21; - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, - regs, MMC_STATE); - regs = 0x15; - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, - regs, MMC_VOLTAGE); - } else { - regs = 0x01; - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, - regs, MMC_GRP); - regs = 0x03; - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, - regs, MMC_TRANS); - regs = 0x00; - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, - regs, MMC_STATE); - regs = 0x09; - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, - regs, MMC_STATE); - regs = 0x15; - twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, - regs, MMC_VOLTAGE); - } - if (!cpu_is_omap44xx()) - ret = mmc_regulator_set_ocr(c->vcc, vdd); + ret = mmc_regulator_set_ocr(c->vcc, vdd); /* 100ms delay required for PBIAS configuration */ msleep(100); @@ -391,9 +340,7 @@ static int twl_mmc1_set_power(struct device *dev, int slot, int power_on, OMAP4_MMC1_PWRDWNZ); } omap_ctrl_writel(reg, control_pbias_offset); - - if (!cpu_is_omap44xx()) - ret = mmc_regulator_set_ocr(c->vcc, 0); + ret = mmc_regulator_set_ocr(c->vcc, 0); /* 100ms delay required for PBIAS configuration */ msleep(100); @@ -420,8 +367,6 @@ static int twl_mmc23_set_power(struct device *dev, int slot, int power_on, int v struct omap_mmc_platform_data *mmc = dev->platform_data; int i; - if (cpu_is_omap44xx()) - return 0; for (i = 1; i < ARRAY_SIZE(hsmmc); i++) { if (mmc == hsmmc[i].mmc) { @@ -453,13 +398,15 @@ static int twl_mmc23_set_power(struct device *dev, int slot, int power_on, int v * chips/cards need an interface voltage rail too. */ if (power_on) { - /* only MMC2 supports a CLKIN */ - if (mmc->slots[0].internal_clock) { - u32 reg; + if (!cpu_is_omap44xx()) { + /* only MMC2 supports a CLKIN */ + if (mmc->slots[0].internal_clock) { + u32 reg; - reg = omap_ctrl_readl(control_devconf1_offset); - reg |= OMAP2_MMCSDIO2ADPCLKISEL; - omap_ctrl_writel(reg, control_devconf1_offset); + reg = omap_ctrl_readl(control_devconf1_offset); + reg |= OMAP2_MMCSDIO2ADPCLKISEL; + omap_ctrl_writel(reg, control_devconf1_offset); + } } ret = mmc_regulator_set_ocr(c->vcc, vdd); /* enable interface voltage rail, if needed */ @@ -538,6 +485,29 @@ static int twl_mmc23_set_sleep(struct device *dev, int slot, int sleep, int vdd, static struct omap_mmc_platform_data *hsmmc_data[OMAP44XX_NR_MMC] __initdata; +#ifdef CONFIG_TIWLAN_SDIO +static struct sdio_embedded_func wifi_func_array[] = { + { + .f_class = SDIO_CLASS_BT_A, + .f_maxblksize = 512, + }, + { + .f_class = SDIO_CLASS_WLAN, + .f_maxblksize = 512, + }, +}; + +static struct embedded_sdio_data omap_wifi_emb_data = { + .cis = { + .vendor = SDIO_VENDOR_ID_TI, + .device = SDIO_DEVICE_ID_TI_WL12xx, + .blksize = 512, + .max_dtr = 24000000, + }, + .funcs = wifi_func_array, +}; +#endif + void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) { struct twl4030_hsmmc_info *c; @@ -591,6 +561,16 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) else snprintf(twl->name, ARRAY_SIZE(twl->name), "mmc%islot%i", c->mmc, 1); + +#ifdef CONFIG_TIWLAN_SDIO + if (c->mmc == CONFIG_TIWLAN_MMC_CONTROLLER) { + mmc->slots[0].embedded_sdio = &omap_wifi_emb_data; + mmc->slots[0].register_status_notify = + &omap_wifi_status_register; + mmc->slots[0].card_detect = &omap_wifi_status; + } +#endif + mmc->slots[0].name = twl->name; mmc->nr_slots = 1; mmc->slots[0].wires = c->wires; @@ -622,6 +602,12 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) mmc->slots[0].card_detect_irq = 384; else mmc->slots[0].card_detect_irq = 0; + if (c->cover_only) + mmc->slots[0].get_cover_state = + twl_mmc_get_cover_state; + else + mmc->slots[0].card_detect = + twl_mmc_card_detect; } mmc->get_context_loss_count = @@ -676,6 +662,9 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) /* off-chip level shifting, or none */ mmc->slots[0].set_power = twl_mmc23_set_power; mmc->slots[0].set_sleep = twl_mmc23_set_sleep; +#ifdef CONFIG_TIWLAN_SDIO + mmc->slots[0].ocr_mask = MMC_VDD_165_195; +#endif break; default: pr_err("MMC%d configuration not supported!\n", c->mmc); diff --git a/arch/arm/mach-omap2/mmc-twl4030.h b/arch/arm/mach-omap2/mmc-twl4030.h index a47e68563fb6..1da38a26c2bf 100644 --- a/arch/arm/mach-omap2/mmc-twl4030.h +++ b/arch/arm/mach-omap2/mmc-twl4030.h @@ -21,6 +21,12 @@ struct twl4030_hsmmc_info { int ocr_mask; /* temporary HACK */ }; +#ifdef CONFIG_TIWLAN_SDIO +int omap_wifi_status_register(void (*callback)(int card_present, + void *dev_id), void *dev_id); +int omap_wifi_status(int irq); +#endif + #if defined(CONFIG_REGULATOR) && \ (defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \ defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)) diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index e071b3fd1878..e028b542f2c4 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c @@ -48,7 +48,7 @@ struct omap_mux_entry { struct list_head node; }; -static unsigned long mux_phys; +static unsigned long __attribute__ ((unused)) mux_phys; static void __iomem *mux_base; static inline u16 omap_mux_read(u16 reg) diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S index 3e5e362786d9..e8650561660b 100644 --- a/arch/arm/mach-omap2/omap-headsmp.S +++ b/arch/arm/mach-omap2/omap-headsmp.S @@ -31,7 +31,7 @@ ENTRY(omap_secondary_startup) hold: ldr r12,=0x103 dsb - smc @ read from AuxCoreBoot0 + smc #0 @ read from AuxCoreBoot0 mov r0, r0, lsr #9 mrc p15, 0, r4, c0, c0, 5 and r4, r4, #0x0f @@ -50,7 +50,7 @@ ENTRY(omap_modify_auxcoreboot0) stmfd sp!, {r1-r12, lr} ldr r12, =0x104 dsb - smc + smc #0 ldmfd sp!, {r1-r12, pc} END(omap_modify_auxcoreboot0) @@ -58,7 +58,7 @@ ENTRY(omap_auxcoreboot_addr) stmfd sp!, {r2-r12, lr} ldr r12, =0x105 dsb - smc + smc #0 ldmfd sp!, {r2-r12, pc} END(omap_auxcoreboot_addr) @@ -66,7 +66,7 @@ ENTRY(omap_read_auxcoreboot0) stmfd sp!, {r2-r12, lr} ldr r12, =0x103 dsb - smc + smc #0 mov r0, r0, lsr #9 ldmfd sp!, {r2-r12, pc} END(omap_read_auxcoreboot0) diff --git a/arch/arm/mach-omap2/omap-hotplug.c b/arch/arm/mach-omap2/omap-hotplug.c index 66499115ac54..605a39fb4b22 100644 --- a/arch/arm/mach-omap2/omap-hotplug.c +++ b/arch/arm/mach-omap2/omap-hotplug.c @@ -27,37 +27,20 @@ static DECLARE_COMPLETION(cpu_killed); static inline void cpu_enter_lowpower(void) { - unsigned int v; - flush_cache_all(); - /* FIXME: check L2 state and see if the l2 flush is necessary */ - - asm volatile( - " mcr p15, 0, %1, c7, c5, 0\n" - " mcr p15, 0, %1, c7, c10, 4\n" - /* FIXME: Need to use secure API for AUX control */ - - " mrc p15, 0, %0, c1, c0, 0\n" - " bic %0, %0, #0x04\n" - " mcr p15, 0, %0, c1, c0, 0\n" - : "=&r" (v) - : "r" (0) - : "cc"); + /* FIXME: Code for OFF /RET */ } static inline void cpu_leave_lowpower(void) { - unsigned int v; - - asm volatile( - "mrc p15, 0, %0, c1, c0, 0\n" - " orr %0, %0, #0x04\n" - " mcr p15, 0, %0, c1, c0, 0\n" - /* FIXME: Need to use secure API for AUX control */ + struct powerdomain *cpu1_pd; + u32 scu_pwr_st; - : "=&r" (v) - : - : "cc"); + scu_pwr_st = omap_readl(0x48240008); + scu_pwr_st &= ~0x8; + omap_writel(scu_pwr_st, 0x48240008); + cpu1_pd = pwrdm_lookup("cpu1_pwrdm"); + pwrdm_set_next_pwrst(cpu1_pd, PWRDM_POWER_ON); } static inline void omap_do_lowpower(unsigned int cpu) @@ -65,29 +48,17 @@ static inline void omap_do_lowpower(unsigned int cpu) u32 scu_pwr_st; struct powerdomain *cpu1_pd; - - if(omap_modify_auxcoreboot0(0x0, 0x200) != 0x0) { + if(omap_modify_auxcoreboot0(0x0, 0x200) != 0x0) printk(KERN_CRIT "Secure clear status failed\n"); - BUG(); - } - /* - * FIXME: Hook up the omap low power here. - */ for (;;) { - /* Program the possible low power state here */ - - /* FIXME: On the ES2.0 silicon SCU power state - * register can be accessed using only secure API - * Also use ioremap instead of omap_read/write here - */ - /* set SCU power status register to dormant mode */ + cpu1_pd = pwrdm_lookup("cpu1_pwrdm"); + pwrdm_set_next_pwrst(cpu1_pd, PWRDM_POWER_RET); scu_pwr_st = omap_readl(0x48240008); scu_pwr_st |= 0x8; omap_writel(scu_pwr_st, 0x48240008); - cpu1_pd = pwrdm_lookup("cpu1_pwrdm"); - pwrdm_set_next_pwrst(cpu1_pd, PWRDM_POWER_RET); - dsb(); + isb(); + wmb(); asm volatile("wfi\n" : : @@ -97,11 +68,6 @@ static inline void omap_do_lowpower(unsigned int cpu) /* * OK, proper wakeup, we're done */ - pwrdm_set_next_pwrst(cpu1_pd, PWRDM_POWER_ON); - scu_pwr_st = omap_readl(0x48240008); - scu_pwr_st &= ~0x8; - omap_writel(scu_pwr_st, 0x48240008); - local_irq_enable(); break; } #ifdef DEBUG diff --git a/arch/arm/mach-omap2/omap4-iommu.c b/arch/arm/mach-omap2/omap4-iommu.c new file mode 100644 index 000000000000..6225616f4e9e --- /dev/null +++ b/arch/arm/mach-omap2/omap4-iommu.c @@ -0,0 +1,110 @@ +/* + * omap iommu: omap4 device registration + * + * Copyright (C) 2009-2010 Nokia Corporation + * + * Written by Hari Kanigeri <h-kanigeri2@ti.com> + * + * Added support for OMAP4. This is based on original file + * omap3-iommu.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 <linux/platform_device.h> + +#include <plat/iommu.h> +#include <plat/irqs.h> + +#define OMAP4_MMU1_BASE 0x55082000 +#define OMAP4_MMU2_BASE 0x4A066000 + +#define OMAP4_MMU1_IRQ INT_44XX_DUCATI_MMU_IRQ +#define OMAP4_MMU2_IRQ INT_44XX_DSP_MMU + + + +static unsigned long iommu_base[] __initdata = { + OMAP4_MMU1_BASE, + OMAP4_MMU2_BASE, +}; + +static int iommu_irq[] __initdata = { + OMAP4_MMU1_IRQ, + OMAP4_MMU2_IRQ, +}; + +static const struct iommu_platform_data omap4_iommu_pdata[] __initconst = { + { + .name = "ducati", + .nr_tlb_entries = 32, + }, +#if defined(CONFIG_MPU_TESLA_IOMMU) + { + .name = "tesla", + .nr_tlb_entries = 32, + }, +#endif +}; +#define NR_IOMMU_DEVICES ARRAY_SIZE(omap4_iommu_pdata) + +static struct platform_device *omap4_iommu_pdev[NR_IOMMU_DEVICES]; + +static int __init omap4_iommu_init(void) +{ + int i, err; + + for (i = 0; i < NR_IOMMU_DEVICES; i++) { + struct platform_device *pdev; + struct resource res[2]; + + pdev = platform_device_alloc("omap-iommu", i); + if (!pdev) { + err = -ENOMEM; + goto err_out; + } + + memset(res, 0, sizeof(res)); + res[0].start = iommu_base[i]; + res[0].end = iommu_base[i] + MMU_REG_SIZE - 1; + res[0].flags = IORESOURCE_MEM; + res[1].start = res[1].end = iommu_irq[i]; + res[1].flags = IORESOURCE_IRQ; + + err = platform_device_add_resources(pdev, res, + ARRAY_SIZE(res)); + if (err) + goto err_out; + err = platform_device_add_data(pdev, &omap4_iommu_pdata[i], + sizeof(omap4_iommu_pdata[0])); + if (err) + goto err_out; + err = platform_device_add(pdev); + if (err) + goto err_out; + omap4_iommu_pdev[i] = pdev; + } + return 0; + +err_out: + while (i--) + platform_device_put(omap4_iommu_pdev[i]); + return err; +} +module_init(omap4_iommu_init); + +static void __exit omap4_iommu_exit(void) +{ + int i; + + for (i = 0; i < NR_IOMMU_DEVICES; i++) + platform_device_unregister(omap4_iommu_pdev[i]); +} +module_exit(omap4_iommu_exit); + +MODULE_AUTHOR("Hiroshi DOYU, Hari Kanigeri"); +MODULE_DESCRIPTION("omap iommu: omap4 device registration"); +MODULE_LICENSE("GPL v2"); + diff --git a/arch/arm/mach-omap2/omap44xx-smc.S b/arch/arm/mach-omap2/omap44xx-smc.S new file mode 100644 index 000000000000..f61c7771ca47 --- /dev/null +++ b/arch/arm/mach-omap2/omap44xx-smc.S @@ -0,0 +1,32 @@ +/* + * OMAP44xx secure APIs file. + * + * Copyright (C) 2010 Texas Instruments, Inc. + * Written by Santosh Shilimkar <santosh.shilimkar@ti.com> + * + * + * 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 <linux/linkage.h> + +/* + * This is common routine to manage secure monitor API + * used to modify the PL310 secure registers. + * 'r0' contains the value to be modified and 'r12' contains + * the monitor API number. It uses few CPU registers + * internally and hence they need be backed up including + * link register "lr". + * Function signature : void omap_smc1(u32 fn, u32 arg) + */ + +ENTRY(omap_smc1) + stmfd sp!, {r2-r12, lr} + mov r12, r0 + mov r0, r1 + dsb + smc #0 + ldmfd sp!, {r2-r12, pc} +END(omap_smc1) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 90f9a3667a5b..248e6a9247e2 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -374,7 +374,8 @@ static int _disable_wakeup(struct omap_hwmod *oh) * mode. Returns -EINVAL upon error or passes along * pwrdm_add_sleepdep() value upon success. */ -static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh) +static int __attribute__ ((unused)) _add_initiator_dep(struct omap_hwmod *oh, + struct omap_hwmod *init_oh) { if (!oh->_clk) return -EINVAL; @@ -538,7 +539,7 @@ static int _disable_clocks(struct omap_hwmod *oh) pr_debug("omap_hwmod: %s: disabling clocks\n", oh->name); - if (oh->_clk && !IS_ERR(oh->_clk)) + if (oh->_clk && !IS_ERR(oh->_clk)) { #ifdef CONFIG_PM if (!strcmp(oh->_clk->name, "emif1_ck") || !strcmp(oh->_clk->name, "emif2_ck") || @@ -551,6 +552,7 @@ static int _disable_clocks(struct omap_hwmod *oh) else #endif clk_disable(oh->_clk); + } if (oh->slaves_cnt > 0) { for (i = 0, os = *oh->slaves; i < oh->slaves_cnt; i++, os++) { @@ -827,10 +829,10 @@ static int _wait_target_ready(struct omap_hwmod *oh) return 0; os = *oh->slaves + oh->_mpu_port_index; - +#if 0 if (!(os->flags & OCPIF_HAS_IDLEST)) return 0; - +#endif /* XXX check module SIDLEMODE */ /* XXX check clock enable states */ @@ -839,11 +841,8 @@ static int _wait_target_ready(struct omap_hwmod *oh) ret = omap2_cm_wait_module_ready(oh->prcm.omap2.module_offs, oh->prcm.omap2.idlest_reg_id, oh->prcm.omap2.idlest_idle_bit); -#if 0 } else if (cpu_is_omap44xx()) { - ret = omap4_cm_wait_module_ready(oh->prcm.omap4.module_offs, - oh->prcm.omap4.device_offs); -#endif + ret = omap4_cm_wait_module_ready(oh->prcm.omap4.device_reg); } else { BUG(); }; @@ -934,16 +933,21 @@ static int _enable(struct omap_hwmod *oh) #endif _enable_clocks(oh); - if (oh->sysconfig) { - if (!(oh->_int_flags & _HWMOD_SYSCONFIG_LOADED)) - _update_sysc_cache(oh); - _sysc_enable(oh); - } - r = _wait_target_ready(oh); - if (!r) + if (!r) { oh->_state = _HWMOD_STATE_ENABLED; + /* Access the sysconfig only if the target is ready */ + if (oh->sysconfig) { + if (!(oh->_int_flags & _HWMOD_SYSCONFIG_LOADED)) + _update_sysc_cache(oh); + _sysc_enable(oh); + } + } + else { + pr_debug("omap_hwmod: %s: _wait_target_ready: %d\n", oh->name, r); + } + return r; } @@ -1032,7 +1036,7 @@ static int _shutdown(struct omap_hwmod *oh) static int _setup(struct omap_hwmod *oh) { struct omap_hwmod_ocp_if *os; - int i; + int i, r; if (!oh) return -EINVAL; @@ -1056,7 +1060,11 @@ static int _setup(struct omap_hwmod *oh) oh->_state = _HWMOD_STATE_INITIALIZED; - _enable(oh); + r = _enable(oh); + if (r) { + pr_warning("omap_hwmod: %s: cannot be enabled (%d)\n", oh->name, oh->_state); + return 0; + } if (!(oh->flags & HWMOD_INIT_NO_RESET)) { /* diff --git a/arch/arm/mach-omap2/omap_hwmod_34xx.h b/arch/arm/mach-omap2/omap_hwmod_34xx.h index 79822efab352..6e5239c5e301 100644 --- a/arch/arm/mach-omap2/omap_hwmod_34xx.h +++ b/arch/arm/mach-omap2/omap_hwmod_34xx.h @@ -1334,7 +1334,7 @@ static struct omap_hwmod omap34xx_gptimer1 = { .prcm = { .omap2 = { .prcm_reg_id = 1, - .module_bit = OMAP3430_GRPSEL_GPT1, + .module_bit = OMAP3430_EN_GPT1_SHIFT, .idlest_reg_id = 1, }, }, @@ -1361,7 +1361,7 @@ static struct omap_hwmod omap34xx_gptimer2 = { .prcm = { .omap2 = { .prcm_reg_id = 1, - .module_bit = OMAP3430_GRPSEL_GPT2, + .module_bit = OMAP3430_EN_GPT2_SHIFT, .idlest_reg_id = 1, }, }, @@ -1388,7 +1388,7 @@ static struct omap_hwmod omap34xx_gptimer3 = { .prcm = { .omap2 = { .prcm_reg_id = 1, - .module_bit = OMAP3430_GRPSEL_GPT3, + .module_bit = OMAP3430_EN_GPT3_SHIFT, .idlest_reg_id = 1, }, }, @@ -1412,7 +1412,7 @@ static struct omap_hwmod omap34xx_gptimer4 = { .prcm = { .omap2 = { .prcm_reg_id = 1, - .module_bit = OMAP3430_GRPSEL_GPT4, + .module_bit = OMAP3430_EN_GPT4_SHIFT, .idlest_reg_id = 1, }, }, @@ -1439,7 +1439,7 @@ static struct omap_hwmod omap34xx_gptimer5 = { .prcm = { .omap2 = { .prcm_reg_id = 1, - .module_bit = OMAP3430_GRPSEL_GPT5, + .module_bit = OMAP3430_EN_GPT5_SHIFT, .idlest_reg_id = 1, }, }, @@ -1466,7 +1466,7 @@ static struct omap_hwmod omap34xx_gptimer6 = { .prcm = { .omap2 = { .prcm_reg_id = 1, - .module_bit = OMAP3430_GRPSEL_GPT6, + .module_bit = OMAP3430_EN_GPT6_SHIFT, .idlest_reg_id = 1, }, }, @@ -1493,7 +1493,7 @@ static struct omap_hwmod omap34xx_gptimer7 = { .prcm = { .omap2 = { .prcm_reg_id = 1, - .module_bit = OMAP3430_GRPSEL_GPT7, + .module_bit = OMAP3430_EN_GPT7_SHIFT, .idlest_reg_id = 1, }, }, @@ -1520,7 +1520,7 @@ static struct omap_hwmod omap34xx_gptimer8 = { .prcm = { .omap2 = { .prcm_reg_id = 1, - .module_bit = OMAP3430_GRPSEL_GPT8, + .module_bit = OMAP3430_EN_GPT8_SHIFT, .idlest_reg_id = 1, }, }, @@ -1547,7 +1547,7 @@ static struct omap_hwmod omap34xx_gptimer9 = { .prcm = { .omap2 = { .prcm_reg_id = 1, - .module_bit = OMAP3430_GRPSEL_GPT9, + .module_bit = OMAP3430_EN_GPT9_SHIFT, .idlest_reg_id = 1, }, }, @@ -1574,7 +1574,7 @@ static struct omap_hwmod omap34xx_gptimer10 = { .prcm = { .omap2 = { .prcm_reg_id = 1, - .module_bit = OMAP3430_GRPSEL_GPT10, + .module_bit = OMAP3430_EN_GPT10_SHIFT, .idlest_reg_id = 1, }, }, @@ -1601,7 +1601,7 @@ static struct omap_hwmod omap34xx_gptimer11 = { .prcm = { .omap2 = { .prcm_reg_id = 1, - .module_bit = OMAP3430_GRPSEL_GPT11, + .module_bit = OMAP3430_EN_GPT11_SHIFT, .idlest_reg_id = 1, }, }, @@ -1628,7 +1628,7 @@ static struct omap_hwmod omap34xx_gptimer12 = { .prcm = { .omap2 = { .prcm_reg_id = 1, - .module_bit = OMAP3430_GRPSEL_GPT12, + .module_bit = OMAP3430_EN_GPT12_SHIFT, .idlest_reg_id = 1, }, }, diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx.h b/arch/arm/mach-omap2/omap_hwmod_44xx.h index 6fb465f25e82..735695e035e8 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx.h +++ b/arch/arm/mach-omap2/omap_hwmod_44xx.h @@ -657,9 +657,11 @@ static struct omap_hwmod_ocp_if *omap44xx_aess_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_aess_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE | + SYSS_MISSING), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), .sysc_fields = &omap_hwmod_sysc_type2, - .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE | SYSS_MISSING, - .idlemodes = SIDLE_FORCE | MSTANDBY_FORCE, }; static struct omap_hwmod omap44xx_aess_hwmod = { @@ -750,7 +752,7 @@ static struct omap_hwmod_ocp_if *omap44xx_dss_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_dss_sysc = { .rev_offs = 0x0000, .syss_offs = 0x0014, - .idlemodes = SIDLE_FORCE, + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), }; static struct omap_hwmod_opt_clk dss_opt_clks[] = { @@ -821,9 +823,11 @@ static struct omap_hwmod_ocp_if *omap44xx_fdif_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_fdif_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSC_HAS_MIDLEMODE | SYSS_MISSING), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), .sysc_fields = &omap_hwmod_sysc_type2, - .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | SYSC_HAS_MIDLEMODE | SYSS_MISSING, - .idlemodes = SIDLE_FORCE | MSTANDBY_FORCE, }; static struct omap_hwmod omap44xx_fdif_hwmod = { @@ -883,9 +887,11 @@ static struct omap_hwmod_ocp_if *omap44xx_gfx_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_gfx_sysc = { .rev_offs = 0xfe00, .sysc_offs = 0xfe10, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE | + SYSS_MISSING), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), .sysc_fields = &omap_hwmod_sysc_type2, - .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE | SYSS_MISSING, - .idlemodes = SIDLE_FORCE | MSTANDBY_FORCE, }; static struct omap_hwmod omap44xx_gfx_hwmod = { @@ -946,7 +952,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hsi_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_hsi_sysc = { .sysc_flags = SYSS_MISSING, - .idlemodes = SIDLE_FORCE, + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), }; static struct omap_hwmod omap44xx_hsi_hwmod = { @@ -1013,9 +1019,11 @@ static struct omap_hwmod_ocp_if *omap44xx_iss_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_iss_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSC_HAS_MIDLEMODE | SYSS_MISSING), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), .sysc_fields = &omap_hwmod_sysc_type2, - .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | SYSC_HAS_MIDLEMODE | SYSS_MISSING, - .idlemodes = SIDLE_FORCE | MSTANDBY_FORCE, }; static struct omap_hwmod_opt_clk iss_opt_clks[] = { @@ -1107,6 +1115,16 @@ static struct omap_hwmod_ocp_if *omap44xx_ivahd_slaves[] = { &omap44xx_l3_2__ivahd, }; +static struct omap_hwmod_sysconfig omap44xx_ivahd_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE | + SYSS_MISSING), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + static struct omap_hwmod omap44xx_ivahd_hwmod = { .name = "ivahd", .mpu_irqs = omap44xx_ivahd_irqs, @@ -1119,6 +1137,7 @@ static struct omap_hwmod omap44xx_ivahd_hwmod = { .device_reg = OMAP4430_CM_IVAHD_IVAHD_CLKCTRL, }, }, + .sysconfig = &omap44xx_ivahd_sysc, .slaves = omap44xx_ivahd_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_ivahd_slaves), .masters = omap44xx_ivahd_masters, @@ -1168,10 +1187,12 @@ static struct omap_hwmod_ocp_if *omap44xx_mmc1_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_mmc1_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, - .sysc_fields = &omap_hwmod_sysc_type2, .syss_offs = 0x0114, - .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET | SYSC_HAS_MIDLEMODE, - .idlemodes = SIDLE_FORCE | MSTANDBY_FORCE, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | + SYSC_HAS_SOFTRESET | SYSC_HAS_MIDLEMODE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type2, }; static struct omap_hwmod omap44xx_mmc1_hwmod = { @@ -1238,10 +1259,12 @@ static struct omap_hwmod_ocp_if *omap44xx_mmc2_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_mmc2_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, - .sysc_fields = &omap_hwmod_sysc_type2, .syss_offs = 0x0114, - .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET | SYSC_HAS_MIDLEMODE, - .idlemodes = SIDLE_FORCE | MSTANDBY_FORCE, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | + SYSC_HAS_SOFTRESET | SYSC_HAS_MIDLEMODE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type2, }; static struct omap_hwmod omap44xx_mmc2_hwmod = { @@ -1348,9 +1371,12 @@ static struct omap_hwmod_ocp_if *omap44xx_unipro1_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_unipro1_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | + SYSC_HAS_SOFTRESET | SYSC_HAS_MIDLEMODE | + SYSS_MISSING), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), .sysc_fields = &omap_hwmod_sysc_type2, - .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET | SYSC_HAS_MIDLEMODE | SYSS_MISSING, - .idlemodes = SIDLE_FORCE | MSTANDBY_FORCE, }; static struct omap_hwmod_opt_clk unipro1_opt_clks[] = { @@ -1481,9 +1507,11 @@ static struct omap_hwmod_sysc_fields omap_hwmod_sysc_type_usb_host_fs = { static struct omap_hwmod_sysconfig omap44xx_usb_host_fs_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0210, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSC_HAS_MIDLEMODE | SYSS_MISSING), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), .sysc_fields = &omap_hwmod_sysc_type_usb_host_fs, - .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | SYSC_HAS_MIDLEMODE | SYSS_MISSING, - .idlemodes = SIDLE_FORCE | MSTANDBY_FORCE, }; static struct omap_hwmod omap44xx_usb_host_fs_hwmod = { @@ -1543,7 +1571,7 @@ static struct omap_hwmod_ocp_if *omap44xx_usb_otg_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_usb_otg_sysc = { .sysc_flags = SYSS_MISSING, - .idlemodes = SIDLE_FORCE, + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), }; static struct omap_hwmod_opt_clk usb_otg_opt_clks[] = { @@ -1666,6 +1694,18 @@ static struct omap_hwmod_ocp_if *omap44xx_sdma_slaves[] = { &omap44xx_l4_cfg__sdma, }; +static struct omap_hwmod_sysconfig omap44xx_sdma_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x002c, + .syss_offs = 0x0028, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSC_HAS_MIDLEMODE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_EMUFREE | SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + static struct omap_hwmod omap44xx_sdma_hwmod = { .name = "sdma", .mpu_irqs = omap44xx_sdma_irqs, @@ -1678,6 +1718,7 @@ static struct omap_hwmod omap44xx_sdma_hwmod = { .device_reg = OMAP4430_CM_SDMA_SDMA_CLKCTRL, }, }, + .sysconfig = &omap44xx_sdma_sysc, .slaves = omap44xx_sdma_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_sdma_slaves), .masters = omap44xx_sdma_masters, @@ -1793,7 +1834,7 @@ static struct omap_hwmod_ocp_if *omap44xx_scrm_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_scrm_sysc = { .sysc_flags = SYSS_MISSING, - .idlemodes = SIDLE_FORCE, + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), }; static struct omap_hwmod omap44xx_scrm_hwmod = { @@ -1951,9 +1992,9 @@ static struct omap_hwmod_ocp_if *omap44xx_devicecorectrl_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_devicecorectrl_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSS_MISSING), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), .sysc_fields = &omap_hwmod_sysc_type2, - .sysc_flags = SYSC_HAS_SIDLEMODE | SYSS_MISSING, - .idlemodes = SIDLE_FORCE, }; static struct omap_hwmod omap44xx_devicecorectrl_hwmod = { @@ -1993,9 +2034,9 @@ static struct omap_hwmod_ocp_if *omap44xx_devicewakeupctrl_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_devicewakeupctrl_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSS_MISSING), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), .sysc_fields = &omap_hwmod_sysc_type2, - .sysc_flags = SYSC_HAS_SIDLEMODE | SYSS_MISSING, - .idlemodes = SIDLE_FORCE, }; static struct omap_hwmod omap44xx_devicewakeupctrl_hwmod = { @@ -2043,9 +2084,10 @@ static struct omap_hwmod_ocp_if *omap44xx_dmic_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_dmic_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | + SYSC_HAS_SOFTRESET | SYSS_MISSING), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), .sysc_fields = &omap_hwmod_sysc_type2, - .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET | SYSS_MISSING, - .idlemodes = SIDLE_FORCE, }; static struct omap_hwmod omap44xx_dmic_hwmod = { @@ -2101,10 +2143,11 @@ static struct omap_hwmod_ocp_if *omap44xx_elm_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_elm_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, - .sysc_fields = &omap_hwmod_sysc_type1, .syss_offs = 0x0014, - .sysc_flags = SYSC_HAS_SOFTRESET | SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_AUTOIDLE, - .idlemodes = SIDLE_FORCE, + .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_SIDLEMODE | + SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, }; static struct omap_hwmod omap44xx_elm_hwmod = { @@ -2156,7 +2199,7 @@ static struct omap_hwmod_ocp_if *omap44xx_emif1_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_emif1_sysc = { .rev_offs = 0x0000, .sysc_flags = SYSS_MISSING, - .idlemodes = SIDLE_FORCE, + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), }; static struct omap_hwmod omap44xx_emif1_hwmod = { @@ -2210,7 +2253,7 @@ static struct omap_hwmod_ocp_if *omap44xx_emif2_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_emif2_sysc = { .rev_offs = 0x0000, .sysc_flags = SYSS_MISSING, - .idlemodes = SIDLE_FORCE, + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), }; static struct omap_hwmod omap44xx_emif2_hwmod = { @@ -2261,19 +2304,18 @@ static struct omap_hwmod_ocp_if *omap44xx_gpio1_slaves[] = { &omap44xx_l4_wkup__gpio1, }; -static struct omap_hwmod_opt_clk gpio1_opt_clks[] = { - { .role = "dbclk", .clkdev_con_id = "sys_32k_ck" }, -}; - static struct omap_hwmod_sysconfig omap44xx_gpio1_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, .syss_offs = 0x0114, - .sysc_flags = (SYSC_HAS_SIDLEMODE | - SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | - SYSC_HAS_AUTOIDLE), + .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), - .sysc_fields = &omap_hwmod_sysc_type1, + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_opt_clk gpio1_opt_clks[] = { + { .role = "dbclk", .clkdev_con_id = "sys_32k_ck" }, }; static struct omap_hwmod omap44xx_gpio1_hwmod = { @@ -2288,9 +2330,9 @@ static struct omap_hwmod omap44xx_gpio1_hwmod = { .device_reg = OMAP4430_CM_WKUP_GPIO1_CLKCTRL, }, }, - .sysconfig = &omap44xx_gpio1_sysc, .opt_clks = gpio1_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks), + .sysconfig = &omap44xx_gpio1_sysc, .slaves = omap44xx_gpio1_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_gpio1_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -2326,19 +2368,18 @@ static struct omap_hwmod_ocp_if *omap44xx_gpio2_slaves[] = { &omap44xx_l4_per__gpio2, }; -static struct omap_hwmod_opt_clk gpio2_opt_clks[] = { - { .role = "dbclk", .clkdev_con_id = "sys_32k_ck" }, -}; - static struct omap_hwmod_sysconfig omap44xx_gpio2_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, .syss_offs = 0x0114, - .sysc_flags = (SYSC_HAS_SIDLEMODE | - SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | - SYSC_HAS_AUTOIDLE), + .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), - .sysc_fields = &omap_hwmod_sysc_type1, + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_opt_clk gpio2_opt_clks[] = { + { .role = "dbclk", .clkdev_con_id = "sys_32k_ck" }, }; static struct omap_hwmod omap44xx_gpio2_hwmod = { @@ -2353,9 +2394,9 @@ static struct omap_hwmod omap44xx_gpio2_hwmod = { .device_reg = OMAP4430_CM_L4PER_GPIO2_CLKCTRL, }, }, - .sysconfig = &omap44xx_gpio2_sysc, .opt_clks = gpio2_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks), + .sysconfig = &omap44xx_gpio2_sysc, .slaves = omap44xx_gpio2_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_gpio2_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -2391,19 +2432,18 @@ static struct omap_hwmod_ocp_if *omap44xx_gpio3_slaves[] = { &omap44xx_l4_per__gpio3, }; -static struct omap_hwmod_opt_clk gpio3_opt_clks[] = { - { .role = "dbclk", .clkdev_con_id = "sys_32k_ck" }, -}; - static struct omap_hwmod_sysconfig omap44xx_gpio3_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, .syss_offs = 0x0114, - .sysc_flags = (SYSC_HAS_SIDLEMODE | - SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | - SYSC_HAS_AUTOIDLE), + .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), - .sysc_fields = &omap_hwmod_sysc_type1, + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_opt_clk gpio3_opt_clks[] = { + { .role = "dbclk", .clkdev_con_id = "sys_32k_ck" }, }; static struct omap_hwmod omap44xx_gpio3_hwmod = { @@ -2418,9 +2458,9 @@ static struct omap_hwmod omap44xx_gpio3_hwmod = { .device_reg = OMAP4430_CM_L4PER_GPIO3_CLKCTRL, }, }, - .sysconfig = &omap44xx_gpio3_sysc, .opt_clks = gpio3_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks), + .sysconfig = &omap44xx_gpio3_sysc, .slaves = omap44xx_gpio3_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_gpio3_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -2456,19 +2496,18 @@ static struct omap_hwmod_ocp_if *omap44xx_gpio4_slaves[] = { &omap44xx_l4_per__gpio4, }; -static struct omap_hwmod_opt_clk gpio4_opt_clks[] = { - { .role = "dbclk", .clkdev_con_id = "sys_32k_ck" }, -}; - static struct omap_hwmod_sysconfig omap44xx_gpio4_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, .syss_offs = 0x0114, - .sysc_flags = (SYSC_HAS_SIDLEMODE | - SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | - SYSC_HAS_AUTOIDLE), + .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), - .sysc_fields = &omap_hwmod_sysc_type1, + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_opt_clk gpio4_opt_clks[] = { + { .role = "dbclk", .clkdev_con_id = "sys_32k_ck" }, }; static struct omap_hwmod omap44xx_gpio4_hwmod = { @@ -2483,9 +2522,9 @@ static struct omap_hwmod omap44xx_gpio4_hwmod = { .device_reg = OMAP4430_CM_L4PER_GPIO4_CLKCTRL, }, }, - .sysconfig = &omap44xx_gpio4_sysc, .opt_clks = gpio4_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio4_opt_clks), + .sysconfig = &omap44xx_gpio4_sysc, .slaves = omap44xx_gpio4_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_gpio4_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -2521,19 +2560,18 @@ static struct omap_hwmod_ocp_if *omap44xx_gpio5_slaves[] = { &omap44xx_l4_per__gpio5, }; -static struct omap_hwmod_opt_clk gpio5_opt_clks[] = { - { .role = "dbclk", .clkdev_con_id = "sys_32k_ck" }, -}; - static struct omap_hwmod_sysconfig omap44xx_gpio5_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, .syss_offs = 0x0114, - .sysc_flags = (SYSC_HAS_SIDLEMODE | - SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | - SYSC_HAS_AUTOIDLE), + .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), - .sysc_fields = &omap_hwmod_sysc_type1, + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_opt_clk gpio5_opt_clks[] = { + { .role = "dbclk", .clkdev_con_id = "sys_32k_ck" }, }; static struct omap_hwmod omap44xx_gpio5_hwmod = { @@ -2548,9 +2586,9 @@ static struct omap_hwmod omap44xx_gpio5_hwmod = { .device_reg = OMAP4430_CM_L4PER_GPIO5_CLKCTRL, }, }, - .sysconfig = &omap44xx_gpio5_sysc, .opt_clks = gpio5_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio5_opt_clks), + .sysconfig = &omap44xx_gpio5_sysc, .slaves = omap44xx_gpio5_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_gpio5_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -2586,19 +2624,18 @@ static struct omap_hwmod_ocp_if *omap44xx_gpio6_slaves[] = { &omap44xx_l4_per__gpio6, }; -static struct omap_hwmod_opt_clk gpio6_opt_clks[] = { - { .role = "dbclk", .clkdev_con_id = "sys_32k_ck" }, -}; - static struct omap_hwmod_sysconfig omap44xx_gpio6_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, .syss_offs = 0x0114, - .sysc_flags = (SYSC_HAS_SIDLEMODE | - SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | - SYSC_HAS_AUTOIDLE), + .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), - .sysc_fields = &omap_hwmod_sysc_type1, + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_opt_clk gpio6_opt_clks[] = { + { .role = "dbclk", .clkdev_con_id = "sys_32k_ck" }, }; static struct omap_hwmod omap44xx_gpio6_hwmod = { @@ -2613,9 +2650,9 @@ static struct omap_hwmod omap44xx_gpio6_hwmod = { .device_reg = OMAP4430_CM_L4PER_GPIO6_CLKCTRL, }, }, - .sysconfig = &omap44xx_gpio6_sysc, .opt_clks = gpio6_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio6_opt_clks), + .sysconfig = &omap44xx_gpio6_sysc, .slaves = omap44xx_gpio6_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_gpio6_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -2655,6 +2692,16 @@ static struct omap_hwmod_ocp_if *omap44xx_gpmc_slaves[] = { &omap44xx_l3_2__gpmc, }; +static struct omap_hwmod_sysconfig omap44xx_gpmc_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + static struct omap_hwmod omap44xx_gpmc_hwmod = { .name = "gpmc", .mpu_irqs = omap44xx_gpmc_irqs, @@ -2669,6 +2716,7 @@ static struct omap_hwmod omap44xx_gpmc_hwmod = { .device_reg = OMAP4430_CM_L3_2_GPMC_CLKCTRL, }, }, + .sysconfig = &omap44xx_gpmc_sysc, .slaves = omap44xx_gpmc_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_gpmc_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -2707,12 +2755,12 @@ static struct omap_hwmod_ocp_if *omap44xx_gptimer1_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_gptimer1_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, - .sysc_fields = &omap_hwmod_sysc_type1, .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | SYSC_HAS_EMUFREE | SYSC_HAS_AUTOIDLE | SYSS_MISSING), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, }; static struct omap_hwmod omap44xx_gptimer1_hwmod = { @@ -2766,12 +2814,12 @@ static struct omap_hwmod_ocp_if *omap44xx_gptimer10_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_gptimer10_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, - .sysc_fields = &omap_hwmod_sysc_type1, .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | SYSC_HAS_EMUFREE | SYSC_HAS_AUTOIDLE | SYSS_MISSING), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, }; static struct omap_hwmod omap44xx_gptimer10_hwmod = { @@ -2825,10 +2873,10 @@ static struct omap_hwmod_ocp_if *omap44xx_gptimer11_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_gptimer11_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, - .sysc_fields = &omap_hwmod_sysc_type2, .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET | SYSS_MISSING), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type2, }; static struct omap_hwmod omap44xx_gptimer11_hwmod = { @@ -2884,12 +2932,12 @@ static struct omap_hwmod_ocp_if *omap44xx_gptimer2_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_gptimer2_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, - .sysc_fields = &omap_hwmod_sysc_type1, .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | SYSC_HAS_EMUFREE | SYSC_HAS_AUTOIDLE | SYSS_MISSING), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, }; static struct omap_hwmod omap44xx_gptimer2_hwmod = { @@ -2943,10 +2991,10 @@ static struct omap_hwmod_ocp_if *omap44xx_gptimer3_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_gptimer3_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, - .sysc_fields = &omap_hwmod_sysc_type2, .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET | SYSS_MISSING), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type2, }; static struct omap_hwmod omap44xx_gptimer3_hwmod = { @@ -3000,10 +3048,10 @@ static struct omap_hwmod_ocp_if *omap44xx_gptimer4_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_gptimer4_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, - .sysc_fields = &omap_hwmod_sysc_type2, .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET | SYSS_MISSING), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type2, }; static struct omap_hwmod omap44xx_gptimer4_hwmod = { @@ -3057,10 +3105,10 @@ static struct omap_hwmod_ocp_if *omap44xx_gptimer5_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_gptimer5_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, - .sysc_fields = &omap_hwmod_sysc_type2, .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET | SYSS_MISSING), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type2, }; static struct omap_hwmod omap44xx_gptimer5_hwmod = { @@ -3114,10 +3162,10 @@ static struct omap_hwmod_ocp_if *omap44xx_gptimer6_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_gptimer6_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, - .sysc_fields = &omap_hwmod_sysc_type2, .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET | SYSS_MISSING), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type2, }; static struct omap_hwmod omap44xx_gptimer6_hwmod = { @@ -3171,9 +3219,10 @@ static struct omap_hwmod_ocp_if *omap44xx_gptimer7_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_gptimer7_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | + SYSC_HAS_SOFTRESET | SYSS_MISSING), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), .sysc_fields = &omap_hwmod_sysc_type2, - .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET | SYSS_MISSING, - .idlemodes = SIDLE_FORCE, }; static struct omap_hwmod omap44xx_gptimer7_hwmod = { @@ -3227,10 +3276,10 @@ static struct omap_hwmod_ocp_if *omap44xx_gptimer8_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_gptimer8_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, - .sysc_fields = &omap_hwmod_sysc_type2, .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET | SYSS_MISSING), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type2, }; static struct omap_hwmod omap44xx_gptimer8_hwmod = { @@ -3284,10 +3333,10 @@ static struct omap_hwmod_ocp_if *omap44xx_gptimer9_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_gptimer9_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, - .sysc_fields = &omap_hwmod_sysc_type2, .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET | SYSS_MISSING), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type2, }; static struct omap_hwmod omap44xx_gptimer9_hwmod = { @@ -3338,6 +3387,15 @@ static struct omap_hwmod_ocp_if *omap44xx_hdq1w_slaves[] = { &omap44xx_l4_per__hdq1w, }; +static struct omap_hwmod_sysconfig omap44xx_hdq1w_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0014, + .syss_offs = 0x0018, + .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + static struct omap_hwmod omap44xx_hdq1w_hwmod = { .name = "hdq1w", .mpu_irqs = omap44xx_hdq1w_irqs, @@ -3350,6 +3408,7 @@ static struct omap_hwmod omap44xx_hdq1w_hwmod = { .device_reg = OMAP4430_CM_L4PER_HDQ1W_CLKCTRL, }, }, + .sysconfig = &omap44xx_hdq1w_sysc, .slaves = omap44xx_hdq1w_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_hdq1w_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -3392,10 +3451,12 @@ static struct omap_hwmod_ocp_if *omap44xx_i2c1_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_i2c1_sysc = { .sysc_offs = 0x0010, - .sysc_fields = &omap_hwmod_sysc_type1, .syss_offs = 0x0090, - .sysc_flags = SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE, - .idlemodes = SIDLE_FORCE, + .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, }; static struct omap_hwmod omap44xx_i2c1_hwmod = { @@ -3455,10 +3516,12 @@ static struct omap_hwmod_ocp_if *omap44xx_i2c2_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_i2c2_sysc = { .sysc_offs = 0x0010, - .sysc_fields = &omap_hwmod_sysc_type1, .syss_offs = 0x0090, - .sysc_flags = SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE, - .idlemodes = SIDLE_FORCE, + .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, }; static struct omap_hwmod omap44xx_i2c2_hwmod = { @@ -3518,10 +3581,12 @@ static struct omap_hwmod_ocp_if *omap44xx_i2c3_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_i2c3_sysc = { .sysc_offs = 0x0010, - .sysc_fields = &omap_hwmod_sysc_type1, .syss_offs = 0x0090, - .sysc_flags = SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE, - .idlemodes = SIDLE_FORCE, + .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, }; static struct omap_hwmod omap44xx_i2c3_hwmod = { @@ -3581,10 +3646,12 @@ static struct omap_hwmod_ocp_if *omap44xx_i2c4_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_i2c4_sysc = { .sysc_offs = 0x0010, - .sysc_fields = &omap_hwmod_sysc_type1, .syss_offs = 0x0090, - .sysc_flags = SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE, - .idlemodes = SIDLE_FORCE, + .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, }; static struct omap_hwmod omap44xx_i2c4_hwmod = { @@ -3640,10 +3707,12 @@ static struct omap_hwmod_ocp_if *omap44xx_keyboard_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_keyboard_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, - .sysc_fields = &omap_hwmod_sysc_type1, .syss_offs = 0x0014, - .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | SYSC_HAS_EMUFREE | SYSC_HAS_AUTOIDLE, - .idlemodes = SIDLE_FORCE, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | + SYSC_HAS_EMUFREE | SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, }; static struct omap_hwmod omap44xx_keyboard_hwmod = { @@ -3672,8 +3741,8 @@ static struct omap_hwmod_irq_info omap44xx_mailbox_irqs[] = { static struct omap_hwmod_addr_space omap44xx_mailbox_addrs[] = { { - .pa_start = 0x5a05a800, - .pa_end = 0x5a05a9ff, + .pa_start = 0x4A0F4000, + .pa_end = 0x4A0F41FF, .flags = ADDR_TYPE_RT }, }; @@ -3694,6 +3763,15 @@ static struct omap_hwmod_ocp_if *omap44xx_mailbox_slaves[] = { &omap44xx_l4_cfg__mailbox, }; +static struct omap_hwmod_sysconfig omap44xx_mailbox_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSS_MISSING), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + static struct omap_hwmod omap44xx_mailbox_hwmod = { .name = "mailbox", .mpu_irqs = omap44xx_mailbox_irqs, @@ -3704,6 +3782,7 @@ static struct omap_hwmod omap44xx_mailbox_hwmod = { .device_reg = OMAP4430_CM_L4CFG_MAILBOX_CLKCTRL, }, }, + .sysconfig = &omap44xx_mailbox_sysc, .slaves = omap44xx_mailbox_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_mailbox_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -3752,9 +3831,9 @@ static struct omap_hwmod_sysc_fields omap_hwmod_sysc_type_mcasp = { static struct omap_hwmod_sysconfig omap44xx_mcasp_sysc = { .sysc_offs = 0x0004, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSS_MISSING), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), .sysc_fields = &omap_hwmod_sysc_type_mcasp, - .sysc_flags = SYSC_HAS_SIDLEMODE | SYSS_MISSING, - .idlemodes = SIDLE_FORCE, }; static struct omap_hwmod omap44xx_mcasp_hwmod = { @@ -3814,9 +3893,11 @@ static struct omap_hwmod_ocp_if *omap44xx_mcbsp1_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_mcbsp1_sysc = { .sysc_offs = 0x008c, + .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SOFTRESET | + SYSS_MISSING), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), .sysc_fields = &omap_hwmod_sysc_type1, - .sysc_flags = SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SOFTRESET | SYSS_MISSING, - .idlemodes = SIDLE_FORCE, }; static struct omap_hwmod omap44xx_mcbsp1_hwmod = { @@ -3876,9 +3957,11 @@ static struct omap_hwmod_ocp_if *omap44xx_mcbsp2_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_mcbsp2_sysc = { .sysc_offs = 0x008c, + .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SOFTRESET | + SYSS_MISSING), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), .sysc_fields = &omap_hwmod_sysc_type1, - .sysc_flags = SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SOFTRESET | SYSS_MISSING, - .idlemodes = SIDLE_FORCE, }; static struct omap_hwmod omap44xx_mcbsp2_hwmod = { @@ -3938,9 +4021,11 @@ static struct omap_hwmod_ocp_if *omap44xx_mcbsp3_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_mcbsp3_sysc = { .sysc_offs = 0x008c, + .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SOFTRESET | + SYSS_MISSING), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), .sysc_fields = &omap_hwmod_sysc_type1, - .sysc_flags = SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SOFTRESET | SYSS_MISSING, - .idlemodes = SIDLE_FORCE, }; static struct omap_hwmod omap44xx_mcbsp3_hwmod = { @@ -4000,9 +4085,11 @@ static struct omap_hwmod_ocp_if *omap44xx_mcbsp4_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_mcbsp4_sysc = { .sysc_offs = 0x008c, + .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SOFTRESET | + SYSS_MISSING), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), .sysc_fields = &omap_hwmod_sysc_type1, - .sysc_flags = SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SOFTRESET | SYSS_MISSING, - .idlemodes = SIDLE_FORCE, }; static struct omap_hwmod omap44xx_mcbsp4_hwmod = { @@ -4069,10 +4156,11 @@ static struct omap_hwmod_ocp_if *omap44xx_mcspi1_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_mcspi1_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, - .sysc_fields = &omap_hwmod_sysc_type2, .syss_offs = 0x0114, - .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET, - .idlemodes = SIDLE_FORCE, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | + SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type2, }; static struct omap_hwmod omap44xx_mcspi1_hwmod = { @@ -4135,10 +4223,11 @@ static struct omap_hwmod_ocp_if *omap44xx_mcspi2_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_mcspi2_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, - .sysc_fields = &omap_hwmod_sysc_type2, .syss_offs = 0x0114, - .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET, - .idlemodes = SIDLE_FORCE, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | + SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type2, }; static struct omap_hwmod omap44xx_mcspi2_hwmod = { @@ -4201,10 +4290,11 @@ static struct omap_hwmod_ocp_if *omap44xx_mcspi3_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_mcspi3_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, - .sysc_fields = &omap_hwmod_sysc_type2, .syss_offs = 0x0114, - .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET, - .idlemodes = SIDLE_FORCE, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | + SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type2, }; static struct omap_hwmod omap44xx_mcspi3_hwmod = { @@ -4265,10 +4355,11 @@ static struct omap_hwmod_ocp_if *omap44xx_mcspi4_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_mcspi4_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, - .sysc_fields = &omap_hwmod_sysc_type2, .syss_offs = 0x0114, - .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET, - .idlemodes = SIDLE_FORCE, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | + SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type2, }; static struct omap_hwmod omap44xx_mcspi4_hwmod = { @@ -4329,10 +4420,12 @@ static struct omap_hwmod_ocp_if *omap44xx_mmc3_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_mmc3_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, - .sysc_fields = &omap_hwmod_sysc_type2, .syss_offs = 0x0114, - .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET | SYSC_HAS_MIDLEMODE, - .idlemodes = SIDLE_FORCE | MSTANDBY_FORCE, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | + SYSC_HAS_SOFTRESET | SYSC_HAS_MIDLEMODE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type2, }; static struct omap_hwmod omap44xx_mmc3_hwmod = { @@ -4393,10 +4486,12 @@ static struct omap_hwmod_ocp_if *omap44xx_mmc4_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_mmc4_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, - .sysc_fields = &omap_hwmod_sysc_type2, .syss_offs = 0x0114, - .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET | SYSC_HAS_MIDLEMODE, - .idlemodes = SIDLE_FORCE | MSTANDBY_FORCE, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | + SYSC_HAS_SOFTRESET | SYSC_HAS_MIDLEMODE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type2, }; static struct omap_hwmod omap44xx_mmc4_hwmod = { @@ -4457,10 +4552,12 @@ static struct omap_hwmod_ocp_if *omap44xx_mmc5_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_mmc5_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, - .sysc_fields = &omap_hwmod_sysc_type2, .syss_offs = 0x0114, - .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET | SYSC_HAS_MIDLEMODE, - .idlemodes = SIDLE_FORCE | MSTANDBY_FORCE, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | + SYSC_HAS_SOFTRESET | SYSC_HAS_MIDLEMODE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type2, }; static struct omap_hwmod omap44xx_mmc5_hwmod = { @@ -4550,9 +4647,10 @@ static struct omap_hwmod_ocp_if *omap44xx_pdm_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_pdm_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | + SYSC_HAS_SOFTRESET | SYSS_MISSING), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), .sysc_fields = &omap_hwmod_sysc_type2, - .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET | SYSS_MISSING, - .idlemodes = SIDLE_FORCE, }; static struct omap_hwmod omap44xx_pdm_hwmod = { @@ -4661,9 +4759,10 @@ static struct omap_hwmod_ocp_if *omap44xx_slimbus1_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_slimbus1_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSS_MISSING), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), .sysc_fields = &omap_hwmod_sysc_type2, - .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | SYSS_MISSING, - .idlemodes = SIDLE_FORCE, }; static struct omap_hwmod_opt_clk slimbus1_opt_clks[] = { @@ -4739,9 +4838,10 @@ static struct omap_hwmod_ocp_if *omap44xx_slimbus2_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_slimbus2_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSS_MISSING), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), .sysc_fields = &omap_hwmod_sysc_type2, - .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | SYSS_MISSING, - .idlemodes = SIDLE_FORCE, }; static struct omap_hwmod_opt_clk slimbus2_opt_clks[] = { @@ -4798,6 +4898,16 @@ static struct omap_hwmod_ocp_if *omap44xx_spinlock_slaves[] = { &omap44xx_l4_cfg__spinlock, }; +static struct omap_hwmod_sysconfig omap44xx_spinlock_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE | SYSS_MISSING), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + static struct omap_hwmod omap44xx_spinlock_hwmod = { .name = "spinlock", .prcm = { @@ -4806,6 +4916,7 @@ static struct omap_hwmod omap44xx_spinlock_hwmod = { .device_reg = OMAP4430_CM_L4CFG_HW_SEM_CLKCTRL, }, }, + .sysconfig = &omap44xx_spinlock_sysc, .slaves = omap44xx_spinlock_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_spinlock_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -4849,9 +4960,10 @@ static struct omap_hwmod_sysc_fields omap_hwmod_sysc_type_sr_core = { static struct omap_hwmod_sysconfig omap44xx_sr_core_sysc = { .sysc_offs = 0x0038, + .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSS_MISSING), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), .sysc_fields = &omap_hwmod_sysc_type_sr_core, - .sysc_flags = SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | SYSS_MISSING, - .idlemodes = SIDLE_FORCE, }; static struct omap_hwmod omap44xx_sr_core_hwmod = { @@ -4910,9 +5022,10 @@ static struct omap_hwmod_sysc_fields omap_hwmod_sysc_type_sr_iva = { static struct omap_hwmod_sysconfig omap44xx_sr_iva_sysc = { .sysc_offs = 0x0038, + .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSS_MISSING), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), .sysc_fields = &omap_hwmod_sysc_type_sr_iva, - .sysc_flags = SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | SYSS_MISSING, - .idlemodes = SIDLE_FORCE, }; static struct omap_hwmod omap44xx_sr_iva_hwmod = { @@ -4971,9 +5084,10 @@ static struct omap_hwmod_sysc_fields omap_hwmod_sysc_type_sr_mpu = { static struct omap_hwmod_sysconfig omap44xx_sr_mpu_sysc = { .sysc_offs = 0x0038, + .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSS_MISSING), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), .sysc_fields = &omap_hwmod_sysc_type_sr_mpu, - .sysc_flags = SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | SYSS_MISSING, - .idlemodes = SIDLE_FORCE, }; static struct omap_hwmod omap44xx_sr_mpu_hwmod = { @@ -5023,9 +5137,9 @@ static struct omap_hwmod_ocp_if *omap44xx_synctimer_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_synctimer_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0004, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSS_MISSING), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), .sysc_fields = &omap_hwmod_sysc_type1, - .sysc_flags = SYSC_HAS_SIDLEMODE | SYSS_MISSING, - .idlemodes = SIDLE_FORCE, }; static struct omap_hwmod omap44xx_synctimer_hwmod = { @@ -5058,7 +5172,7 @@ static struct omap_hwmod_dma_info omap44xx_uart1_sdma_chs[] = { static struct omap_hwmod_addr_space omap44xx_uart1_addrs[] = { { .pa_start = 0x4806a000, - .pa_end = 0x4806a07f, + .pa_end = 0x4806a0ff, .flags = ADDR_TYPE_RT }, }; @@ -5080,11 +5194,13 @@ static struct omap_hwmod_ocp_if *omap44xx_uart1_slaves[] = { }; static struct omap_hwmod_sysconfig omap44xx_uart1_sysc = { + .rev_offs = 0x0050, .sysc_offs = 0x0054, - .sysc_fields = &omap_hwmod_sysc_type1, .syss_offs = 0x0058, - .sysc_flags = SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE, - .idlemodes = SIDLE_FORCE, + .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, }; static struct omap_hwmod omap44xx_uart1_hwmod = { @@ -5121,7 +5237,7 @@ static struct omap_hwmod_dma_info omap44xx_uart2_sdma_chs[] = { static struct omap_hwmod_addr_space omap44xx_uart2_addrs[] = { { .pa_start = 0x4806c000, - .pa_end = 0x4806c07f, + .pa_end = 0x4806c0ff, .flags = ADDR_TYPE_RT }, }; @@ -5143,11 +5259,13 @@ static struct omap_hwmod_ocp_if *omap44xx_uart2_slaves[] = { }; static struct omap_hwmod_sysconfig omap44xx_uart2_sysc = { + .rev_offs = 0x0050, .sysc_offs = 0x0054, - .sysc_fields = &omap_hwmod_sysc_type1, .syss_offs = 0x0058, - .sysc_flags = SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE, - .idlemodes = SIDLE_FORCE, + .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, }; static struct omap_hwmod omap44xx_uart2_hwmod = { @@ -5184,7 +5302,7 @@ static struct omap_hwmod_dma_info omap44xx_uart3_sdma_chs[] = { static struct omap_hwmod_addr_space omap44xx_uart3_addrs[] = { { .pa_start = 0x48020000, - .pa_end = 0x4802007f, + .pa_end = 0x480200ff, .flags = ADDR_TYPE_RT }, }; @@ -5206,11 +5324,13 @@ static struct omap_hwmod_ocp_if *omap44xx_uart3_slaves[] = { }; static struct omap_hwmod_sysconfig omap44xx_uart3_sysc = { + .rev_offs = 0x0050, .sysc_offs = 0x0054, - .sysc_fields = &omap_hwmod_sysc_type1, .syss_offs = 0x0058, - .sysc_flags = SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE, - .idlemodes = SIDLE_FORCE, + .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, }; static struct omap_hwmod omap44xx_uart3_hwmod = { @@ -5247,7 +5367,7 @@ static struct omap_hwmod_dma_info omap44xx_uart4_sdma_chs[] = { static struct omap_hwmod_addr_space omap44xx_uart4_addrs[] = { { .pa_start = 0x4806e000, - .pa_end = 0x4806e07f, + .pa_end = 0x4806e0ff, .flags = ADDR_TYPE_RT }, }; @@ -5269,11 +5389,13 @@ static struct omap_hwmod_ocp_if *omap44xx_uart4_slaves[] = { }; static struct omap_hwmod_sysconfig omap44xx_uart4_sysc = { + .rev_offs = 0x0050, .sysc_offs = 0x0054, - .sysc_fields = &omap_hwmod_sysc_type1, .syss_offs = 0x0058, - .sysc_flags = SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE, - .idlemodes = SIDLE_FORCE, + .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, }; static struct omap_hwmod omap44xx_uart4_hwmod = { @@ -5329,10 +5451,12 @@ static struct omap_hwmod_ocp_if *omap44xx_usb_tll_slaves[] = { static struct omap_hwmod_sysconfig omap44xx_usb_tll_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, - .sysc_fields = &omap_hwmod_sysc_type1, .syss_offs = 0x0014, - .sysc_flags = SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE, - .idlemodes = SIDLE_FORCE, + .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, }; static struct omap_hwmod_opt_clk usb_tll_opt_clks[] = { @@ -5486,8 +5610,13 @@ static struct omap_hwmod_ocp_if *omap44xx_wdt2_slaves[] = { }; static struct omap_hwmod_sysconfig omap44xx_wdt2_sysc = { - .sysc_flags = SYSS_MISSING, - .idlemodes = SIDLE_FORCE, + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | + SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, }; static struct omap_hwmod omap44xx_wdt2_hwmod = { @@ -5516,8 +5645,8 @@ static struct omap_hwmod_irq_info omap44xx_wdt3_irqs[] = { static struct omap_hwmod_addr_space omap44xx_wdt3_addrs[] = { { - .pa_start = 0x40104c00, - .pa_end = 0x40104c3f, + .pa_start = 0x40130000, + .pa_end = 0x4013007f, .flags = ADDR_TYPE_RT }, }; @@ -5538,6 +5667,16 @@ static struct omap_hwmod_ocp_if *omap44xx_wdt3_slaves[] = { &omap44xx_l4_audio__wdt3, }; +static struct omap_hwmod_sysconfig omap44xx_wdt3_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | + SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + static struct omap_hwmod omap44xx_wdt3_hwmod = { .name = "wdt3", .mpu_irqs = omap44xx_wdt3_irqs, @@ -5550,6 +5689,7 @@ static struct omap_hwmod omap44xx_wdt3_hwmod = { .device_reg = OMAP4430_CM1_ABE_WDT3_CLKCTRL, }, }, + .sysconfig = &omap44xx_wdt3_sysc, .slaves = omap44xx_wdt3_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_wdt3_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), @@ -5643,6 +5783,7 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = { &omap44xx_l4_per_hwmod, &omap44xx_l4_wkup_hwmod, &omap44xx_sad2d_fw_hwmod, + /* processor_dma_engine */ &omap44xx_tesla_hwmod, @@ -5706,18 +5847,14 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = { &omap44xx_mmc4_hwmod, &omap44xx_mmc5_hwmod, &omap44xx_ocmc_ram_hwmod, -#if 0 &omap44xx_pdm_hwmod, -#endif &omap44xx_sl2_hwmod, &omap44xx_slimbus1_hwmod, &omap44xx_slimbus2_hwmod, &omap44xx_spinlock_hwmod, -#if 0 &omap44xx_sr_core_hwmod, &omap44xx_sr_iva_hwmod, &omap44xx_sr_mpu_hwmod, -#endif &omap44xx_synctimer_hwmod, &omap44xx_uart1_hwmod, &omap44xx_uart2_hwmod, @@ -5737,9 +5874,7 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = { &omap44xx_gfx_hwmod, #endif &omap44xx_hsi_hwmod, -#if 0 &omap44xx_iss_hwmod, -#endif &omap44xx_ivahd_hwmod, &omap44xx_mmc1_hwmod, &omap44xx_mmc2_hwmod, diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index 77f0cd29869f..dc2e8cfbd5f1 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -51,13 +51,11 @@ extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl, extern void omap34xx_cpu_suspend(u32 *addr, int save_state); extern void save_secure_ram_context(u32 *addr); extern void omap3_save_scratchpad_contents(void); -extern void omap44xx_cpu_suspend(void); extern unsigned int omap24xx_idle_loop_suspend_sz; extern unsigned int omap34xx_suspend_sz; extern unsigned int save_secure_ram_context_sz; extern unsigned int omap24xx_cpu_suspend_sz; extern unsigned int omap34xx_cpu_suspend_sz; -extern unsigned int omap44xx_cpu_suspend_sz; #endif diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index 4c0cd88eb0a9..d13aff317f61 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -18,11 +18,13 @@ #include <linux/clk.h> #include <linux/io.h> #include <plat/control.h> -#include <plat/sram.h> #include <plat/clockdomain.h> #include <plat/powerdomain.h> #include "prm.h" #include "pm.h" +#include "cm.h" +#include "cm-regbits-44xx.h" +#include "clock.h" struct power_state { struct powerdomain *pwrdm; @@ -35,8 +37,6 @@ struct power_state { static LIST_HEAD(pwrst_list); -int (*_omap_sram_idle)(void); - static struct powerdomain *cpu0_pwrdm, *cpu1_pwrdm, *mpu_pwrdm; /* This sets pwrdm state (other than mpu & core. Currently only ON & @@ -111,18 +111,18 @@ static int omap4_pm_suspend(void) if (set_pwrdm_state(pwrst->pwrdm, PWRDM_POWER_RET)) goto restore; - if (_omap_sram_idle) - _omap_sram_idle(); - else - asm volatile("wfi\n" - : - : - : "memory", "cc"); + isb(); + wmb(); + asm volatile("wfi\n" + : + : + : "memory", "cc"); restore: /* Restore next_pwrsts */ list_for_each_entry(pwrst, &pwrst_list, node) { state = pwrdm_read_pwrst(pwrst->pwrdm); - printk("Powerdomain (%s) entered state %d\n", pwrst->pwrdm->name, state); + printk(KERN_INFO "Powerdomain (%s) entered state %d\n", + pwrst->pwrdm->name, state); if (strcmp(pwrst->pwrdm->name, "cpu1_pwrdm")) set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state); } @@ -174,7 +174,8 @@ static struct platform_suspend_ops omap_pm_ops = { }; #endif /* CONFIG_SUSPEND */ -static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) +static int __attribute__ ((unused)) __init + pwrdms_setup(struct powerdomain *pwrdm, void *unused) { struct power_state *pwrst; @@ -199,7 +200,8 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) * supported. Initiate sleep transition for other clockdomains, if * they are not used */ -static int __init clkdms_setup(struct clockdomain *clkdm, void *unused) +static int __attribute__ ((unused)) __init + clkdms_setup(struct clockdomain *clkdm, void *unused) { if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO) omap2_clkdm_allow_idle(clkdm); @@ -209,13 +211,83 @@ static int __init clkdms_setup(struct clockdomain *clkdm, void *unused) return 0; } -#ifdef CONFIG_PM -void omap_push_sram_idle(void) +void __raw_rmw_reg_bits(u32 mask, u32 bits, const volatile void __iomem *addr) { - _omap_sram_idle = omap_sram_push(omap44xx_cpu_suspend, - omap44xx_cpu_suspend_sz); + u32 v; + + v = __raw_readl(addr); + v &= ~mask; + v |= bits; + __raw_writel(v, addr); + +} + +static void __init prcm_setup_regs(void) +{ + struct clk *dpll_abe_ck, *dpll_core_ck, *dpll_iva_ck; + struct clk *dpll_mpu_ck, *dpll_per_ck, *dpll_usb_ck; + struct clk *dpll_unipro_ck; + + /*Enable all the DPLL autoidle */ + dpll_abe_ck = clk_get(NULL, "dpll_abe_ck"); + omap3_dpll_allow_idle(dpll_abe_ck); + dpll_core_ck = clk_get(NULL, "dpll_core_ck"); + omap3_dpll_allow_idle(dpll_core_ck); + dpll_iva_ck = clk_get(NULL, "dpll_iva_ck"); + omap3_dpll_allow_idle(dpll_iva_ck); + dpll_mpu_ck = clk_get(NULL, "dpll_mpu_ck"); + omap3_dpll_allow_idle(dpll_mpu_ck); + dpll_per_ck = clk_get(NULL, "dpll_per_ck"); + omap3_dpll_allow_idle(dpll_per_ck); + dpll_usb_ck = clk_get(NULL, "dpll_usb_ck"); + omap3_dpll_allow_idle(dpll_usb_ck); + dpll_unipro_ck = clk_get(NULL, "dpll_unipro_ck"); + omap3_dpll_allow_idle(dpll_unipro_ck); + + /* Enable autogating for all DPLL post dividers */ + __raw_rmw_reg_bits(OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK, 0x0, + OMAP4430_CM_DIV_M2_DPLL_MPU); + __raw_rmw_reg_bits(OMAP4430_HSDIVIDER_CLKOUT1_GATE_CTRL_MASK, 0x0, + OMAP4430_CM_DIV_M4_DPLL_IVA); + __raw_rmw_reg_bits(OMAP4430_HSDIVIDER_CLKOUT2_GATE_CTRL_MASK, 0x0, + OMAP4430_CM_DIV_M5_DPLL_IVA); + __raw_rmw_reg_bits(OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK, 0x0, + OMAP4430_CM_DIV_M2_DPLL_CORE); + __raw_rmw_reg_bits(OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_MASK, 0x0, + OMAP4430_CM_DIV_M3_DPLL_CORE); + __raw_rmw_reg_bits(OMAP4430_HSDIVIDER_CLKOUT1_GATE_CTRL_MASK, 0x0, + OMAP4430_CM_DIV_M4_DPLL_CORE); + __raw_rmw_reg_bits(OMAP4430_HSDIVIDER_CLKOUT2_GATE_CTRL_MASK, 0x0, + OMAP4430_CM_DIV_M5_DPLL_CORE); + __raw_rmw_reg_bits(OMAP4430_HSDIVIDER_CLKOUT3_GATE_CTRL_MASK, 0x0, + OMAP4430_CM_DIV_M6_DPLL_CORE); + __raw_rmw_reg_bits(OMAP4430_HSDIVIDER_CLKOUT4_GATE_CTRL_MASK, 0x0, + OMAP4430_CM_DIV_M7_DPLL_CORE); + __raw_rmw_reg_bits(OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK, 0x0, + OMAP4430_CM_DIV_M2_DPLL_PER); + __raw_rmw_reg_bits(OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK, 0x0, + OMAP4430_CM_DIV_M2_DPLL_PER); + __raw_rmw_reg_bits(OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_MASK, 0x0, + OMAP4430_CM_DIV_M3_DPLL_PER); + __raw_rmw_reg_bits(OMAP4430_HSDIVIDER_CLKOUT1_GATE_CTRL_MASK, 0x0, + OMAP4430_CM_DIV_M4_DPLL_PER); + __raw_rmw_reg_bits(OMAP4430_HSDIVIDER_CLKOUT2_GATE_CTRL_MASK, 0x0, + OMAP4430_CM_DIV_M5_DPLL_PER); + __raw_rmw_reg_bits(OMAP4430_HSDIVIDER_CLKOUT3_GATE_CTRL_MASK, 0x0, + OMAP4430_CM_DIV_M6_DPLL_PER); + __raw_rmw_reg_bits(OMAP4430_HSDIVIDER_CLKOUT4_GATE_CTRL_MASK, 0x0, + OMAP4430_CM_DIV_M7_DPLL_PER); + __raw_rmw_reg_bits(OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK, 0x0, + OMAP4430_CM_DIV_M2_DPLL_ABE); + __raw_rmw_reg_bits(OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK, 0x0, + OMAP4430_CM_DIV_M2_DPLL_ABE); + __raw_rmw_reg_bits(OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_MASK, 0x0, + OMAP4430_CM_DIV_M3_DPLL_ABE); + __raw_rmw_reg_bits(OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK, 0x0, + OMAP4430_CM_DIV_M2_DPLL_USB); + __raw_rmw_reg_bits(OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK, 0x0, + OMAP4430_CM_DIV_M2_DPLL_UNIPRO); } -#endif static int __init omap4_pm_init(void) { @@ -224,9 +296,11 @@ static int __init omap4_pm_init(void) if (!cpu_is_omap44xx()) return -ENODEV; - printk(KERN_ERR "Power Management for TI OMAP4.\n"); + printk(KERN_INFO "Power Management for TI OMAP4.\n"); #ifdef CONFIG_PM + prcm_setup_regs(); + ret = pwrdm_for_each(pwrdms_setup, NULL); if (ret) { printk(KERN_ERR "Failed to setup powerdomains\n"); diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c index 05cb75ef87b3..7a1dc84f10b3 100644 --- a/arch/arm/mach-omap2/prcm.c +++ b/arch/arm/mach-omap2/prcm.c @@ -130,6 +130,7 @@ u32 omap_prcm_get_reset_sources(void) return prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTST) & 0x7f; if (cpu_is_omap44xx()) return prm_read_mod_reg(WKUP_MOD, OMAP4_RM_RSTST) & 0x7f; + return -EIO; } EXPORT_SYMBOL(omap_prcm_get_reset_sources); diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index ad4f1ec91e91..ed19c1e5bf26 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -27,6 +27,8 @@ #include <linux/platform_device.h> #include <linux/serial_8250.h> +#include <plat/omap-serial.h> + #include <plat/common.h> #include <plat/board.h> #include <plat/clock.h> @@ -254,7 +256,7 @@ static void omap_uart_disable_wakeup(struct omap_uart_state *uart) } } -static inline void omap_uart_smart_idle_enable(struct omap_uart_state *p, +static inline int omap_uart_smart_idle_enable(struct omap_uart_state *p, int enable) { u32 sysc; @@ -286,6 +288,8 @@ static inline void omap_uart_smart_idle_enable(struct omap_uart_state *p, sysc |= 0x1 << sidle_shift; } omap_hwmod_write_sysc(sysc, p->oh); + + return 0; } static void omap_uart_block_sleep(struct omap_uart_state *uart) @@ -542,6 +546,7 @@ static void omap_uart_block_sleep(struct omap_uart_state *uart) #define DEV_CREATE_FILE(dev, attr) #endif /* CONFIG_PM */ +#ifdef CONFIG_SERIAL_8250 /* * Override the default 8250 read handler: mem_serial_in() * Empty RX fifo read causes an abort on omap3630 and omap4 @@ -558,21 +563,7 @@ static unsigned int serial_in_override(struct uart_port *up, int offset) } return __serial_read_reg(up, offset); } - -static void serial_out_override(struct uart_port *up, int offset, int value) -{ - unsigned int status, tmout = 10000; - - /* Wait up to 10ms for the character(s) to be sent. */ - do { - status = __serial_read_reg(up, UART_LSR); - if (--tmout == 0) - break; - udelay(1); - } while (!(status & UART_LSR_THRE)); - - __serial_write_reg(up, offset, value); -} +#endif void __init omap_serial_early_init(void) { @@ -623,7 +614,21 @@ void __init omap_serial_early_init(void) void __init omap_serial_init_port(int port) { struct omap_uart_state *uart; + struct omap_hwmod *oh; + struct omap_device *od; + void *pdata = NULL; + u32 pdata_size = 0; char *name; +#ifdef CONFIG_SERIAL_8250 + struct plat_serial8250_port ports[2] = { + {}, + {.flags = 0}, + }; + struct plat_serial8250_port *p = &ports[0]; +#endif +#ifdef CONFIG_SERIAL_OMAP + struct omap_uart_port_info omap_up; +#endif BUG_ON(port < 0); BUG_ON(port >= num_uarts); @@ -632,20 +637,10 @@ void __init omap_serial_init_port(int port) if (port == uart->num) break; { - - struct omap_hwmod *oh = uart->oh; - struct omap_device *od; - void *pdata = NULL; - u32 pdata_size = 0; - - struct plat_serial8250_port ports[2] = { - {}, - {.flags = 0}, - }; - struct plat_serial8250_port *p = &ports[0]; - - name = "serial8250"; + oh = uart->oh; uart->dma_enabled = 0; +#ifdef CONFIG_SERIAL_8250 + name = "serial8250"; /* * !! 8250 driver does not use standard IORESOURCE* It @@ -671,13 +666,25 @@ void __init omap_serial_init_port(int port) * omap3xxx: Never read empty UART fifo on UARTs * with IP rev >=0x52 */ - if (cpu_is_omap44xx()) { + if (cpu_is_omap44xx()) p->serial_in = serial_in_override; - p->serial_out = serial_out_override; - } pdata = &ports[0]; pdata_size = 2 * sizeof(struct plat_serial8250_port); +#endif +#ifdef CONFIG_SERIAL_OMAP + name = DRIVER_NAME; + + omap_up.dma_enabled = uart->dma_enabled; + omap_up.uartclk = OMAP24XX_BASE_BAUD * 16; + omap_up.mapbase = oh->slaves[0]->addr->pa_start; + omap_up.membase = oh->_rt_va; + omap_up.irqflags = IRQF_SHARED; + omap_up.flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ; + + pdata = &omap_up; + pdata_size = sizeof(struct omap_uart_port_info); +#endif if (WARN_ON(!oh)) return; @@ -725,7 +732,6 @@ void __init omap_serial_init_port(int port) device_init_wakeup(&od->pdev.dev, true); DEV_CREATE_FILE(&od->pdev.dev, &dev_attr_sleep_timeout); } - } } diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep44xx.S deleted file mode 100644 index 7181a95b0252..000000000000 --- a/arch/arm/mach-omap2/sleep44xx.S +++ /dev/null @@ -1,48 +0,0 @@ -/* - * linux/arch/arm/mach-omap2/sleep44xx.S - * - * (C) Copyright 2010 - * Texas Instruments - * Rajendra Nayak <rnayak@ti.com> - * - * 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 the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <linux/linkage.h> -#include <asm/assembler.h> - -/* - * Forces OMAP into idle state - * - * omap44xx_suspend() - This bit of code just executes the WFI - * for normal idles. - * - * Note: This code get's copied to internal SRAM at boot. When the OMAP - * wakes up it continues execution at the point it went to sleep. - */ -ENTRY(omap44xx_cpu_suspend) - stmfd sp!, {r0-r12, lr} @ save registers on stack -loop: - /*b loop*/ @Enable to debug by stepping through code - /* Data memory barrier and Data sync barrier */ - /* FIXME: check whther we need this code executed from SRAM ? */ - dsb - - wfi @ wait for interrupt - - ldmfd sp!, {r0-r12, pc} @ restore regs and return -ENTRY(omap44xx_cpu_suspend_sz) - .word . - omap44xx_cpu_suspend diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index e3348fddcd2f..d271c2f2b6e3 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -769,6 +769,13 @@ config CACHE_L2X0 help This option enables the L2x0 PrimeCell. +config CACHE_PL310 + bool + depends on CACHE_L2X0 + default y if CPU_V7 + help + This option enables support for the PL310 cache controller. + config CACHE_TAUROS2 bool "Enable the Tauros2 L2 cache controller" depends on ARCH_DOVE diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index 88e8c50778c9..cb727d3d96d7 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -26,9 +26,21 @@ #define CACHE_LINE_SIZE 32 static void __iomem *l2x0_base; -static DEFINE_SPINLOCK(l2x0_lock); bool l2x0_disabled; +#ifdef CONFIG_CACHE_PL310 +static inline void cache_wait(void __iomem *reg, unsigned long mask) +{ + /* cache operations are atomic */ +} + +#define l2x0_lock(lock, flags) ((void)(flags)) +#define l2x0_unlock(lock, flags) ((void)(flags)) + +#define block_end(start, end) (end) + +#define L2CC_TYPE "PL310/L2C-310" +#else static inline void cache_wait(void __iomem *reg, unsigned long mask) { /* wait for the operation to complete */ @@ -36,6 +48,22 @@ static inline void cache_wait(void __iomem *reg, unsigned long mask) ; } +static DEFINE_SPINLOCK(l2x0_lock); +#define l2x0_lock(lock, flags) spin_lock_irqsave(lock, flags) +#define l2x0_unlock(lock, flags) spin_unlock_irqrestore(lock, flags) + +#define block_end(start, end) ((start) + min((end) - (start), 4096UL)) + +#define L2CC_TYPE "L2x0" +#endif + +static inline void cache_wait_always(void __iomem *reg, unsigned long mask) +{ + /* wait for the operation to complete */ + while (readl(reg) & mask) + ; +} + static inline void cache_sync(void) { void __iomem *base = l2x0_base; @@ -58,30 +86,16 @@ static inline void l2x0_inv_line(unsigned long addr) } #ifdef CONFIG_PL310_ERRATA_588369 -static noinline void debug_writel(unsigned long val) +static void debug_writel(unsigned long val) { - register unsigned long r0 asm("r0") = val; + extern void omap_smc1(u32 fn, u32 arg); + /* - * Texas Instrument secure monitor api to modify the PL310 - * Debug Control Register. - * r0 contains the value to be modified and "r12" contains - * the monitor API number. This API uses few CPU registers - * internally and hence they need be backed up including - * link register "lr". - * Explicitly save r11 and r12 since the compiler generated - * code won't save it. + * Texas Instrument secure monitor api to modify the + * PL310 Debug Control Register. */ - __asm__ __volatile__( - __asmeq("%0", "r0") - "stmfd r13!, {r11,r12}\n" - "ldr r12, =0x100\n" - "dsb\n" - "smc\n" - "ldmfd r13!, {r11,r12}\n" - : : "r" (r0) - : "r4", "r5", "r10", "lr"); + omap_smc1(0x100, val); } - static inline void l2x0_flush_line(unsigned long addr) { void __iomem *base = l2x0_base; @@ -111,9 +125,9 @@ static void l2x0_cache_sync(void) { unsigned long flags; - spin_lock_irqsave(&l2x0_lock, flags); + l2x0_lock(&l2x0_lock, flags); cache_sync(); - spin_unlock_irqrestore(&l2x0_lock, flags); + l2x0_unlock(&l2x0_lock, flags); } static inline void l2x0_inv_all(void) @@ -121,11 +135,11 @@ static inline void l2x0_inv_all(void) unsigned long flags; /* invalidate all ways */ - spin_lock_irqsave(&l2x0_lock, flags); + l2x0_lock(&l2x0_lock, flags); writel(0xff, l2x0_base + L2X0_INV_WAY); - cache_wait(l2x0_base + L2X0_INV_WAY, 0xff); + cache_wait_always(l2x0_base + L2X0_INV_WAY, 0xff); cache_sync(); - spin_unlock_irqrestore(&l2x0_lock, flags); + l2x0_unlock(&l2x0_lock, flags); } static void l2x0_inv_range(unsigned long start, unsigned long end) @@ -133,7 +147,7 @@ static void l2x0_inv_range(unsigned long start, unsigned long end) void __iomem *base = l2x0_base; unsigned long flags; - spin_lock_irqsave(&l2x0_lock, flags); + l2x0_lock(&l2x0_lock, flags); if (start & (CACHE_LINE_SIZE - 1)) { start &= ~(CACHE_LINE_SIZE - 1); debug_writel(0x03); @@ -150,7 +164,7 @@ static void l2x0_inv_range(unsigned long start, unsigned long end) } while (start < end) { - unsigned long blk_end = start + min(end - start, 4096UL); + unsigned long blk_end = block_end(start, end); while (start < blk_end) { l2x0_inv_line(start); @@ -158,13 +172,13 @@ static void l2x0_inv_range(unsigned long start, unsigned long end) } if (blk_end < end) { - spin_unlock_irqrestore(&l2x0_lock, flags); - spin_lock_irqsave(&l2x0_lock, flags); + l2x0_unlock(&l2x0_lock, flags); + l2x0_lock(&l2x0_lock, flags); } } cache_wait(base + L2X0_INV_LINE_PA, 1); cache_sync(); - spin_unlock_irqrestore(&l2x0_lock, flags); + l2x0_unlock(&l2x0_lock, flags); } static void l2x0_clean_range(unsigned long start, unsigned long end) @@ -172,10 +186,10 @@ static void l2x0_clean_range(unsigned long start, unsigned long end) void __iomem *base = l2x0_base; unsigned long flags; - spin_lock_irqsave(&l2x0_lock, flags); + l2x0_lock(&l2x0_lock, flags); start &= ~(CACHE_LINE_SIZE - 1); while (start < end) { - unsigned long blk_end = start + min(end - start, 4096UL); + unsigned long blk_end = block_end(start, end); while (start < blk_end) { l2x0_clean_line(start); @@ -183,13 +197,13 @@ static void l2x0_clean_range(unsigned long start, unsigned long end) } if (blk_end < end) { - spin_unlock_irqrestore(&l2x0_lock, flags); - spin_lock_irqsave(&l2x0_lock, flags); + l2x0_unlock(&l2x0_lock, flags); + l2x0_lock(&l2x0_lock, flags); } } cache_wait(base + L2X0_CLEAN_LINE_PA, 1); cache_sync(); - spin_unlock_irqrestore(&l2x0_lock, flags); + l2x0_unlock(&l2x0_lock, flags); } static void l2x0_flush_range(unsigned long start, unsigned long end) @@ -197,10 +211,10 @@ static void l2x0_flush_range(unsigned long start, unsigned long end) void __iomem *base = l2x0_base; unsigned long flags; - spin_lock_irqsave(&l2x0_lock, flags); + l2x0_lock(&l2x0_lock, flags); start &= ~(CACHE_LINE_SIZE - 1); while (start < end) { - unsigned long blk_end = start + min(end - start, 4096UL); + unsigned long blk_end = block_end(start, end); debug_writel(0x03); while (start < blk_end) { @@ -210,13 +224,13 @@ static void l2x0_flush_range(unsigned long start, unsigned long end) debug_writel(0x00); if (blk_end < end) { - spin_unlock_irqrestore(&l2x0_lock, flags); - spin_lock_irqsave(&l2x0_lock, flags); + l2x0_unlock(&l2x0_lock, flags); + l2x0_lock(&l2x0_lock, flags); } } cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1); cache_sync(); - spin_unlock_irqrestore(&l2x0_lock, flags); + l2x0_unlock(&l2x0_lock, flags); } void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) @@ -255,7 +269,7 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) outer_cache.flush_range = l2x0_flush_range; outer_cache.sync = l2x0_cache_sync; - printk(KERN_INFO "L2X0 cache controller enabled\n"); + pr_info(L2CC_TYPE " cache controller enabled\n"); } static int __init l2x0_disable(char *unused) diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S index 394a1fac6662..69d0f01ac38a 100644 --- a/arch/arm/mm/cache-v7.S +++ b/arch/arm/mm/cache-v7.S @@ -167,7 +167,11 @@ ENTRY(v7_coherent_user_range) cmp r0, r1 blo 1b mov r0, #0 +#ifdef CONFIG_SMP + mcr p15, 0, r0, c7, c1, 6 @ invalidate BTB Inner Shareable +#else mcr p15, 0, r0, c7, c5, 6 @ invalidate BTB +#endif dsb isb mov pc, lr diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 1708da82da96..c065fea3f7d1 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -420,6 +420,10 @@ static void __init build_mem_type_table(void) user_pgprot |= L_PTE_SHARED; kern_pgprot |= L_PTE_SHARED; vecs_pgprot |= L_PTE_SHARED; + mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_S; + mem_types[MT_DEVICE_WC].prot_pte |= L_PTE_SHARED; + mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S; + mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED; mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S; #endif diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S index a26a605b73bd..e420d6611dcd 100644 --- a/arch/arm/mm/tlb-v7.S +++ b/arch/arm/mm/tlb-v7.S @@ -51,7 +51,11 @@ ENTRY(v7wbi_flush_user_tlb_range) cmp r0, r1 blo 1b mov ip, #0 +#ifdef CONFIG_SMP + mcr p15, 0, ip, c7, c1, 6 @ flush BTAC/BTB Inner Shareable +#else mcr p15, 0, ip, c7, c5, 6 @ flush BTAC/BTB +#endif dsb mov pc, lr ENDPROC(v7wbi_flush_user_tlb_range) @@ -80,7 +84,11 @@ ENTRY(v7wbi_flush_kern_tlb_range) cmp r0, r1 blo 1b mov r2, #0 +#ifdef CONFIG_SMP + mcr p15, 0, r2, c7, c1, 6 @ flush BTAC/BTB Inner Shareable +#else mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB +#endif dsb isb mov pc, lr diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c index 95bbfd168117..4fc2e1366aea 100644 --- a/arch/arm/plat-omap/devices.c +++ b/arch/arm/plat-omap/devices.c @@ -14,6 +14,7 @@ #include <linux/init.h> #include <linux/platform_device.h> #include <linux/io.h> +#include <linux/delay.h> #include <mach/hardware.h> #include <asm/mach-types.h> @@ -27,7 +28,11 @@ #include <mach/gpio.h> #include <plat/menelaus.h> #include <plat/mcbsp.h> +#include <plat/mcpdm.h> #include <plat/dsp_common.h> +#include <plat/omap44xx.h> +#include <plat/omap_hwmod.h> +#include <plat/omap_device.h> #if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE) @@ -192,6 +197,48 @@ void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config, /*-------------------------------------------------------------------------*/ +#if defined(CONFIG_OMAP_MCPDM) || defined(CONFIG_OMAP_MCPDM_MODULE) + +static struct omap_device_pm_latency omap_mcpdm_latency[] = { + { + .deactivate_func = omap_device_idle_hwmods, + .activate_func = omap_device_enable_hwmods, + .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, + }, +}; + +static void omap_init_mcpdm(void) +{ + struct omap_hwmod *oh; + struct omap_device *od; + struct omap_mcpdm_platform_data *pdata; + + oh = omap_hwmod_lookup("pdm"); + if (!oh) + printk(KERN_ERR "Could not look up pdm hw_mod\n"); + + pdata = kzalloc(sizeof(struct omap_mcpdm_platform_data), GFP_KERNEL); + if (!pdata) + printk(KERN_ERR "Could not allocate platform data\n"); + + od = omap_device_build("omap-mcpdm", -1, oh, pdata, + sizeof(struct omap_mcpdm_platform_data), + omap_mcpdm_latency, + ARRAY_SIZE(omap_mcpdm_latency), 0); + + pdata->device_enable = omap_device_enable; + pdata->device_idle = omap_device_idle; + pdata->device_shutdown = omap_device_shutdown; + + if (od <= 0) + printk(KERN_ERR "Could not build omap_device for omap-mcpdm\n"); +} +#else +static inline void omap_init_mcpdm(void) {} +#endif + +/*-------------------------------------------------------------------------*/ + #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \ defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE) @@ -442,6 +489,7 @@ static int __init omap_init_devices(void) omap_init_dsp(); omap_init_kp(); omap_init_rng(); + omap_init_mcpdm(); omap_init_uwire(); omap_init_vout(); omap_init_wdt(); diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c index 3e92dc9ccec6..de5e054272c3 100644 --- a/arch/arm/plat-omap/i2c.c +++ b/arch/arm/plat-omap/i2c.c @@ -36,7 +36,7 @@ */ #define OMAP_I2C_CMDLINE_SETUP (BIT(31)) -#define OMAP_I2C_MAX_CONTROLLERS 3 +#define OMAP_I2C_MAX_CONTROLLERS 4 static struct omap_i2c_platform_data omap_i2c_pdata[OMAP_I2C_MAX_CONTROLLERS]; @@ -145,4 +145,5 @@ int __init omap_plat_register_i2c_bus(int bus_id, u32 clkrate, else if (cpu_class_is_omap2()) return omap2_i2c_add_bus(bus_id); + return 0; } diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h index 89a718630d6a..0fa630bb0556 100644 --- a/arch/arm/plat-omap/include/plat/gpio.h +++ b/arch/arm/plat-omap/include/plat/gpio.h @@ -158,7 +158,11 @@ #define OMAP4_GPIO_IRQSTATUSCLR1 0x0040 #define OMAP4_GPIO_IRQWAKEN0 0x0044 #define OMAP4_GPIO_IRQWAKEN1 0x0048 -#define OMAP4_GPIO_SYSSTATUS 0x0104 +#define OMAP4_GPIO_SYSSTATUS 0x0114 +#define OMAP4_GPIO_IRQENABLE1 0x011c +#define OMAP4_GPIO_WAKE_EN 0x0120 +#define OMAP4_GPIO_IRQSTATUS2 0x0128 +#define OMAP4_GPIO_IRQENABLE2 0x012c #define OMAP4_GPIO_CTRL 0x0130 #define OMAP4_GPIO_OE 0x0134 #define OMAP4_GPIO_DATAIN 0x0138 @@ -169,6 +173,10 @@ #define OMAP4_GPIO_FALLINGDETECT 0x014c #define OMAP4_GPIO_DEBOUNCENABLE 0x0150 #define OMAP4_GPIO_DEBOUNCINGTIME 0x0154 +#define OMAP4_GPIO_CLEARIRQENABLE1 0x0160 +#define OMAP4_GPIO_SETIRQENABLE1 0x0164 +#define OMAP4_GPIO_CLEARWKUENA 0x0180 +#define OMAP4_GPIO_SETWKUENA 0x0184 #define OMAP4_GPIO_CLEARDATAOUT 0x0190 #define OMAP4_GPIO_SETDATAOUT 0x0194 diff --git a/arch/arm/plat-omap/include/plat/io.h b/arch/arm/plat-omap/include/plat/io.h index decd7e03c068..a60b14a0a69c 100644 --- a/arch/arm/plat-omap/include/plat/io.h +++ b/arch/arm/plat-omap/include/plat/io.h @@ -218,6 +218,7 @@ #define L4_PER_44XX_VIRT (L4_PER_44XX_PHYS + OMAP2_L4_IO_OFFSET) #define L4_PER_44XX_SIZE SZ_4M +#define L4_ABE_44XX_BASE 0x49000000 #define L4_ABE_44XX_PHYS L4_ABE_44XX_BASE /* 0x49000000 --> 0xfb000000 */ #define L4_ABE_44XX_VIRT (L4_ABE_44XX_PHYS + OMAP2_L4_IO_OFFSET) diff --git a/arch/arm/plat-omap/include/plat/irqs.h b/arch/arm/plat-omap/include/plat/irqs.h index 4306d2bd4387..1e0e5a485903 100644 --- a/arch/arm/plat-omap/include/plat/irqs.h +++ b/arch/arm/plat-omap/include/plat/irqs.h @@ -435,6 +435,8 @@ #define INT_44XX_MMC3_IRQ (94 + IRQ_GIC_START) #define INT_44XX_MMC4_IRQ (96 + IRQ_GIC_START) #define INT_44XX_DUCATI_MMU_IRQ (100 + IRQ_GIC_START) +#define INT_44XX_MCPDM_IRQ (112 + IRQ_GIC_START) +#define INT_44XX_SYS_NIRQ2 (119 + IRQ_GIC_START) /* Max. 128 level 2 IRQs (OMAP1610), 192 GPIOs (OMAP730/850) and * 16 MPUIO lines */ diff --git a/arch/arm/plat-omap/include/plat/mcbsp.h b/arch/arm/plat-omap/include/plat/mcbsp.h index 4f22e5bb7ff7..15ae75771fdc 100644 --- a/arch/arm/plat-omap/include/plat/mcbsp.h +++ b/arch/arm/plat-omap/include/plat/mcbsp.h @@ -29,6 +29,7 @@ #include <mach/hardware.h> #include <plat/clock.h> +#include <plat/dma.h> #define OMAP7XX_MCBSP1_BASE 0xfffb1000 #define OMAP7XX_MCBSP2_BASE 0xfffb1800 @@ -56,7 +57,7 @@ #define OMAP44XX_MCBSP1_BASE 0x49022000 #define OMAP44XX_MCBSP2_BASE 0x49024000 #define OMAP44XX_MCBSP3_BASE 0x49026000 -#define OMAP44XX_MCBSP4_BASE 0x48074000 +#define OMAP44XX_MCBSP4_BASE 0x48096000 #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) @@ -265,6 +266,95 @@ #define ENAWAKEUP 0x0004 #define SOFTRST 0x0002 +#define OMAP_MCBSP_WORDLEN_NONE 255 + +#define OMAP_MCBSP_MASTER 1 +#define OMAP_MCBSP_SLAVE 0 + +/* McBSP interface operating mode */ +#define OMAP_MCBSP_MASTER 1 +#define OMAP_MCBSP_SLAVE 0 +#define OMAP_MCBSP_AUTO_RST_NONE (0x0) +#define OMAP_MCBSP_AUTO_RRST (0x1<<1) +#define OMAP_MCBSP_AUTO_XRST (0x1<<2) + +/* SRG ENABLE/DISABLE state */ +#define OMAP_MCBSP_ENABLE_FSG_SRG 1 +#define OMAP_MCBSP_DISABLE_FSG_SRG 2 +/* mono to mono mode*/ +#define OMAP_MCBSP_SKIP_NONE (0x0) +/* mono to stereo mode */ +#define OMAP_MCBSP_SKIP_FIRST (0x1<<1) +#define OMAP_MCBSP_SKIP_SECOND (0x1<<2) +/* RRST STATE */ +#define OMAP_MCBSP_RRST_DISABLE 0 +#define OMAP_MCBSP_RRST_ENABLE 1 +/*XRST STATE */ +#define OMAP_MCBSP_XRST_DISABLE 0 +#define OMAP_MCBSP_XRST_ENABLE 1 + +#define OMAP_MCBSP_FRAME_SINGLEPHASE 1 +#define OMAP_MCBSP_FRAME_DUALPHASE 2 + +/* Sample Rate Generator Clock source */ +#define OMAP_MCBSP_SRGCLKSRC_CLKS 1 +#define OMAP_MCBSP_SRGCLKSRC_FCLK 2 +#define OMAP_MCBSP_SRGCLKSRC_CLKR 3 +#define OMAP_MCBSP_SRGCLKSRC_CLKX 4 +/* SRG input clock polarity */ +#define OMAP_MCBSP_CLKS_POLARITY_RISING 1 +#define OMAP_MCBSP_CLKS_POLARITY_FALLING 2 + +#define OMAP_MCBSP_CLKX_POLARITY_RISING 1 +#define OMAP_MCBSP_CLKX_POLARITY_FALLING 2 + +#define OMAP_MCBSP_CLKR_POLARITY_RISING 1 +#define OMAP_MCBSP_CLKR_POLARITY_FALLING 2 + +/* SRG Clock synchronization mode */ +#define OMAP_MCBSP_SRG_FREERUNNING 1 +#define OMAP_MCBSP_SRG_RUNNING 2 + +/* Frame Sync Source */ +#define OMAP_MCBSP_TXFSYNC_EXTERNAL 0 +#define OMAP_MCBSP_TXFSYNC_INTERNAL 1 + +#define OMAP_MCBSP_RXFSYNC_EXTERNAL 0 +#define OMAP_MCBSP_RXFSYNC_INTERNAL 1 + +#define OMAP_MCBSP_CLKRXSRC_EXTERNAL 1 +#define OMAP_MCBSP_CLKRXSRC_INTERNAL 2 + +#define OMAP_MCBSP_CLKTXSRC_EXTERNAL 1 +#define OMAP_MCBSP_CLKTXSRC_INTERNAL 2 + +/* Justification */ +#define OMAP_MCBSP_RJUST_ZEROMSB 0 +#define OMAP_MCBSP_RJUST_SIGNMSB 1 +#define OMAP_MCBSP_LJUST_ZEROLSB 2 + +#define OMAP_MCBSP_DATADELAY0 0 +#define OMAP_MCBSP_DATADELAY1 1 +#define OMAP_MCBSP_DATADELAY2 2 + +/* Reverse mode for 243X and 34XX */ +#define OMAP_MCBSP_MSBFIRST 0 +#define OMAP_MCBSP_LSBFIRST 1 + +/* Multi-Channel partition mode */ +#define OMAP_MCBSP_TWOPARTITION_MODE 0 +#define OMAP_MCBSP_EIGHTPARTITION_MODE 1 + +/* Rx Multichannel selection */ +#define OMAP_MCBSP_RXMUTICH_DISABLE 0 +#define OMAP_MCBSP_RXMUTICH_ENABLE 1 + +/* Tx Multichannel selection */ +#define OMAP_MCBSP_TXMUTICH_DISABLE 0 +#define OMAP_MCBSP_TXMUTICH_ENABLE 1 + +#define OMAP_MCBSP_FRAMELEN_N(NUM_WORDS) ((NUM_WORDS - 1) & 0x7F) + /********************** McBSP DMA operating modes **************************/ #define MCBSP_DMA_MODE_ELEMENT 0 #define MCBSP_DMA_MODE_THRESHOLD 1 @@ -321,6 +411,22 @@ typedef enum { typedef int __bitwise omap_mcbsp_io_type_t; #define OMAP_MCBSP_IRQ_IO ((__force omap_mcbsp_io_type_t) 1) #define OMAP_MCBSP_POLL_IO ((__force omap_mcbsp_io_type_t) 2) +#define omap_mcbsp_check_valid_id(id) (id < omap_mcbsp_count) +#define id_to_mcbsp_ptr(id) mcbsp_ptr[id]; + +typedef void (*omap_mcbsp_dma_cb) (u32 ch_status, void *arg); + +typedef struct omap_mcbsp_dma_transfer_parameters { + + /* Skip the alternate element use fro stereo mode */ + u8 skip_alt; + /* Automagically handle Transfer [XR]RST? */ + u8 auto_reset; + /* callback function executed for every tx/rx completion */ + omap_mcbsp_dma_cb callback; + /* word length of data */ + u32 word_length1; +} omap_mcbsp_dma_transfer_params; typedef enum { OMAP_MCBSP_WORD_8 = 0, @@ -410,12 +516,65 @@ struct omap_mcbsp { struct omap_mcbsp_platform_data *pdata; struct clk *iclk; struct clk *fclk; + + u8 auto_reset; /* Auto Reset */ + u8 txskip_alt; /* Tx skip flags */ + u8 rxskip_alt; /* Rx skip flags */ + void *rx_cb_arg; + void *tx_cb_arg; + omap_mcbsp_dma_cb rx_callback; + omap_mcbsp_dma_cb tx_callback; + int rx_dma_chain_state; + int tx_dma_chain_state; + int interface_mode; /* Master / Slave */ + struct omap_dma_channel_params rx_params; /* Used For Rx FIFO */ + int rx_config_done; + #ifdef CONFIG_ARCH_OMAP34XX int dma_op_mode; u16 max_tx_thres; u16 max_rx_thres; #endif }; + +struct omap_mcbsp_dma_transfer_params { + /* Skip the alternate element use fro stereo mode */ + u8 skip_alt; + /* Automagically handle Transfer [XR]RST? */ + u8 auto_reset; + /* callback function executed for every tx/rx completion */ + omap_mcbsp_dma_cb callback; + /* word length of data */ + u32 word_length1; +}; + +struct omap_mcbsp_cfg_param { + u8 fsync_src; + u8 fs_polarity; + u8 clk_polarity; + u8 clk_mode; + u8 frame_length1; + u8 frame_length2; + u8 word_length1; + u8 word_length2; + u8 justification; + u8 reverse_compand; + u8 phase; + u8 data_delay; +}; + +struct omap_mcbsp_srg_fsg_cfg { + u32 period; /* Frame period */ + u32 pulse_width; /* Frame width */ + u8 fsgm; + u32 sample_rate; + u32 bits_per_sample; + u32 srg_src; + u8 sync_mode; /* SRG free running mode */ + u8 polarity; + u8 dlb; /* digital loopback mode */ +}; + extern struct omap_mcbsp **mcbsp_ptr; extern int omap_mcbsp_count; @@ -450,6 +609,30 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word); int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word); +int omap2_mcbsp_stop_datatx(unsigned int id); +int omap2_mcbsp_stop_datarx(u32 id); +int omap2_mcbsp_reset(unsigned int id); +int omap2_mcbsp_transmitter_index(int id, int *ei, int *fi); +int omap2_mcbsp_receiver_index(int id, int *ei, int *fi); +extern int omap2_mcbsp_set_xrst(unsigned int id, u8 state); +extern int omap2_mcbsp_set_rrst(unsigned int id, u8 state); +extern int omap2_mcbsp_dma_recv_params(unsigned int id, + struct omap_mcbsp_dma_transfer_params *rp); +extern int omap2_mcbsp_dma_trans_params(unsigned int id, + struct omap_mcbsp_dma_transfer_params *tp); +extern int omap2_mcbsp_receive_data(unsigned int id, void *cbdata, + dma_addr_t buf_start_addr, u32 buf_size); +extern int omap2_mcbsp_send_data(unsigned int id, void *cbdata, + dma_addr_t buf_start_addr, u32 buf_size); + +extern void omap_mcbsp_write(void __iomem *io_base, u16 reg, u32 val); +extern int omap_mcbsp_read(void __iomem *io_base, u16 reg); + +extern void omap2_mcbsp_params_cfg(unsigned int id, int interface_mode, + struct omap_mcbsp_cfg_param *rp, + struct omap_mcbsp_cfg_param *tp, + struct omap_mcbsp_srg_fsg_cfg *param); + /* SPI specific API */ void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * spi_cfg); diff --git a/arch/arm/plat-omap/include/plat/mcpdm.h b/arch/arm/plat-omap/include/plat/mcpdm.h new file mode 100644 index 000000000000..3c7c783c36e1 --- /dev/null +++ b/arch/arm/plat-omap/include/plat/mcpdm.h @@ -0,0 +1 @@ +#include "../../../../../sound/soc/omap/mcpdm.h" diff --git a/arch/arm/plat-omap/include/plat/mmc.h b/arch/arm/plat-omap/include/plat/mmc.h index 29937137bf3e..3b1e964cba73 100644 --- a/arch/arm/plat-omap/include/plat/mmc.h +++ b/arch/arm/plat-omap/include/plat/mmc.h @@ -17,6 +17,10 @@ #include <plat/board.h> +#ifdef CONFIG_TIWLAN_SDIO +#include <linux/mmc/card.h> +#endif + #define OMAP15XX_NR_MMC 1 #define OMAP16XX_NR_MMC 2 #define OMAP1_MMC_SIZE 0x080 @@ -43,6 +47,13 @@ #define OMAP_MMC_MAX_SLOTS 2 +#ifdef CONFIG_TIWLAN_SDIO +struct embedded_sdio_data { +struct sdio_cis cis; +struct sdio_embedded_func *funcs; +}; +#endif + struct omap_mmc_platform_data { /* back-link to device */ struct device *dev; @@ -122,6 +133,13 @@ struct omap_mmc_platform_data { unsigned int ban_openended:1; +#ifdef CONFIG_TIWLAN_SDIO + struct embedded_sdio_data *embedded_sdio; + int (*register_status_notify) + (void (*callback)(int card_present, void *dev_id), + void *dev_id); +#endif + } slots[OMAP_MMC_MAX_SLOTS]; }; diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h new file mode 100644 index 000000000000..2a1e7f98b035 --- /dev/null +++ b/arch/arm/plat-omap/include/plat/omap-serial.h @@ -0,0 +1,128 @@ +/* + * Driver for OMAP-UART controller. + * Based on drivers/serial/8250.c + * + * Copyright (C) 2010 Texas Instruments. + * + * Authors: + * Govindraj R <govindraj.raja@ti.com> + * Thara Gopinath <thara@ti.com> + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __OMAP_SERIAL_H__ +#define __OMAP_SERIAL_H__ + +#include <linux/serial_core.h> +#include <linux/platform_device.h> + +#include <plat/control.h> +#include <plat/mux.h> + +#define DRIVER_NAME "omap-hsuart" + +/* + * Use tty device name as ttyO, [O -> OMAP] + * in bootargs we specify as console=ttyO0 if uart1 + * is used as console uart. + */ +#define OMAP_SERIAL_NAME "ttyO" + +#define OMAP_MDR1_DISABLE 0x07 +#define OMAP_MDR1_MODE13X 0x03 +#define OMAP_MDR1_MODE16X 0x00 +#define OMAP_MODE13X_SPEED 230400 + +/* + * LCR = 0XBF: Switch to Configuration Mode B. + * In configuration mode b allow access + * to EFR,DLL,DLH. + * Reference OMAP TRM Chapter 17 + * Section: 1.4.3 Mode Selection + */ +#define OMAP_UART_LCR_CONF_MDB 0XBF + +/* WER = 0x7F + * Enable module level wakeup in WER reg + */ +#define OMAP_UART_WER_MOD_WKUP 0X7F + +/* Enable XON/XOFF flow control on output */ +#define OMAP_UART_SW_TX 0x04 + +/* Enable XON/XOFF flow control on input */ +#define OMAP_UART_SW_RX 0x04 + +#define OMAP_UART_SYSC_RESET 0X07 +#define OMAP_UART_TCR_TRIG 0X0F +#define OMAP_UART_SW_CLR 0XF0 + +#define OMAP_UART_DMA_CH_FREE -1 + +#define RX_TIMEOUT (3 * HZ) +#define OMAP_MAX_HSUART_PORTS 4 + +#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA + +struct omap_uart_port_info { + bool dma_enabled; /* To specify DMA Mode */ + unsigned int uartclk; /* UART clock rate */ + void __iomem *membase; /* ioremap cookie or NULL */ + resource_size_t mapbase; /* resource base */ + unsigned long irqflags; /* request_irq flags */ + upf_t flags; /* UPF_* flags */ +}; + +struct uart_omap_dma { + u8 uart_dma_tx; + u8 uart_dma_rx; + int rx_dma_channel; + int tx_dma_channel; + dma_addr_t rx_buf_dma_phys; + dma_addr_t tx_buf_dma_phys; + unsigned int uart_base; + /* + * Buffer for rx dma.It is not required for tx because the buffer + * comes from port structure. + */ + unsigned char *rx_buf; + unsigned int prev_rx_dma_pos; + int tx_buf_size; + int tx_dma_used; + int rx_dma_used; + spinlock_t tx_lock; + spinlock_t rx_lock; + /* timer to poll activity on rx dma */ + struct timer_list rx_timer; + int rx_buf_size; + int rx_timeout; +}; + +struct uart_omap_port { + struct uart_port port; + struct uart_omap_dma uart_dma; + struct platform_device *pdev; + + unsigned char ier; + unsigned char lcr; + unsigned char mcr; + unsigned char fcr; + unsigned char efr; + + int use_dma; + /* + * Some bits in registers are cleared on a read, so they must + * be saved whenever the register is read but the bits will not + * be immediately processed. + */ + unsigned int lsr_break_flag; + unsigned char msr_saved_flags; + char name[20]; + unsigned long port_activity; +}; + +#endif /* __OMAP_SERIAL_H__ */ diff --git a/arch/arm/plat-omap/include/plat/omap44xx.h b/arch/arm/plat-omap/include/plat/omap44xx.h index 1770a5597e3e..592c5ee88582 100644 --- a/arch/arm/plat-omap/include/plat/omap44xx.h +++ b/arch/arm/plat-omap/include/plat/omap44xx.h @@ -43,6 +43,8 @@ #define OMAP44XX_LOCAL_TWD_BASE 0x48240600 #define OMAP44XX_L2CACHE_BASE 0x48242000 #define OMAP44XX_WKUPGEN_BASE 0x48281000 +#define OMAP44XX_MCPDM_BASE 0x40132000 +#define OMAP44XX_MCPDM_L3_BASE 0x49032000 #define OMAP44XX_MAILBOX_BASE (L4_44XX_BASE + 0xF4000) #define OMAP44XX_HSUSB_OTG_BASE (L4_44XX_BASE + 0xAB000) diff --git a/arch/arm/plat-omap/include/plat/wifi_tiwlan.h b/arch/arm/plat-omap/include/plat/wifi_tiwlan.h new file mode 100755 index 000000000000..b0332b04ddc9 --- /dev/null +++ b/arch/arm/plat-omap/include/plat/wifi_tiwlan.h @@ -0,0 +1,23 @@ +/* mach/wifi_tiwlan.h + * + * 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_WIFI_TIWLAN_H_ +#define _LINUX_WIFI_TIWLAN_H_ + +struct wifi_platform_data { + int (*set_power)(int val); + int (*set_reset)(int val); + int (*set_carddetect)(int val); + void *(*mem_prealloc)(int section, unsigned long size); +}; + +#endif diff --git a/arch/arm/plat-omap/include/syslink/GlobalTypes.h b/arch/arm/plat-omap/include/syslink/GlobalTypes.h new file mode 100644 index 000000000000..6cd959cde952 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/GlobalTypes.h @@ -0,0 +1,154 @@ +/* + * GlobalTypes.h + * + * Syslink driver support for OMAP Processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef __GLOBALTYPES_H +#define __GLOBALTYPES_H + +#define REG volatile + +/* + * Definition: RET_CODE_BASE + * + * DESCRIPTION: Base value for return code offsets + * + * + */ +#define RET_CODE_BASE 0 + +/* + * TYPE: ReturnCode_t + * + * DESCRIPTION: Return codes to be returned by all library functions + * + * + */ +enum ReturnCode_label { +RET_OK = 0, +RET_FAIL = -1, +RET_BAD_NULL_PARAM = -2, +RET_PARAM_OUT_OF_RANGE = -3, +RET_INVALID_ID = -4, +RET_EMPTY = -5, +RET_FULL = -6, +RET_TIMEOUT = -7, +RET_INVALID_OPERATION = -8, +/* Add new error codes at end of above list */ +RET_NUM_RET_CODES /* this should ALWAYS be LAST entry */ +}; + + + +/* + * MACRO: RD_MEM_32_VOLATILE, WR_MEM_32_VOLATILE + * + * DESCRIPTION: 32 bit register access macros + * + * + */ +#define RD_MEM_32_VOLATILE(addr) \ +((unsigned long)(*((REG unsigned long *)(addr)))) + +#define WR_MEM_32_VOLATILE(addr, data) \ +(*((REG unsigned long *)(addr)) = (unsigned long)(data)) + + + + +#ifdef CHECK_INPUT_PARAMS +/* + * MACRO: CHECK_INPUT_PARAMS + * + * DESCRIPTION: Checks an input code and returns a specified value if code is + * invalid value, also writes spy value if error found. + * + * NOTE: Can be disabled to save HW cycles. + * + * + */ +#define CHECK_INPUT_PARAM(actualValue, invalidValue, \ +returnCodeIfMismatch, spyCodeIfMisMatch) do {\ + if ((invalidValue) == (actualValue)) {\ + RES_Set((spyCodeIfMisMatch));\ + return returnCodeIfMismatch; \ + } \ +} while (0) + +/* + * MACRO: CHECK_INPUT_RANGE + * + * DESCRIPTION: Checks an input value and returns a specified value if not in + * specified range, also writes spy value if error found. + * +* NOTE: Can be disabled to save HW cycles. + * + * + */ +#define CHECK_INPUT_RANGE(actualValue, minValidValue, maxValidValue, \ +returnCodeIfMismatch, spyCodeIfMisMatch) do {\ + if (((actualValue) < (minValidValue)) || \ + ((actualValue) > (maxValidValue))) {\ + RES_Set((spyCodeIfMisMatch));\ + return returnCodeIfMismatch; \ + } \ +} while (0) + +/* + * MACRO: CHECK_INPUT_RANGE_MIN0 + * + * DESCRIPTION: Checks an input value and returns a + * specified value if not in + * specified range, also writes spy value if error found. + * The minimum + * value is 0. + * + * NOTE: Can be disabled to save HW cycles. + * + * + */ +#define CHECK_INPUT_RANGE_MIN0(actualValue, maxValidValue, \ +returnCodeIfMismatch, spyCodeIfMisMatch) do {\ + if ((actualValue) > (maxValidValue)) {\ + RES_Set((spyCodeIfMisMatch));\ + return returnCodeIfMismatch; \ + } \ +} while (0) + +#else + +#define CHECK_INPUT_PARAM(actualValue, invalidValue, returnCodeIfMismatch,\ +spyCodeIfMisMatch) + +#define CHECK_INPUT_PARAM_NO_SPY(actualValue, invalidValue, \ +returnCodeIfMismatch) + +#define CHECK_INPUT_RANGE(actualValue, minValidValue, maxValidValue, \ +returnCodeIfMismatch, spyCodeIfMisMatch) + +#define CHECK_INPUT_RANGE_NO_SPY(actualValue, minValidValue , \ +maxValidValue, returnCodeIfMismatch) + +#define CHECK_INPUT_RANGE_MIN0(actualValue, maxValidValue, \ +returnCodeIfMismatch, spyCodeIfMisMatch) + +#define CHECK_INPUT_RANGE_NO_SPY_MIN0(actualValue, \ +maxValidValue, returnCodeIfMismatch) + +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __GLOBALTYPES_H */ diff --git a/arch/arm/plat-omap/include/syslink/MBXAccInt.h b/arch/arm/plat-omap/include/syslink/MBXAccInt.h new file mode 100644 index 000000000000..84e333d0d5da --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/MBXAccInt.h @@ -0,0 +1,550 @@ +/* + * MBXAccInt.h + * + * Notify mailbox driver support for OMAP Processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + + +#ifndef _MLB_ACC_INT_H +#define _MLB_ACC_INT_H + + +/* + * EXPORTED DEFINITIONS + * + */ + + +#define MLB_MAILBOX_MESSAGE___REGSET_0_15_OFFSET (unsigned long)(0x0040) +#define MLB_MAILBOX_MESSAGE___REGSET_0_15_STEP (unsigned long)(0x0004) +#define MLB_MAILBOX_MESSAGE___REGSET_0_15_BANKS (unsigned long)(16) + +/* Register offset address definitions relative +to register set MAILBOX_MESSAGE___REGSET_0_15 */ + +#define MLB_MAILBOX_MESSAGE___0_15_OFFSET (unsigned long)(0x0) + + +/* Register set MAILBOX_FIFOSTATUS___REGSET_0_15 +address offset, bank address increment and number of banks */ + +#define MLB_MAILBOX_FIFOSTATUS___REGSET_0_15_OFFSET (unsigned long)(0x0080) +#define MLB_MAILBOX_FIFOSTATUS___REGSET_0_15_STEP (unsigned long)(0x0004) +#define MLB_MAILBOX_FIFOSTATUS___REGSET_0_15_BANKS (unsigned long)(16) + +/* Register offset address definitions relative to +register set MAILBOX_FIFOSTATUS___REGSET_0_15 */ + +#define MLB_MAILBOX_FIFOSTATUS___0_15_OFFSET (unsigned long)(0x0) + + +/* Register set MAILBOX_MSGSTATUS___REGSET_0_15 +address offset, bank address increment and number of banks */ + +#define MLB_MAILBOX_MSGSTATUS___REGSET_0_15_OFFSET (unsigned long)(0x00c0) +#define MLB_MAILBOX_MSGSTATUS___REGSET_0_15_STEP (unsigned long)(0x0004) +#define MLB_MAILBOX_MSGSTATUS___REGSET_0_15_BANKS (unsigned long)(16) + +/* Register offset address definitions relative to +register set MAILBOX_MSGSTATUS___REGSET_0_15 */ + +#define MLB_MAILBOX_MSGSTATUS___0_15_OFFSET (unsigned long)(0x0) + + +/*Register set MAILBOX_IRQSTATUS___REGSET_0_3 address +offset, bank address increment and number of banks */ + +#define MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET (unsigned long)(0x0100) +#define MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP (unsigned long)(0x0008) +#define MLB_MAILBOX_IRQSTATUS___REGSET_0_3_BANKS (unsigned long)(4) + +#define MLB_MAILBOX_IRQSTATUS_CLR___REGSET_0_3_OFFSET (unsigned long)(0x0104) +#define MLB_MAILBOX_IRQSTATUS_CLR___REGSET_0_3_STEP (unsigned long)(0x0010) +#define MLB_MAILBOX_IRQSTATUS_CLR___REGSET_0_3_BANKS (unsigned long)(4) + +/* Register offset address definitions relative to +register set MAILBOX_IRQSTATUS___REGSET_0_3 */ + +#define MLB_MAILBOX_IRQSTATUS___0_3_OFFSET (unsigned long)(0x0) + + +/* Register set MAILBOX_IRQENABLE___REGSET_0_3 +address offset, bank address increment and number of banks */ + +#define MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET (unsigned long)(0x0104) +#define MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP (unsigned long)(0x0008) +#define MLB_MAILBOX_IRQENABLE___REGSET_0_3_BANKS (unsigned long)(4) + +#define MLB_MAILBOX_IRQENABLE_SET___REGSET_0_3_OFFSET (unsigned long)(0x0108) +#define MLB_MAILBOX_IRQENABLE_SET___REGSET_0_3_STEP (unsigned long)(0x0010) +#define MLB_MAILBOX_IRQENABLE_SET___REGSET_0_3_BANKS (unsigned long)(4) + +#define MLB_MAILBOX_IRQENABLE_CLR___REGSET_0_3_OFFSET (unsigned long)(0x010C) +#define MLB_MAILBOX_IRQENABLE_CLR___REGSET_0_3_STEP (unsigned long)(0x0010) +#define MLB_MAILBOX_IRQENABLE_CLR___REGSET_0_3_BANKS (unsigned long)(4) + +/* Register offset address definitions relative to register +set MAILBOX_IRQENABLE___REGSET_0_3 */ + +#define MLB_MAILBOX_IRQENABLE___0_3_OFFSET (unsigned long)(0x0) + + +/* Register offset address definitions */ + +#define MLB_MAILBOX_REVISION_OFFSET (unsigned long)(0x0) +#define MLB_MAILBOX_SYSCONFIG_OFFSET (unsigned long)(0x10) +#define MLB_MAILBOX_SYSSTATUS_OFFSET (unsigned long)(0x14) + + +/* Bitfield mask and offset declarations */ + +#define MLB_MAILBOX_REVISION_Rev_MASK (unsigned long)(0xff) +#define MLB_MAILBOX_REVISION_Rev_OFFSET (unsigned long)(0) + +#define MLB_MAILBOX_SYSCONFIG_ClockActivity_MASK (unsigned long)(0x100) +#define MLB_MAILBOX_SYSCONFIG_ClockActivity_OFFSET (unsigned long)(8) + +#define MLB_MAILBOX_SYSCONFIG_SIdleMode_MASK (unsigned long)(0x18) +#define MLB_MAILBOX_SYSCONFIG_SIdleMode_OFFSET (unsigned long)(3) + +#define MLB_MAILBOX_SYSCONFIG_SoftReset_MASK (unsigned long)(0x2) +#define MLB_MAILBOX_SYSCONFIG_SoftReset_OFFSET (unsigned long)(1) + +#define MLB_MAILBOX_SYSCONFIG_AutoIdle_MASK (unsigned long)(0x1) +#define MLB_MAILBOX_SYSCONFIG_AutoIdle_OFFSET (unsigned long)(0) + +#define MLB_MAILBOX_SYSSTATUS_ResetDone_MASK (unsigned long)(0x1) +#define MLB_MAILBOX_SYSSTATUS_ResetDone_OFFSET (unsigned long)(0) + +#define MLB_MAILBOX_MESSAGE___0_15_MessageValueMBm_MASK \ +(unsigned long)(0xffffffff) + +#define MLB_MAILBOX_MESSAGE___0_15_MessageValueMBm_OFFSET (unsigned long)(0) + +#define MLB_MAILBOX_FIFOSTATUS___0_15_FifoFullMBm_MASK (unsigned long)(0x1) +#define MLB_MAILBOX_FIFOSTATUS___0_15_FifoFullMBm_OFFSET (unsigned long)(0) + +#define MLB_MAILBOX_MSGSTATUS___0_15_NbOfMsgMBm_MASK (unsigned long)(0x7f) +#define MLB_MAILBOX_MSGSTATUS___0_15_NbOfMsgMBm_OFFSET (unsigned long)(0) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB15_MASK \ +(unsigned long)(0x80000000) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB15_OFFSET \ +(unsigned long)(31) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB15_MASK \ +(unsigned long)(0x40000000) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB15_OFFSET \ +(unsigned long)(30) + + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB14_MASK \ +(unsigned long)(0x20000000) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB14_OFFSET \ +(unsigned long)(29) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB14_MASK \ +(unsigned long)(0x10000000) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB14_OFFSET \ +(unsigned long)(28) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB13_MASK \ +(unsigned long)(0x8000000) +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB13_OFFSET \ +(unsigned long)(27) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB13_MASK \ +(unsigned long)(0x4000000) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB13_OFFSET \ +(unsigned long)(26) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB12_MASK \ +(unsigned long)(0x2000000) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB12_OFFSET \ +(unsigned long)(25) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB12_MASK \ +(unsigned long)(0x1000000) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB12_OFFSET \ +(unsigned long)(24) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB11_MASK \ +(unsigned long)(0x800000) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB11_OFFSET \ +(unsigned long)(23) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB11_MASK \ +(unsigned long)(0x400000) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB11_OFFSET \ +(unsigned long)(22) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB10_MASK \ +(unsigned long)(0x200000) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB10_OFFSET \ +(unsigned long)(21) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB10_MASK \ +(unsigned long)(0x100000) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB10_OFFSET \ +(unsigned long)(20) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB9_MASK \ +(unsigned long)(0x80000) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB9_OFFSET \ +(unsigned long)(19) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB9_MASK \ +(unsigned long)(0x40000) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB9_OFFSET \ +(unsigned long)(18) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB8_MASK \ +(unsigned long)(0x20000) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB8_OFFSET \ +(unsigned long)(17) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB8_MASK \ +(unsigned long)(0x10000) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB8_OFFSET \ +(unsigned long)(16) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB7_MASK \ +(unsigned long)(0x8000) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB7_OFFSET \ +(unsigned long)(15) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB7_MASK \ +(unsigned long)(0x4000) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB7_OFFSET \ +(unsigned long)(14) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB6_MASK \ +(unsigned long)(0x2000) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB6_OFFSET \ +(unsigned long)(13) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB6_MASK \ +(unsigned long)(0x1000) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB6_OFFSET \ +(unsigned long)(12) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB5_MASK \ +(unsigned long)(0x800) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB5_OFFSET \ +(unsigned long)(11) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB5_MASK \ +(unsigned long)(0x400) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB5_OFFSET \ +(unsigned long)(10) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB4_MASK \ +(unsigned long)(0x200) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB4_OFFSET \ +(unsigned long)(9) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB4_MASK \ +(unsigned long)(0x100) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB4_OFFSET \ +(unsigned long)(8) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB3_MASK \ +(unsigned long)(0x80) +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB3_OFFSET \ +(unsigned long)(7) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB3_MASK \ +(unsigned long)(0x40) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB3_OFFSET \ +(unsigned long)(6) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB2_MASK \ +(unsigned long)(0x20) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB2_OFFSET \ +(unsigned long)(5) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB2_MASK \ +(unsigned long)(0x10) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB2_OFFSET \ +(unsigned long)(4) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB1_MASK \ +(unsigned long)(0x8) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB1_OFFSET \ +(unsigned long)(3) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB1_MASK \ +(unsigned long)(0x4) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB1_OFFSET \ +(unsigned long)(2) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB0_MASK \ +(unsigned long)(0x2) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB0_OFFSET \ +(unsigned long)(1) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB0_MASK \ +(unsigned long)(0x1) + +#define MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB0_OFFSET \ +(unsigned long)(0) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB15_MASK \ +(unsigned long)(0x80000000) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB15_OFFSET \ +(unsigned long)(31) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB15_MASK \ +(unsigned long)(0x40000000) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB15_OFFSET \ +(unsigned long)(30) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB14_MASK \ +(unsigned long)(0x20000000) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB14_OFFSET \ +(unsigned long)(29) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB14_MASK \ +(unsigned long)(0x10000000) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB14_OFFSET \ +(unsigned long)(28) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB13_MASK \ +(unsigned long)(0x8000000) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB13_OFFSET \ +(unsigned long)(27) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB13_MASK \ +(unsigned long)(0x4000000) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB13_OFFSET \ +(unsigned long)(26) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB12_MASK \ +(unsigned long)(0x2000000) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB12_OFFSET \ +(unsigned long)(25) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB12_MASK \ +(unsigned long)(0x1000000) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB12_OFFSET \ +(unsigned long)(24) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB11_MASK \ +(unsigned long)(0x800000) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB11_OFFSET \ +(unsigned long)(23) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB11_MASK \ +(unsigned long)(0x400000) +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB11_OFFSET \ +(unsigned long)(22) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB10_MASK \ +(unsigned long)(0x200000) +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB10_OFFSET \ +(unsigned long)(21) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB10_MASK \ +(unsigned long)(0x100000) +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB10_OFFSET \ +(unsigned long)(20) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB9_MASK \ +(unsigned long)(0x80000) +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB9_OFFSET \ +(unsigned long)(19) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB9_MASK \ +(unsigned long)(0x40000) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB9_OFFSET \ +(unsigned long)(18) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB8_MASK \ +(unsigned long)(0x20000) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB8_OFFSET \ +(unsigned long)(17) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB8_MASK \ +(unsigned long)(0x10000) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB8_OFFSET \ +(unsigned long)(16) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB7_MASK \ +(unsigned long)(0x8000) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB7_OFFSET \ +(unsigned long)(15) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB7_MASK \ +(unsigned long)(0x4000) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB7_OFFSET \ +(unsigned long)(14) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB6_MASK \ +(unsigned long)(0x2000) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB6_OFFSET \ +(unsigned long)(13) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB6_MASK \ +(unsigned long)(0x1000) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB6_OFFSET \ +(unsigned long)(12) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB5_MASK \ +(unsigned long)(0x800) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB5_OFFSET \ +(unsigned long)(11) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB5_MASK \ +(unsigned long)(0x400) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB5_OFFSET \ +(unsigned long)(10) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB4_MASK \ +(unsigned long)(0x200) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB4_OFFSET \ +(unsigned long)(9) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB4_MASK \ +(unsigned long)(0x100) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB4_OFFSET \ +(unsigned long)(8) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB3_MASK \ +(unsigned long)(0x80) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB3_OFFSET \ +(unsigned long)(7) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB3_MASK \ +(unsigned long)(0x40) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB3_OFFSET \ +(unsigned long)(6) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB2_MASK \ +(unsigned long)(0x20) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB2_OFFSET \ +(unsigned long)(5) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB2_MASK \ +(unsigned long)(0x10) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB2_OFFSET \ +(unsigned long)(4) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB1_MASK \ +(unsigned long)(0x8) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB1_OFFSET \ +(unsigned long)(3) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB1_MASK \ +(unsigned long)(0x4) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB1_OFFSET \ +(unsigned long)(2) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB0_MASK \ +(unsigned long)(0x2) + +#define MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB0_OFFSET \ +(unsigned long)(1) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB0_MASK \ +(unsigned long)(0x1) + +#define MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB0_OFFSET \ +(unsigned long)(0) + + +/* + * EXPORTED TYPES + * + */ + +/* The following type definitions +represent the enumerated values for each bitfield */ + +enum MLBMAILBOX_SYSCONFIGSIdleModeE { + MLBMAILBOX_SYSCONFIGSIdleModeb00 = 0x0000, + MLBMAILBOX_SYSCONFIGSIdleModeb01 = 0x0001, + MLBMAILBOX_SYSCONFIGSIdleModeb10 = 0x0002, + MLBMAILBOX_SYSCONFIGSIdleModeb11 = 0x0003 +}; + +enum MLBMAILBOX_SYSCONFIGSoftResetE { + MLBMAILBOX_SYSCONFIGSoftResetb0 = 0x0000, + MLBMAILBOX_SYSCONFIGSoftResetb1 = 0x0001 +}; + +enum MLBMAILBOX_SYSCONFIGAutoIdleE { + MLBMAILBOX_SYSCONFIGAutoIdleb0 = 0x0000, + MLBMAILBOX_SYSCONFIGAutoIdleb1 = 0x0001 +}; + +enum MLBMAILBOX_SYSSTATUSResetDoneE { + MLBMAILBOX_SYSSTATUSResetDonerstongoing = 0x0000, + MLBMAILBOX_SYSSTATUSResetDonerstcomp = 0x0001 +}; + +#endif /* _MLB_ACC_INT_H */ diff --git a/arch/arm/plat-omap/include/syslink/MBXRegAcM.h b/arch/arm/plat-omap/include/syslink/MBXRegAcM.h new file mode 100644 index 000000000000..1c6732ecc9a2 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/MBXRegAcM.h @@ -0,0 +1,3027 @@ +/* + * MBXRegAcM.h + * + * Notify mailbox driver support for OMAP Processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef _MBX_REG_ACM_H +#define _MBX_REG_ACM_H + + +#include <syslink/GlobalTypes.h> +#include <syslink/MBXAccInt.h> + + +/* + * EXPORTED DEFINITIONS + * + */ + +#if defined(USE_LEVEL_1_MACROS) + +#define MLBMAILBOX_REVISIONReadRegister32(base_address)\ +(RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +MLB_MAILBOX_REVISION_OFFSET)) + + + +#define MLBMAILBOX_REVISIONRevRead32(base_address)\ +((((RD_MEM_32_VOLATILE((((unsigned long)(base_address))+ \ +(MLB_MAILBOX_REVISION_OFFSET)))) &\ +MLB_MAILBOX_REVISION_Rev_MASK) >>\ +MLB_MAILBOX_REVISION_Rev_OFFSET)) + + + +#define MLBMAILBOX_REVISIONRevGet32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_REVISION_Rev_MASK) \ +>> MLB_MAILBOX_REVISION_Rev_OFFSET)) + + + +#define MLBMAILBOX_SYSCONFIGReadRegister32(base_address)\ +(RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +MLB_MAILBOX_SYSCONFIG_OFFSET)) + + +#define MLBMAILBOX_SYSCONFIGWriteRegister32(base_address, value)\ +do {\ + const unsigned long offset = MLB_MAILBOX_SYSCONFIG_OFFSET;\ + register unsigned long newValue = ((unsigned long)(value));\ + WR_MEM_32_VOLATILE(((unsigned long)(base_address))+ \ + offset, newValue);\ +} while (0) + + +#define MLBMAILBOX_SYSCONFIGClockActivityRead32(base_address)\ +((((RD_MEM_32_VOLATILE((((unsigned long)(base_address))+\ +(MLB_MAILBOX_SYSCONFIG_OFFSET)))) &\ +MLB_MAILBOX_SYSCONFIG_ClockActivity_MASK) >>\ +MLB_MAILBOX_SYSCONFIG_ClockActivity_OFFSET)) + + +#define MLBMAILBOX_SYSCONFIGClockActivityGet32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_SYSCONFIG_ClockActivity_MASK) \ +>> MLB_MAILBOX_SYSCONFIG_ClockActivity_OFFSET)) + + +#define MLBMAILBOX_SYSCONFIGSIdleModeRead32(base_address)\ +((((RD_MEM_32_VOLATILE((((unsigned long)(base_address))+\ +(MLB_MAILBOX_SYSCONFIG_OFFSET)))) &\ +MLB_MAILBOX_SYSCONFIG_SIdleMode_MASK) >>\ +MLB_MAILBOX_SYSCONFIG_SIdleMode_OFFSET)) + + +#define MLBMAILBOX_SYSCONFIGSIdleModeReadIsb0032(base_address)\ +((MLBMAILBOX_SYSCONFIGSIdleModeb00 == (MLBMAILBOX_SYSCONFIGSIdleModeE)\ +(((RD_MEM_32_VOLATILE((((unsigned long)(base_address))+\ +(MLB_MAILBOX_SYSCONFIG_OFFSET)))) &\ +MLB_MAILBOX_SYSCONFIG_SIdleMode_MASK) >>\ +MLB_MAILBOX_SYSCONFIG_SIdleMode_OFFSET))) + + +#define MLBMAILBOX_SYSCONFIGSIdleModeReadIsb0132(base_address)\ +((MLBMAILBOX_SYSCONFIGSIdleModeb01 == (MLBMAILBOX_SYSCONFIGSIdleModeE)\ +(((RD_MEM_32_VOLATILE((((unsigned long)(base_address))+\ +(MLB_MAILBOX_SYSCONFIG_OFFSET)))) &\ +MLB_MAILBOX_SYSCONFIG_SIdleMode_MASK) >>\ +MLB_MAILBOX_SYSCONFIG_SIdleMode_OFFSET))) + + +#define MLBMAILBOX_SYSCONFIGSIdleModeReadIsb1032(base_address)\ +((MLBMAILBOX_SYSCONFIGSIdleModeb10 == (MLBMAILBOX_SYSCONFIGSIdleModeE)\ +(((RD_MEM_32_VOLATILE((((unsigned long)(base_address))+\ +(MLB_MAILBOX_SYSCONFIG_OFFSET)))) &\ +MLB_MAILBOX_SYSCONFIG_SIdleMode_MASK) >>\ +MLB_MAILBOX_SYSCONFIG_SIdleMode_OFFSET))) + +#define MLBMAILBOX_SYSCONFIGSIdleModeReadIsb1132(base_address)\ +((MLBMAILBOX_SYSCONFIGSIdleModeb11 == (MLBMAILBOX_SYSCONFIGSIdleModeE)\ +(((RD_MEM_32_VOLATILE((((unsigned long)(base_address))+\ +(MLB_MAILBOX_SYSCONFIG_OFFSET)))) &\ +MLB_MAILBOX_SYSCONFIG_SIdleMode_MASK) >>\ +MLB_MAILBOX_SYSCONFIG_SIdleMode_OFFSET))) + +#define MLBMAILBOX_SYSCONFIGSIdleModeGet32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_SYSCONFIG_SIdleMode_MASK) >> \ +MLB_MAILBOX_SYSCONFIG_SIdleMode_OFFSET)) + +#define MLBMAILBOX_SYSCONFIGSIdleModeIsb0032(var)\ +((MLBMAILBOX_SYSCONFIGSIdleModeb00 == \ +(MLBMAILBOX_SYSCONFIGSIdleModeE)\ +((((unsigned long)(var)) & MLB_MAILBOX_SYSCONFIG_SIdleMode_MASK) >>\ +MLB_MAILBOX_SYSCONFIG_SIdleMode_OFFSET))) + +#define MLBMAILBOX_SYSCONFIGSIdleModeIsb0132(var)\ +((MLBMAILBOX_SYSCONFIGSIdleModeb01 == (MLBMAILBOX_SYSCONFIGSIdleModeE)\ +((((unsigned long)(var)) & MLB_MAILBOX_SYSCONFIG_SIdleMode_MASK) >>\ +MLB_MAILBOX_SYSCONFIG_SIdleMode_OFFSET))) + +#define MLBMAILBOX_SYSCONFIGSIdleModeIsb1032(var)\ +((MLBMAILBOX_SYSCONFIGSIdleModeb10 == (MLBMAILBOX_SYSCONFIGSIdleModeE)\ +((((unsigned long)(var)) & MLB_MAILBOX_SYSCONFIG_SIdleMode_MASK) >>\ +MLB_MAILBOX_SYSCONFIG_SIdleMode_OFFSET))) + +#define MLBMAILBOX_SYSCONFIGSIdleModeIsb1132(var)\ +((MLBMAILBOX_SYSCONFIGSIdleModeb11 == (MLBMAILBOX_SYSCONFIGSIdleModeE)\ +((((unsigned long)(var)) & MLB_MAILBOX_SYSCONFIG_SIdleMode_MASK) >>\ +MLB_MAILBOX_SYSCONFIG_SIdleMode_OFFSET))) + +#define MLBMAILBOX_SYSCONFIGSIdleModeWrite32(base_address, value)\ +do {\ + const unsigned long offset = MLB_MAILBOX_SYSCONFIG_OFFSET;\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_SYSCONFIG_SIdleMode_MASK);\ + newValue <<= MLB_MAILBOX_SYSCONFIG_SIdleMode_OFFSET;\ + newValue &= MLB_MAILBOX_SYSCONFIG_SIdleMode_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+ \ + offset, newValue);\ +} while (0) + +#define MLBMAILBOX_SYSCONFIGSIdleModeWriteb0032(base_address)\ +do {\ + const unsigned long offset = MLB_MAILBOX_SYSCONFIG_OFFSET;\ + const unsigned long newValue = \ + (unsigned long)MLBMAILBOX_SYSCONFIGSIdleModeb00 <<\ + MLB_MAILBOX_SYSCONFIG_SIdleMode_OFFSET;\ + register unsigned long data = \ + RD_MEM_32_VOLATILE((unsigned long)(base_address)+offset);\ + data &= ~(MLB_MAILBOX_SYSCONFIG_SIdleMode_MASK);\ + data |= newValue;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, data);\ +} while (0) + +#define MLBMAILBOX_SYSCONFIGSIdleModeWriteb0132(base_address)\ +do {\ + const unsigned long offset = MLB_MAILBOX_SYSCONFIG_OFFSET;\ + const unsigned long newValue = \ + (unsigned long)MLBMAILBOX_SYSCONFIGSIdleModeb01 <<\ + MLB_MAILBOX_SYSCONFIG_SIdleMode_OFFSET;\ + register unsigned long data = \ + RD_MEM_32_VOLATILE((unsigned long)(base_address)+offset);\ + data &= ~(MLB_MAILBOX_SYSCONFIG_SIdleMode_MASK);\ + data |= newValue;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, data);\ +} while (0) + +#define MLBMAILBOX_SYSCONFIGSIdleModeWriteb1032(base_address)\ +do {\ + const unsigned long offset = MLB_MAILBOX_SYSCONFIG_OFFSET;\ + const unsigned long newValue = \ + (unsigned long)MLBMAILBOX_SYSCONFIGSIdleModeb10 <<\ + MLB_MAILBOX_SYSCONFIG_SIdleMode_OFFSET;\ + register unsigned long data = \ + RD_MEM_32_VOLATILE((unsigned long)(base_address)+offset);\ + data &= ~(MLB_MAILBOX_SYSCONFIG_SIdleMode_MASK);\ + data |= newValue;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, data);\ +} while (0) + +#define MLBMAILBOX_SYSCONFIGSIdleModeWriteb1132(base_address)\ +do {\ + const unsigned long offset = MLB_MAILBOX_SYSCONFIG_OFFSET;\ + const unsigned long newValue = \ + (unsigned long)MLBMAILBOX_SYSCONFIGSIdleModeb11 <<\ + MLB_MAILBOX_SYSCONFIG_SIdleMode_OFFSET;\ + register unsigned long data = \ + RD_MEM_32_VOLATILE((unsigned long)(base_address)+offset);\ + data &= ~(MLB_MAILBOX_SYSCONFIG_SIdleMode_MASK);\ + data |= newValue;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, data);\ +} while (0) + +#define MLBMAILBOX_SYSCONFIGSIdleModeSet32(var, value)\ +(((((unsigned long)(var)) & ~(MLB_MAILBOX_SYSCONFIG_SIdleMode_MASK)) |\ +((((unsigned long)(value)) << MLB_MAILBOX_SYSCONFIG_SIdleMode_OFFSET) &\ +MLB_MAILBOX_SYSCONFIG_SIdleMode_MASK))) + +#define MLBMAILBOX_SYSCONFIGSoftResetRead32(base_address)\ +((((RD_MEM_32_VOLATILE((((unsigned long)(base_address))+\ +(MLB_MAILBOX_SYSCONFIG_OFFSET)))) &\ +MLB_MAILBOX_SYSCONFIG_SoftReset_MASK) >>\ +MLB_MAILBOX_SYSCONFIG_SoftReset_OFFSET)) + +#define MLBMAILBOX_SYSCONFIGSoftResetReadIsb032(base_address)\ +((MLBMAILBOX_SYSCONFIGSoftResetb0 == (MLBMAILBOX_SYSCONFIGSoftResetE)\ +(((RD_MEM_32_VOLATILE((((unsigned long)(base_address))+\ +(MLB_MAILBOX_SYSCONFIG_OFFSET)))) &\ +MLB_MAILBOX_SYSCONFIG_SoftReset_MASK) >>\ +MLB_MAILBOX_SYSCONFIG_SoftReset_OFFSET))) + +#define MLBMAILBOX_SYSCONFIGSoftResetReadIsb132(base_address)\ +((MLBMAILBOX_SYSCONFIGSoftResetb1 == (MLBMAILBOX_SYSCONFIGSoftResetE)\ +(((RD_MEM_32_VOLATILE((((unsigned long)(base_address))+\ +(MLB_MAILBOX_SYSCONFIG_OFFSET)))) &\ +MLB_MAILBOX_SYSCONFIG_SoftReset_MASK) >>\ +MLB_MAILBOX_SYSCONFIG_SoftReset_OFFSET))) + +#define MLBMAILBOX_SYSCONFIGSoftResetGet32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_SYSCONFIG_SoftReset_MASK) >> \ +MLB_MAILBOX_SYSCONFIG_SoftReset_OFFSET)) + +#define MLBMAILBOX_SYSCONFIGSoftResetIsb032(var)\ +((MLBMAILBOX_SYSCONFIGSoftResetb0 == (MLBMAILBOX_SYSCONFIGSoftResetE)\ +((((unsigned long)(var)) & MLB_MAILBOX_SYSCONFIG_SoftReset_MASK) >>\ +MLB_MAILBOX_SYSCONFIG_SoftReset_OFFSET))) + +#define MLBMAILBOX_SYSCONFIGSoftResetIsb132(var)\ +((MLBMAILBOX_SYSCONFIGSoftResetb1 == (MLBMAILBOX_SYSCONFIGSoftResetE)\ +((((unsigned long)(var)) & MLB_MAILBOX_SYSCONFIG_SoftReset_MASK) >>\ +MLB_MAILBOX_SYSCONFIG_SoftReset_OFFSET))) + +#define MLBMAILBOX_SYSCONFIGSoftResetWrite32(base_address, value)\ +do {\ + const unsigned long offset = MLB_MAILBOX_SYSCONFIG_OFFSET;\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_SYSCONFIG_SoftReset_MASK);\ + newValue <<= MLB_MAILBOX_SYSCONFIG_SoftReset_OFFSET;\ + newValue &= MLB_MAILBOX_SYSCONFIG_SoftReset_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_SYSCONFIGSoftResetWriteb032(base_address)\ +do {\ + const unsigned long offset = MLB_MAILBOX_SYSCONFIG_OFFSET;\ + const unsigned long newValue = \ + (unsigned long)MLBMAILBOX_SYSCONFIGSoftResetb0 <<\ + MLB_MAILBOX_SYSCONFIG_SoftReset_OFFSET;\ + register unsigned long data = \ + RD_MEM_32_VOLATILE((unsigned long)(base_address)+offset);\ + data &= ~(MLB_MAILBOX_SYSCONFIG_SoftReset_MASK);\ + data |= newValue;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, data);\ +} while (0) + +#define MLBMAILBOX_SYSCONFIGSoftResetWriteb132(base_address)\ +do {\ + const unsigned long offset = MLB_MAILBOX_SYSCONFIG_OFFSET;\ + const unsigned long newValue = \ + (unsigned long)MLBMAILBOX_SYSCONFIGSoftResetb1 <<\ + MLB_MAILBOX_SYSCONFIG_SoftReset_OFFSET;\ + register unsigned long data = \ + RD_MEM_32_VOLATILE((unsigned long)(base_address)+offset);\ + data &= ~(MLB_MAILBOX_SYSCONFIG_SoftReset_MASK);\ + data |= newValue;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, data);\ +} while (0) + +#define MLBMAILBOX_SYSCONFIGSoftResetSet32(var, value)\ +(((((unsigned long)(var)) & ~(MLB_MAILBOX_SYSCONFIG_SoftReset_MASK)) |\ +((((unsigned long)(value)) << MLB_MAILBOX_SYSCONFIG_SoftReset_OFFSET) &\ +MLB_MAILBOX_SYSCONFIG_SoftReset_MASK))) + +#define MLBMAILBOX_SYSCONFIGAutoIdleRead32(base_address)\ +((((RD_MEM_32_VOLATILE((((unsigned long)(base_address))+\ +(MLB_MAILBOX_SYSCONFIG_OFFSET)))) &\ +MLB_MAILBOX_SYSCONFIG_AutoIdle_MASK) >>\ +MLB_MAILBOX_SYSCONFIG_AutoIdle_OFFSET)) + +#define MLBMAILBOX_SYSCONFIGAutoIdleReadIsb032(base_address)\ +((MLBMAILBOX_SYSCONFIGAutoIdleb0 == (MLBMAILBOX_SYSCONFIGAutoIdleE)\ +(((RD_MEM_32_VOLATILE((((unsigned long)(base_address))+\ +(MLB_MAILBOX_SYSCONFIG_OFFSET)))) &\ +MLB_MAILBOX_SYSCONFIG_AutoIdle_MASK) >>\ +MLB_MAILBOX_SYSCONFIG_AutoIdle_OFFSET))) + +#define MLBMAILBOX_SYSCONFIGAutoIdleReadIsb132(base_address)\ +((MLBMAILBOX_SYSCONFIGAutoIdleb1 == (MLBMAILBOX_SYSCONFIGAutoIdleE)\ +(((RD_MEM_32_VOLATILE((((unsigned long)(base_address))+\ +(MLB_MAILBOX_SYSCONFIG_OFFSET)))) &\ +MLB_MAILBOX_SYSCONFIG_AutoIdle_MASK) >>\ +MLB_MAILBOX_SYSCONFIG_AutoIdle_OFFSET))) + +#define MLBMAILBOX_SYSCONFIGAutoIdleGet32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_SYSCONFIG_AutoIdle_MASK) >> MLB_MAILBOX_SYSCONFIG_AutoIdle_OFFSET)) + +#define MLBMAILBOX_SYSCONFIGAutoIdleIsb032(var)\ +((MLBMAILBOX_SYSCONFIGAutoIdleb0 == (MLBMAILBOX_SYSCONFIGAutoIdleE)\ +((((unsigned long)(var)) & MLB_MAILBOX_SYSCONFIG_AutoIdle_MASK) >>\ +MLB_MAILBOX_SYSCONFIG_AutoIdle_OFFSET))) + +#define MLBMAILBOX_SYSCONFIGAutoIdleIsb132(var)\ +((MLBMAILBOX_SYSCONFIGAutoIdleb1 == (MLBMAILBOX_SYSCONFIGAutoIdleE)\ +((((unsigned long)(var)) & MLB_MAILBOX_SYSCONFIG_AutoIdle_MASK) >>\ +MLB_MAILBOX_SYSCONFIG_AutoIdle_OFFSET))) + +#define MLBMAILBOX_SYSCONFIGAutoIdleWrite32(base_address, value)\ +do {\ + const unsigned long offset = MLB_MAILBOX_SYSCONFIG_OFFSET;\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_SYSCONFIG_AutoIdle_MASK);\ + newValue <<= MLB_MAILBOX_SYSCONFIG_AutoIdle_OFFSET;\ + newValue &= MLB_MAILBOX_SYSCONFIG_AutoIdle_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_SYSCONFIGAutoIdleWriteb032(base_address)\ +do {\ + const unsigned long offset = MLB_MAILBOX_SYSCONFIG_OFFSET;\ + const unsigned long newValue = \ + (unsigned long)MLBMAILBOX_SYSCONFIGAutoIdleb0 <<\ + MLB_MAILBOX_SYSCONFIG_AutoIdle_OFFSET;\ + register unsigned long data = \ + RD_MEM_32_VOLATILE((unsigned long)(base_address)+offset);\ + data &= ~(MLB_MAILBOX_SYSCONFIG_AutoIdle_MASK);\ + data |= newValue;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, data);\ +} while (0) + +#define MLBMAILBOX_SYSCONFIGAutoIdleWriteb132(base_address)\ +do {\ + const unsigned long offset = MLB_MAILBOX_SYSCONFIG_OFFSET;\ + const unsigned long newValue = \ + (unsigned long)MLBMAILBOX_SYSCONFIGAutoIdleb1 <<\ + MLB_MAILBOX_SYSCONFIG_AutoIdle_OFFSET;\ + register unsigned long data = \ + RD_MEM_32_VOLATILE((unsigned long)(base_address)+offset);\ + data &= ~(MLB_MAILBOX_SYSCONFIG_AutoIdle_MASK);\ + data |= newValue;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, data);\ +} while (0) + +#define MLBMAILBOX_SYSCONFIGAutoIdleSet32(var, value)\ +(((((unsigned long)(var)) & ~(MLB_MAILBOX_SYSCONFIG_AutoIdle_MASK)) |\ +((((unsigned long)(value)) << MLB_MAILBOX_SYSCONFIG_AutoIdle_OFFSET) &\ +MLB_MAILBOX_SYSCONFIG_AutoIdle_MASK))) + +#define MLBMAILBOX_SYSSTATUSReadRegister32(base_address)\ +(RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +MLB_MAILBOX_SYSSTATUS_OFFSET)) + +#define MLBMAILBOX_SYSSTATUSResetDoneRead32(base_address)\ +((((RD_MEM_32_VOLATILE((((unsigned long)(base_address))+\ +(MLB_MAILBOX_SYSSTATUS_OFFSET)))) &\ +MLB_MAILBOX_SYSSTATUS_ResetDone_MASK) >>\ +MLB_MAILBOX_SYSSTATUS_ResetDone_OFFSET)) + +#define MLBMAILBOX_SYSSTATUSResetDoneReadisrstongoing32(base_address)\ +((MLBMAILBOX_SYSSTATUSResetDonerstongoing == (MLBMAILBOX_SYSSTATUSResetDoneE)\ +(((RD_MEM_32_VOLATILE((((unsigned long)(base_address))+\ +(MLB_MAILBOX_SYSSTATUS_OFFSET)))) &\ +MLB_MAILBOX_SYSSTATUS_ResetDone_MASK) >>\ +MLB_MAILBOX_SYSSTATUS_ResetDone_OFFSET))) + +#define MLBMAILBOX_SYSSTATUSResetDoneReadisrstcomp32(base_address)\ +((MLBMAILBOX_SYSSTATUSResetDonerstcomp == (MLBMAILBOX_SYSSTATUSResetDoneE)\ +(((RD_MEM_32_VOLATILE((((unsigned long)(base_address))+\ +(MLB_MAILBOX_SYSSTATUS_OFFSET)))) &\ +MLB_MAILBOX_SYSSTATUS_ResetDone_MASK) >>\ +MLB_MAILBOX_SYSSTATUS_ResetDone_OFFSET))) + +#define MLBMAILBOX_SYSSTATUSResetDoneGet32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_SYSSTATUS_ResetDone_MASK) >> \ +MLB_MAILBOX_SYSSTATUS_ResetDone_OFFSET)) + +#define MLBMAILBOX_SYSSTATUSResetDoneisrstongoing32(var)\ +((MLBMAILBOX_SYSSTATUSResetDonerstongoing == (MLBMAILBOX_SYSSTATUSResetDoneE)\ +((((unsigned long)(var)) & MLB_MAILBOX_SYSSTATUS_ResetDone_MASK) >>\ +MLB_MAILBOX_SYSSTATUS_ResetDone_OFFSET))) + +#define MLBMAILBOX_SYSSTATUSResetDoneisrstcomp32(var)\ +((MLBMAILBOX_SYSSTATUSResetDonerstcomp == (MLBMAILBOX_SYSSTATUSResetDoneE)\ +((((unsigned long)(var)) & MLB_MAILBOX_SYSSTATUS_ResetDone_MASK) >>\ +MLB_MAILBOX_SYSSTATUS_ResetDone_OFFSET))) + +#define MLBMAILBOX_MESSAGE___0_15ReadRegister32(base_address, bank)\ +(RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_MESSAGE___REGSET_0_15_OFFSET +\ +MLB_MAILBOX_MESSAGE___0_15_OFFSET+((bank)*\ +MLB_MAILBOX_MESSAGE___REGSET_0_15_STEP)))) + +#define MLBMAILBOX_MESSAGE___0_15WriteRegister32(base_address, bank, value)\ +do {\ + const unsigned long offset = MLB_MAILBOX_MESSAGE___REGSET_0_15_OFFSET +\ + MLB_MAILBOX_MESSAGE___0_15_OFFSET +\ + ((bank) * MLB_MAILBOX_MESSAGE___REGSET_0_15_STEP);\ + register unsigned long newValue = ((unsigned long)(value));\ + WR_MEM_32_VOLATILE(((unsigned long)(base_address))+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_MESSAGE___0_15MessageValueMBmRead32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_MESSAGE___REGSET_0_15_OFFSET +\ +MLB_MAILBOX_MESSAGE___0_15_OFFSET+((bank)*\ +MLB_MAILBOX_MESSAGE___REGSET_0_15_STEP)))) &\ +MLB_MAILBOX_MESSAGE___0_15_MessageValueMBm_MASK) >>\ +MLB_MAILBOX_MESSAGE___0_15_MessageValueMBm_OFFSET)) + +#define MLBMAILBOX_MESSAGE___0_15MessageValueMBmGet32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_MESSAGE___0_15_MessageValueMBm_MASK) >> \ +MLB_MAILBOX_MESSAGE___0_15_MessageValueMBm_OFFSET)) + +#define MLBMAILBOX_MESSAGE___0_15MessageValueMBmWrite32\ +(base_address, bank, value) do {\ + const unsigned long offset = \ + MLB_MAILBOX_MESSAGE___REGSET_0_15_OFFSET +\ + MLB_MAILBOX_MESSAGE___0_15_OFFSET +\ + ((bank) * MLB_MAILBOX_MESSAGE___REGSET_0_15_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_MESSAGE___0_15_MessageValueMBm_MASK);\ + newValue <<= MLB_MAILBOX_MESSAGE___0_15_MessageValueMBm_OFFSET;\ + newValue &= MLB_MAILBOX_MESSAGE___0_15_MessageValueMBm_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_MESSAGE___0_15MessageValueMBmSet32(var, value)\ +(((((unsigned long)(var)) & \ +~(MLB_MAILBOX_MESSAGE___0_15_MessageValueMBm_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_MESSAGE___0_15_MessageValueMBm_OFFSET) &\ +MLB_MAILBOX_MESSAGE___0_15_MessageValueMBm_MASK))) + +#define MLBMAILBOX_FIFOSTATUS___0_15ReadRegister32(base_address, bank)\ +(RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_FIFOSTATUS___REGSET_0_15_OFFSET +\ +MLB_MAILBOX_FIFOSTATUS___0_15_OFFSET+((bank)*\ +MLB_MAILBOX_FIFOSTATUS___REGSET_0_15_STEP)))) + +#define MLBMAILBOX_FIFOSTATUS___0_15FifoFullMBmRead32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_FIFOSTATUS___REGSET_0_15_OFFSET +\ +MLB_MAILBOX_FIFOSTATUS___0_15_OFFSET+((bank)*\ +MLB_MAILBOX_FIFOSTATUS___REGSET_0_15_STEP)))) &\ +MLB_MAILBOX_FIFOSTATUS___0_15_FifoFullMBm_MASK) >>\ +MLB_MAILBOX_FIFOSTATUS___0_15_FifoFullMBm_OFFSET)) + +#define MLBMAILBOX_FIFOSTATUS___0_15FifoFullMBmGet32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_FIFOSTATUS___0_15_FifoFullMBm_MASK) >> \ +MLB_MAILBOX_FIFOSTATUS___0_15_FifoFullMBm_OFFSET)) + +#define MLBMAILBOX_MSGSTATUS___0_15ReadRegister32(base_address, bank)\ +(RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_MSGSTATUS___REGSET_0_15_OFFSET +\ +MLB_MAILBOX_MSGSTATUS___0_15_OFFSET+((bank)*\ +MLB_MAILBOX_MSGSTATUS___REGSET_0_15_STEP)))) + +#define MLBMAILBOX_MSGSTATUS___0_15NbOfMsgMBmRead32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_MSGSTATUS___REGSET_0_15_OFFSET +\ +MLB_MAILBOX_MSGSTATUS___0_15_OFFSET+((bank)*\ +MLB_MAILBOX_MSGSTATUS___REGSET_0_15_STEP)))) &\ +MLB_MAILBOX_MSGSTATUS___0_15_NbOfMsgMBm_MASK) >>\ +MLB_MAILBOX_MSGSTATUS___0_15_NbOfMsgMBm_OFFSET)) + +#define MLBMAILBOX_MSGSTATUS___0_15NbOfMsgMBmGet32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_MSGSTATUS___0_15_NbOfMsgMBm_MASK) \ +>> MLB_MAILBOX_MSGSTATUS___0_15_NbOfMsgMBm_OFFSET)) + +#if defined(OMAP44XX) || defined(VPOM4430_1_06) + +#define MLBMAILBOX_IRQSTATUS_CLR___0_3ReadRegister32(base_address, bank)\ +(RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS_CLR___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS_CLR___REGSET_0_3_STEP)))) + +#else + +#define MLBMAILBOX_IRQSTATUS___0_3ReadRegister32(base_address, bank)\ +(RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) + +#endif + +#if defined(OMAP44XX) || defined(VPOM4430_1_06) + +#define MLBMAILBOX_IRQSTATUS_CLR___0_3WriteRegister32\ +(base_address, bank, value) do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS_CLR___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * \ + MLB_MAILBOX_IRQSTATUS_CLR___REGSET_0_3_STEP);\ + register unsigned long newValue = ((unsigned long)(value));\ + WR_MEM_32_VOLATILE(((unsigned long)(base_address))+ \ + offset, newValue);\ +} while (0) + +#else + +#define MLBMAILBOX_IRQSTATUS___0_3WriteRegister32(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long newValue = ((unsigned long)(value));\ + WR_MEM_32_VOLATILE(((unsigned long)(base_address))+offset, newValue);\ +} while (0) + +#endif + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB15Read32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB15_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB15_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB15Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB15_MASK) \ +>> MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB15_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB15Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB15_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB15_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB15_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB15Set32(var, value)\ +(((((unsigned long)(var)) & \ +~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB15_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB15_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB15_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB15Read32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB15_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB15_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB15Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB15_MASK) \ +>> MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB15_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB15Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB15_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB15_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB15_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB15Set32(var, value)\ +(((((unsigned long)(var)) & \ +~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB15_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB15_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB15_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB14Read32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+\ +((bank)*MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB14_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB14_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB14Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB14_MASK) \ +>> MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB14_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB14Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB14_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB14_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB14_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB14Set32(var, value)\ +(((((unsigned long)(var)) & \ +~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB14_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB14_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB14_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB14Read32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB14_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB14_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB14Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB14_MASK) \ +>> MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB14_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB14Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB14_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB14_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB14_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB14Set32(var, value)\ +(((((unsigned long)(var)) & \ +~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB14_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB14_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB14_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB13Read32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB13_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB13_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB13Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB13_MASK) \ +>> MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB13_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB13Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB13_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB13_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB13_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB13Set32(var, value)\ +(((((unsigned long)(var)) & \ +~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB13_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB13_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB13_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB13Read32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB13_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB13_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB13Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB13_MASK) \ +>> MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB13_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB13Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB13_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB13_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB13_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB13Set32(var, value)\ +(((((unsigned long)(var)) & \ +~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB13_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB13_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB13_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB12Read32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB12_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB12_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB12Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB12_MASK) >> \ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB12_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB12Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB12_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB12_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB12_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB12Set32(var, value)\ +(((((unsigned long)(var)) & \ +~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB12_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB12_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB12_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB12Read32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB12_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB12_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB12Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB12_MASK) \ +>> MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB12_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB12Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB12_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB12_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB12_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB12Set32(var, value)\ +(((((unsigned long)(var)) & \ +~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB12_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB12_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB12_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB11Read32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB11_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB11_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB11Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB11_MASK) \ +>> MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB11_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB11Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB11_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB11_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB11_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB11Set32(var, value)\ +(((((unsigned long)(var)) & \ +~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB11_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB11_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB11_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB11Read32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB11_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB11_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB11Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB11_MASK) \ +>> MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB11_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB11Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB11_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB11_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB11_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB11Set32(var, value)\ +(((((unsigned long)(var)) & \ +~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB11_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB11_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB11_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB10Read32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB10_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB10_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB10Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB10_MASK) \ +>> MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB10_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB10Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB10_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB10_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB10_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB10Set32(var, value)\ +(((((unsigned long)(var)) & \ +~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB10_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB10_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB10_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB10Read32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB10_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB10_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB10Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB10_MASK) \ +>> MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB10_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB10Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB10_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB10_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB10_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB10Set32(var, value)\ +(((((unsigned long)(var)) & \ +~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB10_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB10_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB10_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB9Read32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB9_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB9_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB9Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB9_MASK) \ +>> MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB9_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB9Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB9_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB9_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB9_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB9Set32(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB9_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB9_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB9_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB9Read32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB9_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB9_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB9Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB9_MASK) \ +>> MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB9_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB9Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB9_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB9_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB9_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB9Set32(var, value)\ +(((((unsigned long)(var)) & \ +~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB9_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB9_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB9_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB8Read32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB8_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB8_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB8Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB8_MASK) \ +>> MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB8_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB8Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB8_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB8_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB8_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB8Set32(var, value)\ +(((((unsigned long)(var)) & \ +~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB8_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB8_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB8_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB8Read32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB8_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB8_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB8Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB8_MASK) \ +>> MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB8_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB8Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB8_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB8_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB8_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB8Set32(var, value)\ +(((((unsigned long)(var)) & \ +~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB8_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB8_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB8_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB7Read32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB7_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB7_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB7Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB7_MASK) \ +>> MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB7_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB7Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB7_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB7_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB7_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB7Set32(var, value)\ +(((((unsigned long)(var)) & \ +~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB7_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB7_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB7_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB7Read32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB7_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB7_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB7Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB7_MASK) \ +>> MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB7_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB7Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB7_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB7_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB7_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB7Set32(var, value)\ +(((((unsigned long)(var)) & \ +~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB7_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB7_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB7_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB6Read32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB6_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB6_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB6Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB6_MASK) >> \ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB6_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB6Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB6_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB6_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB6_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB6Set32(var, value)\ +(((((unsigned long)(var)) & \ +~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB6_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB6_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB6_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB6Read32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB6_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB6_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB6Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB6_MASK) \ +>> MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB6_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB6Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB6_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB6_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB6_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB6Set32(var, value)\ +(((((unsigned long)(var)) & \ +~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB6_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB6_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB6_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB5Read32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+\ +((bank)*MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB5_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB5_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB5Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB5_MASK) \ +>> MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB5_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB5Write32\ +(base_address, bank, value)\ +do {\ + onst unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB5_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB5_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB5_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB5Set32(var, value)\ +(((((unsigned long)(var)) & \ +~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB5_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB5_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB5_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB5Read32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB5_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB5_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB5Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB5_MASK) \ +>> MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB5_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB5Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB5_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB5_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB5_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB5Set32(var, value)\ +(((((unsigned long)(var)) & \ +~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB5_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB5_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB5_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB4Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB4_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB4_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB4Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB4_MASK) >> \ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB4_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB4Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB4_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB4_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB4_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB4Set32(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB4_MASK)) |\ +((((unsigned long)(value)) << \ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB4_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB4_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB4Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB4_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB4_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB4Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB4_MASK) >> \ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB4_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB4Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB4_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB4_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB4_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB4Set32(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB4_MASK)) |\ +((((unsigned long)(value)) << \ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB4_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB4_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB3Read32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))\ ++(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)\ +*MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB3_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB3_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB3Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB3_MASK) >> \ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB3_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB3Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB3_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB3_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB3_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB3Set32(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB3_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB3_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB3_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB3Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB3_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB3_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB3Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB3_MASK) >> \ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB3_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB3Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB3_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB3_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB3_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB3Set32(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB3_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB3_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB3_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB2Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB2_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB2_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB2Get32(var)\ +((unsigned long)((((unsigned long)(var)) \ +& MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB2_MASK) \ +>> MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB2_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB2Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB2_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB2_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB2_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB2Set32(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB2_MASK)) |\ +((((unsigned long)(value)) << \ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB2_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB2_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB2Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB2_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB2_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB2Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB2_MASK) \ +>> MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB2_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB2Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB2_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB2_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB2_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB2Set32(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB2_MASK)) |\ +((((unsigned long)(value)) << \ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB2_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB2_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB1Read32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+\ +((bank)*MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB1_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB1_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB1Get32(var)\ +((unsigned long)((((unsigned long)(var)) \ +& MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB1_MASK) >> \ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB1_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB1Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = RD_\ + MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB1_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB1_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB1_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB1Set32(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB1_MASK)) |\ +((((unsigned long)(value)) << \ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB1_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB1_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB1Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB1_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB1_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB1Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB1_MASK) >> \ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB1_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB1Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB1_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB1_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB1_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB1Set32(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB1_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB1_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB1_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB0Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB0_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB0_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB0Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB0_MASK) >> \ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB0_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB0Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB0_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB0_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB0_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NotFullStatusUuMB0Set32(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB0_MASK)) |\ +((((unsigned long)(value)) << \ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB0_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NotFullStatusUuMB0_MASK))) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB0Read32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB0_MASK) >>\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB0_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB0Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB0_MASK) >> \ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB0_OFFSET)) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB0Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB0_MASK);\ + newValue <<= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB0_OFFSET;\ + newValue &= MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB0_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQSTATUS___0_3NewMsgStatusUuMB0Set32(var, value)\ +(((((unsigned long)(var)) & \ +~(MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB0_MASK)) |\ +((((unsigned long)(value)) << \ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB0_OFFSET) &\ +MLB_MAILBOX_IRQSTATUS___0_3_NewMsgStatusUuMB0_MASK))) + +#if defined(OMAP44XX) || defined(VPOM4430_1_06) + +#define MLBMAILBOX_IRQENABLE_SET___0_3ReadRegister32(base_address, bank)\ +(RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQENABLE_SET___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE_SET___REGSET_0_3_STEP)))) + +#else + +#define MLBMAILBOX_IRQENABLE___0_3ReadRegister32(base_address, bank)\ +(RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) + +#endif + +#if defined(OMAP44XX) || defined(VPOM4430_1_06) + +#define MLBMAILBOX_IRQENABLE_SET___0_3WriteRegister32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE_SET___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * \ + MLB_MAILBOX_IRQENABLE_SET___REGSET_0_3_STEP);\ + register unsigned long newValue = ((unsigned long)(value));\ + WR_MEM_32_VOLATILE(((unsigned long)(base_address))+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE_CLR___0_3WriteRegister32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE_CLR___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * \ + MLB_MAILBOX_IRQENABLE_CLR___REGSET_0_3_STEP);\ + register unsigned long newValue = ((unsigned long)(value));\ + WR_MEM_32_VOLATILE(((unsigned long)(base_address))+offset, newValue);\ +} while (0) + +#else + +#define MLBMAILBOX_IRQENABLE___0_3WriteRegister32(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long newValue = ((unsigned long)(value));\ + WR_MEM_32_VOLATILE(((unsigned long)(base_address))+offset, newValue);\ +} while (0) + +#endif + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB15Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB15_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB15_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB15Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB15_MASK) >> \ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB15_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB15Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB15_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB15_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB15_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB15Set32(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB15_MASK)) |\ +((((unsigned long)(value)) << \ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB15_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB15_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB15Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB15_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB15_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB15Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB15_MASK) >> \ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB15_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB15Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB15_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB15_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB15_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB15Set32(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB15_MASK)) |\ +((((unsigned long)(value)) << \ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB15_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB15_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB14Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB14_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB14_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB14Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB14_MASK) \ +>> MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB14_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB14Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB14_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB14_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB14_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB14Set32\ +(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB14_MASK)) |\ +((((unsigned long)(value)) << \ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB14_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB14_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB14Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB14_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB14_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB14Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB14_MASK) \ +>> MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB14_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB14Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB14_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB14_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB14_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB14Set32(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB14_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB14_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB14_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB13Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB13_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB13_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB13Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB13_MASK) >> \ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB13_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB13Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB13_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB13_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB13_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB13Set32\ +(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB13_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB13_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB13_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB13Read32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB13_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB13_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB13Get32(var)\ +((unsigned long)((((unsigned long)(var)) \ +& MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB13_MASK) \ +>> MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB13_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB13Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB13_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB13_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB13_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB13Set32(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB13_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB13_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB13_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB12Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB12_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB12_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB12Get32(var)\ +((unsigned long)((((unsigned long)(var)) \ +& MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB12_MASK) \ +>> MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB12_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB12Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB12_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB12_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB12_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB12Set32(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB12_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB12_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB12_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB12Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB12_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB12_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB12Get32(var)\ +((unsigned long)((((unsigned long)(var)) \ +& MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB12_MASK) \ +>> MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB12_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB12Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB12_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB12_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB12_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB12Set32(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB12_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB12_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB12_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB11Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB11_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB11_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB11Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB11_MASK) \ +>> MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB11_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB11Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB11_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB11_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB11_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB11Set32(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB11_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB11_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB11_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB11Read32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB11_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB11_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB11Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB11_MASK) \ +>> MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB11_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB11Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB11_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB11_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB11_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB11Set32(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB11_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB11_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB11_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB10Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB10_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB10_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB10Get32(var)\ +((unsigned long)((((unsigned long)(var)) \ +& MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB10_MASK) \ +>> MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB10_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB10Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = \ + ((unsigned long)(value));\ + data &= \ + ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB10_MASK);\ + newValue <<= \ + MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB10_OFFSET;\ + newValue \ + &= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB10_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB10Set32(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB10_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB10_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB10_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB10Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+\ +((bank)*MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB10_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB10_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB10Get32(var)\ +((unsigned long)((((unsigned long)(var)) \ +& MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB10_MASK) \ +>> MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB10_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB10Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = \ + ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB10_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB10_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB10_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB10Set32\ +(var, value)\ +(((((unsigned long)(var)) &\ +~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB10_MASK)) |\ +((((unsigned long)(value)) << \ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB10_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB10_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB9Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB9_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB9_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB9Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB9_MASK) >> \ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB9_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB9Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB9_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB9_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB9_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB9Set32(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB9_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB9_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB9_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB9Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB9_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB9_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB9Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB9_MASK) >> \ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB9_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB9Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB9_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB9_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB9_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB9Set32(var, value)\ +(((((unsigned long)(var)) & \ +~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB9_MASK)) |\ +((((unsigned long)(value)) << \ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB9_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB9_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB8Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))\ ++(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB8_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB8_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB8Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB8_MASK) \ +>> MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB8_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB8Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB8_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB8_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB8_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB8Set32(var, value)\ +(((((unsigned long)(var)) & \ +~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB8_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB8_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB8_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB8Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB8_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB8_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB8Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB8_MASK) >> \ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB8_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB8Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB8_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB8_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB8_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB8Set32(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB8_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB8_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB8_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB7Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB7_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB7_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB7Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB7_MASK) \ +>> MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB7_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB7Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB7_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB7_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB7_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB7Set32(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB7_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB7_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB7_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB7Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB7_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB7_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB7Get32(var)\ +((unsigned long)((((unsigned long)(var)) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB7_MASK) >> \ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB7_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB7Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB7_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB7_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB7_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB7Set32(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB7_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB7_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB7_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB6Read32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB6_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB6_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB6Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB6_MASK) >> \ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB6_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB6Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB6_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB6_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB6_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB6Set32\ +(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB6_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB6_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB6_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB6Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB6_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB6_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB6Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB6_MASK) >> \ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB6_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB6Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB6_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB6_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB6_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB6Set32(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB6_MASK)) |\ +((((unsigned long)(value)) << \ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB6_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB6_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB5Read32(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB5_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB5_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB5Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB5_MASK) >> \ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB5_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB5Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB5_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB5_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB5_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB5Set32\ +(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB5_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB5_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB5_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB5Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))\ ++(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB5_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB5_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB5Get32(var)\ +((unsigned long)((((unsigned long)(var)) \ +& MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB5_MASK) >> \ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB5_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB5Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB5_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB5_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB5_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB5Set32(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB5_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB5_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB5_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB4Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))\ ++(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB4_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB4_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB4Get32\ +(var)\ +((unsigned long)((((unsigned long)(var)) \ +& MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB4_MASK) >> \ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB4_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB4Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB4_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB4_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB4_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB4Set32\ +(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB4_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB4_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB4_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB4Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB4_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB4_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB4Get32(var)\ +((unsigned long)((((unsigned long)(var)) \ +& MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB4_MASK) \ +>> MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB4_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB4Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB4_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB4_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB4_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB4Set32\ +(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB4_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB4_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB4_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB3Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))\ ++(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)\ +*MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB3_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB3_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB3Get32\ +(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB3_MASK) >> \ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB3_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB3Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB3_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB3_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB3_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB3Set32\ +(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB3_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB3_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB3_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB3Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB3_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB3_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB3Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB3_MASK) \ +>> MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB3_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB3Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB3_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB3_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB3_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB3Set32(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB3_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB3_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB3_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB2Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB2_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB2_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB2Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB2_MASK) >> \ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB2_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB2Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB2_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB2_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB2_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB2Set32(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB2_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB2_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB2_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB2Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB2_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB2_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB2Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB2_MASK) >> \ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB2_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB2Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB2_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB2_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB2_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB2Set32\ +(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB2_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB2_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB2_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB1Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))\ ++(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)\ +*MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB1_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB1_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB1Get32(var)\ +((unsigned long)((((unsigned long)(var)) \ +& MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB1_MASK) \ +>> MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB1_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB1Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB1_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB1_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB1_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB1Set32\ +(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB1_MASK)) |\ +((((unsigned long)(value)) << \ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB1_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB1_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB1Read32\ +(base_address, bank) do {\ + ((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ + (MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ + MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB1_MASK) >>\ + MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB1_OFFSET))\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB1Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB1_MASK) >> \ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB1_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB1Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB1_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB1_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB1_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB1Set32(var, value)\ +(((((unsigned long)(var)) &\ +~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB1_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB1_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB1_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB0Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB0_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB0_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB0Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB0_MASK) \ +>> MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB0_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB0Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB0_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB0_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB0_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NotFullEnableUuMB0Set32(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB0_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB0_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NotFullEnableUuMB0_MASK))) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB0Read32\ +(base_address, bank)\ +((((RD_MEM_32_VOLATILE(((unsigned long)(base_address))+\ +(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+((bank)*\ +MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB0_MASK) >>\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB0_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB0Get32(var)\ +((unsigned long)((((unsigned long)(var)) & \ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB0_MASK) \ +>> MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB0_OFFSET)) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB0Write32\ +(base_address, bank, value)\ +do {\ + const unsigned long offset = \ + MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank) * MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register unsigned long data = \ + RD_MEM_32_VOLATILE(((unsigned long)(base_address))+offset);\ + register unsigned long newValue = ((unsigned long)(value));\ + data &= ~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB0_MASK);\ + newValue <<= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB0_OFFSET;\ + newValue &= MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB0_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((unsigned long)(base_address)+offset, newValue);\ +} while (0) + +#define MLBMAILBOX_IRQENABLE___0_3NewMsgEnableUuMB0Set32(var, value)\ +(((((unsigned long)(var)) \ +& ~(MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB0_MASK)) |\ +((((unsigned long)(value)) \ +<< MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB0_OFFSET) &\ +MLB_MAILBOX_IRQENABLE___0_3_NewMsgEnableUuMB0_MASK))) + +#endif /* USE_LEVEL_1_MACROS */ + + +#endif /* _MBX_REG_ACM_H */ diff --git a/arch/arm/plat-omap/include/syslink/MLBAccInt.h b/arch/arm/plat-omap/include/syslink/MLBAccInt.h new file mode 100644 index 000000000000..6cd469709005 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/MLBAccInt.h @@ -0,0 +1,132 @@ +/* + * MLBAccInt.h + * + * DSP-BIOS Bridge driver support functions for TI OMAP processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + + +#ifndef _MLB_ACC_INT_H +#define _MLB_ACC_INT_H + +/* Mappings of level 1 EASI function numbers to function names */ + +#define EASIL1_MLBMAILBOX_SYSCONFIGReadRegister32 (MLB_BASE_EASIL1 + 3) +#define EASIL1_MLBMAILBOX_SYSCONFIGWriteRegister32 (MLB_BASE_EASIL1 + 4) +#define EASIL1_MLBMAILBOX_SYSCONFIGSIdleModeRead32 (MLB_BASE_EASIL1 + 7) +#define EASIL1_MLBMAILBOX_SYSCONFIGSIdleModeWrite32 (MLB_BASE_EASIL1 + 17) +#define EASIL1_MLBMAILBOX_SYSCONFIGSoftResetWrite32 (MLB_BASE_EASIL1 + 29) +#define EASIL1_MLBMAILBOX_SYSCONFIGAutoIdleRead32 \ + (MLB_BASE_EASIL1 + 33) +#define EASIL1_MLBMAILBOX_SYSCONFIGAutoIdleWrite32 (MLB_BASE_EASIL1 + 39) +#define EASIL1_MLBMAILBOX_SYSSTATUSResetDoneRead32 (MLB_BASE_EASIL1 + 44) +#define EASIL1_MLBMAILBOX_MESSAGE___0_15ReadRegister32 \ + (MLB_BASE_EASIL1 + 50) +#define EASIL1_MLBMAILBOX_MESSAGE___0_15WriteRegister32 \ + (MLB_BASE_EASIL1 + 51) +#define EASIL1_MLBMAILBOX_FIFOSTATUS___0_15ReadRegister32 \ + (MLB_BASE_EASIL1 + 56) +#define EASIL1_MLBMAILBOX_FIFOSTATUS___0_15FifoFullMBmRead32 \ + (MLB_BASE_EASIL1 + 57) +#define EASIL1_MLBMAILBOX_MSGSTATUS___0_15NbOfMsgMBmRead32 \ + (MLB_BASE_EASIL1 + 60) +#define EASIL1_MLBMAILBOX_IRQSTATUS___0_3ReadRegister32 \ + (MLB_BASE_EASIL1 + 62) +#define EASIL1_MLBMAILBOX_IRQSTATUS___0_3WriteRegister32 \ + (MLB_BASE_EASIL1 + 63) +#define EASIL1_MLBMAILBOX_IRQENABLE___0_3ReadRegister32 \ + (MLB_BASE_EASIL1 + 192) +#define EASIL1_MLBMAILBOX_IRQENABLE___0_3WriteRegister32 \ + (MLB_BASE_EASIL1 + 193) + +/* Register set MAILBOX_MESSAGE___REGSET_0_15 address offset, bank address + * increment and number of banks */ + +#define MLB_MAILBOX_MESSAGE___REGSET_0_15_OFFSET (u32)(0x0040) +#define MLB_MAILBOX_MESSAGE___REGSET_0_15_STEP (u32)(0x0004) + +/* Register offset address definitions relative to register set + * MAILBOX_MESSAGE___REGSET_0_15 */ + +#define MLB_MAILBOX_MESSAGE___0_15_OFFSET (u32)(0x0) + + +/* Register set MAILBOX_FIFOSTATUS___REGSET_0_15 address offset, bank address + * increment and number of banks */ + +#define MLB_MAILBOX_FIFOSTATUS___REGSET_0_15_OFFSET (u32)(0x0080) +#define MLB_MAILBOX_FIFOSTATUS___REGSET_0_15_STEP (u32)(0x0004) + +/* Register offset address definitions relative to register set + * MAILBOX_FIFOSTATUS___REGSET_0_15 */ + +#define MLB_MAILBOX_FIFOSTATUS___0_15_OFFSET (u32)(0x0) + + +/* Register set MAILBOX_MSGSTATUS___REGSET_0_15 address offset, bank address + * increment and number of banks */ + +#define MLB_MAILBOX_MSGSTATUS___REGSET_0_15_OFFSET (u32)(0x00c0) +#define MLB_MAILBOX_MSGSTATUS___REGSET_0_15_STEP (u32)(0x0004) + +/* Register offset address definitions relative to register set + * MAILBOX_MSGSTATUS___REGSET_0_15 */ + +#define MLB_MAILBOX_MSGSTATUS___0_15_OFFSET (u32)(0x0) + + +/* Register set MAILBOX_IRQSTATUS___REGSET_0_3 address offset, bank address + * increment and number of banks */ + +#define MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET (u32)(0x0100) +#define MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP (u32)(0x0008) + +/* Register offset address definitions relative to register set + * MAILBOX_IRQSTATUS___REGSET_0_3 */ + +#define MLB_MAILBOX_IRQSTATUS___0_3_OFFSET (u32)(0x0) + + +/* Register set MAILBOX_IRQENABLE___REGSET_0_3 address offset, bank address + * increment and number of banks */ + +#define MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET (u32)(0x0104) +#define MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP (u32)(0x0008) + +/* Register offset address definitions relative to register set + * MAILBOX_IRQENABLE___REGSET_0_3 */ + +#define MLB_MAILBOX_IRQENABLE___0_3_OFFSET (u32)(0x0) + + +/* Register offset address definitions */ + +#define MLB_MAILBOX_SYSCONFIG_OFFSET (u32)(0x10) +#define MLB_MAILBOX_SYSSTATUS_OFFSET (u32)(0x14) + + +/* Bitfield mask and offset declarations */ + +#define MLB_MAILBOX_SYSCONFIG_SIdleMode_MASK (u32)(0x18) +#define MLB_MAILBOX_SYSCONFIG_SIdleMode_OFFSET (u32)(3) +#define MLB_MAILBOX_SYSCONFIG_SoftReset_MASK (u32)(0x2) +#define MLB_MAILBOX_SYSCONFIG_SoftReset_OFFSET (u32)(1) +#define MLB_MAILBOX_SYSCONFIG_AutoIdle_MASK (u32)(0x1) +#define MLB_MAILBOX_SYSCONFIG_AutoIdle_OFFSET (u32)(0) +#define MLB_MAILBOX_SYSSTATUS_ResetDone_MASK (u32)(0x1) +#define MLB_MAILBOX_SYSSTATUS_ResetDone_OFFSET (u32)(0) +#define MLB_MAILBOX_FIFOSTATUS___0_15_FifoFullMBm_MASK (u32)(0x1) +#define MLB_MAILBOX_FIFOSTATUS___0_15_FifoFullMBm_OFFSET (u32)(0) +#define MLB_MAILBOX_MSGSTATUS___0_15_NbOfMsgMBm_MASK (u32)(0x7f) +#define MLB_MAILBOX_MSGSTATUS___0_15_NbOfMsgMBm_OFFSET (u32)(0) + +#endif /* _MLB_ACC_INT_H */ diff --git a/arch/arm/plat-omap/include/syslink/MLBRegAcM.h b/arch/arm/plat-omap/include/syslink/MLBRegAcM.h new file mode 100644 index 000000000000..5ef9cf32aef2 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/MLBRegAcM.h @@ -0,0 +1,206 @@ +/* + * MLBRegAcM.h + * + * DSP-BIOS Bridge driver support functions for TI OMAP processors. + * + * Copyright (C) 2007 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef _MLB_REG_ACM_H +#define _MLB_REG_ACM_H + +#include <syslink/GlobalTypes.h> +#include <syslink/EasiGlobal.h> +#include <syslink/MLBAccInt.h> + +#if defined(USE_LEVEL_1_MACROS) + +#define MLBMAILBOX_SYSCONFIGReadRegister32(base_address)\ +(_DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_SYSCONFIGReadRegister32),\ +RD_MEM_32_VOLATILE(((u32)(base_address))+ \ +MLB_MAILBOX_SYSCONFIG_OFFSET)) + + +#define MLBMAILBOX_SYSCONFIGWriteRegister32(base_address, value)\ +do {\ + const u32 offset = MLB_MAILBOX_SYSCONFIG_OFFSET;\ + register u32 newValue = ((u32)(value));\ + _DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_SYSCONFIGWriteRegister32);\ + WR_MEM_32_VOLATILE(((u32)(base_address))+offset, newValue);\ +} while (0) + + +#define MLBMAILBOX_SYSCONFIGSIdleModeRead32(base_address)\ +(_DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_SYSCONFIGSIdleModeRead32),\ +(((RD_MEM_32_VOLATILE((((u32)(base_address))+\ +(MLB_MAILBOX_SYSCONFIG_OFFSET)))) &\ +MLB_MAILBOX_SYSCONFIG_SIdleMode_MASK) >>\ +MLB_MAILBOX_SYSCONFIG_SIdleMode_OFFSET)) + + +#define MLBMAILBOX_SYSCONFIGSIdleModeWrite32(base_address, value)\ +do {\ + const u32 offset = MLB_MAILBOX_SYSCONFIG_OFFSET;\ + register u32 data = RD_MEM_32_VOLATILE(((u32)(base_address)) +\ + offset);\ + register u32 newValue = ((u32)(value));\ + _DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_SYSCONFIGSIdleModeWrite32);\ + data &= ~(MLB_MAILBOX_SYSCONFIG_SIdleMode_MASK);\ + newValue <<= MLB_MAILBOX_SYSCONFIG_SIdleMode_OFFSET;\ + newValue &= MLB_MAILBOX_SYSCONFIG_SIdleMode_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((u32)(base_address)+offset, newValue);\ +} while (0) + + +#define MLBMAILBOX_SYSCONFIGSoftResetWrite32(base_address, value)\ +do {\ + const u32 offset = MLB_MAILBOX_SYSCONFIG_OFFSET;\ + register u32 data =\ + RD_MEM_32_VOLATILE(((u32)(base_address))+offset);\ + register u32 newValue = ((u32)(value));\ + printk(KERN_ALERT "In SYSCONFIG MACOR line %i file %s", \ + __LINE__, __FILE__);\ + _DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_SYSCONFIGSoftResetWrite32);\ + printk(KERN_ALERT "******************BEFORE DATA WRITE");\ + data &= ~(MLB_MAILBOX_SYSCONFIG_SoftReset_MASK);\ + printk(KERN_ALERT "line %i file %s", __LINE__, __FILE__);\ + newValue <<= MLB_MAILBOX_SYSCONFIG_SoftReset_OFFSET;\ + newValue &= MLB_MAILBOX_SYSCONFIG_SoftReset_MASK;\ + newValue |= data;\ + printk(KERN_ALERT "line %i file %s", __LINE__, __FILE__);\ + WR_MEM_32_VOLATILE((u32)(base_address)+offset, newValue);\ + printk(KERN_ALERT "line %i file %s", __LINE__, __FILE__);\ +} while (0) + + +#define MLBMAILBOX_SYSCONFIGAutoIdleRead32(base_address)\ +(_DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_SYSCONFIGAutoIdleRead32),\ +(((RD_MEM_32_VOLATILE((((u32)(base_address))+\ +(MLB_MAILBOX_SYSCONFIG_OFFSET)))) &\ +MLB_MAILBOX_SYSCONFIG_AutoIdle_MASK) >>\ +MLB_MAILBOX_SYSCONFIG_AutoIdle_OFFSET)) + + +#define MLBMAILBOX_SYSCONFIGAutoIdleWrite32(base_address, value)\ +{\ + const u32 offset = MLB_MAILBOX_SYSCONFIG_OFFSET;\ + register u32 data =\ + RD_MEM_32_VOLATILE(((u32)(base_address))+offset);\ + register u32 newValue = ((u32)(value));\ + _DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_SYSCONFIGAutoIdleWrite32);\ + data &= ~(MLB_MAILBOX_SYSCONFIG_AutoIdle_MASK);\ + newValue <<= MLB_MAILBOX_SYSCONFIG_AutoIdle_OFFSET;\ + newValue &= MLB_MAILBOX_SYSCONFIG_AutoIdle_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE((u32)(base_address)+offset, newValue);\ +} + + +#define MLBMAILBOX_SYSSTATUSResetDoneRead32(base_address)\ +(_DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_SYSSTATUSResetDoneRead32),\ +(((RD_MEM_32_VOLATILE((((u32)(base_address))+\ +(MLB_MAILBOX_SYSSTATUS_OFFSET)))) &\ +MLB_MAILBOX_SYSSTATUS_ResetDone_MASK) >>\ +MLB_MAILBOX_SYSSTATUS_ResetDone_OFFSET)) + + +#define MLBMAILBOX_MESSAGE___0_15ReadRegister32(base_address, bank)\ +(_DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_MESSAGE___0_15ReadRegister32),\ +RD_MEM_32_VOLATILE(((u32)(base_address))+\ +(MLB_MAILBOX_MESSAGE___REGSET_0_15_OFFSET +\ +MLB_MAILBOX_MESSAGE___0_15_OFFSET+(\ +(bank)*MLB_MAILBOX_MESSAGE___REGSET_0_15_STEP)))) + + +#define MLBMAILBOX_MESSAGE___0_15WriteRegister32(base_address, bank, value)\ +do {\ + const u32 offset = MLB_MAILBOX_MESSAGE___REGSET_0_15_OFFSET +\ + MLB_MAILBOX_MESSAGE___0_15_OFFSET +\ + ((bank)*MLB_MAILBOX_MESSAGE___REGSET_0_15_STEP);\ + register u32 newValue = ((u32)(value));\ + _DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_MESSAGE___0_15WriteRegister32);\ + WR_MEM_32_VOLATILE(((u32)(base_address))+offset, newValue);\ +} while (0) + + +#define MLBMAILBOX_FIFOSTATUS___0_15ReadRegister32(base_address, bank)\ +(_DEBUG_LEVEL_1_EASI(\ +EASIL1_MLBMAILBOX_FIFOSTATUS___0_15ReadRegister32),\ +RD_MEM_32_VOLATILE(((u32)(base_address))+\ +(MLB_MAILBOX_FIFOSTATUS___REGSET_0_15_OFFSET +\ +MLB_MAILBOX_FIFOSTATUS___0_15_OFFSET+\ +((bank)*MLB_MAILBOX_FIFOSTATUS___REGSET_0_15_STEP)))) + + +#define MLBMAILBOX_FIFOSTATUS___0_15FifoFullMBmRead32(base_address, bank)\ +(_DEBUG_LEVEL_1_EASI(\ +EASIL1_MLBMAILBOX_FIFOSTATUS___0_15FifoFullMBmRead32),\ +(((RD_MEM_32_VOLATILE(((u32)(base_address))+\ +(MLB_MAILBOX_FIFOSTATUS___REGSET_0_15_OFFSET +\ +MLB_MAILBOX_FIFOSTATUS___0_15_OFFSET+\ +((bank)*MLB_MAILBOX_FIFOSTATUS___REGSET_0_15_STEP)))) &\ +MLB_MAILBOX_FIFOSTATUS___0_15_FifoFullMBm_MASK) >>\ +MLB_MAILBOX_FIFOSTATUS___0_15_FifoFullMBm_OFFSET)) + + +#define MLBMAILBOX_MSGSTATUS___0_15NbOfMsgMBmRead32(base_address, bank)\ +(_DEBUG_LEVEL_1_EASI(\ +EASIL1_MLBMAILBOX_MSGSTATUS___0_15NbOfMsgMBmRead32),\ +(((RD_MEM_32_VOLATILE(((u32)(base_address))+\ +(MLB_MAILBOX_MSGSTATUS___REGSET_0_15_OFFSET +\ +MLB_MAILBOX_MSGSTATUS___0_15_OFFSET+\ +((bank)*MLB_MAILBOX_MSGSTATUS___REGSET_0_15_STEP)))) &\ +MLB_MAILBOX_MSGSTATUS___0_15_NbOfMsgMBm_MASK) >>\ +MLB_MAILBOX_MSGSTATUS___0_15_NbOfMsgMBm_OFFSET)) + + +#define MLBMAILBOX_IRQSTATUS___0_3ReadRegister32(base_address, bank)\ +(_DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_IRQSTATUS___0_3ReadRegister32),\ +RD_MEM_32_VOLATILE(((u32)(base_address))+\ +(MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQSTATUS___0_3_OFFSET+\ +((bank)*MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP)))) + + +#define MLBMAILBOX_IRQSTATUS___0_3WriteRegister32(base_address, bank, value)\ +do {\ + const u32 offset = MLB_MAILBOX_IRQSTATUS___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQSTATUS___0_3_OFFSET +\ + ((bank)*MLB_MAILBOX_IRQSTATUS___REGSET_0_3_STEP);\ + register u32 newValue = ((u32)(value));\ + _DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_IRQSTATUS___0_3WriteRegister32);\ + WR_MEM_32_VOLATILE(((u32)(base_address))+offset, newValue);\ +} while (0) + + +#define MLBMAILBOX_IRQENABLE___0_3ReadRegister32(base_address, bank)\ +(_DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_IRQENABLE___0_3ReadRegister32),\ +RD_MEM_32_VOLATILE(((u32)(base_address))+\ +(MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ +MLB_MAILBOX_IRQENABLE___0_3_OFFSET+\ +((bank)*MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP)))) + + +#define MLBMAILBOX_IRQENABLE___0_3WriteRegister32(base_address, bank, value)\ +do {\ + const u32 offset = MLB_MAILBOX_IRQENABLE___REGSET_0_3_OFFSET +\ + MLB_MAILBOX_IRQENABLE___0_3_OFFSET +\ + ((bank)*MLB_MAILBOX_IRQENABLE___REGSET_0_3_STEP);\ + register u32 newValue = ((u32)(value));\ + _DEBUG_LEVEL_1_EASI(EASIL1_MLBMAILBOX_IRQENABLE___0_3WriteRegister32);\ + WR_MEM_32_VOLATILE(((u32)(base_address))+offset, newValue);\ +} while (0) + + +#endif /* USE_LEVEL_1_MACROS */ + +#endif /* _MLB_REG_ACM_H */ diff --git a/arch/arm/plat-omap/include/syslink/MMUAccInt.h b/arch/arm/plat-omap/include/syslink/MMUAccInt.h new file mode 100644 index 000000000000..2aa0fa2436ae --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/MMUAccInt.h @@ -0,0 +1,180 @@ +/* + * MMUAccInt.h + * + * Syslink ducati driver support for OMAP Processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef _MMU_ACC_INT_H +#define _MMU_ACC_INT_H + + +/* Register offset address definitions */ + +#define MMU_MMU_REVISION_OFFSET 0x0 +#define MMU_MMU_SYSCONFIG_OFFSET 0x10 +#define MMU_MMU_SYSSTATUS_OFFSET 014 +#define MMU_MMU_IRQSTATUS_OFFSET 0x18 +#define MMU_MMU_IRQENABLE_OFFSET 0x1c +#define MMU_MMU_WALKING_ST_OFFSET 0x40 +#define MMU_MMU_CNTL_OFFSET 0x44 +#define MMU_MMU_FAULT_AD_OFFSET 0x48 +#define MMU_MMU_TTB_OFFSET 0x4c +#define MMU_MMU_LOCK_OFFSET 0x50 +#define MMU_MMU_LD_TLB_OFFSET 0x54 +#define MMU_MMU_CAM_OFFSET 0x58 +#define MMU_MMU_RAM_OFFSET 0x5c +#define MMU_MMU_GFLUSH_OFFSET 0x60 +#define MMU_MMU_FLUSH_ENTRY_OFFSET 0x64 +#define MMU_MMU_READ_CAM_OFFSET 0x68 +#define MMU_MMU_READ_RAM_OFFSET 0x6c +#define MMU_MMU_EMU_FAULT_AD_OFFSET 0x70 +#define MMU_MMU_FAULT_PC_OFFSET 0x80 +#define MMU_MMU_FAULT_STATUS_OFFSET 0x84 + +/* Bitfield mask and offset declarations */ + +#define MMU_MMU_REVISION_Rev_MASK 0xff +#define MMU_MMU_REVISION_Rev_OFFSET 0 + +#define MMU_MMU_SYSCONFIG_ClockActivity_MASK 0x300 +#define MMU_MMU_SYSCONFIG_ClockActivity_OFFSET 8 + +#define MMU_MMU_SYSCONFIG_IdleMode_MASK 0x18 +#define MMU_MMU_SYSCONFIG_IdleMode_OFFSET 3 + +#define MMU_MMU_SYSCONFIG_SoftReset_MASK 0x2 +#define MMU_MMU_SYSCONFIG_SoftReset_OFFSET 1 + +#define MMU_MMU_SYSCONFIG_AutoIdle_MASK 0x1 +#define MMU_MMU_SYSCONFIG_AutoIdle_OFFSET 0 + +#define MMU_MMU_SYSSTATUS_ResetDone_MASK 0x1 +#define MMU_MMU_SYSSTATUS_ResetDone_OFFSET 0 + +#define MMU_MMU_IRQSTATUS_MultiHitFault_MASK 0x10 +#define MMU_MMU_IRQSTATUS_MultiHitFault_OFFSET 4 + +#define MMU_MMU_IRQSTATUS_TableWalkFault_MASK 0x8 +#define MMU_MMU_IRQSTATUS_TableWalkFault_OFFSET 3 + +#define MMU_MMU_IRQSTATUS_EMUMiss_MASK 0x4 +#define MMU_MMU_IRQSTATUS_EMUMiss_OFFSET 2 + +#define MMU_MMU_IRQSTATUS_TranslationFault_MASK 0x2 +#define MMU_MMU_IRQSTATUS_TranslationFault_OFFSET 1 + +#define MMU_MMU_IRQSTATUS_TLBMiss_MASK 0x1 +#define MMU_MMU_IRQSTATUS_TLBMiss_OFFSET 0 + +#define MMU_MMU_IRQENABLE_MultiHitFault_MASK 0x10 +#define MMU_MMU_IRQENABLE_MultiHitFault_OFFSET 4 + +#define MMU_MMU_IRQENABLE_TableWalkFault_MASK 0x8 +#define MMU_MMU_IRQENABLE_TableWalkFault_OFFSET 3 + +#define MMU_MMU_IRQENABLE_EMUMiss_MASK 0x4 +#define MMU_MMU_IRQENABLE_EMUMiss_OFFSET 2 + +#define MMU_MMU_IRQENABLE_TranslationFault_MASK 0x2 +#define MMU_MMU_IRQENABLE_TranslationFault_OFFSET 1 + +#define MMU_MMU_IRQENABLE_TLBMiss_MASK 0x1 +#define MMU_MMU_IRQENABLE_TLBMiss_OFFSET 0 + +#define MMU_MMU_WALKING_ST_TWLRunning_MASK 0x1 +#define MMU_MMU_WALKING_ST_TWLRunning_OFFSET 0 + +#define MMU_MMU_CNTL_EmuTLBUpdate_MASK 0x8 +#define MMU_MMU_CNTL_EmuTLBUpdate_OFFSET 3 + +#define MMU_MMU_CNTL_TWLEnable_MASK 0x4 +#define MMU_MMU_CNTL_TWLEnable_OFFSET 2 + +#define MMU_MMU_CNTL_MMUEnable_MASK 0x2 +#define MMU_MMU_CNTL_MMUEnable_OFFSET 1 + +#define MMU_MMU_FAULT_AD_FaultAddress_MASK 0xffffffff +#define MMU_MMU_FAULT_AD_FaultAddress_OFFSET 0 + +#define MMU_MMU_TTB_TTBAddress_MASK 0xffffff00 +#define MMU_MMU_TTB_TTBAddress_OFFSET 8 + +#define MMU_MMU_LOCK_BaseValue_MASK 0xfc00 +#define MMU_MMU_LOCK_BaseValue_OFFSET 10 + +#define MMU_MMU_LOCK_CurrentVictim_MASK 0x3f0 +#define MMU_MMU_LOCK_CurrentVictim_OFFSET 4 + +#define MMU_MMU_LD_TLB_LdTLBItem_MASK 0x1 +#define MMU_MMU_LD_TLB_LdTLBItem_OFFSET 0 + +#define MMU_MMU_CAM_VATag_MASK 0xfffff000 +#define MMU_MMU_CAM_VATag_OFFSET 12 + +#define MMU_MMU_CAM_P_MASK 0x8 +#define MMU_MMU_CAM_P_OFFSET 3 + +#define MMU_MMU_CAM_V_MASK 0x4 +#define MMU_MMU_CAM_V_OFFSET 2 + +#define MMU_MMU_CAM_PageSize_MASK 0x3 +#define MMU_MMU_CAM_PageSize_OFFSET 0 + +#define MMU_MMU_RAM_PhysicalAddress_MASK 0xfffff000 +#define MMU_MMU_RAM_PhysicalAddress_OFFSET 12 + +#define MMU_MMU_RAM_Endianness_MASK 0x200 +#define MMU_MMU_RAM_Endianness_OFFSET 9 + +#define MMU_MMU_RAM_ElementSize_MASK 0x180 +#define MMU_MMU_RAM_ElementSize_OFFSET 7 + +#define MMU_MMU_RAM_Mixed_MASK 0x40 +#define MMU_MMU_RAM_Mixed_OFFSET 6 + +#define MMU_MMU_GFLUSH_GlobalFlush_MASK 0x1 +#define MMU_MMU_GFLUSH_GlobalFlush_OFFSET 0 + +#define MMU_MMU_FLUSH_ENTRY_FlushEntry_MASK 0x1 +#define MMU_MMU_FLUSH_ENTRY_FlushEntry_OFFSET 0 + +#define MMU_MMU_READ_CAM_VATag_MASK 0xfffff000 +#define MMU_MMU_READ_CAM_VATag_OFFSET 12 + +#define MMU_MMU_READ_CAM_P_MASK 0x8 +#define MMU_MMU_READ_CAM_P_OFFSET 3 + +#define MMU_MMU_READ_CAM_V_MASK 0x4 +#define MMU_MMU_READ_CAM_V_OFFSET 2 + +#define MMU_MMU_READ_CAM_PageSize_MASK 0x3 +#define MMU_MMU_READ_CAM_PageSize_OFFSET 0 + +#define MMU_MMU_READ_RAM_PhysicalAddress_MASK 0xfffff000 +#define MMU_MMU_READ_RAM_PhysicalAddress_OFFSET 12 + +#define MMU_MMU_READ_RAM_Endianness_MASK 0x200 +#define MMU_MMU_READ_RAM_Endianness_OFFSET 9 + +#define MMU_MMU_READ_RAM_ElementSize_MASK 0x180 +#define MMU_MMU_READ_RAM_ElementSize_OFFSET 7 + +#define MMU_MMU_READ_RAM_Mixed_MASK 0x40 +#define MMU_MMU_READ_RAM_Mixed_OFFSET 6 + +#define MMU_MMU_EMU_FAULT_AD_EmuFaultAddress_MASK 0xffffffff +#define MMU_MMU_EMU_FAULT_AD_EmuFaultAddress_OFFSET 0 + +#endif /* _MMU_ACC_INT_H */ +/* EOF */ + diff --git a/arch/arm/plat-omap/include/syslink/MMURegAcM.h b/arch/arm/plat-omap/include/syslink/MMURegAcM.h new file mode 100644 index 000000000000..c4944110789e --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/MMURegAcM.h @@ -0,0 +1,434 @@ +/* + * MMURegAcM.h + * + * Notify driver support for OMAP Processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef _MMU_REG_ACM_H +#define _MMU_REG_ACM_H + + + +#include "GlobalTypes.h" +#include "MMUAccInt.h" + + +/* +* EXPORTED DEFINITIONS +* +*/ + +#if defined(USE_LEVEL_1_MACROS) + + +#define MMUMMU_SYSCONFIGReadRegister32(base_address)\ + (RD_MEM_32_VOLATILE((base_address)+MMU_MMU_SYSCONFIG_OFFSET)) + + +#define MMUMMU_SYSCONFIGWriteRegister32(base_address, value)\ +{\ + const u32 offset = MMU_MMU_SYSCONFIG_OFFSET;\ + register u32 newValue = (value);\ + WR_MEM_32_VOLATILE((base_address)+offset, newValue);\ +} + +#define MMUMMU_SYSCONFIGClockActivityGet32(var)\ + ((u32)(((var) & MMU_MMU_SYSCONFIG_ClockActivity_MASK)\ + >> MMU_MMU_SYSCONFIG_ClockActivity_OFFSET)) + +#define mmu_sisconf_auto_idle_set32(var, value)\ + ((((var) & ~(MMU_MMU_SYSCONFIG_AutoIdle_MASK)) |\ + (((value) << MMU_MMU_SYSCONFIG_AutoIdle_OFFSET) &\ + MMU_MMU_SYSCONFIG_AutoIdle_MASK))) + +#define MMUMMU_IRQSTATUSReadRegister32(base_address)\ + (RD_MEM_32_VOLATILE((base_address)+MMU_MMU_IRQSTATUS_OFFSET)) + + +#define MMUMMU_IRQSTATUSWriteRegister32(base_address, value)\ +{\ + const u32 offset = MMU_MMU_IRQSTATUS_OFFSET;\ + register u32 newValue = (value);\ + WR_MEM_32_VOLATILE((base_address)+offset, newValue);\ +} + + +#define MMUMMU_IRQENABLEReadRegister32(base_address)\ + (RD_MEM_32_VOLATILE((base_address)+MMU_MMU_IRQENABLE_OFFSET)) + + +#define MMUMMU_IRQENABLEWriteRegister32(base_address, value)\ +{\ + const u32 offset = MMU_MMU_IRQENABLE_OFFSET;\ + register u32 newValue = (value);\ + WR_MEM_32_VOLATILE((base_address)+offset, newValue);\ +} + +#define MMUMMU_IRQENABLETableWalkFaultSet32(var, value)\ + ((((var) & ~(MMU_MMU_IRQENABLE_TableWalkFault_MASK)) |\ + (((value) << MMU_MMU_IRQENABLE_TableWalkFault_OFFSET) &\ + MMU_MMU_IRQENABLE_TableWalkFault_MASK))) + +#define MMUMMU_IRQENABLETranslationFaultRead32(base_address)\ + ((((RD_MEM_32_VOLATILE(((base_address)+(MMU_MMU_IRQENABLE_OFFSET)))) &\ + MMU_MMU_IRQENABLE_TranslationFault_MASK) >>\ + MMU_MMU_IRQENABLE_TranslationFault_OFFSET)) + + + +#define MMUMMU_IRQENABLETranslationFaultSet32(var, value)\ + ((((var) & ~(MMU_MMU_IRQENABLE_TranslationFault_MASK)) |\ + (((value) << MMU_MMU_IRQENABLE_TranslationFault_OFFSET) &\ + MMU_MMU_IRQENABLE_TranslationFault_MASK))) + + +#define MMUMMU_IRQENABLETLBMissRead32(base_address)\ + ((((RD_MEM_32_VOLATILE(((base_address)+(MMU_MMU_IRQENABLE_OFFSET)))) &\ + MMU_MMU_IRQENABLE_TLBMiss_MASK) >>\ + MMU_MMU_IRQENABLE_TLBMiss_OFFSET)) + + +#define MMUMMU_IRQENABLETLBMissReadIsTrMissIntM32(base_address)\ + ((MMUMMU_IRQENABLETLBMissTrMissIntM == (MMUMMU_IRQENABLETLBMissE)\ + (((RD_MEM_32_VOLATILE(((base_address)+(MMU_MMU_IRQENABLE_OFFSET)))) &\ + MMU_MMU_IRQENABLE_TLBMiss_MASK) >>\ + MMU_MMU_IRQENABLE_TLBMiss_OFFSET))) + + +#define MMUMMU_IRQENABLETLBMissReadIsTrMissGInt32(base_address)\ + ((MMUMMU_IRQENABLETLBMissTrMissGInt == (MMUMMU_IRQENABLETLBMissE)\ + (((RD_MEM_32_VOLATILE(((base_address)+(MMU_MMU_IRQENABLE_OFFSET)))) &\ + MMU_MMU_IRQENABLE_TLBMiss_MASK) >>\ + MMU_MMU_IRQENABLE_TLBMiss_OFFSET))) + + +#define MMUMMU_IRQENABLETLBMissGet32(var)\ + ((u32)(((var) & MMU_MMU_IRQENABLE_TLBMiss_MASK)\ + >> MMU_MMU_IRQENABLE_TLBMiss_OFFSET)) + + +#define MMUMMU_IRQENABLETLBMissIsTrMissIntM32(var)\ + ((MMUMMU_IRQENABLETLBMissTrMissIntM == \ + (MMUMMU_IRQENABLETLBMissE)(((var) & MMU_MMU_IRQENABLE_TLBMiss_MASK) >>\ + MMU_MMU_IRQENABLE_TLBMiss_OFFSET))) + +#define MMUMMU_IRQENABLETLBMissIsTrMissGInt32(var)\ + ((MMUMMU_IRQENABLETLBMissTrMissGInt ==\ + (MMUMMU_IRQENABLETLBMissE)(((var) & MMU_MMU_IRQENABLE_TLBMiss_MASK) >>\ + MMU_MMU_IRQENABLE_TLBMiss_OFFSET))) + +#define MMUMMU_IRQENABLETLBMissWrite32(base_address, value)\ +{\ + const u32 offset = MMU_MMU_IRQENABLE_OFFSET;\ + register u32 data = RD_MEM_32_VOLATILE((base_address)+offset);\ + register u32 newValue = (value);\ + data &= ~(MMU_MMU_IRQENABLE_TLBMiss_MASK);\ + newValue <<= MMU_MMU_IRQENABLE_TLBMiss_OFFSET;\ + newValue &= MMU_MMU_IRQENABLE_TLBMiss_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE(base_address+offset, newValue);\ +} + + +#define MMUMMU_IRQENABLETLBMissWriteTrMissIntM32(base_address)\ +{\ + const u32 offset = MMU_MMU_IRQENABLE_OFFSET;\ + const u32 newValue = (u32)MMUMMU_IRQENABLETLBMissTrMissIntM <<\ + MMU_MMU_IRQENABLE_TLBMiss_OFFSET;\ + register u32 data = RD_MEM_32_VOLATILE(base_address+offset);\ + data &= ~(MMU_MMU_IRQENABLE_TLBMiss_MASK);\ + data |= newValue;\ + WR_MEM_32_VOLATILE(base_address+offset, data);\ +} + + +#define MMUMMU_IRQENABLETLBMissWriteTrMissGInt32(base_address)\ +{\ + const u32 offset = MMU_MMU_IRQENABLE_OFFSET;\ + const u32 newValue = (u32)MMUMMU_IRQENABLETLBMissTrMissGInt <<\ + MMU_MMU_IRQENABLE_TLBMiss_OFFSET;\ + register u32 data = RD_MEM_32_VOLATILE(base_address+offset);\ + data &= ~(MMU_MMU_IRQENABLE_TLBMiss_MASK);\ + data |= newValue;\ + WR_MEM_32_VOLATILE(base_address+offset, data);\ +} + + +#define MMUMMU_IRQENABLETLBMissSet32(var, value)\ + ((((var) & ~(MMU_MMU_IRQENABLE_TLBMiss_MASK)) |\ + (((value) << MMU_MMU_IRQENABLE_TLBMiss_OFFSET) &\ + MMU_MMU_IRQENABLE_TLBMiss_MASK))) + + +#define MMUMMU_WALKING_STTWLRunningRead32(base_address)\ + ((((RD_MEM_32_VOLATILE(((base_address)+(MMU_MMU_WALKING_ST_OFFSET)))) &\ + MMU_MMU_WALKING_ST_TWLRunning_MASK) >>\ + MMU_MMU_WALKING_ST_TWLRunning_OFFSET)) + + + +#define MMUMMU_CNTLTWLEnableRead32(base_address)\ + ((((RD_MEM_32_VOLATILE(((base_address)+(MMU_MMU_CNTL_OFFSET)))) &\ + MMU_MMU_CNTL_TWLEnable_MASK) >>\ + MMU_MMU_CNTL_TWLEnable_OFFSET)) + + +#define MMUMMU_CNTLTWLEnableWrite32(base_address, value)\ +{\ + const u32 offset = MMU_MMU_CNTL_OFFSET;\ + register u32 data = RD_MEM_32_VOLATILE((base_address)+offset);\ + register u32 newValue = (value);\ + data &= ~(MMU_MMU_CNTL_TWLEnable_MASK);\ + newValue <<= MMU_MMU_CNTL_TWLEnable_OFFSET;\ + newValue &= MMU_MMU_CNTL_TWLEnable_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE(base_address+offset, newValue);\ +} + + +#define MMUMMU_CNTLMMUEnableWrite32(base_address, value)\ +{\ + const u32 offset = MMU_MMU_CNTL_OFFSET;\ + register u32 data = RD_MEM_32_VOLATILE((base_address)+offset);\ + register u32 newValue = (value);\ + data &= ~(MMU_MMU_CNTL_MMUEnable_MASK);\ + newValue <<= MMU_MMU_CNTL_MMUEnable_OFFSET;\ + newValue &= MMU_MMU_CNTL_MMUEnable_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE(base_address+offset, newValue);\ +} + + +#define MMUMMU_FAULT_ADReadRegister32(base_address)\ + (RD_MEM_32_VOLATILE((base_address)+MMU_MMU_FAULT_AD_OFFSET)) + + +#define MMUMMU_FAULT_ADFaultAddressRead32(base_address)\ + ((((RD_MEM_32_VOLATILE(((base_address)+(MMU_MMU_FAULT_AD_OFFSET)))) &\ + MMU_MMU_FAULT_AD_FaultAddress_MASK) >>\ + MMU_MMU_FAULT_AD_FaultAddress_OFFSET)) + +#define MMUMMU_FAULT_ADFaultAddressGet32(var)\ + ((u32)(((var) & MMU_MMU_FAULT_AD_FaultAddress_MASK)\ + >> MMU_MMU_FAULT_AD_FaultAddress_OFFSET)) + + +#define MMUMMU_TTBReadRegister32(base_address)\ + (RD_MEM_32_VOLATILE((base_address)+MMU_MMU_TTB_OFFSET)) + +#define MMUMMU_TTBWriteRegister32(base_address, value)\ +{\ + const u32 offset = MMU_MMU_TTB_OFFSET;\ + register u32 newValue = (value);\ + WR_MEM_32_VOLATILE((base_address)+offset, newValue);\ +} + +#define MMUMMU_TTBTTBAddressRead32(base_address)\ + ((((RD_MEM_32_VOLATILE(((base_address)+(MMU_MMU_TTB_OFFSET)))) &\ + MMU_MMU_TTB_TTBAddress_MASK) >>\ + MMU_MMU_TTB_TTBAddress_OFFSET)) + +#define MMUMMU_TTBTTBAddressGet32(var)\ + ((u32)(((var) & MMU_MMU_TTB_TTBAddress_MASK)\ + >> MMU_MMU_TTB_TTBAddress_OFFSET)) + + +#define MMUMMU_TTBTTBAddressWrite32(base_address, value)\ +{\ + const u32 offset = MMU_MMU_TTB_OFFSET;\ + register u32 data = RD_MEM_32_VOLATILE((base_address)+offset);\ + register u32 newValue = (value);\ + data &= ~(MMU_MMU_TTB_TTBAddress_MASK);\ + newValue <<= MMU_MMU_TTB_TTBAddress_OFFSET;\ + newValue &= MMU_MMU_TTB_TTBAddress_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE(base_address+offset, newValue);\ +} + +#define MMUMMU_TTBTTBAddressSet32(var, value)\ + ((((var) & ~(MMU_MMU_TTB_TTBAddress_MASK)) |\ + (((value) << MMU_MMU_TTB_TTBAddress_OFFSET) &\ + MMU_MMU_TTB_TTBAddress_MASK))) + + +#define mmu_lckread_reg_32(base_address)\ + (RD_MEM_32_VOLATILE((base_address)+MMU_MMU_LOCK_OFFSET)) + +#define mmu_lck_write_reg32(base_address, value)\ +{\ + const u32 offset = MMU_MMU_LOCK_OFFSET;\ + register u32 newValue = (value);\ + WR_MEM_32_VOLATILE((base_address)+offset, newValue);\ +} + + +#define MMUMMU_LOCKBaseValueRead32(base_address)\ + ((((RD_MEM_32_VOLATILE(((base_address)+(MMU_MMU_LOCK_OFFSET)))) &\ + MMU_MMU_LOCK_BaseValue_MASK) >>\ + MMU_MMU_LOCK_BaseValue_OFFSET)) +#define MMUMMU_LOCKBaseValueGet32(var)\ + ((u32)(((var) & MMU_MMU_LOCK_BaseValue_MASK)\ + >> MMU_MMU_LOCK_BaseValue_OFFSET)) + + +#define MMUMMU_LOCKBaseValueWrite32(base_address, value)\ +{\ + const u32 offset = MMU_MMU_LOCK_OFFSET;\ + register u32 data = RD_MEM_32_VOLATILE((base_address)+offset);\ + register u32 newValue = (value);\ + data &= ~(MMU_MMU_LOCK_BaseValue_MASK);\ + newValue <<= MMU_MMU_LOCK_BaseValue_OFFSET;\ + newValue &= MMU_MMU_LOCK_BaseValue_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE(base_address+offset, newValue);\ +} + + +#define MMUMMU_LOCKBaseValueSet32(var, value)\ + ((((var) & ~(MMU_MMU_LOCK_BaseValue_MASK)) |\ + (((value) << MMU_MMU_LOCK_BaseValue_OFFSET) &\ + MMU_MMU_LOCK_BaseValue_MASK))) + +#define MMUMMU_LOCKCurrentVictimRead32(base_address)\ + ((((RD_MEM_32_VOLATILE(((base_address)+(MMU_MMU_LOCK_OFFSET)))) &\ + MMU_MMU_LOCK_CurrentVictim_MASK) >>\ + MMU_MMU_LOCK_CurrentVictim_OFFSET)) + + +#define MMUMMU_LOCKCurrentVictimGet32(var)\ + ((u32)(((var) & MMU_MMU_LOCK_CurrentVictim_MASK)\ + >> MMU_MMU_LOCK_CurrentVictim_OFFSET)) + + +#define mmu_lck_crnt_vctmwite32(base_address, value)\ +{\ + const u32 offset = MMU_MMU_LOCK_OFFSET;\ + register u32 data = RD_MEM_32_VOLATILE((base_address)+offset);\ + register u32 newValue = (value);\ + data &= ~(MMU_MMU_LOCK_CurrentVictim_MASK);\ + newValue <<= MMU_MMU_LOCK_CurrentVictim_OFFSET;\ + newValue &= MMU_MMU_LOCK_CurrentVictim_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE(base_address+offset, newValue);\ +} + + +#define MMUMMU_LOCKCurrentVictimSet32(var, value)\ + ((((var) & ~(MMU_MMU_LOCK_CurrentVictim_MASK)) |\ + (((value) << MMU_MMU_LOCK_CurrentVictim_OFFSET) &\ + MMU_MMU_LOCK_CurrentVictim_MASK))) + + +#define MMUMMU_LD_TLBReadRegister32(base_address)\ + (RD_MEM_32_VOLATILE((base_address)+MMU_MMU_LD_TLB_OFFSET)) + +#define mmu_ld_tlbwrt_reg32(base_address, value)\ +{\ + const u32 offset = MMU_MMU_LD_TLB_OFFSET;\ + register u32 newValue = (value);\ + WR_MEM_32_VOLATILE((base_address)+offset, newValue);\ +} + +#define MMUMMU_LD_TLBLdTLBItemRead32(base_address)\ + ((((RD_MEM_32_VOLATILE(((base_address)+(MMU_MMU_LD_TLB_OFFSET)))) &\ + MMU_MMU_LD_TLB_LdTLBItem_MASK) >>\ + MMU_MMU_LD_TLB_LdTLBItem_OFFSET)) + + +#define MMUMMU_CAMReadRegister32(base_address)\ + (RD_MEM_32_VOLATILE((base_address)+MMU_MMU_READ_CAM_OFFSET)) + + +#define MMUMMU_CAMWriteRegister32(base_address, value)\ +{\ + const u32 offset = MMU_MMU_CAM_OFFSET;\ + register u32 newValue = (value);\ + WR_MEM_32_VOLATILE((base_address)+offset, newValue);\ +} + +#define MMUMMU_RAMReadRegister32(base_address)\ + (RD_MEM_32_VOLATILE((base_address)+MMU_MMU_READ_RAM_OFFSET)) + + +#define MMUMMU_RAMWriteRegister32(base_address, value)\ +{\ + const u32 offset = MMU_MMU_RAM_OFFSET;\ + register u32 newValue = (value);\ + WR_MEM_32_VOLATILE((base_address)+offset, newValue);\ +} + +#define MMUMMU_GFLUSHGlobalFlushWrite32(base_address, value)\ +{\ + const u32 offset = MMU_MMU_GFLUSH_OFFSET;\ + register u32 data = RD_MEM_32_VOLATILE((base_address)+offset);\ + register u32 newValue = (value);\ + data &= ~(MMU_MMU_GFLUSH_GlobalFlush_MASK);\ + newValue <<= MMU_MMU_GFLUSH_GlobalFlush_OFFSET;\ + newValue &= MMU_MMU_GFLUSH_GlobalFlush_MASK;\ + newValue |= data;\ + WR_MEM_32_VOLATILE(base_address+offset, newValue);\ +} + +#define MMUMMU_GFLUSHGlobalFlushWritenft_w32(base_address)\ +{\ + const u32 offset = MMU_MMU_GFLUSH_OFFSET;\ + const u32 newValue = (u32)MMUMMU_GFLUSHGlobalFlushnft_w <<\ + MMU_MMU_GFLUSH_GlobalFlush_OFFSET;\ + register u32 data = RD_MEM_32_VOLATILE(base_address+offset);\ + data &= ~(MMU_MMU_GFLUSH_GlobalFlush_MASK);\ + data |= newValue;\ + WR_MEM_32_VOLATILE(base_address+offset, data);\ +} + +#define MMUMMU_GFLUSHGlobalFlushWriteflush_w32(base_address)\ +{\ + const u32 offset = MMU_MMU_GFLUSH_OFFSET;\ + const u32 newValue = (u32)MMUMMU_GFLUSHGlobalFlushflush_w <<\ + MMU_MMU_GFLUSH_GlobalFlush_OFFSET;\ + register u32 data = RD_MEM_32_VOLATILE(base_address+offset);\ + data &= ~(MMU_MMU_GFLUSH_GlobalFlush_MASK);\ + data |= newValue;\ + WR_MEM_32_VOLATILE(base_address+offset, data);\ +} + + +#define MMUMMU_GFLUSHGlobalFlushSet32(var, value)\ + ((((var) & ~(MMU_MMU_GFLUSH_GlobalFlush_MASK)) |\ + (((value) << MMU_MMU_GFLUSH_GlobalFlush_OFFSET) &\ + MMU_MMU_GFLUSH_GlobalFlush_MASK))) + +#define MMUMMU_FLUSH_ENTRYReadRegister32(base_address)\ + (RD_MEM_32_VOLATILE((base_address)+MMU_MMU_FLUSH_ENTRY_OFFSET)) + + +#define MMUMMU_FLUSH_ENTRYWriteRegister32(base_address, value)\ +{\ + const u32 offset = MMU_MMU_FLUSH_ENTRY_OFFSET;\ + register u32 newValue = (value);\ + WR_MEM_32_VOLATILE((base_address)+offset, newValue);\ +} + +#define MMUMMU_FAULT_PCReadRegister32(base_address)\ + (RD_MEM_32_VOLATILE((base_address)+MMU_MMU_FAULT_PC_OFFSET)) + +#define MMUMMU_FAULT_STATUSReadRegister32(base_address)\ + (RD_MEM_32_VOLATILE((base_address)+MMU_MMU_FAULT_STATUS_OFFSET)) + +#define MMUMMU_FAULT_EMUAddressReadRegister32(base_address)\ + (RD_MEM_32_VOLATILE((base_address)+MMU_MMU_EMU_FAULT_AD_OFFSET)) + +#endif /* USE_LEVEL_1_MACROS */ + +#endif /* _MMU_REG_ACM_H */ +/* EOF */ + diff --git a/arch/arm/plat-omap/include/syslink/_sysmgr.h b/arch/arm/plat-omap/include/syslink/_sysmgr.h new file mode 100644 index 000000000000..58fbdd378155 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/_sysmgr.h @@ -0,0 +1,50 @@ +/* + * _sysmgr.h + * + * Defines for system manager functions + * + * Copyright (C) 2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef __SYSMGR_H_ +#define __SYSMGR_H_ + +/* Structure to retrieve the scalability proc info from the slave */ +struct sysmgr_proc_config { + u32 proc_id; + u32 use_notify; + u32 use_messageq; + u32 use_heapbuf; + u32 use_frameq; + u32 use_ringio; + u32 use_listmp; + u32 use_nameserver; + u32 boot_mode; +}; + +/* Function to set the boot load page address for a slave */ +void sysmgr_set_boot_load_page(u16 proc_id, u32 boot_load_page); + +/* Function to get configuration values for a host object(component/instance) */ +u32 sysmgr_get_object_config(u16 proc_id, void *config, u32 cmd_id, u32 size); + +/* Function to put configuration values for a slave object(component/instance)*/ +u32 sysmgr_put_object_config(u16 proc_id, void *config, u32 cmd_id, u32 size); + +/* Function to wait for scalability handshake value. */ +void sysmgr_wait_for_scalability_info(u16 proc_id); + +/* Function to wait for slave to complete setup */ +void sysmgr_wait_for_slave_setup(u16 proc_id); + + +#endif /* ifndef __SYSMGR_H_ */ diff --git a/arch/arm/plat-omap/include/syslink/atomic_linux.h b/arch/arm/plat-omap/include/syslink/atomic_linux.h new file mode 100644 index 000000000000..76fd8a1b9dc5 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/atomic_linux.h @@ -0,0 +1,105 @@ +/* +* atomic_linux.h +* +* Atomic operations functions +* +* Copyright (C) 2008-2009 Texas Instruments, Inc. +* +* This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR +* PURPOSE. +*/ + +#ifndef _ATOMIC_LINUX_H +#define _ATOMIC_LINUX_H + +#include <linux/types.h> +#include <generated/autoconf.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <asm/atomic.h> + +/* + * ======== atomic_cmpmask_and_set ======== + * Purpose: + * This will compare a mask and set if not equal + */ +static inline void atomic_cmpmask_and_set(atomic_t *v, u32 mask, u32 val) +{ + s32 ret; + unsigned long flags; + atomic_t *atm = v; + + raw_local_irq_save(flags); + ret = atm->counter; + if (likely(((ret & mask) != mask))) + atm->counter = val; + raw_local_irq_restore(flags); +} + +/* + * ======== atomic_cmpmask_and_set ======== + * Purpose: + * This will compare a mask and then check current value less than + * provided value. + */ +static inline bool atomic_cmpmask_and_lt(atomic_t *v, u32 mask, u32 val) +{ + bool ret = true; + atomic_t *atm = v; + s32 cur; + unsigned long flags; + + raw_local_irq_save(flags); + cur = atm->counter; + /* Compare mask, if matches then compare val */ + if (likely(((cur & mask) == mask))) { + if (likely(cur >= val)) + ret = false; + } + raw_local_irq_restore(flags); + + /* retval = true if mask matches and current value is less than given + * value */ + /* retval = false either mask doesnot matches or current value is not + * less than given value */ + return ret; +} + + +/* + * ======== atomic_cmpmask_and_set ======== + * Purpose: + * This will compare a mask and then check current value greater than + * provided value. + */ +static inline bool atomic_cmpmask_and_gt(atomic_t *v, u32 mask, u32 val) +{ + bool ret = false; + atomic_t *atm = v; + s32 cur; + unsigned long flags; + + raw_local_irq_save(flags); + cur = atm->counter; + /* Compare mask, if matches then compare val */ + if (likely(((cur & mask) == mask))) { + if (likely(cur > val)) + ret = true; + } + + raw_local_irq_restore(flags); + /* retval = true if mask matches and current value is less than given + * value */ + /* etval =false either mask doesnot matches or current value is not + * greater than given value */ + return ret; +} + +#endif /* if !defined(_ATOMIC_LINUX_H) */ + diff --git a/arch/arm/plat-omap/include/syslink/ducatienabler.h b/arch/arm/plat-omap/include/syslink/ducatienabler.h new file mode 100644 index 000000000000..f2f8023ce8b4 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/ducatienabler.h @@ -0,0 +1,291 @@ +/* + * ducatienabler.h + * + * Syslink driver support for OMAP Processors. + * + * Copyright (C) 2009-2010 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ +#ifndef _DDUCATIMMU_ENABLER_H_ +#define _DDUCATIMMU_ENABLER_H_ + +#include <linux/types.h> +#include <linux/mm.h> + +#include <syslink/hw_defs.h> +#include <syslink/hw_mmu.h> + + +#define PAGE_SIZE_4KB 0x1000 +#define PAGE_SIZE_64KB 0x10000 +#define PAGE_SIZE_1MB 0x100000 +#define PAGE_SIZE_16MB 0x1000000 + +/* Define the Peripheral PAs and their Ducati VAs. */ +#define L4_PERIPHERAL_MBOX 0x4A0F4000 +#define DUCATI_PERIPHERAL_MBOX 0xAA0F4000 + +#define L4_PERIPHERAL_I2C1 0x48070000 +#define DUCATI_PERIPHERAL_I2C1 0xA8070000 +#define L4_PERIPHERAL_I2C2 0x48072000 +#define DUCATI_PERIPHERAL_I2C2 0xA8072000 +#define L4_PERIPHERAL_I2C3 0x48060000 +#define DUCATI_PERIPHERAL_I2C3 0xA8060000 + +#define L4_PERIPHERAL_DMA 0x4A056000 +#define DUCATI_PERIPHERAL_DMA 0xAA056000 + +#define L4_PERIPHERAL_GPIO1 0x4A310000 +#define DUCATI_PERIPHERAL_GPIO1 0xAA310000 +#define L4_PERIPHERAL_GPIO2 0x48055000 +#define DUCATI_PERIPHERAL_GPIO2 0xA8055000 +#define L4_PERIPHERAL_GPIO3 0x48057000 +#define DUCATI_PERIPHERAL_GPIO3 0xA8057000 + +#define L4_PERIPHERAL_GPTIMER3 0x48034000 +#define DUCATI_PERIPHERAL_GPTIMER3 0xA8034000 +#define L4_PERIPHERAL_GPTIMER4 0x48036000 +#define DUCATI_PERIPHERAL_GPTIMER4 0xA8036000 +#define L4_PERIPHERAL_GPTIMER9 0x48040000 +#define DUCATI_PERIPHERAL_GPTIMER9 0xA8040000 +#define L4_PERIPHERAL_GPTIMER11 0x48088000 +#define DUCATI_PERIPHERAL_GPTIMER11 0xA8088000 + +#define L4_PERIPHERAL_UART1 0x4806A000 +#define DUCATI_PERIPHERAL_UART1 0xA806A000 +#define L4_PERIPHERAL_UART2 0x4806C000 +#define DUCATI_PERIPHERAL_UART2 0xA806C000 +#define L4_PERIPHERAL_UART3 0x48020000 +#define DUCATI_PERIPHERAL_UART3 0xA8020000 +#define L4_PERIPHERAL_UART4 0x4806E000 +#define DUCATI_PERIPHERAL_UART4 0xA806E000 + + +#define L3_TILER_VIEW0_ADDR 0x60000000 +#define DUCATIVA_TILER_VIEW0_ADDR 0x60000000 +#define DUCATIVA_TILER_VIEW0_LEN 0x20000000 + + + +#if 0 /* Original definitions for OMAP4430. */ +/* Define the various Ducati Memory Regions. */ +/* The first 4K page of BOOTVECS is programmed as a TLB entry. The remaining */ +/* three pages are not used and are mapped to minimize number of PTEs */ +#define DUCATI_BOOTVECS_ADDR 0x1000 +#define DUCATI_BOOTVECS_LEN 0x3000 + +#define DUCATI_EXTMEM_SYSM3_ADDR 0x4000 +#define DUCATI_EXTMEM_SYSM3_LEN 0x1FC000 + +#define DUCATI_EXTMEM_APPM3_ADDR 0x10000000 +#define DUCATI_EXTMEM_APPM3_LEN 0x200000 + +#define DUCATI_PRIVATE_SYSM3_DATA_ADDR 0x84000000 +#define DUCATI_PRIVATE_SYSM3_DATA_LEN 0x200000 + +#define DUCATI_PRIVATE_APPM3_DATA_ADDR 0x8A000000 +#define DUCATI_PRIVATE_APPM3_DATA_LEN 0x200000 + +#define DUCATI_SHARED_M3_DATA_ADDR 0x90000000 +#define DUCATI_SHARED_M3_DATA_LEN 0x100000 + +#define DUCATI_SHARED_IPC_ADDR 0x98000000 +#define DUCATI_SHARED_IPC_LEN 0x100000 + +#define DUCATI_SW_DMM_ADDR 0x80000000 +#define DUCATI_SW_DMM_LEN 0x400000 +#endif + +/* OMAP4430 SDC definitions */ +#define L4_PERIPHERAL_L4CFG 0x4A000000 +#define DUCATI_PERIPHERAL_L4CFG 0xAA000000 + +#define L4_PERIPHERAL_L4PER 0x48000000 +#define DUCATI_PERIPHERAL_L4PER 0xA8000000 + +#define L3_IVAHD_CONFIG 0x5A000000 +#define DUCATI_IVAHD_CONFIG 0xBA000000 + +#define L3_IVAHD_SL2 0x5B000000 +#define DUCATI_IVAHD_SL2 0xBB000000 + +#define L3_TILER_MODE0_1_ADDR 0x60000000 +#define DUCATI_TILER_MODE0_1_ADDR 0x60000000 +#define DUCATI_TILER_MODE0_1_LEN 0x10000000 + +#define L3_TILER_MODE3_ADDR 0x78000000 +#define DUCATI_TILER_MODE3_ADDR 0x78000000 +#define DUCATI_TILER_MODE3_LEN 0x8000000 + +#define DUCATI_BOOTVECS_UNUSED_ADDR 0x1000 +#define DUCATI_BOOTVECS_UNUSED_LEN 0x3000 + +#define DUCATI_MEM_CODE_SYSM3_ADDR 0x4000 +#define DUCATI_MEM_CODE_SYSM3_LEN 0x1FC000 + +#define DUCATI_MEM_CODE_APPM3_ADDR 0x800000 +#define DUCATI_MEM_CODE_APPM3_LEN 0x200000 + +#define DUCATI_MEM_CONST_SYSM3_ADDR 0x80000000 +#define DUCATI_MEM_CONST_SYSM3_LEN 0x100000 + +#define DUCATI_MEM_CONST_APPM3_ADDR 0x80100000 +#define DUCATI_MEM_CONST_APPM3_LEN 0x100000 + +#define DUCATI_MEM_HEAP_SYSM3_ADDR 0x80200000 +#define DUCATI_MEM_HEAP_SYSM3_LEN 0x100000 + +#define DUCATI_MEM_HEAP_APPM3_ADDR 0x80300000 +#define DUCATI_MEM_HEAP_APPM3_LEN 0x1000000 + +#define DUCATI_MEM_MPU_DUCATI_SHMEM_ADDR 0x81300000 +#define DUCATI_MEM_MPU_DUCATI_SHMEM_LEN 0xC00000 + +#define DUCATI_MEM_IPC_SHMEM_ADDR 0x81F00000 +#define DUCATI_MEM_IPC_SHMEM_LEN 0x100000 + +#define DUCATI_MEM_IPC_HEAP0_ADDR 0xA0000000 +#define DUCATI_MEM_IPC_HEAP0_LEN 0x55000 + +#define DUCATI_MEM_IPC_HEAP1_ADDR 0xA0055000 +#define DUCATI_MEM_IPC_HEAP1_LEN 0x55000 + +#define DUCATI_MEM_IPC_HEAP2_ADDR 0xA00AA000 +#define DUCATI_MEM_IPC_HEAP2_LEN 0x56000 + + +/* Types of mapping attributes */ + +/* MPU address is virtual and needs to be translated to physical addr */ +#define DSP_MAPVIRTUALADDR 0x00000000 +#define DSP_MAPPHYSICALADDR 0x00000001 + +/* Mapped data is big endian */ +#define DSP_MAPBIGENDIAN 0x00000002 +#define DSP_MAPLITTLEENDIAN 0x00000000 + +/* Element size is based on DSP r/w access size */ +#define DSP_MAPMIXEDELEMSIZE 0x00000004 + +/* + * Element size for MMU mapping (8, 16, 32, or 64 bit) + * Ignored if DSP_MAPMIXEDELEMSIZE enabled + */ +#define DSP_MAPELEMSIZE8 0x00000008 +#define DSP_MAPELEMSIZE16 0x00000010 +#define DSP_MAPELEMSIZE32 0x00000020 +#define DSP_MAPELEMSIZE64 0x00000040 + +#define DSP_MAPVMALLOCADDR 0x00000080 +#define DSP_MAPTILERADDR 0x00000100 + + +#define PG_MASK(pg_size) (~((pg_size)-1)) +#define PG_ALIGN_LOW(addr, pg_size) ((addr) & PG_MASK(pg_size)) +#define PG_ALIGN_HIGH(addr, pg_size) (((addr)+(pg_size)-1) & PG_MASK(pg_size)) + + +struct mmu_entry { + u32 ul_phy_addr ; + u32 ul_virt_addr ; + u32 ul_size ; +}; + +struct memory_entry { + u32 ul_virt_addr; + u32 ul_size; +}; + +#if 0 /* Original definitions for OMAP4430. */ +static const struct mmu_entry l4_map[] = { + /* Mailbox 4KB*/ + {L4_PERIPHERAL_MBOX, DUCATI_PERIPHERAL_MBOX, HW_PAGE_SIZE_4KB}, + /* I2C 4KB each */ + {L4_PERIPHERAL_I2C1, DUCATI_PERIPHERAL_I2C1, HW_PAGE_SIZE_4KB}, + {L4_PERIPHERAL_I2C2, DUCATI_PERIPHERAL_I2C2, HW_PAGE_SIZE_4KB}, + {L4_PERIPHERAL_I2C3, DUCATI_PERIPHERAL_I2C3, HW_PAGE_SIZE_4KB}, + /* DMA 4KB */ + {L4_PERIPHERAL_DMA, DUCATI_PERIPHERAL_DMA, HW_PAGE_SIZE_4KB}, + /* GPIO Banks 4KB each */ + {L4_PERIPHERAL_GPIO1, DUCATI_PERIPHERAL_GPIO1, HW_PAGE_SIZE_4KB}, + {L4_PERIPHERAL_GPIO2, DUCATI_PERIPHERAL_GPIO2, HW_PAGE_SIZE_4KB}, + {L4_PERIPHERAL_GPIO3, DUCATI_PERIPHERAL_GPIO3, HW_PAGE_SIZE_4KB}, + /* GPTimers 4KB each */ + {L4_PERIPHERAL_GPTIMER3, DUCATI_PERIPHERAL_GPTIMER3, HW_PAGE_SIZE_4KB}, + {L4_PERIPHERAL_GPTIMER4, DUCATI_PERIPHERAL_GPTIMER4, HW_PAGE_SIZE_4KB}, + {L4_PERIPHERAL_GPTIMER9, DUCATI_PERIPHERAL_GPTIMER9, HW_PAGE_SIZE_4KB}, + {L4_PERIPHERAL_GPTIMER11, DUCATI_PERIPHERAL_GPTIMER11, + HW_PAGE_SIZE_4KB}, + /* UARTs 4KB each */ + {L4_PERIPHERAL_UART1, DUCATI_PERIPHERAL_UART1, HW_PAGE_SIZE_4KB}, + {L4_PERIPHERAL_UART2, DUCATI_PERIPHERAL_UART2, HW_PAGE_SIZE_4KB}, + {L4_PERIPHERAL_UART3, DUCATI_PERIPHERAL_UART3, HW_PAGE_SIZE_4KB}, + {L4_PERIPHERAL_UART4, DUCATI_PERIPHERAL_UART4, + HW_PAGE_SIZE_4KB}, +}; + +static const struct memory_entry l3_memory_regions[] = { + /* BootVecs regions */ + {0, (PAGE_SIZE_1MB * 2)}, + /* EXTMEM_CORE1: 0x10000000 to 0x100FFFFF */ + {DUCATI_EXTMEM_APPM3_ADDR, DUCATI_EXTMEM_APPM3_LEN}, + /* PRIVATE_SYSM3_DATA*/ + {DUCATI_PRIVATE_SYSM3_DATA_ADDR, DUCATI_PRIVATE_SYSM3_DATA_LEN}, + /* PRIVATE_APPM3_DATA*/ + {DUCATI_PRIVATE_APPM3_DATA_ADDR, DUCATI_PRIVATE_APPM3_DATA_LEN}, + /* SHARED_M3_DATA*/ + {DUCATI_SHARED_M3_DATA_ADDR, DUCATI_SHARED_M3_DATA_LEN}, + /* IPC*/ + {DUCATI_SHARED_IPC_ADDR, DUCATI_SHARED_IPC_LEN}, + /* DMM*/ + {DUCATI_SW_DMM_ADDR, DUCATI_SW_DMM_LEN}, +}; +#endif + +/* OMAP4430 SDC definitions */ +static const struct mmu_entry l4_map[] = { + /* TILER 8-bit and 16-bit modes */ + {L3_TILER_MODE0_1_ADDR, DUCATI_TILER_MODE0_1_ADDR, + (HW_PAGE_SIZE_16MB * 16)}, + /* TILER: Pages-mode */ + {L3_TILER_MODE3_ADDR, DUCATI_TILER_MODE3_ADDR, + (HW_PAGE_SIZE_16MB * 8)}, + /* L4_CFG: Covers all modules in L4_CFG 16MB*/ + {L4_PERIPHERAL_L4CFG, DUCATI_PERIPHERAL_L4CFG, HW_PAGE_SIZE_16MB}, + /* L4_PER: Covers all modules in L4_PER 16MB*/ + {L4_PERIPHERAL_L4PER, DUCATI_PERIPHERAL_L4PER, HW_PAGE_SIZE_16MB}, + /* IVA_HD Config: Covers all modules in IVA_HD Config space 16MB */ + {L3_IVAHD_CONFIG, DUCATI_IVAHD_CONFIG, HW_PAGE_SIZE_16MB}, + /* IVA_HD SL2: Covers all memory in IVA_HD SL2 space 16MB */ + {L3_IVAHD_SL2, DUCATI_IVAHD_SL2, HW_PAGE_SIZE_16MB}, +}; + +static const struct memory_entry l3_memory_regions[] = { + /* MEM_IPC_HEAP0, MEM_IPC_HEAP1, MEM_IPC_HEAP2 */ + {DUCATI_MEM_IPC_HEAP0_ADDR, PAGE_SIZE_1MB}, + /* MEM_INTVECS_SYSM3, MEM_INTVECS_APPM3, MEM_CODE_SYSM3, + MEM_CODE_APPM3 */ + {0, PAGE_SIZE_16MB}, + /* MEM_CONST_SYSM3, MEM_CONST_APPM3, MEM_HEAP_SYSM3, MEM_HEAP_APPM3, + MEM_MPU_DUCATI_SHMEM, MEM_IPC_SHMEM */ + {DUCATI_MEM_CONST_SYSM3_ADDR, (PAGE_SIZE_16MB * 2)}, +}; + + +void dbg_print_ptes(bool ashow_inv_entries, bool ashow_repeat_entries); +int ducati_setup(void); +void ducati_destroy(void); +u32 get_ducati_virt_mem(void); +void unmap_ducati_virt_mem(u32 shm_virt_addr); +int ducati_mem_map(u32 va, u32 da, u32 num_bytes, u32 map_attr); +int ducati_mem_unmap(u32 da, u32 num_bytes); +u32 user_va2pa(struct mm_struct *mm, u32 address); +inline u32 ducati_mem_virtToPhys(u32 da); +#endif /* _DDUCATIMMU_ENABLER_H_*/ diff --git a/arch/arm/plat-omap/include/syslink/gate_remote.h b/arch/arm/plat-omap/include/syslink/gate_remote.h new file mode 100644 index 000000000000..e8115d59535a --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/gate_remote.h @@ -0,0 +1,34 @@ +/* + * gate_remote.h + * + * This includes the functions to handle remote gates + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef _NAMESERVER_REMOTE_H_ +#define _GATE_REMOTE_H_ + +#include <linux/types.h> + +/* + * This function is used to enter in to a remote gate + */ +int gate_remote_enter(void *ghandle, u32 key); + +/* + * This function is used to leave from a remote gate + */ +int gate_remote_leave(void *ghandle, u32 key); + +#endif /* _GATE_REMOTE_H_ */ + diff --git a/arch/arm/plat-omap/include/syslink/gatepeterson.h b/arch/arm/plat-omap/include/syslink/gatepeterson.h new file mode 100644 index 000000000000..f2e3f78bf146 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/gatepeterson.h @@ -0,0 +1,167 @@ +/* + * gatepeterson.h + * + * The Gate Peterson Algorithm for mutual exclusion of shared memory. + * Current implementation works for 2 processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef _GATEPETERSON_H_ +#define _GATEPETERSON_H_ + +#include <linux/types.h> + +/* + * GATEPETERSON_MODULEID + * Unique module ID + */ +#define GATEPETERSON_MODULEID (0xF415) + +/* + * A set of context protection levels that each correspond to + * single processor gates used for local protection + */ +enum gatepeterson_protect { + GATEPETERSON_PROTECT_DEFAULT = 0, + GATEPETERSON_PROTECT_NONE = 1, + GATEPETERSON_PROTECT_INTERRUPT = 2, + GATEPETERSON_PROTECT_TASKLET = 3, + GATEPETERSON_PROTECT_THREAD = 4, + GATEPETERSON_PROTECT_PROCESS = 5, + GATEPETERSON_PROTECT_END_VALUE = 6 +}; + +/* + * Structure defining config parameters for the Gate Peterson + * module + */ +struct gatepeterson_config { + enum gatepeterson_protect default_protection; + /*!< Default module-wide local context protection level. The level of + * protection specified here determines which local gate is created per + * GatePeterson instance for local protection during create. The instance + * configuration parameter may be usedto override this module setting per + * instance. The configuration used here should reflect both the context + * in which enter and leave are to be called,as well as the maximum level + * of protection needed locally. + */ + u32 max_name_len; /* GP name len */ + bool use_nameserver; + /*!< Whether to have this module use the NameServer or not. If the + * NameServer is not needed, set this configuration parameter to false. + * This informs GatePeterson not to pull in the NameServer module. + * In this case, all names passed into create and open are ignored. + */ +}; + +/* + * Structure defining config parameters for the Gate Peterson + * instances + */ +struct gatepeterson_params { + void *shared_addr; + /* Address of the shared memory. The creator must supply a cache-aligned + * address in shared memory that will be used to store shared state + * information. + */ + + u32 shared_addr_size; + /* Size of the shared memory region. Can use gatepeterson_shared_memreq + * call to determine the required size. + */ + + char *name; + /* If using nameserver, name of this instance. The name (if not NULL) must + * be unique among all gatepeterson instances in the entire system. + */ + + enum gatepeterson_protect local_protection; + /* Local gate protection level. The default value, (Protect_DEFAULT) + * results in inheritance from module-level defaultProtection. This + * instance setting should be set to an alternative only if a different + * local protection level is needed for the instance. + */ + bool use_nameserver; + /* Whether to have this module use the nameserver or not. If the + * nameserver is not needed, set this configuration parameter to + * false.This informs gatepeterson not to pull in the nameaerver + * module. In this case, all names passed into create and open are + * ignored. + */ +}; + +/* + * Function to initialize the parameter structure + */ +void gatepeterson_get_config(struct gatepeterson_config *config); + +/* + * Function to initialize GP module + */ +int gatepeterson_setup(const struct gatepeterson_config *config); + +/* + * Function to destroy the GP module + */ +int gatepeterson_destroy(void); + +/* + * Function to initialize the parameter structure + */ +void gatepeterson_params_init(void *handle, + struct gatepeterson_params *params); + +/* + * Function to create an instance of GatePeterson + */ +void *gatepeterson_create(const struct gatepeterson_params *params); + +/* + * Function to delete an instance of GatePeterson + */ +int gatepeterson_delete(void **gphandle); + +/* + * Function to open a previously created instance + */ +int gatepeterson_open(void **gphandle, + struct gatepeterson_params *params); + +/* + * Function to close a previously opened instance + */ +int gatepeterson_close(void **gphandle); + +/* + * Function to enter the gate peterson + */ +u32 gatepeterson_enter(void *gphandle); + +/* + *Function to leave the gate peterson + */ +void gatepeterson_leave(void *gphandle, u32 flag); + + +/* + * Returns the gatepeterson kernel object pointer + */ +void *gatepeterson_get_knl_handle(void **gpHandle); + +/* + * Function to return the shared memory requirement + */ +u32 gatepeterson_shared_memreq(const struct gatepeterson_params *params); + +#endif /* _GATEPETERSON_H_ */ + diff --git a/arch/arm/plat-omap/include/syslink/gatepeterson_ioctl.h b/arch/arm/plat-omap/include/syslink/gatepeterson_ioctl.h new file mode 100644 index 000000000000..ed7ab86b75bc --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/gatepeterson_ioctl.h @@ -0,0 +1,193 @@ +/* + * gatepeterson_ioctl.h + * + * The Gate Peterson Algorithm for mutual exclusion of shared memory. + * Current implementation works for 2 processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef _GATEPETERSON_IOCTL_ +#define _GATEPETERSON_IOCTL_ + +#include <linux/ioctl.h> +#include <linux/types.h> + +#include <ipc_ioctl.h> +#include <gatepeterson.h> + +enum CMD_GATEPETERSON { + GATEPETERSON_GETCONFIG = GATEPETERSON_BASE_CMD, + GATEPETERSON_SETUP, + GATEPETERSON_DESTROY, + GATEPETERSON_PARAMS_INIT, + GATEPETERSON_CREATE, + GATEPETERSON_DELETE, + GATEPETERSON_OPEN, + GATEPETERSON_CLOSE, + GATEPETERSON_ENTER, + GATEPETERSON_LEAVE, + GATEPETERSON_SHAREDMEMREQ +}; + +/* + * IOCTL command IDs for gatepeterson + */ + +/* + * Command for gatepeterson_get_config + */ +#define CMD_GATEPETERSON_GETCONFIG _IOWR(IPC_IOC_MAGIC, \ + GATEPETERSON_GETCONFIG, \ + struct gatepeterson_cmd_args) + +/* + * Command for gatepeterson_setup + */ +#define CMD_GATEPETERSON_SETUP _IOWR(IPC_IOC_MAGIC, \ + GATEPETERSON_SETUP, \ + struct gatepeterson_cmd_args) + +/* + * Command for gatepeterson_setup + */ +#define CMD_GATEPETERSON_DESTROY _IOWR(IPC_IOC_MAGIC, \ + GATEPETERSON_DESTROY, \ + struct gatepeterson_cmd_args) + +/* + * Command for gatepeterson_destroy + */ +#define CMD_GATEPETERSON_PARAMS_INIT _IOWR(IPC_IOC_MAGIC, \ + GATEPETERSON_PARAMS_INIT, \ + struct gatepeterson_cmd_args) + +/* + * Command for gatepeterson_create + */ +#define CMD_GATEPETERSON_CREATE _IOWR(IPC_IOC_MAGIC, \ + GATEPETERSON_CREATE, \ + struct gatepeterson_cmd_args) + +/* + * Command for gatepeterson_delete + */ +#define CMD_GATEPETERSON_DELETE _IOWR(IPC_IOC_MAGIC, \ + GATEPETERSON_DELETE, \ + struct gatepeterson_cmd_args) +/* + * Command for gatepeterson_open + */ +#define CMD_GATEPETERSON_OPEN _IOWR(IPC_IOC_MAGIC, \ + GATEPETERSON_OPEN, \ + struct gatepeterson_cmd_args) + +/* + * Command for gatepeterson_close + */ +#define CMD_GATEPETERSON_CLOSE _IOWR(IPC_IOC_MAGIC, \ + GATEPETERSON_CLOSE, \ + struct gatepeterson_cmd_args) +/* + * Command for gatepeterson_enter + */ +#define CMD_GATEPETERSON_ENTER _IOWR(IPC_IOC_MAGIC, \ + GATEPETERSON_ENTER, \ + struct gatepeterson_cmd_args) + +/* + * Command for gatepeterson_leave + */ +#define CMD_GATEPETERSON_LEAVE _IOWR(IPC_IOC_MAGIC, \ + GATEPETERSON_LEAVE, \ + struct gatepeterson_cmd_args) + +/* + * Command for gatepeterson_shared_memreq + */ +#define CMD_GATEPETERSON_SHAREDMEMREQ _IOWR(IPC_IOC_MAGIC, \ + GATEPETERSON_SHAREDMEMREQ, \ + struct gatepeterson_cmd_args) + +/* + * Command arguments for gatepeterson + */ +union gatepeterson_arg { + struct { + void *handle; + struct gatepeterson_params *params; + } params_init; + + struct { + struct gatepeterson_config *config; + } get_config; + + struct { + struct gatepeterson_config *config; + } setup; + + struct { + void *handle; + struct gatepeterson_params *params; + u32 name_len; + u32 shared_addr_srptr; + } create; + + struct { + void *handle; + } delete; + + struct { + void *handle; + struct gatepeterson_params *params; + u32 name_len; + u32 shared_addr_srptr; + } open; + + struct { + void *handle; + } close; + + struct { + void *handle; + u32 flags; + } enter; + + struct { + void *handle; + u32 flags; + } leave; + + struct { + void *handle; + struct gatepeterson_params *params; + u32 bytes; + } shared_memreq; + +}; + +/* + * Command arguments for gatepeterson + */ +struct gatepeterson_cmd_args { + union gatepeterson_arg args; + s32 api_status; +}; + +/* + * This ioctl interface for gatepeterson module + */ +int gatepeterson_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long args); + +#endif /* _GATEPETERSON_IOCTL_ */ + diff --git a/arch/arm/plat-omap/include/syslink/gt.h b/arch/arm/plat-omap/include/syslink/gt.h new file mode 100644 index 000000000000..95e3feb18e7b --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/gt.h @@ -0,0 +1,320 @@ + +/* + * gt.h + * + * DSP-BIOS Bridge driver support functions for TI OMAP processors. + * + * Copyright (C) 2008 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + + +/* + * ======== gt.h ======== + * Purpose: + * There are two definitions that affect which portions of trace + * are acutally compiled into the client: GT_TRACE and GT_ASSERT. If + * GT_TRACE is set to 0 then all trace statements (except for assertions) + * will be compiled out of the client. If GT_ASSERT is set to 0 then + * assertions will be compiled out of the client. GT_ASSERT can not be + * set to 0 unless GT_TRACE is also set to 0 (i.e. GT_TRACE == 1 implies + * GT_ASSERT == 1). + * + *! Revision History + *! ================ + *! 02-Feb-2000 rr: Renamed this file to gtce.h. GT CLASS and trace + *! definitions are WinCE Specific. + *! 03-Jan-1997 ge Replaced "GT_" prefix to GT_Config structure members + *! to eliminate preprocessor confusion with other macros. + */ +#include <linux/types.h> +#ifndef GT_ +#define GT_ + +#ifndef GT_TRACE +#define GT_TRACE 0 /* 0 = "trace compiled out"; 1 = "trace active" */ +#endif + +/* #include <syslink/host_os.h> */ + +typedef s32(*Fxn)(); /* generic function type */ + + +#if !defined(GT_ASSERT) || GT_TRACE +#define GT_ASSERT 1 +#endif + +struct GT_Config { + Fxn PRINTFXN; + Fxn PIDFXN; + Fxn TIDFXN; + Fxn ERRORFXN; +}; + +extern struct GT_Config *GT; + +struct gt_mask { + char *modName; + u8 *flags; +} ; + +/* + * New GT Class defenitions. + * + * The following are the explanations and how it could be used in the code + * + * - GT_ENTER On Entry to Functions + * + * - GT_1CLASS Display level of debugging status- Object/Automatic + * variables + * - GT_2CLASS ---- do ---- + * + * - GT_3CLASS ---- do ---- + It can be used(recommended) for debug + * status in the ISR, IST + * - GT_4CLASS ---- do ---- + * + * - GT_5CLASS Display entry for module init/exit functions + * + * - GT_6CLASS Warn whenever SERVICES function fails + * + * - GT_7CLASS Warn failure of Critical failures + * + */ + +#define GT_ENTER ((u8)0x01) +#define GT_1CLASS ((u8)0x02) +#define GT_2CLASS ((u8)0x04) +#define GT_3CLASS ((u8)0x08) +#define GT_4CLASS ((u8)0x10) +#define GT_5CLASS ((u8)0x20) +#define GT_6CLASS ((u8)0x40) +#define GT_7CLASS ((u8)0x80) +#define GT_LEAVE ((u8)0x02) + +#ifdef _LINT_ + +/* LINTLIBRARY */ + +/* + * ======== GT_assert ======== + */ +/* ARGSUSED */ +void GT_assert(struct gt_mask mask, s32 expr) +{ +} + +/* + * ======== GT_config ======== + */ +/* ARGSUSED */ +void GT_config(struct GT_Config config) +{ +} + +/* + * ======== GT_create ======== + */ +/* ARGSUSED */ +void GT_create(struct gt_mask *mask, char *modName) +{ +} + +/* + * ======== GT_curline ======== + * Purpose: + * Returns the current source code line number. Is useful for performing + * branch testing using trace. For example, + * + * gt_1trace(curTrace, GT_1CLASS, + * "in module XX_mod, executing line %u\n", GT_curline()); + */ +/* ARGSUSED */ +u16 GT_curline(void) +{ + return (u16)NULL; +} + +/* + * ======== GT_exit ======== + */ +/* ARGSUSED */ +void GT_exit(void) +{ +} + +/* + * ======== GT_init ======== + */ +/* ARGSUSED */ +void GT_init(void) +{ +} + +/* + * ======== GT_query ======== + */ +/* ARGSUSED */ +bool GT_query(struct gt_mask mask, u8 class) +{ + return false; +} + +/* + * ======== GT_set ======== + * sets trace mask according to settings + */ + +/* ARGSUSED */ +void GT_set(char *settings) +{ +} + +/* + * ======== GT_setprintf ======== + * sets printf function + */ + +/* ARGSUSED */ +void GT_setprintf(Fxn fxn) +{ +} + +/* ARGSUSED */ +void gt_0trace(struct gt_mask mask, u8 class, char *format) +{ +} + +/* ARGSUSED */ +void gt_1trace(struct gt_mask mask, u8 class, char *format, ...) +{ +} + +/* ARGSUSED */ +void gt_2trace(struct gt_mask mask, u8 class, char *format, ...) +{ +} + +/* ARGSUSED */ +void gt_3trace(struct gt_mask mask, u8 class, char *format, ...) +{ +} + +/* ARGSUSED */ +void gt_4trace(struct gt_mask mask, u8 class, char *format, ...) +{ +} + +/* ARGSUSED */ +void gt_5trace(struct gt_mask mask, u8 class, char *format, ...) +{ +} + +/* ARGSUSED */ +void GT_6trace(struct gt_mask mask, u8 class, char *format, ...) +{ +} + +#else + +#define GT_BOUND 26 /* 26 letters in alphabet */ + +extern void _GT_create(struct gt_mask *mask, char *modName); + +#define GT_exit() + +extern void GT_init(void); +extern void _GT_set(char *str); +extern s32 _GT_trace(struct gt_mask *mask, char *format, ...); + +#if GT_ASSERT == 0 + +#define GT_assert(mask, expr) +#define GT_config(config) +#define GT_configInit(config) +#define GT_seterror(fxn) + +#else + +extern struct GT_Config _GT_params; + +#define GT_assert(mask, expr) \ + (!(expr) ? \ + printk(KERN_ALERT "assertion violation: %s, line %d\n", \ + __FILE__, __LINE__), NULL : NULL) + +#define GT_config(config) (_GT_params = *(config)) +#define GT_configInit(config) (*(config) = _GT_params) +#define GT_seterror(fxn) (_GT_params.ERRORFXN = (Fxn)(fxn)) + +#endif + +#if GT_TRACE == 0 + +#define GT_curline() ((u16)__LINE__) +#define GT_create(mask, modName) +#define GT_exit() +#define GT_init() +#define GT_set(settings) +#define GT_setprintf(fxn) + +#define GT_query(mask, class) false + +#define gt_0trace(mask, class, format) +#define gt_1trace(mask, class, format, arg1) +#define gt_2trace(mask, class, format, arg1, arg2) +#define gt_3trace(mask, class, format, arg1, arg2, arg3) +#define gt_4trace(mask, class, format, arg1, arg2, arg3, arg4) +#define gt_5trace(mask, class, format, arg1, arg2, arg3, arg4, arg5) +#define GT_6trace(mask, class, format, arg1, arg2, arg3, arg4, arg5, arg6) + +#else /* GT_TRACE == 1 */ + +#define GT_create(mask, modName) _GT_create((mask), (modName)) +#define GT_curline() ((u16)__LINE__) +#define GT_set(settings) _GT_set(settings) +#define GT_setprintf(fxn) (_GT_params.PRINTFXN = (Fxn)(fxn)) + +#define GT_query(mask, class) ((*(mask).flags & (class))) + +#define gt_0trace(mask, class, format) \ + ((*(mask).flags & (class)) ? \ + _GT_trace(&(mask), (format)) : 0) + +#define gt_1trace(mask, class, format, arg1) \ + ((*(mask).flags & (class)) ? \ + _GT_trace(&(mask), (format), (arg1)) : 0) + +#define gt_2trace(mask, class, format, arg1, arg2) \ + ((*(mask).flags & (class)) ? \ + _GT_trace(&(mask), (format), (arg1), (arg2)) : 0) + +#define gt_3trace(mask, class, format, arg1, arg2, arg3) \ + ((*(mask).flags & (class)) ? \ + _GT_trace(&(mask), (format), (arg1), (arg2), (arg3)) : 0) + +#define gt_4trace(mask, class, format, arg1, arg2, arg3, arg4) \ + ((*(mask).flags & (class)) ? \ + _GT_trace(&(mask), (format), (arg1), (arg2), (arg3), (arg4)) : 0) + +#define gt_5trace(mask, class, format, arg1, arg2, arg3, arg4, arg5) \ + ((*(mask).flags & (class)) ? \ + _GT_trace(&(mask), (format), (arg1), (arg2), (arg3), (arg4), (arg5)) \ + : 0) + +#define GT_6trace(mask, class, format, arg1, arg2, arg3, arg4, arg5, arg6) \ + ((*(mask).flags & (class)) ? \ + _GT_trace(&(mask), (format), (arg1), (arg2), (arg3), (arg4), (arg5), \ + (arg6)) : 0) + +#endif /* GT_TRACE */ + +#endif /* _LINT_ */ + +#endif /* GTCE_ */ diff --git a/arch/arm/plat-omap/include/syslink/heap.h b/arch/arm/plat-omap/include/syslink/heap.h new file mode 100644 index 000000000000..f03a692a71ab --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/heap.h @@ -0,0 +1,91 @@ +/* + * heap.h + * + * Heap module manages fixed size buffers that can be used + * in a multiprocessor system with shared memory. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef _HEAP_H_ +#define _HEAP_H_ + +#include <linux/types.h> + +/* + * Structure defining memory related statistics + */ +struct memory_stats{ + u32 *total_size; /* Total memory size */ + u32 *total_free_size; /* Total free memory size */ + u32 *largest_free_size; /* Largest free memory size */ +}; + +/*! + * ======== extendedstats ======== + * Stats structure for the get_extended_stats API. + * + * max_allocated_blocks: The maximum number of blocks allocated + * from this heap at any single point in time during the lifetime of this + * heap instance. + * + * num_allocated_blocks: The total number of blocks currently + * allocated in this Heap instance. + */ +struct heap_extended_stats { + u32 max_allocated_blocks; + u32 num_allocated_blocks; +}; + +/* + * Structure defining config parameters for the heapbuf module + */ +struct heap_config { + u32 max_name_len; /* Maximum length of name */ + bool track_max_allocs; /* Track the max number of allocated blocks */ +}; + +/* + * Structure for the handle for the heap + */ +struct heap_object { + void* (*alloc) (void *handle, u32 size, u32 align); + int (*free) (void *handle, void *block, u32 size); + int (*get_stats) (void *handle, struct memory_stats *stats); + int (*get_extended_stats) (void *handle, + struct heap_extended_stats *stats); + void *obj; +}; + +/* + * Allocate a block + */ +void *heap_alloc(void *handle, u32 size, u32 align); + +/* + * Frees the block to this Heap + */ +int heap_free(void *handle, void *block, u32 size); + +/* + * Get heap statistics + */ +int heap_get_stats(void *handle, struct memory_stats *stats); + +/* + * Get heap extended statistics + */ +int heap_get_extended_stats(void *hphandle, + struct heap_extended_stats *stats); + +#endif /* _HEAP_H_ */ + diff --git a/arch/arm/plat-omap/include/syslink/heapbuf.h b/arch/arm/plat-omap/include/syslink/heapbuf.h new file mode 100644 index 000000000000..3667c4675d49 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/heapbuf.h @@ -0,0 +1,152 @@ +/* + * heapbuf.h + * + * Heap module manages fixed size buffers that can be used + * in a multiprocessor system with shared memory. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef _HEAPBUF_H_ +#define _HEAPBUF_H_ + +#include <linux/types.h> +#include <heap.h> +#include <listmp.h> + +/*! + * @def LISTMP_MODULEID + * @brief Unique module ID. + */ +#define HEAPBUF_MODULEID (0x4cd5) + +/* + * Creation of Heap Buf succesful. +*/ +#define HEAPBUF_CREATED (0x05251995) + +/* + * Version. + */ +#define HEAPBUF_VERSION (1) + +/* + * Structure defining config parameters for the HeapBuf module. + */ +struct heapbuf_config { + u32 max_name_len; /* Maximum length of name */ + bool use_nameserver; /* To have this module use the NameServer or not */ + bool track_max_allocs; /* Track the maximum number of allocated blocks */ +}; + +/* + * Structure defining parameters for the HeapBuf module + */ +struct heapbuf_params { + void *gate; + bool exact; /* Only allocate on exact match of rquested size */ + char *name; /* Name when using nameserver */ + int resource_id; /* Resource id of the hardware linked list */ + bool cache_flag; /* Whether to perform cache coherency calls */ + u32 align; /* Alignment (in MAUs, power of 2) of each block */ + u32 num_blocks; /* Number of fixed-size blocks */ + u32 block_size; /* Size (in MAUs) of each block*/ + void *shared_addr; /* Physical address of the shared memory */ + u32 shared_addr_size; /* Size of shareAddr */ + void *shared_buf; /* Physical address of the shared buffers */ + u32 shared_buf_size; /* Size of sharedBuf */ +}; + +/* + * Stats structure for the getExtendedStats API. + */ +struct heapbuf_extended_stats { + u32 max_allocated_blocks; + /* maximum number of blocks allocated from this heap instance */ + u32 num_allocated_blocks; + /* total number of blocks currently allocated from this heap instance*/ +}; + + +/* + * Function to get default configuration for the heapbuf module + */ +int heapbuf_get_config(struct heapbuf_config *cfgparams); + +/* + * Function to setup the heapbuf module + */ +int heapbuf_setup(const struct heapbuf_config *cfg); + +/* + * Function to destroy the heapbuf module + */ +int heapbuf_destroy(void); + +/* Initialize this config-params structure with supplier-specified + * defaults before instance creation + */ +void heapbuf_params_init(void *handle, struct heapbuf_params *params); + +/* + * Creates a new instance of heapbuf module + */ +void *heapbuf_create(const struct heapbuf_params *params); + +/* + * Deletes a instance of heapbuf module + */ +int heapbuf_delete(void **handle_ptr); + +/* + * Opens a created instance of heapbuf module + */ +int heapbuf_open(void **handle_ptr, struct heapbuf_params *params); + +/* + * Closes previously opened/created instance of heapbuf module + */ +int heapbuf_close(void *handle_ptr); + +/* + * Returns the amount of shared memory required for creation + * of each instance + */ +int heapbuf_shared_memreq(const struct heapbuf_params *params, u32 *buf_size); + +/* + * Allocate a block + */ +void *heapbuf_alloc(void *hphandle, u32 size, u32 align); + +/* + * Frees the block to this heapbuf + */ +int heapbuf_free(void *hphandle, void *block, u32 size); + +/* + * Get memory statistics + */ +int heapbuf_get_stats(void *hphandle, struct memory_stats *stats); + +/* + * Indicate whether the heap may block during an alloc or free call + */ +bool heapbuf_isblocking(void *handle); + +/* + * Get extended statistics + */ +int heapbuf_get_extended_stats(void *hphandle, + struct heapbuf_extended_stats *stats); + +#endif /* _HEAPBUF_H_ */ diff --git a/arch/arm/plat-omap/include/syslink/heapbuf_ioctl.h b/arch/arm/plat-omap/include/syslink/heapbuf_ioctl.h new file mode 100644 index 000000000000..80165dcfc436 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/heapbuf_ioctl.h @@ -0,0 +1,215 @@ +/* + * heapbuf_ioctl.h + * + * Heap module manages fixed size buffers that can be used + * in a multiprocessor system with shared memory. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef _HEAPBUF_IOCTL_ +#define _HEAPBUF_IOCTL_ + +#include <linux/ioctl.h> +#include <linux/types.h> + +#include <ipc_ioctl.h> +#include <heap.h> +#include <heapbuf.h> + + +enum CMD_HEAPBUF { + HEAPBUF_GETCONFIG = HEAPBUF_BASE_CMD, + HEAPBUF_SETUP, + HEAPBUF_DESTROY, + HEAPBUF_PARAMS_INIT, + HEAPBUF_CREATE, + HEAPBUF_DELETE, + HEAPBUF_OPEN, + HEAPBUF_CLOSE, + HEAPBUF_ALLOC, + HEAPBUF_FREE, + HEAPBUF_SHAREDMEMREQ, + HEAPBUF_GETSTATS, + HEAPBUF_GETEXTENDEDSTATS +}; + +/* + * Command for heapbuf_get_config + */ +#define CMD_HEAPBUF_GETCONFIG _IOWR(IPC_IOC_MAGIC, HEAPBUF_GETCONFIG,\ + struct heapbuf_cmd_args) + +/* + * Command for heapbuf_setup + */ +#define CMD_HEAPBUF_SETUP _IOWR(IPC_IOC_MAGIC, HEAPBUF_SETUP, \ + struct heapbuf_cmd_args) +/* + * Command for heapbuf_destroy + */ +#define CMD_HEAPBUF_DESTROY _IOWR(IPC_IOC_MAGIC, HEAPBUF_DESTROY, \ + struct heapbuf_cmd_args) + +/* + * Command for heapbuf_prams_init + */ +#define CMD_HEAPBUF_PARAMS_INIT _IOWR(IPC_IOC_MAGIC, \ + HEAPBUF_PARAMS_INIT, \ + struct heapbuf_cmd_args) + +/* + * Command for heapbuf_create + */ +#define CMD_HEAPBUF_CREATE _IOWR(IPC_IOC_MAGIC, HEAPBUF_CREATE, \ + struct heapbuf_cmd_args) + +/* + * Command for heapbuf_delete + */ +#define CMD_HEAPBUF_DELETE _IOWR(IPC_IOC_MAGIC, HEAPBUF_DELETE, \ + struct heapbuf_cmd_args) + +/* + * Command for heapbuf_open + */ +#define CMD_HEAPBUF_OPEN _IOWR(IPC_IOC_MAGIC, HEAPBUF_OPEN, \ + struct heapbuf_cmd_args) + +/* + * Command for heapbuf_close + */ +#define CMD_HEAPBUF_CLOSE _IOWR(IPC_IOC_MAGIC, HEAPBUF_CLOSE, \ + struct heapbuf_cmd_args) + +/* + * Command for heapbuf_alloc + */ +#define CMD_HEAPBUF_ALLOC _IOWR(IPC_IOC_MAGIC, HEAPBUF_ALLOC, \ + struct heapbuf_cmd_args) + +/* + * Command for heapbuf_free + */ +#define CMD_HEAPBUF_FREE _IOWR(IPC_IOC_MAGIC, HEAPBUF_FREE, \ + struct heapbuf_cmd_args) + +/* + * Command for heapbuf_shared_memreq + */ +#define CMD_HEAPBUF_SHAREDMEMREQ _IOWR(IPC_IOC_MAGIC, \ + HEAPBUF_SHAREDMEMREQ, \ + struct heapbuf_cmd_args) + +/* + * Command for heapbuf_get_stats + */ +#define CMD_HEAPBUF_GETSTATS _IOWR(IPC_IOC_MAGIC, \ + HEAPBUF_GETSTATS, \ + struct heapbuf_cmd_args) + +/* + * Command for heapbuf_get_extended_stats + */ +#define CMD_HEAPBUF_GETEXTENDEDSTATS _IOWR(IPC_IOC_MAGIC, \ + HEAPBUF_GETEXTENDEDSTATS, \ + struct heapbuf_cmd_args) + + +/* + * Command arguments for heapbuf + */ +union heapbuf_arg { + struct { + void *handle; + struct heapbuf_params *params; + } params_init; + + struct { + struct heapbuf_config *config; + } get_config; + + struct { + struct heapbuf_config *config; + } setup; + + struct { + void *handle; + struct heapbuf_params *params; + u32 name_len; + u32 *shared_addr_srptr; + u32 *shared_buf_srptr; + void *knl_gate; + } create; + + struct { + void *handle; + } delete; + + struct { + void *handle; + struct heapbuf_params *params; + u32 name_len; + u32 *shared_addr_srptr; + void *knl_gate; + } open; + + struct { + void *handle; + } close; + + struct { + void *handle; + u32 size; + u32 align; + u32 *block_srptr; + } alloc; + + struct { + void *handle; + u32 *block_srptr; + u32 size; + } free; + + struct { + void *handle; + struct memory_stats *stats; + } get_stats; + + struct { + void *handle; + struct heapbuf_extended_stats *stats; + } get_extended_stats; + + struct { + void *handle; + struct heapbuf_params *params; + u32 buf_size; + u32 bytes; + } shared_memreq; +}; + +/* + * Command arguments for heapbuf + */ +struct heapbuf_cmd_args{ + union heapbuf_arg args; + s32 api_status; +}; + +/* + * This ioctl interface for heapbuf module + */ +int heapbuf_ioctl(struct inode *pinode, struct file *filp, + unsigned int cmd, unsigned long args); + +#endif /* _HEAPBUF_IOCTL_ */ diff --git a/arch/arm/plat-omap/include/syslink/host_os.h b/arch/arm/plat-omap/include/syslink/host_os.h new file mode 100644 index 000000000000..2e2164f314fa --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/host_os.h @@ -0,0 +1,72 @@ + +/* + * host_os.h + * + * DSP-BIOS Bridge driver support functions for TI OMAP processors. + * + * Copyright (C) 2008 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + + +/* + * ======== windows.h ======== + * + *! Revision History + *! ================ + *! 08-Mar-2004 sb Added cacheflush.h to support Dynamic Memory Mapping feature + *! 16-Feb-2004 sb Added headers required for consistent_alloc + */ + +#ifndef _HOST_OS_H_ +#define _HOST_OS_H_ + +#include <generated/autoconf.h> +#include <asm/system.h> +#include <asm/atomic.h> +#include <linux/semaphore.h> +#include <linux/uaccess.h> +#include <asm/irq.h> +#include <linux/io.h> +#include <linux/syscalls.h> +#include <linux/version.h> +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/stddef.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/spinlock.h> +#include <linux/sched.h> +#include <linux/fs.h> +#include <linux/file.h> +#include <linux/slab.h> +#include <linux/delay.h> +#include <linux/ctype.h> +#include <linux/mm.h> +#include <linux/device.h> +#include <linux/vmalloc.h> +#include <linux/ioport.h> +#include <linux/platform_device.h> +#include <linux/clk.h> +#include <linux/pagemap.h> +#include <asm/cacheflush.h> +#include <linux/dma-mapping.h> + +/* ----------------------------------- Macros */ + +#define SEEK_SET 0 /* Seek from beginning of file. */ +#define SEEK_CUR 1 /* Seek from current position. */ +#define SEEK_END 2 /* Seek from end of file. */ + +/* TODO -- Remove, once BP defines them */ +#define INT_MAIL_MPU_IRQ 26 +#define INT_DSP_MMU_IRQ 28 + +#endif diff --git a/arch/arm/plat-omap/include/syslink/hw_defs.h b/arch/arm/plat-omap/include/syslink/hw_defs.h new file mode 100644 index 000000000000..440dbb14445e --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/hw_defs.h @@ -0,0 +1,63 @@ +/* + * hw_defs.h + * + * Syslink driver support for OMAP Processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef __HW_DEFS_H +#define __HW_DEFS_H + +#include <syslink/GlobalTypes.h> + +/* Page size */ +#define HW_PAGE_SIZE_4KB 0x1000 +#define HW_PAGE_SIZE_64KB 0x10000 +#define HW_PAGE_SIZE_1MB 0x100000 +#define HW_PAGE_SIZE_16MB 0x1000000 + +/* hw_status: return type for HW API */ +typedef long hw_status; + +/* hw_set_clear_t: Enumerated Type used to set and clear any bit */ +enum hw_set_clear_t { + HW_CLEAR, + HW_SET +} ; + +/* hw_endianism_t: Enumerated Type used to specify the endianism + * Do NOT change these values. They are used as bit fields. */ +enum hw_endianism_t { + HW_LITTLE_ENDIAN, + HW_BIG_ENDIAN + +} ; + +/* hw_elemnt_siz_t: Enumerated Type used to specify the element size + * Do NOT change these values. They are used as bit fields. */ +enum hw_elemnt_siz_t { + HW_ELEM_SIZE_8BIT, + HW_ELEM_SIZE_16BIT, + HW_ELEM_SIZE_32BIT, + HW_ELEM_SIZE_64BIT + +} ; + +/* HW_IdleMode_t: Enumerated Type used to specify Idle modes */ +enum HW_IdleMode_t { + HW_FORCE_IDLE, + HW_NO_IDLE, + HW_SMART_IDLE +} ; + +#endif /* __HW_DEFS_H */ diff --git a/arch/arm/plat-omap/include/syslink/hw_mbox.h b/arch/arm/plat-omap/include/syslink/hw_mbox.h new file mode 100644 index 000000000000..f50ef782e66f --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/hw_mbox.h @@ -0,0 +1,447 @@ +/* + * hw_mbox.h + * + * Syslink driver support for OMAP Processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef __MBOX_H +#define __MBOX_H + +#include <syslink/hw_defs.h> + + +#define HW_MBOX_INT_NEW_MSG 0x1 +#define HW_MBOX_INT_NOT_FULL 0x2 +#define HW_MBOX_INT_ALL 0x3 + +/* + * DEFINITION: HW_MBOX_MAX_NUM_MESSAGES + * + * DESCRIPTION: Maximum number of messages that mailbox can hald at a time. + * + * + */ + +#define HW_MBOX_MAX_NUM_MESSAGES 4 + + + /* width in bits of MBOX Id */ +#define HW_MBOX_ID_WIDTH 2 + + +/* + * TYPE: enum hw_mbox_id_t + * + * DESCRIPTION: Enumerated Type used to specify Mail Box Sub Module Id Number + * + * + */ + enum hw_mbox_id_t { + HW_MBOX_ID_0, + HW_MBOX_ID_1, + HW_MBOX_ID_2, + HW_MBOX_ID_3, + HW_MBOX_ID_4, + HW_MBOX_ID_5 + }; + +/* + * TYPE: enum hw_mbox_userid_t + * + * DESCRIPTION: Enumerated Type used to specify Mail box User Id + * + * + */ + enum hw_mbox_userid_t { + HW_MBOX_U0_ARM11, + HW_MBOX_U1_UMA, + HW_MBOX_U2_IVA, + HW_MBOX_U3_ARM11 + }; + +#if defined(OMAP3430) +/* +* TYPE: mailbox_context +* +* DESCRIPTION: Mailbox context settings +* +* +*/ +struct mailbox_context { + unsigned long sysconfig; + unsigned long irqEnable0; + unsigned long irqEnable1; +}; +#endif/* defined(OMAP3430)*/ + +/* +* FUNCTION : hw_mbox_msg_read +* +* INPUTS: +* +* Identifier : base_address +* Type : const unsigned long +* Description : Base Address of instance of Mailbox module +* +* Identifier : mail_box_id +* Type : const enum hw_mbox_id_t +* Description : Mail Box Sub module Id to read +* +* OUTPUTS: +* +* Identifier : p_read_value +* Type : unsigned long *const +* Description : Value read from MailBox +* +* RETURNS: +* +* Type : ReturnCode_t +* Description : RET_OK No errors occured +* RET_BAD_NULL_PARAM Address/pointer Paramater was set to 0/NULL +* RET_INVALID_ID Invalid Id used +* RET_EMPTY Mailbox empty +* +* PURPOSE: +* : this function reads a unsigned long from the sub module message +* box Specified. if there are no messages in the mailbox +* then and error is returned. +* +*/ +extern long hw_mbox_msg_read( + const unsigned long base_address, + const enum hw_mbox_id_t mail_box_id, + unsigned long *const p_read_value + ); + +/* +* FUNCTION : hw_mbox_msg_write +* +* INPUTS: +* +* Identifier : base_address +* Type : const unsigned long +* Description : Base Address of instance of Mailbox module +* +* Identifier : mail_box_id +* Type : const enum hw_mbox_id_t +* Description : Mail Box Sub module Id to write +* +* Identifier : write_value +* Type : const unsigned long +* Description : Value to write to MailBox +* +* RETURNS: +* +* Type : ReturnCode_t +* Description : RET_OK No errors occured +* RET_BAD_NULL_PARAM Address/pointer Paramater was set to 0/NULL +* RET_INVALID_ID Invalid Id used +* +* PURPOSE:: this function writes a unsigned long from the sub module message +* box Specified. +* +* +*/ +extern long hw_mbox_msg_write( + const unsigned long base_address, + const enum hw_mbox_id_t mail_box_id, + const unsigned long write_value + ); + +/* +* FUNCTION : hw_mbox_is_full +* +* INPUTS: +* +* Identifier : base_address +* Type : const unsigned long +* Description : Base Address of instance of Mailbox module +* +* Identifier : mail_box_id +* Type : const enum hw_mbox_id_t +* Description : Mail Box Sub module Id to check +* +* OUTPUTS: +* +* Identifier : p_is_full +* Type : unsigned long *const +* Description : false means mail box not Full +* true means mailbox full. +* +* RETURNS: +* +* Type : ReturnCode_t +* Description : RET_OK No errors occured +* RET_BAD_NULL_PARAM Address/pointer Paramater was set to 0/NULL +* RET_INVALID_ID Invalid Id used +* +* PURPOSE: : this function reads the full status register for mailbox. +* +* +*/ +extern long hw_mbox_is_full( + const unsigned long base_address, + const enum hw_mbox_id_t mail_box_id, + unsigned long *const p_is_full + ); + +/* ----------------------------------------------------------------- +* FUNCTION : hw_mbox_nomsg_get +* +* INPUTS: +* +* Identifier : base_address +* Type : const unsigned long +* Description : Base Address of instance of Mailbox module +* +* Identifier : mail_box_id +* Type : const enum hw_mbox_id_t +* Description : Mail Box Sub module Id to get num messages +* +* OUTPUTS: +* +* Identifier : p_num_msg +* Type : unsigned long *const +* Description : Number of messages in mailbox +* +* RETURNS: +* +* Type : ReturnCode_t +* Description : RET_OK No errors occured +* RET_BAD_NULL_PARAM Address/pointer Paramater was set to 0/NULL +* RET_INVALID_ID Inavlid ID input at parameter +* +* PURPOSE: +* : this function gets number of messages in a specified mailbox. +* +* +*/ +extern long hw_mbox_nomsg_get( + const unsigned long base_address, + const enum hw_mbox_id_t mail_box_id, + unsigned long *const p_num_msg + ); + +/* +* FUNCTION : hw_mbox_event_enable +* +* INPUTS: +* +* Identifier : base_address +* Type : const unsigned long +* RET_BAD_NULL_PARAM Address/pointer Paramater was set to 0/NULL +* +* Identifier : mail_box_id +* Type : const enum hw_mbox_id_t +* Description : Mail Box Sub module Id to enable +* +* Identifier : user_id +* Type : const enum hw_mbox_userid_t +* Description : Mail box User Id to enable +* +* Identifier : enableIrq +* Type : const unsigned long +* Description : Irq value to enable +* +* RETURNS: +* +* Type : ReturnCode_t +* Description : RET_OK No errors occured +* RET_BAD_NULL_PARAM A Pointer Paramater was set to NULL +* RET_INVALID_ID Invalid Id used +* +* PURPOSE: : this function enables the specified IRQ. +* +* +*/ +extern long hw_mbox_event_enable( + const unsigned long base_address, + const enum hw_mbox_id_t mail_box_id, + const enum hw_mbox_userid_t user_id, + const unsigned long events + ); + +/* +* FUNCTION : hw_mbox_event_disable +* +* INPUTS: +* +* Identifier : base_address +* Type : const unsigned long +* RET_BAD_NULL_PARAM Address/pointer Paramater was set to 0/NULL +* +* Identifier : mail_box_id +* Type : const enum hw_mbox_id_t +* Description : Mail Box Sub module Id to disable +* +* Identifier : user_id +* Type : const enum hw_mbox_userid_t +* Description : Mail box User Id to disable +* +* Identifier : enableIrq +* Type : const unsigned long +* Description : Irq value to disable +* +* RETURNS: +* +* Type : ReturnCode_t +* Description : RET_OK No errors occured +* RET_BAD_NULL_PARAM A Pointer Paramater was set to NULL +* RET_INVALID_ID Invalid Id used +* +* PURPOSE: : this function disables the specified IRQ. +* +* +*/ +extern long hw_mbox_event_disable( + const unsigned long base_address, + const enum hw_mbox_id_t mail_box_id, + const enum hw_mbox_userid_t user_id, + const unsigned long events + ); + +/* +* FUNCTION : hw_mbox_event_status +* +* INPUTS: +* +* Identifier : base_address +* Type : const unsigned long +* Description : Base Address of instance of Mailbox module +* +* Identifier : mail_box_id +* Type : const enum hw_mbox_id_t +* Description : Mail Box Sub module Id to clear +* +* Identifier : user_id +* Type : const enum hw_mbox_userid_t +* Description : Mail box User Id to clear +* +* OUTPUTS: +* +* Identifier : pIrqStatus +* Type : pMBOX_Int_t *const +* Description : The value in IRQ status register +* +* RETURNS: +* +* Type : ReturnCode_t +* Description : RET_OK No errors occured +* RET_BAD_NULL_PARAM Address/pointer Paramater was set to 0/NULL +* RET_INVALID_ID Invalid Id used +* +* PURPOSE: : this function gets the status of the specified IRQ. +* +* +*/ +extern long hw_mbox_event_status( + const unsigned long base_address, + const enum hw_mbox_id_t mail_box_id, + const enum hw_mbox_userid_t user_id, + unsigned long *const p_eventStatus + ); + +/* +* FUNCTION : hw_mbox_event_ack +* +* INPUTS: +* +* Identifier : base_address +* Type : const unsigned long +* Description : Base Address of instance of Mailbox module +* +* Identifier : mail_box_id +* Type : const enum hw_mbox_id_t +* Description : Mail Box Sub module Id to set +* +* Identifier : user_id +* Type : const enum hw_mbox_userid_t +* Description : Mail box User Id to set +* +* Identifier : irqStatus +* Type : const unsigned long +* Description : The value to write IRQ status +* +* OUTPUTS: +* +* RETURNS: +* +* Type : ReturnCode_t +* Description : RET_OK No errors occured +* RET_BAD_NULL_PARAM Address Paramater was set to 0 +* RET_INVALID_ID Invalid Id used +* +* PURPOSE: : this function sets the status of the specified IRQ. +* +* +*/ +extern long hw_mbox_event_ack( + const unsigned long base_address, + const enum hw_mbox_id_t mail_box_id, + const enum hw_mbox_userid_t user_id, + const unsigned long event + ); + +#if defined(OMAP3430) +/* --------------------------------------------------------------- +* FUNCTION : hw_mbox_save_settings +* +* INPUTS: +* +* Identifier : base_address +* Type : const unsigned long +* Description : Base Address of instance of Mailbox module +* +* +* RETURNS: +* +* Type : ReturnCode_t +* Description : RET_OK No errors occured +* RET_BAD_NULL_PARAM Address/pointer Paramater was set to 0/NULL +* RET_INVALID_ID Invalid Id used +* RET_EMPTY Mailbox empty +* +* PURPOSE: : this function saves the context of mailbox +* +* ---------------------------------------------------------------- +*/ +extern long hw_mbox_save_settings(unsigned long baseAddres); + +/* +* FUNCTION : hw_mbox_restore_settings +* +* INPUTS: +* +* Identifier : base_address +* Type : const unsigned long +* Description : Base Address of instance of Mailbox module +* +* +* RETURNS: +* +* Type : ReturnCode_t +* Description : RET_OK No errors occured +* RET_BAD_NULL_PARAM Address/pointer Paramater was set to 0/NULL +* RET_INVALID_ID Invalid Id used +* RET_EMPTY Mailbox empty +* +* PURPOSE: : this function restores the context of mailbox +* +* +*/ +extern long hw_mbox_restore_settings(unsigned long baseAddres); +#endif/* defined(OMAP3430)*/ + +#endif /* __MBOX_H */ + diff --git a/arch/arm/plat-omap/include/syslink/hw_mmu.h b/arch/arm/plat-omap/include/syslink/hw_mmu.h new file mode 100644 index 000000000000..3463fe1e4086 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/hw_mmu.h @@ -0,0 +1,171 @@ +/* + * hw_mbox.h + * + * Syslink driver support for OMAP Processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef __HW_MMU_H +#define __HW_MMU_H + +#include <linux/types.h> + +/* Bitmasks for interrupt sources */ +#define HW_MMU_TRANSLATION_FAULT 0x2 +#define HW_MMU_ALL_INTERRUPTS 0x1F + +#define HW_MMU_COARSE_PAGE_SIZE 0x400 + +/* hw_mmu_mixed_size_t: Enumerated Type used to specify whether to follow + CPU/TLB Element size */ +enum hw_mmu_mixed_size_t { + HW_MMU_TLBES, + HW_MMU_CPUES + +} ; + +/* hw_mmu_map_attrs_t: Struct containing MMU mapping attributes */ +struct hw_mmu_map_attrs_t { + enum hw_endianism_t endianism; + enum hw_elemnt_siz_t element_size; + enum hw_mmu_mixed_size_t mixedSize; +} ; + +extern hw_status hw_mmu_enable(const u32 base_address); + +extern hw_status hw_mmu_disable(const u32 base_address); + +extern hw_status hw_mmu_numlocked_set(const u32 base_address, + u32 num_lcked_entries); + +extern hw_status hw_mmu_victim_numset(const u32 base_address, + u32 vctm_entry_num); + +/* For MMU faults */ +extern hw_status hw_mmu_eventack(const u32 base_address, + u32 irq_mask); + +extern hw_status hw_mmu_event_disable(const u32 base_address, + u32 irq_mask); + +extern hw_status hw_mmu_event_enable(const u32 base_address, + u32 irq_mask); + +extern hw_status hw_mmu_event_status(const u32 base_address, + u32 *irq_mask); + +extern hw_status hw_mmu_flt_adr_rd(const u32 base_address, + u32 *addr); + +/* Set the TT base address */ +extern hw_status hw_mmu_ttbset(const u32 base_address, + u32 ttb_phys_addr); + +extern hw_status hw_mmu_twl_enable(const u32 base_address); + +extern hw_status hw_mmu_twl_disable(const u32 base_address); + +extern hw_status hw_mmu_tlb_flush(const u32 base_address, + u32 virtual_addr, + u32 page_size); + +extern hw_status hw_mmu_tlb_flushAll(const u32 base_address); + +extern hw_status hw_mmu_tlb_add(const u32 base_address, + u32 physical_addr, + u32 virtual_addr, + u32 page_size, + u32 entryNum, + struct hw_mmu_map_attrs_t *map_attrs, + enum hw_set_clear_t preserve_bit, + enum hw_set_clear_t valid_bit); + + +/* For PTEs */ +extern hw_status hw_mmu_pte_set(const u32 pg_tbl_va, + u32 physical_addr, + u32 virtual_addr, + u32 page_size, + struct hw_mmu_map_attrs_t *map_attrs); + +extern hw_status hw_mmu_pte_clear(const u32 pg_tbl_va, + u32 pg_size, + u32 virtual_addr); + +static inline u32 hw_mmu_pte_addr_l1(u32 l1_base, u32 va) +{ + u32 pte_addr; + u32 VA_31_to_20; + + VA_31_to_20 = va >> (20 - 2); /* Left-shift by 2 here itself */ + VA_31_to_20 &= 0xFFFFFFFCUL; + pte_addr = l1_base + VA_31_to_20; + + return pte_addr; +} + +static inline u32 hw_mmu_pte_addr_l2(u32 l2_base, u32 va) +{ + u32 pte_addr; + + pte_addr = (l2_base & 0xFFFFFC00) | ((va >> 10) & 0x3FC); + + return pte_addr; +} + +static inline u32 hw_mmu_pte_coarsel1(u32 pte_val) +{ + u32 pteCoarse; + + pteCoarse = pte_val & 0xFFFFFC00; + + return pteCoarse; +} + +static inline u32 hw_mmu_pte_sizel1(u32 pte_val) +{ + u32 pte_size = 0; + + if ((pte_val & 0x3) == 0x1) { + /* Points to L2 PT */ + pte_size = HW_MMU_COARSE_PAGE_SIZE; + } + + if ((pte_val & 0x3) == 0x2) { + if (pte_val & (1 << 18)) + pte_size = HW_PAGE_SIZE_16MB; + else + pte_size = HW_PAGE_SIZE_1MB; + } + + return pte_size; +} + +static inline u32 hw_mmu_pte_sizel2(u32 pte_val) +{ + u32 pte_size = 0; + + if (pte_val & 0x2) + pte_size = HW_PAGE_SIZE_4KB; + else if (pte_val & 0x1) + pte_size = HW_PAGE_SIZE_64KB; + + return pte_size; +} +extern hw_status hw_mmu_tlb_dump(u32 base_address, bool shw_inv_entries); + +extern u32 hw_mmu_pte_phyaddr(u32 pte_val, u32 pte_size); + +extern u32 hw_mmu_fault_dump(const u32 base_address); + +#endif /* __HW_MMU_H */ diff --git a/arch/arm/plat-omap/include/syslink/hw_ocp.h b/arch/arm/plat-omap/include/syslink/hw_ocp.h new file mode 100644 index 000000000000..7277bbfcde33 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/hw_ocp.h @@ -0,0 +1,60 @@ +/* + * hw_ocp.h + * + * Syslink driver support for OMAP Processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + + +#ifndef __HW_OCP_H +#define __HW_OCP_H + +#include <syslink/GlobalTypes.h> +#include <syslink/hw_ocp.h> +#include <syslink/hw_defs.h> +#include <syslink/MBXRegAcM.h> +#include <syslink/MBXAccInt.h> + + +/* +* TYPE: HW_IdleMode_t +* +* DESCRIPTION: Enumerated Type for idle modes in OCP SYSCONFIG register +* +* +*/ +enum hal_ocp_idlemode_t { + HW_OCP_FORCE_IDLE, + HW_OCP_NO_IDLE, + HW_OCP_SMART_IDLE +}; + +extern long hw_ocp_soft_reset(const unsigned long base_address); + +extern long hw_ocp_soft_reset_isdone(const unsigned long base_address, + unsigned long *reset_is_done); + +extern long hw_ocp_idle_modeset(const unsigned long base_address, + enum hal_ocp_idlemode_t idle_mode); + +extern long hw_ocp_idlemode_get(const unsigned long base_address, + enum hal_ocp_idlemode_t *idle_mode); + +extern long hw_ocp_autoidle_set(const unsigned long base_address, + enum hw_set_clear_t auto_idle); + +extern long hw_ocp_autoidle_get(const unsigned long base_address, + enum hw_set_clear_t *auto_idle); + +#endif /* __HW_OCP_H */ + diff --git a/arch/arm/plat-omap/include/syslink/ipc_ioctl.h b/arch/arm/plat-omap/include/syslink/ipc_ioctl.h new file mode 100644 index 000000000000..5a5078fcf3bd --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/ipc_ioctl.h @@ -0,0 +1,92 @@ +/* + * ipc_ioctl.h + * + * Base file for all TI OMAP IPC ioctl's. + * Linux-OMAP IPC has allocated base 0xEE with a range of 0x00-0xFF. + * (need to get the real one from open source maintainers) + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef _IPC_IOCTL_H +#define _IPC_IOCTL_H + +#include <linux/ioctl.h> +#include <linux/types.h> +#include <linux/fs.h> + +#define IPC_IOC_MAGIC 0xE0 +#define IPC_IOC_BASE 2 + +enum ipc_command_count { + MULTIPROC_CMD_NOS = 4, + NAMESERVER_CMD_NOS = 13, + HEAPBUF_CMD_NOS = 13, + SHAREDREGION_CMD_NOS = 10, + GATEPETERSON_CMD_NOS = 11, + LISTMP_SHAREDMEMORY_CMD_NOS = 18, + MESSAGEQ_CMD_NOS = 17, + MESSAGEQ_TRANSPORTSHM_CMD_NOS = 9, + NAMESERVERREMOTENOTIFY_CMD_NOS = 8, + SYSMGR_CMD_NOS = 5, + SYSMEMMGR_CMD_NOS = 6 +}; + +enum ipc_command_ranges { + MULTIPROC_BASE_CMD = IPC_IOC_BASE, + MULTIPROC_END_CMD = (MULTIPROC_BASE_CMD + \ + MULTIPROC_CMD_NOS - 1), + + NAMESERVER_BASE_CMD = 10, + NAMESERVER_END_CMD = (NAMESERVER_BASE_CMD + \ + NAMESERVER_CMD_NOS - 1), + + HEAPBUF_BASE_CMD = 30, + HEAPBUF_END_CMD = (HEAPBUF_BASE_CMD + \ + HEAPBUF_CMD_NOS - 1), + + SHAREDREGION_BASE_CMD = 50, + SHAREDREGION_END_CMD = (SHAREDREGION_BASE_CMD + \ + SHAREDREGION_CMD_NOS - 1), + + GATEPETERSON_BASE_CMD = 70, + GATEPETERSON_END_CMD = (GATEPETERSON_BASE_CMD + \ + GATEPETERSON_CMD_NOS - 1), + + LISTMP_SHAREDMEMORY_BASE_CMD = 90, + LISTMP_SHAREDMEMORY_END_CMD = (LISTMP_SHAREDMEMORY_BASE_CMD + \ + LISTMP_SHAREDMEMORY_CMD_NOS - 1), + + MESSAGEQ_BASE_CMD = 110, + MESSAGEQ_END_CMD = (MESSAGEQ_BASE_CMD + \ + MESSAGEQ_CMD_NOS - 1), + + MESSAGEQ_TRANSPORTSHM_BASE_CMD = 130, + MESSAGEQ_TRANSPORTSHM_END_CMD = (MESSAGEQ_TRANSPORTSHM_BASE_CMD + \ + MESSAGEQ_TRANSPORTSHM_CMD_NOS - 1), + + NAMESERVERREMOTENOTIFY_BASE_CMD = 160, + NAMESERVERREMOTENOTIFY_END_CMD = (NAMESERVERREMOTENOTIFY_BASE_CMD + \ + NAMESERVERREMOTENOTIFY_CMD_NOS - 1), + + SYSMGR_BASE_CMD = 170, + SYSMGR_END_CMD = (SYSMGR_BASE_CMD + \ + SYSMGR_CMD_NOS - 1), + + SYSMEMMGR_BASE_CMD = 180, + SYSMEMMGR_END_CMD = (SYSMEMMGR_BASE_CMD + \ + SYSMEMMGR_CMD_NOS - 1) +}; + +int ipc_ioc_router(u32 cmd, ulong arg); + +#endif /* _IPC_IOCTL_H */ diff --git a/arch/arm/plat-omap/include/syslink/listmp.h b/arch/arm/plat-omap/include/syslink/listmp.h new file mode 100644 index 000000000000..536f1804da91 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/listmp.h @@ -0,0 +1,267 @@ +/* + * listmp.h + * + * The listmp module defines the shared memory doubly linked list. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef _LISTMP_H_ +#define _LISTMP_H_ + +/* Standard headers */ +#include <linux/types.h> + +/* Utilities headers */ +#include <linux/list.h> +/*#include <heap.h>*/ + +/* ============================================================================= + * All success and failure codes for the module + * ============================================================================= + */ +/*! + * @def LISTMP_MODULEID + * @brief Unique module ID. + */ +#define LISTMP_MODULEID (0xa413) + +/*! + * @def LISTMP_ERRORCODEBASE + * @brief Error code base for ListMP. + */ +#define LISTMP_ERRORCODEBASE (LISTMP_MODULEID << 12) + +/*! + * @def LISTMP_MAKE_FAILURE + * @brief Macro to make error code. + */ +#define LISTMP_MAKE_FAILURE(x) ((int)(0x80000000 \ + + (LISTMP_ERRORCODEBASE + (x)))) + +/*! + * @def LISTMP_MAKE_SUCCESS + * @brief Macro to make success code. + */ +#define LISTMP_MAKE_SUCCESS(x) (LISTMP_ERRORCODEBASE + (x)) + +/*! + * @def LISTMP_E_INVALIDARG + * @brief Argument passed to a function is invalid. + */ +#define LISTMP_E_INVALIDARG LISTMP_MAKE_FAILURE(1) + +/*! + * @def LISTMP_E_MEMORY + * @brief Memory allocation failed. + */ +#define LISTMP_E_MEMORY LISTMP_MAKE_FAILURE(2) + +/*! + * @def LISTMP_E_BUSY + * @brief The name is already registered or not. + */ +#define LISTMP_E_BUSY LISTMP_MAKE_FAILURE(3) + +/*! + * @def LISTMP_E_FAIL + * @brief Generic failure. + */ +#define LISTMP_E_FAIL LISTMP_MAKE_FAILURE(4) + +/*! + * @def LISTMP_E_NOTFOUND + * @brief Name not found in the nameserver. + */ +#define LISTMP_E_NOTFOUND LISTMP_MAKE_FAILURE(5) + +/*! + * @def LISTMP_E_INVALIDSTATE + * @brief Module is not initialized. + */ +#define LISTMP_E_INVALIDSTATE LISTMP_MAKE_FAILURE(6) + +/*! + * @def LISTMP_E_OSFAILURE + * @brief Failure in OS call. + */ +#define LISTMP_E_OSFAILURE LISTMP_MAKE_FAILURE(7) + +/*! + * @def LISTMP_SUCCESS + * @brief Operation successful. + */ +#define LISTMP_SUCCESS LISTMP_MAKE_SUCCESS(0) + +/*! + * @def LISTMP_S_ALREADYSETUP + * @brief The LISTMP module has already been setup in this process. + */ +#define LISTMP_S_ALREADYSETUP LISTMP_MAKE_SUCCESS(1) + +/* ============================================================================= + * Macros and types + * ============================================================================= + */ +/*! + * @brief Enum defining types of list for the ListMP module. + */ +enum listmp_type { + listmp_type_SHARED = 0, + /*!< List in shared memory */ + listmp_type_FAST = 1 + /*!< Hardware Queue */ +}; + +/*! + * @brief Structure defining config parameters for the ListMP module. + */ +struct listmp_config { + u32 max_name_len; + /*!< Maximum length of name */ + bool use_name_server; + /*!< Whether to have this module use the NameServer or not. If the + * NameServer is not needed, set this configuration parameter to false. + * This informs ListMPSharedMemory not to pull in the NameServer module + * In this case, all names passed into create and open are ignored. + */ +}; + +/*! + * @brief Structure defining list element for the ListMP. + */ +struct listmp_elem { + volatile struct listmp_elem *next; + volatile struct listmp_elem *prev; +}; + +/*! + * @brief Structure defining config parameters for the ListMP instances. + */ +struct listmp_params { + bool cache_flag; + /*!< Set to 1 by the open() call. No one else should touch this! */ + struct mutex *gate; + /*!< Lock used for critical region management of the list */ + void *shared_addr; + /*!< shared memory address */ + u32 shared_addr_size; + /*!< shared memory size */ + char *name; + /*!< Name of the object */ + int resource_id; + /*!< + * resourceId Specifies the resource id number. + * Parameter is used only when type is set to Fast List + */ + enum listmp_type list_type ; + /*!< Type of list */ +}; + + +/* ============================================================================= + * Forward declarations + * ============================================================================= + */ +/*! + * @brief Structure defining config parameters for the ListMPSharedMemory. + */ +struct listmp_object { + bool (*empty)(void *listmp_handle); + /* Function to check if list is empty */ + void *(*get_head)(void *listmp_handle); + /* Function to get head element from list */ + void *(*get_tail)(void *listmp_handle); + /* Function to get tail element from list */ + int (*put_head)(void *listmp_handle, struct listmp_elem *elem); + /* Function to put head element into list */ + int (*put_tail)(void *listmp_handle, struct listmp_elem *elem); + /* Function to put tail element into list */ + int (*insert)(void *listmp_handle, struct listmp_elem *elem, + struct listmp_elem *curElem); + /* Function to insert element into list */ + int (*remove)(void *listmp_handle, struct listmp_elem *elem); + /* Function to remove element from list */ + void *(*next)(void *listmp_handle, struct listmp_elem *elem); + /* Function to traverse to next element in list */ + void *(*prev)(void *listmp_handle, struct listmp_elem *elem); + /* Function to traverse to prev element in list */ + void *obj; + /*!< Handle to ListMP */ + enum listmp_type list_type; + /* Type of list */ +}; + +/* + * Function initializes listmp parameters + */ +void listmp_params_init(void *listmp_handle, + struct listmp_params *params); + +/* + * Function to get shared memory requirement for the module + */ +int listmp_shared_memreq(struct listmp_params *params); + +/* ============================================================================= + * Functions to create instance of a list + * ============================================================================= + */ +/* Function to create an instance of ListMP */ +void *listmp_create(struct listmp_params *params); + +/* Function to delete an instance of ListMP */ +int listmp_delete(void **listmp_handle_ptr); + +/* ============================================================================= + * Functions to open/close handle to list instance + * ============================================================================= + */ +/* Function to open a previously created instance */ +int listmp_open(void **listmp_handle_ptr, struct listmp_params *params); + +/* Function to close a previously opened instance */ +int listmp_close(void *listmp_handle); + +/* ============================================================================= + * Function pointer types for list operations + * ============================================================================= + */ +/* Function to check if list is empty */ +bool listmp_empty(void *listmp_handle); + +/* Function to get head element from list */ +void *listmp_get_head(void *listmp_handle); + +/* Function to get tail element from list */ +void *listmp_get_tail(void *listmp_handle); + +/* Function to put head element into list */ +int listmp_put_head(void *listmp_handle, struct listmp_elem *elem); + +/* Function to put tail element into list */ +int listmp_put_tail(void *listmp_handle, struct listmp_elem *elem); + +/* Function to insert element into list */ +int listmp_insert(void *listmp_handle, struct listmp_elem *elem, + struct listmp_elem *curElem); + +/* Function to traverse to remove element from list */ +int listmp_remove(void *listmp_handle, struct listmp_elem *elem); + +/* Function to traverse to next element in list */ +void *listmp_next(void *listmp_handle, struct listmp_elem *elem); + +/* Function to traverse to prev element in list */ +void *listmp_prev(void *listmp_handle, struct listmp_elem *elem); + +#endif /* _LISTMP_H_ */ diff --git a/arch/arm/plat-omap/include/syslink/listmp_sharedmemory.h b/arch/arm/plat-omap/include/syslink/listmp_sharedmemory.h new file mode 100644 index 000000000000..c6fd1629728e --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/listmp_sharedmemory.h @@ -0,0 +1,289 @@ +/* + * listmp_sharedmemory.c + * + * The listmp_sharedmemory is a double linked-list based module designed to be + * used in a multi-processor environment. It is designed to provide a means + * of communication between different processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef _LISTMP_SHAREDMEMORY_H_ +#define _LISTMP_SHAREDMEMORY_H_ + +/* Standard headers */ +#include <linux/types.h> + +/* Utilities headers */ + +/* Other headers */ +#include <listmp.h> + +/* ============================================================================= + * All success and failure codes for the module + * ============================================================================= + */ +/*! + * @def LISTMPSHAREDMEMORY_MODULEID + * @brief Unique module ID. + */ +#define LISTMPSHAREDMEMORY_MODULEID (0xDD3C) + +/*! + * @def LISTMPSHAREDMEMORY_ERRORCODEBASE + * @brief Error code base for ListMPSharedMemory. + */ +#define LISTMPSHAREDMEMORY_ERRORCODEBASE \ + (LISTMPSHAREDMEMORY_MODULEID << 12) + +/*! + * @def LISTMPSHAREDMEMORY_MAKE_FAILURE + * @brief Macro to make error code. + */ +#define LISTMPSHAREDMEMORY_MAKE_FAILURE(x) \ + ((int) (0x80000000 \ + + (LISTMPSHAREDMEMORY_ERRORCODEBASE \ + + (x)))) + +/*! + * @def LISTMPSHAREDMEMORY_MAKE_SUCCESS + * @brief Macro to make success code. + */ +#define LISTMPSHAREDMEMORY_MAKE_SUCCESS(x) \ + (LISTMPSHAREDMEMORY_ERRORCODEBASE + (x)) + +/*! + * @def LISTMPSHAREDMEMORY_E_INVALIDARG + * @brief Argument passed to a function is invalid. + */ +#define LISTMPSHAREDMEMORY_E_INVALIDARG \ + LISTMPSHAREDMEMORY_MAKE_FAILURE(1) + +/*! + * @def LISTMPSHAREDMEMORY_E_MEMORY + * @brief Memory allocation failed. + */ +#define LISTMPSHAREDMEMORY_E_MEMORY \ + LISTMPSHAREDMEMORY_MAKE_FAILURE(2) + +/*! + * @def LISTMPSHAREDMEMORY_E_FAIL + * @brief Generic failure. + */ +#define LISTMPSHAREDMEMORY_E_FAIL \ + LISTMPSHAREDMEMORY_MAKE_FAILURE(3) + +/*! + * @def LISTMPSHAREDMEMORY_E_INVALIDSTATE + * @brief Module is not initialized. + */ +#define LISTMPSHAREDMEMORY_E_INVALIDSTATE \ + LISTMPSHAREDMEMORY_MAKE_FAILURE(4) + +/*! + * @def LISTMPSHAREDMEMORY_E_OSFAILURE + * @brief Failure in OS call. + */ +#define LISTMPSHAREDMEMORY_E_OSFAILURE \ + LISTMPSHAREDMEMORY_MAKE_FAILURE(5) + +/*! + * @def LISTMPSHAREDMEMORY_E_NOTONWER + * @brief Instance is not created on this processor. + */ +#define LISTMPSHAREDMEMORY_E_NOTOWNER \ + LISTMPSHAREDMEMORY_MAKE_FAILURE(6) + +/*! + * @def LISTMPSHAREDMEMORY_E_REMOTEACTIVE + * @brief Remote opener of the instance has not closed the instance. + */ +#define LISTMPSHAREDMEMORY_E_REMOTEACTIVE \ + LISTMPSHAREDMEMORY_MAKE_FAILURE(7) + +/*! + * @def LISTMPSHAREDMEMORY_E_INUSE + * @brief Indicates that the instance is in use.. + */ +#define LISTMPSHAREDMEMORY_E_INUSE \ + LISTMPSHAREDMEMORY_MAKE_FAILURE(8) + +/*! + * @def LISTMPSHAREDMEMORY_E_NOTFOUND + * @brief name not found in the nameserver. + */ +#define LISTMPSHAREDMEMORY_E_NOTFOUND \ + LISTMPSHAREDMEMORY_MAKE_FAILURE(9) + +/*! + * @def LISTMPSHAREDMEMORY_E_NOTCREATED + * @brief Instance is not created yet + */ +#define LISTMPSHAREDMEMORY_E_NOTCREATED \ + LISTMPSHAREDMEMORY_MAKE_FAILURE(10) + +/*! + * @def LISTMPSHAREDMEMORY_E_VERSION + * @brief Version mismatch error. + */ +#define LISTMPSHAREDMEMORY_E_VERSION \ + LISTMPSHAREDMEMORY_MAKE_FAILURE(11) + +/*! + * @def LISTMPSHAREDMEMORY_E_BUSY + * @brief the name is already registered or not. + */ +#define LISTMPSHAREDMEMORY_E_BUSY \ + LISTMPSHAREDMEMORY_MAKE_FAILURE(12) + + +/*! + * @def LISTMPSHAREDMEMORY_SUCCESS + * @brief Operation successful. + */ +#define LISTMPSHAREDMEMORY_SUCCESS \ + LISTMPSHAREDMEMORY_MAKE_SUCCESS(0) + +/*! + * @def LISTMPSHAREDMEMORY_S_ALREADYSETUP + * @brief The LISTMPSHAREDMEMORY module has already been setup in this + * process. + */ +#define LISTMPSHAREDMEMORY_S_ALREADYSETUP \ + LISTMPSHAREDMEMORY_MAKE_SUCCESS(1) + +/*! + * @def listmp_sharedmemory_CREATED + * @brief Creation of list succesful. +*/ +#define LISTMP_SHAREDMEMORY_CREATED (0x12181964) + +/*! + * @def LISTMP_SHAREDMEMORY_VERSION + * @brief Version. + */ +#define LISTMP_SHAREDMEMORY_VERSION (1) + +/* ============================================================================= + * Structure definitions + * ============================================================================= + */ +/*! + * @brief Structure defining config parameters for the ListMP instances. + */ +#define listmp_sharedmemory_params struct listmp_params + + +/*! @brief Forward declaration of structure defining object for the + * ListMPSharedMemory. + */ +/*! + * @brief Object for the ListMPSharedMemory Handle + */ +#define listmp_sharedmemory_object struct listmp_object + +/*! + * @brief Handle for the ListMPSharedMemory + */ +#define listmp_sharedmemory_handle void * + +/* ============================================================================= + * Functions to create the module + * ============================================================================= + */ +/* Function to get configuration parameters to setup + * the ListMPSharedMemory module. + */ +int listmp_sharedmemory_get_config(struct listmp_config *cfgParams); + +/* Function to setup the ListMPSharedMemory module. */ +int listmp_sharedmemory_setup(struct listmp_config *config) ; + +/* Function to destroy the ListMPSharedMemory module. */ +int listmp_sharedmemory_destroy(void); + +/* ============================================================================= + * Functions to create instance of a list + * ============================================================================= + */ +/* Function to create an instance of ListMP */ +listmp_sharedmemory_handle listmp_sharedmemory_create + (listmp_sharedmemory_params *params); + +/* Function to delete an instance of ListMP */ +int listmp_sharedmemory_delete(listmp_sharedmemory_handle *listMPHandlePtr); + +/* ============================================================================= + * Functions to open/close handle to list instance + * ============================================================================= + */ +/* + * Initialize this config-params structure with supplier-specified + * defaults before instance creation. + */ +void listmp_sharedmemory_params_init(listmp_sharedmemory_handle handle, + listmp_sharedmemory_params *params); + +/* Function to open a previously created instance */ +int listmp_sharedmemory_open(listmp_sharedmemory_handle *listMpHandlePtr, + listmp_sharedmemory_params *params); + +/* Function to close a previously opened instance */ +int listmp_sharedmemory_close(listmp_sharedmemory_handle listMPHandle); + +/* ============================================================================= + * Functions for list operations + * ============================================================================= + */ +/* Function to check if list is empty */ +bool listmp_sharedmemory_empty(listmp_sharedmemory_handle listMPHandle); + +/* Function to get head element from list */ +void *listmp_sharedmemory_get_head(listmp_sharedmemory_handle listMPHandle); + +/* Function to get tail element from list */ +void *listmp_sharedmemory_get_tail(listmp_sharedmemory_handle listMPHandle); + +/* Function to put head element into list */ +int listmp_sharedmemory_put_head(listmp_sharedmemory_handle listMPHandle, + struct listmp_elem *elem); + +/* Function to put tail element into list */ +int listmp_sharedmemory_put_tail(listmp_sharedmemory_handle listMPHandle, + struct listmp_elem *elem); + +/* Function to insert element into list */ +int listmp_sharedmemory_insert(listmp_sharedmemory_handle listMPHandle, + struct listmp_elem *elem, + struct listmp_elem *curElem); + +/* Function to traverse to remove element from list */ +int listmp_sharedmemory_remove(listmp_sharedmemory_handle listMPHandle, + struct listmp_elem *elem); + +/* Function to traverse to next element in list */ +void *listmp_sharedmemory_next(listmp_sharedmemory_handle listMPHandle, + struct listmp_elem *elem); + +/* Function to traverse to prev element in list */ +void *listmp_sharedmemory_prev(listmp_sharedmemory_handle listMPHandle, + struct listmp_elem *elem); + +/* ============================================================================= + * Functions for shared memory requirements + * ============================================================================= + */ +/* Amount of shared memory required for creation of each instance. */ +int listmp_sharedmemory_shared_memreq( + listmp_sharedmemory_params *params); + +#endif /* _LISTMP_SHAREDMEMORY_H_ */ diff --git a/arch/arm/plat-omap/include/syslink/listmp_sharedmemory_ioctl.h b/arch/arm/plat-omap/include/syslink/listmp_sharedmemory_ioctl.h new file mode 100644 index 000000000000..42fc4d6edd24 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/listmp_sharedmemory_ioctl.h @@ -0,0 +1,258 @@ +/* + * listmp_sharedmemory_ioctl.h + * + * Definitions of listmp_sharedmemory driver types and structures. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef _LISTMP_SHAREDMEMORY_IOCTL_H_ +#define _LISTMP_SHAREDMEMORY_IOCTL_H_ + +/* Standard headers */ +#include <linux/types.h> + +/* Syslink headers */ +#include <ipc_ioctl.h> +#include <listmp_sharedmemory.h> +#include <sharedregion.h> + +/* ============================================================================= + * Macros and types + * ============================================================================= + */ +/* Base command ID for listmp_sharedmemory */ +#define LISTMP_SHAREDMEMORY_IOC_MAGIC IPC_IOC_MAGIC +enum listmp_sharedmemory_drv_cmd { + LISTMP_SHAREDMEMORY_GETCONFIG = LISTMP_SHAREDMEMORY_BASE_CMD, + LISTMP_SHAREDMEMORY_SETUP, + LISTMP_SHAREDMEMORY_DESTROY, + LISTMP_SHAREDMEMORY_PARAMS_INIT, + LISTMP_SHAREDMEMORY_CREATE, + LISTMP_SHAREDMEMORY_DELETE, + LISTMP_SHAREDMEMORY_OPEN, + LISTMP_SHAREDMEMORY_CLOSE, + LISTMP_SHAREDMEMORY_ISEMPTY, + LISTMP_SHAREDMEMORY_GETHEAD, + LISTMP_SHAREDMEMORY_GETTAIL, + LISTMP_SHAREDMEMORY_PUTHEAD, + LISTMP_SHAREDMEMORY_PUTTAIL, + LISTMP_SHAREDMEMORY_INSERT, + LISTMP_SHAREDMEMORY_REMOVE, + LISTMP_SHAREDMEMORY_NEXT, + LISTMP_SHAREDMEMORY_PREV, + LISTMP_SHAREDMEMORY_SHAREDMEMREQ +}; + +/* ---------------------------------------------------------------------------- + * IOCTL command IDs for listmp_sharedmemory + * ---------------------------------------------------------------------------- + */ +/* Command for listmp_sharedmemory_get_config */ +#define CMD_LISTMP_SHAREDMEMORY_GETCONFIG \ + _IOWR(LISTMP_SHAREDMEMORY_IOC_MAGIC, LISTMP_SHAREDMEMORY_GETCONFIG, \ + struct listmp_sharedmemory_cmd_args) + +/* Command for listmp_sharedmemory_setup */ +#define CMD_LISTMP_SHAREDMEMORY_SETUP \ + _IOWR(LISTMP_SHAREDMEMORY_IOC_MAGIC, LISTMP_SHAREDMEMORY_SETUP, \ + struct listmp_sharedmemory_cmd_args) + +/* Command for listmp_sharedmemory_destroy */ +#define CMD_LISTMP_SHAREDMEMORY_DESTROY \ + _IOWR(LISTMP_SHAREDMEMORY_IOC_MAGIC, LISTMP_SHAREDMEMORY_DESTROY, \ + struct listmp_sharedmemory_cmd_args) + +/* Command for listmp_sharedmemory_params_init */ +#define CMD_LISTMP_SHAREDMEMORY_PARAMS_INIT \ + _IOWR(LISTMP_SHAREDMEMORY_IOC_MAGIC, LISTMP_SHAREDMEMORY_PARAMS_INIT, \ + struct listmp_sharedmemory_cmd_args) + +/* Command for listmp_sharedmemory_create */ +#define CMD_LISTMP_SHAREDMEMORY_CREATE \ + _IOWR(LISTMP_SHAREDMEMORY_IOC_MAGIC, LISTMP_SHAREDMEMORY_CREATE, \ + struct listmp_sharedmemory_cmd_args) + +/* Command for listmp_sharedmemory_delete */ +#define CMD_LISTMP_SHAREDMEMORY_DELETE \ + _IOWR(LISTMP_SHAREDMEMORY_IOC_MAGIC, LISTMP_SHAREDMEMORY_DELETE, \ + struct listmp_sharedmemory_cmd_args) + +/* Command for listmp_sharedmemory_open */ +#define CMD_LISTMP_SHAREDMEMORY_OPEN \ + _IOWR(LISTMP_SHAREDMEMORY_IOC_MAGIC, LISTMP_SHAREDMEMORY_OPEN, \ + struct listmp_sharedmemory_cmd_args) + +/* Command for listmp_sharedmemory_close */ +#define CMD_LISTMP_SHAREDMEMORY_CLOSE \ + _IOWR(LISTMP_SHAREDMEMORY_IOC_MAGIC, LISTMP_SHAREDMEMORY_CLOSE, \ + struct listmp_sharedmemory_cmd_args) + +/* Command for listmp_sharedmemory_is_empty */ +#define CMD_LISTMP_SHAREDMEMORY_ISEMPTY \ + _IOWR(LISTMP_SHAREDMEMORY_IOC_MAGIC, LISTMP_SHAREDMEMORY_ISEMPTY, \ + struct listmp_sharedmemory_cmd_args) + +/* Command for listmp_sharedmemory_get_head */ +#define CMD_LISTMP_SHAREDMEMORY_GETHEAD \ + _IOWR(LISTMP_SHAREDMEMORY_IOC_MAGIC, LISTMP_SHAREDMEMORY_GETHEAD, \ + struct listmp_sharedmemory_cmd_args) + +/* Command for listmp_sharedmemory_get_tail */ +#define CMD_LISTMP_SHAREDMEMORY_GETTAIL \ + _IOWR(LISTMP_SHAREDMEMORY_IOC_MAGIC, LISTMP_SHAREDMEMORY_GETTAIL, \ + struct listmp_sharedmemory_cmd_args) + +/* Command for listmp_sharedmemory_put_head */ +#define CMD_LISTMP_SHAREDMEMORY_PUTHEAD \ + _IOWR(LISTMP_SHAREDMEMORY_IOC_MAGIC, LISTMP_SHAREDMEMORY_PUTHEAD, \ + struct listmp_sharedmemory_cmd_args) + +/* Command for listmp_sharedmemory_put_tail */ +#define CMD_LISTMP_SHAREDMEMORY_PUTTAIL \ + _IOWR(LISTMP_SHAREDMEMORY_IOC_MAGIC, LISTMP_SHAREDMEMORY_PUTTAIL, \ + struct listmp_sharedmemory_cmd_args) + +/* Command for listmp_sharedmemory_insert */ +#define CMD_LISTMP_SHAREDMEMORY_INSERT \ + _IOWR(LISTMP_SHAREDMEMORY_IOC_MAGIC, LISTMP_SHAREDMEMORY_INSERT, \ + struct listmp_sharedmemory_cmd_args) + +/* Command for listmp_sharedmemory_remove */ +#define CMD_LISTMP_SHAREDMEMORY_REMOVE \ + _IOWR(LISTMP_SHAREDMEMORY_IOC_MAGIC, LISTMP_SHAREDMEMORY_REMOVE, \ + struct listmp_sharedmemory_cmd_args) + +/* Command for listmp_sharedmemory_next */ +#define CMD_LISTMP_SHAREDMEMORY_NEXT \ + _IOWR(LISTMP_SHAREDMEMORY_IOC_MAGIC, LISTMP_SHAREDMEMORY_NEXT, \ + struct listmp_sharedmemory_cmd_args) + +/* Command for listmp_sharedmemory_prev */ +#define CMD_LISTMP_SHAREDMEMORY_PREV \ + _IOWR(LISTMP_SHAREDMEMORY_IOC_MAGIC, LISTMP_SHAREDMEMORY_PREV, \ + struct listmp_sharedmemory_cmd_args) + +/* Command for listmp_sharedmemory_shared_memreq */ +#define CMD_LISTMP_SHAREDMEMORY_SHAREDMEMREQ \ + _IOWR(LISTMP_SHAREDMEMORY_IOC_MAGIC, LISTMP_SHAREDMEMORY_SHAREDMEMREQ, \ + struct listmp_sharedmemory_cmd_args) + +/* Command arguments for listmp_sharedmemory */ +struct listmp_sharedmemory_cmd_args { + union { + struct { + void *listmp_handle; + struct listmp_params *params; + } params_init; + + struct { + struct listmp_config *config; + } get_config; + + struct { + struct listmp_config *config; + } setup; + + struct { + void *listmp_handle; + struct listmp_params *params; + u32 name_len; + u32 shared_addr_srptr; + void *knl_gate; + } create; + + struct { + void *listmp_handle; + } delete_listmp; + + struct { + void *listmp_handle; + struct listmp_params *params; + u32 name_len; + u32 shared_addr_srptr; + void *knl_gate; + } open; + + struct { + void *listmp_handle; + } close; + + struct { + void *listmp_handle; + bool is_empty; + } is_empty; + + struct { + void *listmp_handle; + u32 *elem_srptr ; + } get_head; + + struct { + void *listmp_handle; + u32 *elem_srptr ; + } get_tail; + + struct { + void *listmp_handle; + u32 *elem_srptr ; + } put_head; + + struct { + void *listmp_handle; + u32 *elem_srptr ; + } put_tail; + + struct { + void *listmp_handle; + u32 *new_elem_srptr; + u32 *cur_elem_srptr; + } insert; + + struct { + void *listmp_handle; + u32 *elem_srptr ; + } remove; + + struct { + void *listmp_handle; + u32 *elem_srptr ; + u32 *next_elem_srptr ; + } next; + + struct { + void *listmp_handle; + u32 *elem_srptr ; + u32 *prev_elem_srptr ; + } prev; + + struct { + void *listmp_handle; + struct listmp_params *params; + u32 bytes; + } shared_memreq; + } args; + + int api_status; +}; + +/* ---------------------------------------------------------------------------- + * IOCTL functions for listmp_sharedmemory module + * ---------------------------------------------------------------------------- + */ +/* + * ioctl interface function for listmp_sharedmemory + */ +int listmp_sharedmemory_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long args); + +#endif /* _LISTMP_SHAREDMEMORY_IOCTL_H_ */ diff --git a/arch/arm/plat-omap/include/syslink/messageq.h b/arch/arm/plat-omap/include/syslink/messageq.h new file mode 100644 index 000000000000..90ba6f070048 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/messageq.h @@ -0,0 +1,464 @@ +/* + * messageq.h + * + * The MessageQ module supports the structured sending and receiving of + * variable length messages. This module can be used for homogeneous or + * heterogeneous multi-processor messaging. + * + * Copyright (C) 2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef _MESSAGEQ_H_ +#define _MESSAGEQ_H_ + +/* Standard headers */ +#include <linux/types.h> + +/* Utilities headers */ +#include <linux/list.h> + +/* Syslink headers */ +#include <listmp.h> +#include <messageq_transportshm.h> + + +/*! + * @def MESSAGEQ_MODULEID + * @brief Unique module ID. + */ +#define MESSAGEQ_MODULEID (0xded2) + +/* ============================================================================= + * All success and failure codes for the module + * ============================================================================= + */ + +/*! + * @def MESSAGEQ_STATUSCODEBASE + * @brief Error code base for MessageQ. + */ +#define MESSAGEQ_STATUSCODEBASE (MESSAGEQ_MODULEID << 12) + +/*! + * @def MESSAGEQ_MAKE_FAILURE + * @brief Macro to make error code. + */ +#define MESSAGEQ_MAKE_FAILURE(x) ((int) (0x80000000 + \ + (MESSAGEQ_STATUSCODEBASE + \ + (x)))) + +/*! + * @def MESSAGEQ_MAKE_SUCCESS + * @brief Macro to make success code. + */ +#define MESSAGEQ_MAKE_SUCCESS(x) (MESSAGEQ_STATUSCODEBASE + (x)) + +/*! + * @def MESSAGEQ_E_INVALIDARG + * @brief Argument passed to a function is invalid. + */ +#define MESSAGEQ_E_INVALIDARG MESSAGEQ_MAKE_FAILURE(1) + +/*! + * @def MESSAGEQ_E_MEMORY + * @brief Memory allocation failed. + */ +#define MESSAGEQ_E_MEMORY MESSAGEQ_MAKE_FAILURE(2) + +/*! + * @def MESSAGEQ_E_BUSY + * @brief the name is already registered or not. + */ +#define MESSAGEQ_E_BUSY MESSAGEQ_MAKE_FAILURE(3) + +/*! + * @def MESSAGEQ_E_FAIL + * @brief Generic failure. + */ +#define MESSAGEQ_E_FAIL MESSAGEQ_MAKE_FAILURE(4) + +/*! + * @def MESSAGEQ_E_NOTFOUND + * @brief name not found in the nameserver. + */ +#define MESSAGEQ_E_NOTFOUND MESSAGEQ_MAKE_FAILURE(5) + +/*! + * @def MESSAGEQ_E_INVALIDSTATE + * @brief Module is not initialized. + */ +#define MESSAGEQ_E_INVALIDSTATE MESSAGEQ_MAKE_FAILURE(6) + +/*! + * @def MESSAGEQ_E_NOTONWER + * @brief Instance is not created on this processor. + */ +#define MESSAGEQ_E_NOTONWER MESSAGEQ_MAKE_FAILURE(7) + +/*! + * @def MESSAGEQ_E_REMOTEACTIVE + * @brief Remote opener of the instance has not closed the instance. + */ +#define MESSAGEQ_E_REMOTEACTIVE MESSAGEQ_MAKE_FAILURE(8) + +/*! + * @def MESSAGEQ_E_INUSE + * @brief Indicates that the instance is in use.. + */ +#define MESSAGEQ_E_INUSE MESSAGEQ_MAKE_FAILURE(9) + +/*! + * @def MESSAGEQ_E_INVALIDCONTEXT + * @brief Indicates that the api is called with wrong handle + */ +#define MESSAGEQ_E_INVALIDCONTEXT MESSAGEQ_MAKE_FAILURE(10) + +/*! + * @def MESSAGEQ_E_INVALIDMSG + * @brief Indicates that an invalid msg has been specified + * + */ +#define MESSAGEQ_E_INVALIDMSG MESSAGEQ_MAKE_FAILURE(11) + +/*! + * @def MESSAGEQ_E_INVALIDHEAPID + * @brief Indicates that an invalid heap has been specified + */ +#define MESSAGEQ_E_INVALIDHEAPID MESSAGEQ_MAKE_FAILURE(12) + +/*! + * @def MESSAGEQ_E_INVALIDPROCID + * @brief Indicates that an invalid proc id has been specified + */ +#define MESSAGEQ_E_INVALIDPROCID MESSAGEQ_MAKE_FAILURE(13) + +/*! + * @def MESSAGEQ_E_MAXREACHED + * @brief Indicates that all message queues are taken + */ +#define MESSAGEQ_E_MAXREACHED MESSAGEQ_MAKE_FAILURE(14) + +/*! + * @def MESSAGEQ_E_UNREGISTERHEAPID + * @brief Indicates that heap id has not been registered + */ +#define MESSAGEQ_E_UNREGISTERHEAPID MESSAGEQ_MAKE_FAILURE(15) + +/*! + * @def MESSAGEQ_E_CANNOTFREESTATICMSG + * @brief Indicates that static msg cannot be freed + */ +#define MESSAGEQ_E_CANNOTFREESTATICMSG MESSAGEQ_MAKE_FAILURE(16) + +/*! + * @def MESSAGEQ_E_HEAPIDINVALID + * @brief Indicates that the heap id is invalid + */ +#define MESSAGEQ_E_HEAPIDINVALID MESSAGEQ_MAKE_FAILURE(17) + +/*! + * @def MESSAGEQ_E_PROCIDINVALID + * @brief Indicates that the proc id is invalid + */ +#define MESSAGEQ_E_PROCIDINVALID MESSAGEQ_MAKE_FAILURE(18) + +/*! + * @def MESSAGEQ_E_OSFAILURE + * @brief Failure in OS call. + */ +#define MESSAGEQ_E_OSFAILURE MESSAGEQ_MAKE_FAILURE(19) + +/*! + * @def MESSAGEQ_E_ALREADYEXISTS + * @brief Specified entity already exists + */ +#define MESSAGEQ_E_ALREADYEXISTS MESSAGEQ_MAKE_FAILURE(20) + +/*! + * @def MESSAGEQ_E_TIMEOUT + * @brief Timeout while attempting to get a message + */ +#define MESSAGEQ_E_TIMEOUT MESSAGEQ_MAKE_FAILURE(21) + +/*! + * @def MESSAGEQ_SUCCESS + * @brief Operation successful. + */ +#define MESSAGEQ_SUCCESS MESSAGEQ_MAKE_SUCCESS(0) + +/*! + * @def MESSAGEQ_S_ALREADYSETUP + * @brief The MESSAGEQ module has already been setup in this process. + */ +#define MESSAGEQ_S_ALREADYSETUP MESSAGEQ_MAKE_SUCCESS(1) + + +/* ============================================================================= + * Macros and types + * ============================================================================= + */ +/*! + * @brief Mask to extract version setting + */ +#define MESSAGEQ_HEADERVERSION 0x2000u + +/*! + * @brief Mask to extract priority setting + */ +#define MESSAGEQ_PRIORITYMASK 0x3u + +/*! + * @brief Mask to extract priority setting + */ +#define MESSAGEQ_TRANSPORTPRIORITYMASK 0x01u + +/*! + * Mask to extract version setting + */ +#define MESSAGEQ_VERSIONMASK 0xE000; + +/*! + * Used as the timeout value to specify wait forever + */ +#define MESSAGEQ_FOREVER (~((u32) 0)) + +/*! + * Invalid message id + */ +#define MESSAGEQ_INVALIDMSGID 0xFFFF + +/*! + * Invalid message queue + */ +#define MESSAGEQ_INVALIDMESSAGEQ 0xFFFF + +/*! + * Indicates that if maximum number of message queues are already created, + * should allow growth to create additional Message Queue. + */ +#define MESSAGEQ_ALLOWGROWTH (~((u32) 0)) + +/*! + * Number of types of priority queues for each transport + */ +#define MESSAGEQ_NUM_PRIORITY_QUEUES 2 + + +/* ============================================================================= + * Structures & Enums + * ============================================================================= + */ +/*! + * Message priority + */ +enum messageq_priority { + MESSAGEQ_NORMALPRI = 0, + /*!< Normal priority message */ + MESSAGEQ_HIGHPRI = 1, + /*!< High priority message */ + MESSAGEQ_RESERVEDPRI = 2, + /*!< Reserved value for message priority */ + MESSAGEQ_URGENTPRI = 3 + /*!< Urgent priority message */ +}; + +/*! Structure which defines the first field in every message */ +struct msgheader { + u32 reserved0; + /*!< Reserved field */ + u32 reserved1; + /*!< Reserved field */ + u32 msg_size; + /*!< Size of the message (including header) */ + u16 flags; + /*!< Flags */ + u16 msg_id; + /*!< Maximum length for Message queue names */ + u16 dst_id; + /*!< Maximum length for Message queue names */ + u16 dst_proc; + /*!< Maximum length for Message queue names */ + u16 reply_id; + /*!< Maximum length for Message queue names */ + u16 reply_proc; + /*!< Maximum length for Message queue names */ + u16 src_proc; + /*!< Maximum length for Message queue names */ + u16 heap_id; + /*!< Maximum length for Message queue names */ + u32 reserved; + /*!< Reserved field */ +}; +/*! Structure which defines the first field in every message */ +#define messageq_msg struct msgheader * +/*typedef struct msgheader *messageq_msg;*/ + + +/*! + * @brief Structure defining config parameters for the MessageQ Buf module. + */ +struct messageq_config { + u16 num_heaps; + /*! + * Number of heapIds in the system + * + * This allows MessageQ to pre-allocate the heaps table. + * The heaps table is used when registering heaps. + * + * The default is 1 since generally all systems need at least + * one heap. + * + * There is no default heap, so unless the system is only using + * staticMsgInit, the application must register a heap. + */ + + u32 max_runtime_entries; + /*! + * Maximum number of MessageQs that can be dynamically created + */ + + struct mutex *name_table_gate; + /*! + * Gate used to make the name table thread safe. If NULL is passed, gate + * will be created internally. + */ + + u32 max_name_len; + /*! + * Maximum length for Message queue names + */ +}; + +struct messageq_params { + u32 reserved; + /*!< No parameters required currently. Reserved field. */ + u32 max_name_len; + /*!< Maximum length for Message queue names */ +}; + +/* ============================================================================= + * APIs + * ============================================================================= + */ +/* Functions to get the configuration for messageq setup */ +void messageq_get_config(struct messageq_config *cfg); + +/* Function to setup the MessageQ module. */ +int messageq_setup(const struct messageq_config *cfg); + +/* Function to destroy the MessageQ module. */ +int messageq_destroy(void); + +/* Initialize this config-params structure with supplier-specified + * defaults before instance creation. + */ +void messageq_params_init(void *messageq_handle, + struct messageq_params *params); + +/* Create a message queue */ +void *messageq_create(char *name, const struct messageq_params *params); + +/* Deletes a instance of MessageQ module. */ +int messageq_delete(void **messageq_handleptr); + +/* Allocates a message from the heap */ +messageq_msg messageq_alloc(u16 heapId, u32 size); + +/* Frees a message back to the heap */ +int messageq_free(messageq_msg msg); + +/* Open a message queue */ +int messageq_open(char *name, u32 *queue_id); + +/* Close an opened message queue handle */ +void messageq_close(u32 *queue_id); + +/* Initializes a message not obtained from MessageQ_alloc */ +void messageq_static_msg_init(messageq_msg msg, u32 size); + +/* Place a message onto a message queue */ +int messageq_put(u32 queueId, messageq_msg msg); + +/* Gets a message for a message queue and blocks if the queue is empty */ +int messageq_get(void *messageq_handle, messageq_msg *msg, + u32 timeout); + +/* Register a heap with MessageQ */ +int messageq_register_heap(void *heap_handle, u16 heap_id); + +/* Unregister a heap with MessageQ */ +int messageq_unregister_heap(u16 heapId); + +/* Returns the number of messages in a message queue */ +int messageq_count(void *messageq_handle); + +/* Set the destination queue of the message. */ +void messageq_set_reply_queue(void *messageq_handle, messageq_msg msg); + +/* Get the queue Id of the message. */ +u32 messageq_get_queue_id(void *messageq_handle); + +/* Get the proc Id of the message. */ +u16 messageq_get_proc_id(void *messageq_handle); + +/* + * Functions to set Message properties + */ +/*! + * @brief Returns the MessageQ_Queue handle of the destination + * message queue for the specified message. + */ +u32 messageq_get_dst_queue(messageq_msg msg); + +/*! + * @brief Returns the message ID of the specified message. + */ +u16 messageq_get_msg_id(messageq_msg msg); + +/*! + * @brief Returns the size of the specified message. + */ +u32 messageq_get_msg_size(messageq_msg msg); + +/*! + * @brief Gets the message priority of a message + */ +u32 messageq_get_msg_pri(messageq_msg msg); + +/*! + * @brief Returns the MessageQ_Queue handle of the destination + * message queue for the specified message. + */ +u32 messageq_get_reply_queue(messageq_msg msg); + +/*! + * @brief Sets the message ID in the specified message. + */ +void messageq_set_msg_id(messageq_msg msg, u16 msg_id); +/*! + * @brief Sets the message priority in the specified message. + */ +void messageq_set_msg_pri(messageq_msg msg, u32 priority); + +/* ============================================================================= + * APIs called internally by MessageQ transports + * ============================================================================= + */ +/* Register a transport with MessageQ */ +int messageq_register_transport(void *messageq_transportshm_handle, + u16 proc_id, u32 priority); + +/* Unregister a transport with MessageQ */ +int messageq_unregister_transport(u16 proc_id, u32 priority); + + +#endif /* _MESSAGEQ_H_ */ diff --git a/arch/arm/plat-omap/include/syslink/messageq_ioctl.h b/arch/arm/plat-omap/include/syslink/messageq_ioctl.h new file mode 100644 index 000000000000..2f8424c21d7e --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/messageq_ioctl.h @@ -0,0 +1,237 @@ +/* + * messageq_ioctl.h + * + * Definitions of messageq driver types and structures. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef _MESSAGEQ_IOCTL_H_ +#define _MESSAGEQ_IOCTL_H_ + +/* Standard headers */ +#include <linux/types.h> + +/* Syslink headers */ +#include <ipc_ioctl.h> +#include <messageq.h> +#include <heap.h> +#include <sharedregion.h> + +/* ============================================================================= + * Macros and types + * ============================================================================= + */ +#define MESSAGEQ_IOC_MAGIC IPC_IOC_MAGIC +enum messageq_drv_cmd { + MESSAGEQ_GETCONFIG = MESSAGEQ_BASE_CMD, + MESSAGEQ_SETUP, + MESSAGEQ_DESTROY, + MESSAGEQ_PARAMS_INIT, + MESSAGEQ_CREATE, + MESSAGEQ_DELETE, + MESSAGEQ_OPEN, + MESSAGEQ_CLOSE, + MESSAGEQ_COUNT, + MESSAGEQ_ALLOC, + MESSAGEQ_FREE, + MESSAGEQ_PUT, + MESSAGEQ_REGISTERHEAP, + MESSAGEQ_UNREGISTERHEAP, + MESSAGEQ_REGISTERTRANSPORT, + MESSAGEQ_UNREGISTERTRANSPORT, + MESSAGEQ_GET +}; + +/* ---------------------------------------------------------------------------- + * IOCTL command IDs for messageq + * ---------------------------------------------------------------------------- + */ +/* Base command ID for messageq */ +#define MESSAGEQ_BASE_CMD 0x0 + +/* Command for messageq_get_config */ +#define CMD_MESSAGEQ_GETCONFIG \ + _IOWR(MESSAGEQ_IOC_MAGIC, MESSAGEQ_GETCONFIG, \ + struct messageq_cmd_args) + +/* Command for messageq_setup */ +#define CMD_MESSAGEQ_SETUP \ + _IOWR(MESSAGEQ_IOC_MAGIC, MESSAGEQ_SETUP, \ + struct messageq_cmd_args) + +/* Command for messageq_destroy */ +#define CMD_MESSAGEQ_DESTROY \ + _IOWR(MESSAGEQ_IOC_MAGIC, MESSAGEQ_DESTROY, \ + struct messageq_cmd_args) + +/* Command for messageq_params_init */ +#define CMD_MESSAGEQ_PARAMS_INIT \ + _IOWR(MESSAGEQ_IOC_MAGIC, MESSAGEQ_PARAMS_INIT, \ + struct messageq_cmd_args) + +/* Command for messageq_create */ +#define CMD_MESSAGEQ_CREATE \ + _IOWR(MESSAGEQ_IOC_MAGIC, MESSAGEQ_CREATE, \ + struct messageq_cmd_args) + +/* Command for messageq_delete */ +#define CMD_MESSAGEQ_DELETE \ + _IOWR(MESSAGEQ_IOC_MAGIC, MESSAGEQ_DELETE, \ + struct messageq_cmd_args) + +/* Command for messageq_open */ +#define CMD_MESSAGEQ_OPEN \ + _IOWR(MESSAGEQ_IOC_MAGIC, MESSAGEQ_OPEN, \ + struct messageq_cmd_args) + +/* Command for messageq_close */ +#define CMD_MESSAGEQ_CLOSE \ + _IOWR(MESSAGEQ_IOC_MAGIC, MESSAGEQ_CLOSE, \ + struct messageq_cmd_args) + +/* Command for messageq_count */ +#define CMD_MESSAGEQ_COUNT \ + _IOWR(MESSAGEQ_IOC_MAGIC, MESSAGEQ_COUNT, \ + struct messageq_cmd_args) + +/* Command for messageq_alloc */ +#define CMD_MESSAGEQ_ALLOC \ + _IOWR(MESSAGEQ_IOC_MAGIC, MESSAGEQ_ALLOC, \ + struct messageq_cmd_args) + +/* Command for messageq_free */ +#define CMD_MESSAGEQ_FREE \ + _IOWR(MESSAGEQ_IOC_MAGIC, MESSAGEQ_FREE, \ + struct messageq_cmd_args) + +/* Command for messageq_put */ +#define CMD_MESSAGEQ_PUT \ + _IOWR(MESSAGEQ_IOC_MAGIC, MESSAGEQ_PUT, \ + struct messageq_cmd_args) + +/* Command for messageq_register_heap */ +#define CMD_MESSAGEQ_REGISTERHEAP \ + _IOWR(MESSAGEQ_IOC_MAGIC, MESSAGEQ_REGISTERHEAP, \ + struct messageq_cmd_args) + +/* Command for messageq_unregister_heap */ +#define CMD_MESSAGEQ_UNREGISTERHEAP \ + _IOWR(MESSAGEQ_IOC_MAGIC, MESSAGEQ_UNREGISTERHEAP, \ + struct messageq_cmd_args) + + +/* Command for messageq_register_transport */ +#define CMD_MESSAGEQ_REGISTERTRANSPORT \ + _IOWR(MESSAGEQ_IOC_MAGIC, MESSAGEQ_REGISTERTRANSPORT, \ + struct messageq_cmd_args) + + +/* Command for messageq_unregister_transport */ +#define CMD_MESSAGEQ_UNREGISTERTRANSPORT \ + _IOWR(MESSAGEQ_IOC_MAGIC, MESSAGEQ_UNREGISTERTRANSPORT, \ + struct messageq_cmd_args) + + +/* Command for messageq_get */ +#define CMD_MESSAGEQ_GET \ + _IOWR(MESSAGEQ_IOC_MAGIC, MESSAGEQ_GET, \ + struct messageq_cmd_args) + +/* Command arguments for messageq */ +struct messageq_cmd_args { + union { + struct { + void *messageq_handle; + struct messageq_params *params; + } params_init; + + struct { + struct messageq_config *config; + } get_config; + + struct { + struct messageq_config *config; + } setup; + + struct { + void *messageq_handle; + char *name; + struct messageq_params *params; + u32 name_len; + u32 queue_id; + } create; + + struct { + void *messageq_handle; + } delete_messageq; + + struct { + char *name; + u32 queue_id; + u32 name_len; + } open; + + struct { + u32 queue_id; + } close; + + struct { + void *messageq_handle; + u32 timeout; + u32 *msg_srptr; + } get; + + struct { + void *messageq_handle; + int count; + } count; + + struct { + u16 heap_id; + u32 size; + u32 *msg_srptr; + } alloc; + + struct { + u32 *msg_srptr; + } free; + + struct { + u32 queue_id; + u32 *msg_srptr; + } put; + + struct { + void *heap_handle; + u16 heap_id; + } register_heap; + + struct { + u16 heap_id; + } unregister_heap; + } args; + + int api_status; +}; + +/* ---------------------------------------------------------------------------- + * IOCTL functions for messageq module + * ---------------------------------------------------------------------------- + */ +/* + * ioctl interface function for messageq + */ +int messageq_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long args); + +#endif /* _MESSAGEQ_IOCTL_H_ */ diff --git a/arch/arm/plat-omap/include/syslink/messageq_transportshm.h b/arch/arm/plat-omap/include/syslink/messageq_transportshm.h new file mode 100644 index 000000000000..e2b55f6b0b4d --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/messageq_transportshm.h @@ -0,0 +1,283 @@ +/* + * messageq_transportshm.h + * + * MessageQ shared memory based physical transport for + * communication with the remote processor. + * + * This file contains the declarations of types and APIs as part + * of interface of the MessageQ shared memory transport. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef _MESSAGEQ_TRANSPORTSHM_H_ +#define _MESSAGEQ_TRANSPORTSHM_H_ + +/* Standard headers */ +#include <linux/types.h> + +/* Utilities headers */ +#include <linux/list.h> + +/* ============================================================================= + * All success and failure codes for the module + * ============================================================================= + */ +/*! + * @def MESSAGEQ_TRANSPORTSHM_MODULEID + * @brief Unique module ID. + */ +#define MESSAGEQ_TRANSPORTSHM_MODULEID (0x0a7a) + +/* ============================================================================= + * All success and failure codes for the module + * ============================================================================= + */ +/*! + * @def MESSAGEQ_TRANSPORTSHM_STATUSCODEBASE + * @brief Error code base for MessageQ. + */ +#define MESSAGEQ_TRANSPORTSHM_STATUSCODEBASE \ + (MESSAGEQ_TRANSPORTSHM_MODULEID << 12) + +/*! + * @def MESSAGEQ_TRANSPORTSHM_MAKE_FAILURE + * @brief Macro to make error code. + */ +#define MESSAGEQ_TRANSPORTSHM_MAKE_FAILURE(x) ((int) (0x80000000 \ + + (MESSAGEQ_TRANSPORTSHM_STATUSCODEBASE \ + + (x)))) + +/*! + * @def MESSAGEQ_TRANSPORTSHM_MAKE_SUCCESS + * @brief Macro to make success code. + */ +#define MESSAGEQ_TRANSPORTSHM_MAKE_SUCCESS(x) \ + (MESSAGEQ_TRANSPORTSHM_STATUSCODEBASE + (x)) + +/*! + * @def MESSAGEQ_TRANSPORTSHM_E_INVALIDARG + * @brief Argument passed to a function is invalid. + */ +#define MESSAGEQ_TRANSPORTSHM_E_INVALIDARG \ + MESSAGEQ_TRANSPORTSHM_MAKE_FAILURE(1) + +/*! + * @def MESSAGEQ_TRANSPORTSHM_E_INVALIDSIZE + * @brief Invalid shared address size + */ +#define MESSAGEQ_TRANSPORTSHM_E_INVALIDSIZE \ + MESSAGEQ_TRANSPORTSHM_MAKE_FAILURE(2) + +/*! + * @def MESSAGEQ_TRANSPORTSHM_E_INVALIDSTATE + * @brief Module is not initialized. + */ +#define MESSAGEQ_TRANSPORTSHM_E_INVALIDSTATE \ + MESSAGEQ_TRANSPORTSHM_MAKE_FAILURE(3) + +/*! + * @def MESSAGEQ_TRANSPORTSHM_E_BADVERSION + * @brief Versions don't match + */ +#define MESSAGEQ_TRANSPORTSHM_E_BADVERSION \ + MESSAGEQ_TRANSPORTSHM_MAKE_FAILURE(4) + +/*! + * @def MESSAGEQ_TRANSPORTSHM_E_FAIL + * @brief General Failure +*/ +#define MESSAGEQ_TRANSPORTSHM_E_FAIL \ + MESSAGEQ_TRANSPORTSHM_MAKE_FAILURE(5) + +/*! + * @def MESSAGEQ_TRANSPORTSHM_E_MEMORY + * @brief Memory allocation failed + */ +#define MESSAGEQ_TRANSPORTSHM_E_MEMORY \ + MESSAGEQ_TRANSPORTSHM_MAKE_FAILURE(6) + +/*! + * @def MESSAGEQ_TRANSPORTSHM_E_OSFAILURE + * @brief Failure in OS call. + */ +#define MESSAGEQ_TRANSPORTSHM_E_OSFAILURE \ + MESSAGEQ_TRANSPORTSHM_MAKE_FAILURE(7) + +/*! + * @def MESSAGEQ_TRANSPORTSHM_E_HANDLE + * @brief Invalid handle specified. + */ +#define MESSAGEQ_TRANSPORTSHM_E_HANDLE \ + MESSAGEQ_TRANSPORTSHM_MAKE_FAILURE(8) + +/*! + * @def MESSAGEQTRANSPORTSHM_E_NOTSUPPORTED + * @brief The specified operation is not supported. + */ +#define MESSAGEQTRANSPORTSHM_E_NOTSUPPORTED \ + MESSAGEQ_TRANSPORTSHM_MAKE_FAILURE(9) + +/*! + * @def MESSAGEQ_TRANSPORTSHM_SUCCESS + * @brief Operation successful. + */ +#define MESSAGEQ_TRANSPORTSHM_SUCCESS \ + MESSAGEQ_TRANSPORTSHM_MAKE_SUCCESS(0) + +/*! + * @def MESSAGETRANSPORTSHM_S_ALREADYSETUP + * @brief The MESSAGETRANSPORTSHM module has + * already been setup in this process. + */ +#define MESSAGEQ_TRANSPORTSHM_S_ALREADYSETUP \ + MESSAGEQ_TRANSPORTSHM_MAKE_SUCCESS(1) + + +/* ============================================================================= + * Structures & Enums + * ============================================================================= + */ + +/*! + * @brief Structure defining the reason for error function being called + */ +enum MessageQTransportShm_Reason { + MessageQTransportShm_Reason_FAILEDPUT, + /*!< Failed to send the message. */ + MessageQTransportShm_Reason_INTERNALERR, + /*!< An internal error occurred in the transport */ + MessageQTransportShm_Reason_PHYSICALERR, + /*!< An error occurred in the physical link in the transport */ + MessageQTransportShm_Reason_FAILEDALLOC + /*!< Failed to allocate a message. */ +}; + +/*! + * @brief transport error callback function. + * + * First parameter: Why the error function is being called. + * + * Second parameter: Handle of transport that had the error. NULL denotes + * that it is a system error, not a specific transport. + * + * Third parameter: Pointer to the message. This is only valid for + * #MessageQTransportShm_Reason_FAILEDPUT. + * + * Fourth parameter: Transport specific information. Refer to individual + * transports for more details. + */ + +/*! + * @brief Module configuration structure. + */ +struct messageq_transportshm_config { + void (*err_fxn)(enum MessageQTransportShm_Reason reason, + void *handle, + void *msg, + u32 info); + /*!< Asynchronous error function for the transport module */ +}; + +/*! + * @brief Structure defining config parameters for the MessageQ transport + * instances. + */ +struct messageq_transportshm_params { + u32 priority; + /*!< Priority of messages supported by this transport */ + void *gate; + /*!< Gate used for critical region management of the shared memory */ + void *shared_addr; + /*!< Address of the shared memory. The creator must supply the shared + * memory that this will use for maintain shared state information. + */ + u32 shared_addr_size; + /*!< Size of shared region provided. */ + u32 notify_event_no; + /*!< Notify event number to be used by the transport */ + void *notify_driver; + /*!< Notify driver to be used by the transport */ +}; + +/*! + * @brief Structure defining Transport status values + */ +enum messageq_transportshm_status { + messageq_transportshm_status_INIT, + /*!< MessageQ transport Shm instance has not not completed + * initialization. */ + messageq_transportshm_status_UP, + /*!< MessageQ transport Shm instance is up and functional. */ + messageq_transportshm_status_DOWN, + /*!< MessageQ transport Shm instance is down and not functional. */ + messageq_transportshm_status_RESETTING + /*!< MessageQ transport Shm instance was up at one point and is in + * process of resetting. + */ +}; + + +/* ============================================================================= + * APIs called by applications + * ============================================================================= + */ +/* Function to get the default configuration for the MessageQTransportShm + * module. */ +void messageq_transportshm_get_config(struct messageq_transportshm_config *cfg); + +/* Function to setup the MessageQTransportShm module. */ +int messageq_transportshm_setup(const struct messageq_transportshm_config *cfg); + +/* Function to destroy the MessageQTransportShm module. */ +int messageq_transportshm_destroy(void); + +/* Get the default parameters for the NotifyShmDriver. */ +void messageq_transportshm_params_init(void *mqtshm_handle, + struct messageq_transportshm_params *params); + +/* Create an instance of the MessageQTransportShm. */ +void *messageq_transportshm_create(u16 proc_id, + const struct messageq_transportshm_params *params); + +/* Delete an instance of the MessageQTransportShm. */ +int messageq_transportshm_delete(void **mqtshm_handleptr); + +/* Get the shared memory requirements for the MessageQTransportShm. */ +u32 messageq_transportshm_shared_mem_req(const + struct messageq_transportshm_params *params); + +/* Set the asynchronous error function for the transport module */ +void messageq_transportshm_set_err_fxn( + void (*err_fxn)( + enum MessageQTransportShm_Reason reason, + void *handle, + void *msg, + u32 info)); + + +/* ============================================================================= + * APIs called internally by MessageQ module. + * ============================================================================= + */ +/* Put msg to remote list */ +int messageq_transportshm_put(void *mqtshm_handle, void *msg); + +/* Control Function */ +int messageq_transportshm_control(void *mqtshm_handle, u32 cmd, + u32 *cmd_arg); + +/* Get current status of the MessageQTransportShm */ +enum messageq_transportshm_status messageq_transportshm_get_status( + void *mqtshm_handle); + +#endif /* _MESSAGEQ_TRANSPORTSHM_H_ */ diff --git a/arch/arm/plat-omap/include/syslink/messageq_transportshm_ioctl.h b/arch/arm/plat-omap/include/syslink/messageq_transportshm_ioctl.h new file mode 100644 index 000000000000..3790dc0d22e8 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/messageq_transportshm_ioctl.h @@ -0,0 +1,160 @@ +/* + * messageq_transportshm_ioctl.h + * + * Definitions of messageq_transportshm driver types and structures. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef _MESSAGEQ_TRANSPORTSHM_IOCTL_H_ +#define _MESSAGEQ_TRANSPORTSHM_IOCTL_H_ + +/* Standard headers */ +#include <linux/types.h> + +/* Syslink headers */ +#include <ipc_ioctl.h> +#include <messageq_transportshm.h> +#include <sharedregion.h> + + +/* ============================================================================= + * Macros and types + * ============================================================================= + */ +/* Base command ID for messageq_transportshm */ +#define MESSAGEQ_TRANSPORTSHM_IOC_MAGIC IPC_IOC_MAGIC +enum messageq_transportshm_drv_cmd { + MESSAGEQ_TRANSPORTSHM_GETCONFIG = MESSAGEQ_TRANSPORTSHM_BASE_CMD, + MESSAGEQ_TRANSPORTSHM_SETUP, + MESSAGEQ_TRANSPORTSHM_DESTROY, + MESSAGEQ_TRANSPORTSHM_PARAMS_INIT, + MESSAGEQ_TRANSPORTSHM_CREATE, + MESSAGEQ_TRANSPORTSHM_DELETE, + MESSAGEQ_TRANSPORTSHM_PUT, + MESSAGEQ_TRANSPORTSHM_SHAREDMEMREQ, + MESSAGEQ_TRANSPORTSHM_GETSTATUS +}; + +/* ---------------------------------------------------------------------------- + * IOCTL command IDs for messageq_transportshm + * ---------------------------------------------------------------------------- + */ +/* Base command ID for messageq_transportshm */ +#define MESSAGEQ_TRANSPORTSHM_BASE_CMD 0x0 + +/* Command for messageq_transportshm_get_config */ +#define CMD_MESSAGEQ_TRANSPORTSHM_GETCONFIG \ + _IOWR(MESSAGEQ_TRANSPORTSHM_IOC_MAGIC, \ + MESSAGEQ_TRANSPORTSHM_GETCONFIG, struct messageq_transportshm_cmd_args) + +/* Command for messageq_transportshm_setup */ +#define CMD_MESSAGEQ_TRANSPORTSHM_SETUP \ + _IOWR(MESSAGEQ_TRANSPORTSHM_IOC_MAGIC, MESSAGEQ_TRANSPORTSHM_SETUP, \ + struct messageq_transportshm_cmd_args) + +/* Command for messageq_transportshm_setup */ +#define CMD_MESSAGEQ_TRANSPORTSHM_DESTROY \ + _IOWR(MESSAGEQ_TRANSPORTSHM_IOC_MAGIC, MESSAGEQ_TRANSPORTSHM_DESTROY, \ + struct messageq_transportshm_cmd_args) + +/* Command for messageq_transportshm_destroy */ +#define CMD_MESSAGEQ_TRANSPORTSHM_PARAMS_INIT \ + _IOWR(MESSAGEQ_TRANSPORTSHM_IOC_MAGIC, \ + MESSAGEQ_TRANSPORTSHM_PARAMS_INIT, \ + struct messageq_transportshm_cmd_args) + +/* Command for messageq_transportshm_create */ +#define CMD_MESSAGEQ_TRANSPORTSHM_CREATE \ + _IOWR(MESSAGEQ_TRANSPORTSHM_IOC_MAGIC, MESSAGEQ_TRANSPORTSHM_CREATE, \ + struct messageq_transportshm_cmd_args) + +/* Command for messageq_transportshm_delete */ +#define CMD_MESSAGEQ_TRANSPORTSHM_DELETE \ + _IOWR(MESSAGEQ_TRANSPORTSHM_IOC_MAGIC, MESSAGEQ_TRANSPORTSHM_DELETE, \ + struct messageq_transportshm_cmd_args) + +/* Command for messageq_transportshm_put */ +#define CMD_MESSAGEQ_TRANSPORTSHM_PUT \ + _IOWR(MESSAGEQ_TRANSPORTSHM_IOC_MAGIC, MESSAGEQ_TRANSPORTSHM_PUT, \ + struct messageq_transportshm_cmd_args) + +/* Command for messageq_transportshm_shared_memreq */ +#define CMD_MESSAGEQ_TRANSPORTSHM_SHAREDMEMREQ \ + _IOWR(MESSAGEQ_TRANSPORTSHM_IOC_MAGIC, \ + MESSAGEQ_TRANSPORTSHM_SHAREDMEMREQ, \ + struct messageq_transportshm_cmd_args) + +/* Command for messageq_transportshm_get_status */ +#define CMD_MESSAGEQ_TRANSPORTSHM_GETSTATUS \ + _IOWR(MESSAGEQ_TRANSPORTSHM_IOC_MAGIC, \ + MESSAGEQ_TRANSPORTSHM_GETSTATUS, struct messageq_transportshm_cmd_args) + +/* Command arguments for messageq_transportshm */ +struct messageq_transportshm_cmd_args { + union { + struct { + struct messageq_transportshm_config *config; + } get_config; + + struct { + struct messageq_transportshm_config *config; + } setup; + + struct { + void *messageq_transportshm_handle; + struct messageq_transportshm_params *params; + } params_init; + + struct { + void *messageq_transportshm_handle; + u16 proc_id; + struct messageq_transportshm_params *params; + u32 shared_addr_srptr; + void *knl_lock_handle; + void *knl_notify_driver; + } create; + + struct { + void *messageq_transportshm_handle; + } delete_transport; + + struct { + void *messageq_transportshm_handle; + u32 *msg_srptr; + } put; + + struct { + void *messageq_transportshm_handle; + enum messageq_transportshm_status status; + } get_status; + + struct { + struct messageq_transportshm_params *params; + u32 bytes; + } shared_memreq; + } args; + + int api_status; +}; + +/* ---------------------------------------------------------------------------- + * IOCTL functions for messageq_transportshm module + * ---------------------------------------------------------------------------- + */ +/* + * ioctl interface function for messageq_transportshm + */ +int messageq_transportshm_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long args); + +#endif /* _MESSAGEQ_TRANSPORTSHM_IOCTL_H_ */ diff --git a/arch/arm/plat-omap/include/syslink/multiproc.h b/arch/arm/plat-omap/include/syslink/multiproc.h new file mode 100644 index 000000000000..6361bae80d19 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/multiproc.h @@ -0,0 +1,83 @@ +/* +* multiproc.h +* +* Many multi-processor modules have the concept of processor id. multiproc +* centeralizes the processor id management. +* +* Copyright (C) 2008-2009 Texas Instruments, Inc. +* +* This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR +* PURPOSE. +*/ + +#ifndef _MULTIPROC_H_ +#define _MULTIPROC_H_ + +#include <linux/types.h> + + +#define VOLATILE volatile + +/* + * Unique module ID + */ +#define MULTIPROC_MODULEID (u16)0xB522 + +/* Macro to define invalid processor id */ +#define MULTIPROC_INVALIDID ((u16)0xFFFF) + +/* + * Maximum number of processors in the system + * OMAP4 has 4 processors in single core. + */ +#define MULTIPROC_MAXPROCESSORS 4 + +/* + * Max name length for a processor name + */ +#define MULTIPROC_MAXNAMELENGTH 32 + +/* + * Configuration structure for multiproc module + */ +struct multiproc_config { + s32 max_processors; /* Max number of procs for particular system */ + char name_list[MULTIPROC_MAXPROCESSORS][MULTIPROC_MAXNAMELENGTH]; + /* Name List for processors in the system */ + u16 id; /* Local Proc ID. This needs to be set before calling any + other APIs */ +}; + +/* ============================================================================= + * APIs + * ============================================================================= + */ + +/* Function to get the default configuration for the multiproc module. */ +void multiproc_get_config(struct multiproc_config *cfg); + +/* Function to setup the multiproc Module */ +s32 multiproc_setup(struct multiproc_config *cfg); + +/* Function to destroy the multiproc module */ +s32 multiproc_destroy(void); + +/* Function to set local processor Id */ +int multiproc_set_local_id(u16 proc_id); + +/* Function to get processor id from processor name. */ +u16 multiproc_get_id(const char *proc_name); + +/* Function to get name from processor id. */ +char *multiproc_get_name(u16 proc_id); + +/* Function to get maximum proc Id in the system. */ +u16 multiproc_get_max_processors(void); + +#endif /* _MULTIPROC_H_ */ diff --git a/arch/arm/plat-omap/include/syslink/multiproc_ioctl.h b/arch/arm/plat-omap/include/syslink/multiproc_ioctl.h new file mode 100644 index 000000000000..0c9780136b02 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/multiproc_ioctl.h @@ -0,0 +1,94 @@ +/* +* multiproc_ioctl.h +* +* This provides the ioctl interface for multiproc module +* +* Copyright (C) 2008-2009 Texas Instruments, Inc. +* +* This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR +* PURPOSE. +*/ + +#ifndef _MULTIPROC_IOCTL_H_ +#define _MULTIPROC_IOCTL_H_ + +#include <linux/ioctl.h> +#include <linux/types.h> + +#include <ipc_ioctl.h> +#include <multiproc.h> + +enum CMD_MULTIPROC { + MULTIPROC_SETUP = MULTIPROC_BASE_CMD, + MULTIPROC_DESTROY, + MULTIPROC_GETCONFIG, + MULTIPROC_SETLOCALID +}; + +/* ---------------------------------------------------------------------------- + * IOCTL command IDs for MultiProc + * ---------------------------------------------------------------------------- + */ + +/* + * Command for multiproc_setup + */ +#define CMD_MULTIPROC_SETUP _IOWR(IPC_IOC_MAGIC, MULTIPROC_SETUP, \ + struct multiproc_cmd_args) + +/* + * Command for multiproc_destroy + */ +#define CMD_MULTIPROC_DESTROY _IOWR(IPC_IOC_MAGIC, MULTIPROC_DESTROY, \ + struct multiproc_cmd_args) + +/* + * Command for multiproc_get_config + */ +#define CMD_MULTIPROC_GETCONFIG _IOWR(IPC_IOC_MAGIC, MULTIPROC_GETCONFIG, \ + struct multiproc_cmd_args) + +/* + * Command for multiproc_set_local_id + */ +#define CMD_MULTIPROC_SETLOCALID _IOWR(IPC_IOC_MAGIC, MULTIPROC_SETLOCALID, \ + struct multiproc_cmd_args) + +/* + * Command arguments for multiproc + */ +union multiproc_arg { + struct { + struct multiproc_config *config; + } get_config; + + struct { + struct multiproc_config *config; + } setup; + + struct { + u16 id; + } set_local_id; +}; + +/* + * Command arguments for multiproc + */ +struct multiproc_cmd_args { + union multiproc_arg args; + s32 api_status; +}; + +/* + * This ioctl interface for multiproc module + */ +int multiproc_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long args); + +#endif /* _MULTIPROC_IOCTL_H_ */ diff --git a/arch/arm/plat-omap/include/syslink/nameserver.h b/arch/arm/plat-omap/include/syslink/nameserver.h new file mode 100644 index 000000000000..87265d856d9b --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/nameserver.h @@ -0,0 +1,131 @@ +/* + * nameserver.h + * + * The nameserver module manages local name/value pairs that + * enables an application and other modules to store and retrieve + * values based on a name. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef _NAMESERVER_H_ +#define _NAMESERVER_H_ + +#include <linux/types.h> +#include <linux/list.h> + +/* + * NAMESERVER_MODULEID + * Unique module ID + */ +#define NAMESERVER_MODULEID (0xF414) + +/* + * Instance config-params object. + */ +struct nameserver_params { + bool check_existing; /* Prevents duplicate entry add in to the table */ + void *gate_handle; /* Lock used for critical region of the table */ + u16 max_name_len; /* Length, in MAUs, of name field */ + u32 max_runtime_entries; + u32 max_value_len; /* Length, in MAUs, of the value field */ + void *table_heap; /* Table is placed into a section on dyn creates */ +}; + +/* + * Function to setup the nameserver module + */ +int nameserver_setup(void); + +/* + * Function to destroy the nameserver module + */ +int nameserver_destroy(void); + +/* + * Function to initialize the parameter structure + */ +int nameserver_params_init(struct nameserver_params *params); + +/* + * Function to initialize the parameter structure + */ +int nameserver_get_params(void *handle, + struct nameserver_params *params); + +/* + * Function to create a name server + */ +void *nameserver_create(const char *name, + const struct nameserver_params *params); + +/* + * Function to delete a name server + */ +int nameserver_delete(void **handle); + +/* + * Function to add a variable length value into the local table + */ +void *nameserver_add(void *handle, const char *name, + void *buffer, u32 length); + +/* + * Function to add a 32 bit value into the local table + */ +void *nameserver_add_uint32(void *handle, + const char *name, u32 value); + +/* + * Function to Retrieve the value portion of a name/value pair + */ +int nameserver_get(void *handle, const char *name, + void *buffer, u32 length, u16 procId[]); + +/* + * Function to get the value portion of a name/value pair from local table + */ +int nameserver_get_local(void *handle, const char *name, + void *buffer, u32 length); + +/* + * Function to removes a value/pair + */ +int nameserver_remove(void *handle, const char *name); + +/* + * Function to Remove an entry from the table + */ +int nameserver_remove_entry(void *nshandle, void *nsentry); + +/* + * Function to handle for a name + */ +void *nameserver_get_handle(const char *name); + +/* + * Function to Match the name + */ +int nameserver_match(void *handle, const char *name, u32 *value); + +/* + * Function to register a remote driver + */ +int nameserver_register_remote_driver(void *handle, u16 proc_id); + +/* + * Function to unregister a remote driver + */ +int nameserver_unregister_remote_driver(u16 proc_id); + +#endif /* _NAMESERVER_H_ */ + diff --git a/arch/arm/plat-omap/include/syslink/nameserver_ioctl.h b/arch/arm/plat-omap/include/syslink/nameserver_ioctl.h new file mode 100644 index 000000000000..defb71fae47b --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/nameserver_ioctl.h @@ -0,0 +1,230 @@ +/* +* nameserver_ioctl.h +* +* This provides the ioctl interface for nameserver module +* +* Copyright (C) 2008-2009 Texas Instruments, Inc. +* +* This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR +* PURPOSE. +*/ + +#ifndef _NAMESERVER_IOCTL_H_ +#define _NAMESERVER_IOCTL_H_ + +#include <linux/ioctl.h> +#include <linux/types.h> + +#include <ipc_ioctl.h> +#include <nameserver.h> + +enum CMD_NAMESERVER { + NAMESERVER_SETUP = NAMESERVER_BASE_CMD, + NAMESERVER_DESTROY, + NAMESERVER_PARAMS_INIT, + NAMESERVER_CREATE, + NAMESERVER_DELETE, + NAMESERVER_ADD, + NAMESERVER_ADDUINT32, + NAMESERVER_GET, + NAMESERVER_GETLOCAL, + NAMESERVER_MATCH, + NAMESERVER_REMOVE, + NAMESERVER_REMOVEENTRY, + NAMESERVER_GETHANDLE, +}; + +/* + * IOCTL command IDs for nameserver + * + */ +/* + * Command for nameserver_setup + */ +#define CMD_NAMESERVER_SETUP _IOWR(IPC_IOC_MAGIC, NAMESERVER_SETUP, \ + struct nameserver_cmd_args) + +/* + * Command for nameserver_destroy + */ +#define CMD_NAMESERVER_DESTROY _IOWR(IPC_IOC_MAGIC, \ + NAMESERVER_DESTROY, \ + struct nameserver_cmd_args) + +/* + * Command for nameserver_params_init + */ +#define CMD_NAMESERVER_PARAMS_INIT _IOWR(IPC_IOC_MAGIC, \ + NAMESERVER_PARAMS_INIT, \ + struct nameserver_cmd_args) + +/* + * Command for nameserver_create + */ +#define CMD_NAMESERVER_CREATE _IOWR(IPC_IOC_MAGIC, \ + NAMESERVER_CREATE, \ + struct nameserver_cmd_args) + +/* + * Command for nameserver_delete + */ +#define CMD_NAMESERVER_DELETE _IOWR(IPC_IOC_MAGIC, \ + NAMESERVER_DELETE, \ + struct nameserver_cmd_args) + +/* + * Command for nameserver_add + */ +#define CMD_NAMESERVER_ADD _IOWR(IPC_IOC_MAGIC, NAMESERVER_ADD, \ + struct nameserver_cmd_args) + +/* + * Command for nameserver_addu32 + */ +#define CMD_NAMESERVER_ADDUINT32 _IOWR(IPC_IOC_MAGIC, \ + NAMESERVER_ADDUINT32, \ + struct nameserver_cmd_args) +/* + * Command for nameserver_get + */ +#define CMD_NAMESERVER_GET _IOWR(IPC_IOC_MAGIC, NAMESERVER_GET, \ + struct nameserver_cmd_args) + +/* + * Command for nameserver_get_local + */ +#define CMD_NAMESERVER_GETLOCAL _IOWR(IPC_IOC_MAGIC, \ + NAMESERVER_GETLOCAL, \ + struct nameserver_cmd_args) + +/* + * Command for nameserver_match + */ +#define CMD_NAMESERVER_MATCH _IOWR(IPC_IOC_MAGIC, NAMESERVER_MATCH, \ + struct nameserver_cmd_args) + +/* + * Command for nameserver_remove + */ +#define CMD_NAMESERVER_REMOVE _IOWR(IPC_IOC_MAGIC, NAMESERVER_REMOVE,\ + struct nameserver_cmd_args) + +/* + * Command for nameserver_remove_entry + */ +#define CMD_NAMESERVER_REMOVEENTRY _IOWR(IPC_IOC_MAGIC, \ + NAMESERVER_REMOVEENTRY, \ + struct nameserver_cmd_args) + +/* + * Command for nameserver_get_handle + */ +#define CMD_NAMESERVER_GETHANDLE _IOWR(IPC_IOC_MAGIC, \ + NAMESERVER_GETHANDLE, \ + struct nameserver_cmd_args) + +/* + * Command arguments for nameserver + */ + union nameserver_arg { + struct { + struct nameserver_params *params; + } params_init; + + struct { + void *handle; + char *name; + u32 name_len; + struct nameserver_params *params; + } create; + + struct { + void *handle; + } delete_instance; + + struct { + void *handle; + char *name; + u32 name_len; + void *buf; + s32 len; + void *entry; + struct nameserver_entry *node; + } add; + + struct { + void *handle; + char *name; + u32 name_len; + u32 value; + void *entry; + } addu32; + + struct { + void *handle; + char *name; + u32 name_len; + void *buf; + u32 len; + u16 *proc_id; + u32 proc_len; + u32 count; + } get; + + struct { + void *handle; + char *name; + u32 name_len; + void *buf; + u32 len; + u32 count; + } get_local; + + struct { + void *handle; + char *name; + u32 name_len; + u32 *value; + u32 count; + } match; + + struct { + void *handle; + char *name; + u32 name_len; + } remove; + + struct { + void *handle; + void *entry; + } remove_entry; + + struct { + void *handle; + char *name; + u32 name_len; + } get_handle; +}; + +/* + * Command arguments for nameserver + */ +struct nameserver_cmd_args { + union nameserver_arg args; + s32 api_status; +}; + +/* + * This ioctl interface for nameserver module + */ +int nameserver_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long args); + +#endif /* _NAMESERVER_IOCTL_H_ */ + diff --git a/arch/arm/plat-omap/include/syslink/nameserver_remote.h b/arch/arm/plat-omap/include/syslink/nameserver_remote.h new file mode 100644 index 000000000000..dbdcedfc7ac3 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/nameserver_remote.h @@ -0,0 +1,39 @@ +/* + * nameserver_remote.h + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef _NAMESERVER_REMOTE_H_ +#define _NAMESERVER_REMOTE_H_ + +#include <linux/types.h> + +/* + * Structure defining object for the nameserver remote driver + */ +struct nameserver_remote_object { + int (*get)(const struct nameserver_remote_object *obj, + const char *instance_name, const char *name, + void *value, u32 value_len, void *reserved); + /* Function to get data from remote nameserver */ + void *obj; /* Implementation specific object */ +}; + +/* + * Function get data from remote name server + */ +int nameserver_remote_get(const struct nameserver_remote_object *handle, + const char *instance_name, const char *name, + void *value, u32 value_len); + +#endif /* _NAMESERVER_REMOTE_H_ */ diff --git a/arch/arm/plat-omap/include/syslink/nameserver_remotenotify.h b/arch/arm/plat-omap/include/syslink/nameserver_remotenotify.h new file mode 100644 index 000000000000..852da8effcc6 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/nameserver_remotenotify.h @@ -0,0 +1,100 @@ +/* + * nameserver_remotenotify.h + * + * The nameserver_remotenotify module provides functionality to get name + * value pair from a remote nameserver. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef _NAMESERVER_REMOTENOTIFY_H_ +#define _NAMESERVER_REMOTENOTIFY_H_ + +#include <linux/types.h> + +/* + * NAMESERVERREMOTENOTIFY_MODULEID + * Unique module ID + */ +#define NAMESERVERREMOTENOTIFY_MODULEID (0x08FD) + +/* + * Module configuration structure + */ +struct nameserver_remotenotify_config { + u32 reserved; + /* Reserved value (not currently used) */ +}; + +/* + * Module configuration structure + */ +struct nameserver_remotenotify_params { + u32 notify_event_no; /* Notify event number */ + void *notify_driver; /* Notify Driver handle */ + void *shared_addr; /* Address of the shared memory */ + u32 shared_addr_size; /* Size of the shared memory */ + void *gate; /* Handle to the gate used for protecting + nameserver add and delete */ +}; + +/* + * Function to get the default configuration for the nameserver_remotenotify + * module + */ +void nameserver_remotenotify_get_config( + struct nameserver_remotenotify_config *cfg); + +/* + * Function to setup the nameserver_remotenotify module + */ +int nameserver_remotenotify_setup(struct nameserver_remotenotify_config *cfg); + +/* + * Function to destroy the nameserver_remotenotify module + */ +int nameserver_remotenotify_destroy(void); + +/* + * Function to get the current configuration values + */ +void nameserver_remotenotify_params_init(void *handle, + struct nameserver_remotenotify_params *params); + +/* + * Function to setup the Name Server remote notify + */ +void *nameserver_remotenotify_create(u16 proc_id, + const struct nameserver_remotenotify_params *params); + +/* + * Function to destroy the Name Server remote notify + */ +int nameserver_remotenotify_delete(void **handle); + + +/* + * Function to get a name/value from remote nameserver + */ +int nameserver_remotenotify_get(void *handle, + const char *instance_name, const char *name, + void *value, u32 value_len, void *reserved); + +/* + * Get the shared memory requirements for the nameserver_remotenotify + */ +u32 nameserver_remotenotify_shared_memreq( + const struct nameserver_remotenotify_params *params); + + +#endif /* _NAMESERVER_REMOTENOTIFY_H_ */ + diff --git a/arch/arm/plat-omap/include/syslink/nameserver_remotenotify_ioctl.h b/arch/arm/plat-omap/include/syslink/nameserver_remotenotify_ioctl.h new file mode 100644 index 000000000000..e8a355456c09 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/nameserver_remotenotify_ioctl.h @@ -0,0 +1,163 @@ +/* + * nameserver_remotenotify_ioctl.h + * + * The nameserver_remotenotify module provides functionality to get name + * value pair from a remote nameserver. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef _NAMESERVERREMOTENOTIFY_DRVDEFS_H +#define _NAMESERVERREMOTENOTIFY_DRVDEFS_H + + +#include <linux/ioctl.h> +#include <linux/types.h> + +#include <ipc_ioctl.h> +#include <nameserver_remotenotify.h> + +enum CMD_NAMESERVERREMOTENOTIFY { + NAMESERVERREMOTENOTIFY_GETCONFIG = NAMESERVERREMOTENOTIFY_BASE_CMD, + NAMESERVERREMOTENOTIFY_SETUP, + NAMESERVERREMOTENOTIFY_DESTROY, + NAMESERVERREMOTENOTIFY_PARAMS_INIT, + NAMESERVERREMOTENOTIFY_CREATE, + NAMESERVERREMOTENOTIFY_DELETE, + NAMESERVERREMOTENOTIFY_GET, + NAMESERVERREMOTENOTIFY_SHAREDMEMREQ +}; + + +/* + * IOCTL command IDs for nameserver_remotenotify + * + */ + +/* + * Command for nameserver_remotenotify_get_config + */ +#define CMD_NAMESERVERREMOTENOTIFY_GETCONFIG _IOWR(IPC_IOC_MAGIC, \ + NAMESERVERREMOTENOTIFY_GETCONFIG, \ + struct nameserver_remotenotify_cmd_args) +/* + * Command for nameserver_remotenotify_setup + */ +#define CMD_NAMESERVERREMOTENOTIFY_SETUP _IOWR(IPC_IOC_MAGIC, \ + NAMESERVERREMOTENOTIFY_SETUP, \ + struct nameserver_remotenotify_cmd_args) + +/* + * Command for nameserver_remotenotify_setup + */ +#define CMD_NAMESERVERREMOTENOTIFY_DESTROY _IOWR(IPC_IOC_MAGIC, \ + NAMESERVERREMOTENOTIFY_DESTROY, \ + struct nameserver_remotenotify_cmd_args) + +/* + * Command for nameserver_remotenotify_destroy + */ +#define CMD_NAMESERVERREMOTENOTIFY_PARAMS_INIT _IOWR(IPC_IOC_MAGIC, \ + NAMESERVERREMOTENOTIFY_PARAMS_INIT, \ + struct nameserver_remotenotify_cmd_args) + +/* + * Command for nameserver_remotenotify_create + */ +#define CMD_NAMESERVERREMOTENOTIFY_CREATE _IOWR(IPC_IOC_MAGIC, \ + NAMESERVERREMOTENOTIFY_CREATE, \ + struct nameserver_remotenotify_cmd_args) + +/* + * Command for nameserver_remotenotify_delete + */ +#define CMD_NAMESERVERREMOTENOTIFY_DELETE _IOWR(IPC_IOC_MAGIC, \ + NAMESERVERREMOTENOTIFY_DELETE, \ + struct nameserver_remotenotify_cmd_args) + +/* + * Command for nameserver_remotenotify_get + */ +#define CMD_NAMESERVERREMOTENOTIFY_GET _IOWR(IPC_IOC_MAGIC, \ + NAMESERVERREMOTENOTIFY_GET, \ + struct nameserver_remotenotify_cmd_args) + +/* + * Command for nameserver_remotenotify_shared_memreq + */ +#define CMD_NAMESERVERREMOTENOTIFY_SHAREDMEMREQ _IOWR(IPC_IOC_MAGIC, \ + NAMESERVERREMOTENOTIFY_SHAREDMEMREQ, \ + struct nameserver_remotenotify_cmd_args) + +/* + * Command arguments for nameserver_remotenotify + */ +union nameserver_remotenotify_arg { + struct { + struct nameserver_remotenotify_config *config; + } get_config; + + struct { + struct nameserver_remotenotify_config *config; + } setup; + + struct { + void *handle; + struct nameserver_remotenotify_params *params; + } params_init; + + struct { + void *handle; + u16 proc_id; + struct nameserver_remotenotify_params *params; + } create; + + struct { + void *handle; + } delete_instance; + + struct { + void *handle; + char *instance_name; + u32 instance_name_len; + char *name; + u32 name_len; + u8 *value; + s32 value_len; + void *reserved; + s32 len; + } get; + + struct { + void *handle; + struct nameserver_remotenotify_params *params; + u32 shared_mem_size; + } shared_memreq; +}; + +/* + * Command arguments for nameserver_remotenotify + */ +struct nameserver_remotenotify_cmd_args { + union nameserver_remotenotify_arg args; + s32 api_status; +}; + +/* + * This ioctl interface for nameserver_remotenotify module + */ +int nameserver_remotenotify_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long args); + + +#endif /* _NAMESERVERREMOTENOTIFY_DRVDEFS_H */ + diff --git a/arch/arm/plat-omap/include/syslink/notify.h b/arch/arm/plat-omap/include/syslink/notify.h new file mode 100644 index 000000000000..6cf0e943b85d --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/notify.h @@ -0,0 +1,267 @@ +/* + * notify.h + * + * Notify driver support for OMAP Processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + + +#if !defined NOTIFY_H +#define NOTIFY_H + +#include <syslink/host_os.h> + +#define NOTIFY_MAX_DRIVERS 16 + +/* + * desc Maximum length of the name of Notify drivers, inclusive of NULL + * string terminator. + * + */ +#define NOTIFY_MAX_NAMELEN 32 + +#define NOTIFY_MODULEID 0x5f84 + +/* + *Status code base for Notify module. + */ +#define NOTIFY_STATUSCODEBASE (NOTIFY_MODULEID << 12u) + +/* + * Macro to make error code. + */ +#define NOTIFY_MAKE_FAILURE(x) ((int)(0x80000000\ + | (NOTIFY_STATUSCODEBASE + (x)))) + +/* + * Macro to make success code. + */ +#define NOTIFY_MAKE_SUCCESS(x) (NOTIFY_STATUSCODEBASE + (x)) + +/* + * Generic failure. + */ +#define NOTIFY_E_FAIL NOTIFY_MAKE_FAILURE(1) + +/* + * A timeout occurred while performing the specified operation. + */ +#define NOTIFY_E_TIMEOUT NOTIFY_MAKE_FAILURE(2) + +/* + *Configuration failure. + */ +#define NOTIFY_E_CONFIG NOTIFY_MAKE_FAILURE(3) + +/* + * The module is already initialized + */ +#define NOTIFY_E_ALREADYINIT NOTIFY_MAKE_FAILURE(4) + +/* + * Unable to find the specified entity (e.g. registered event, driver). + */ +#define NOTIFY_E_NOTFOUND NOTIFY_MAKE_FAILURE(5) + +/* + * The specified operation is not supported. + */ +#define NOTIFY_E_NOTSUPPORTED NOTIFY_MAKE_FAILURE(6) + +/* +* Invalid event number specified to the Notify operation. + */ +#define NOTIFY_E_INVALIDEVENT NOTIFY_MAKE_FAILURE(7) + +/* + * Invalid pointer provided. + */ +#define NOTIFY_E_POINTER NOTIFY_MAKE_FAILURE(8) +/* + * The specified value is out of valid range. + */ +#define NOTIFY_E_RANGE NOTIFY_MAKE_FAILURE(9) + +/* An invalid handle was provided. + */ +#define NOTIFY_E_HANDLE NOTIFY_MAKE_FAILURE(10) + +/* + * An invalid argument was provided to the API. + */ +#define NOTIFY_E_INVALIDARG NOTIFY_MAKE_FAILURE(11) + +/* + * A memory allocation failure occurred. + */ +#define NOTIFY_E_MEMORY NOTIFY_MAKE_FAILURE(12) + +/* + * The module has not been setup. + */ +#define NOTIFY_E_INVALIDSTATE NOTIFY_MAKE_FAILURE(13) + +/* + * Maximum number of supported drivers have already been registered. + */ +#define NOTIFY_E_MAXDRIVERS NOTIFY_MAKE_FAILURE(14) + +/* + * Invalid attempt to use a reserved event number. + */ +#define NOTIFY_E_RESERVEDEVENT NOTIFY_MAKE_FAILURE(15) + +/* + * The specified entity (e.g. driver) already exists. + */ +#define NOTIFY_E_ALREADYEXISTS NOTIFY_MAKE_FAILURE(16) + +/* + * brief The Notify driver has not been initialized. + */ +#define NOTIFY_E_DRIVERINIT NOTIFY_MAKE_FAILURE(17) + +/* +* The remote processor is not ready to receive the event. + */ +#define NOTIFY_E_NOTREADY NOTIFY_MAKE_FAILURE(18) + +/* + * brief Failed to register driver with Notify module. + */ +#define NOTIFY_E_REGDRVFAILED NOTIFY_MAKE_FAILURE(19) + +/* +* Failed to unregister driver with Notify module. + */ +#define NOTIFY_E_UNREGDRVFAILED NOTIFY_MAKE_FAILURE(20) + +/* +* Failure in an OS-specific operation. + */ +#define NOTIFY_E_OSFAILURE NOTIFY_MAKE_FAILURE(21) + +/* + *Maximum number of supported events have already been registered. + */ +#define NOTIFY_E_MAXEVENTS NOTIFY_MAKE_FAILURE(22) + +/* Maximum number of supported user clients have already been + * registered. + */ +#define NOTIFY_E_MAXCLIENTS NOTIFY_MAKE_FAILURE(23) + +/* Operation is successful. + */ +#define NOTIFY_SUCCESS NOTIFY_MAKE_SUCCESS(0) + +/* The ProcMgr module has already been setup in this process. + */ +#define NOTIFY_S_ALREADYSETUP NOTIFY_MAKE_SUCCESS(1) + +/* Other ProcMgr clients have still setup the ProcMgr module. + */ +#define NOTIFY_S_SETUP NOTIFY_MAKE_SUCCESS(2) + +/* Other ProcMgr handles are still open in this process. + */ +#define NOTIFY_S_OPENHANDLE NOTIFY_MAKE_SUCCESS(3) + +/* The ProcMgr instance has already been created/opened in this process + */ +#define NOTIFY_S_ALREADYEXISTS NOTIFY_MAKE_SUCCESS(4) + +/* Maximum depth for nesting Notify_disable / Notify_restore calls. + */ +#define NOTIFY_MAXNESTDEPTH 2 + + +/* brief Macro to make a correct module magic number with refCount */ +#define NOTIFY_MAKE_MAGICSTAMP(x) ((NOTIFY_MODULEID << 12u) | (x)) + + +/* + * const NOTIFYSHMDRV_DRIVERNAME + * + * desc Name of the Notify Shared Memory Mailbox driver. + * + */ +#define NOTIFYMBXDRV_DRIVERNAME "NOTIFYMBXDRV" + +#define REG volatile +/* + * const NOTIFYSHMDRV_RESERVED_EVENTS + * + * desc Maximum number of events marked as reserved events by the + * notify_shmdrv driver. + * If required, this value can be changed by the system integrator. + * + */ +#define NOTIFYSHMDRV_RESERVED_EVENTS 3 + +/* +* This key must be provided as the upper 16 bits of the eventNo when + * registering for an event, if any reserved event numbers are to be + * used. + */ +#define NOTIFY_SYSTEM_KEY 0xC1D2 + +struct notify_config { + u32 maxDrivers; + /* Maximum number of drivers that can be created for Notify at a time */ +}; + +typedef void (*notify_callback_fxn)(u16 proc_id, u32 eventNo, void *arg, + u32 payload); + +extern struct notify_module_object notify_state; + +/* Function to get the default configuration for the Notify module. */ +void notify_get_config(struct notify_config *cfg); + +/* Function to setup the Notify Module */ +int notify_setup(struct notify_config *cfg); + +/* Function to destroy the Notify module */ +int notify_destroy(void); + +/* Function to register an event */ +int notify_register_event(void *notify_driver_handle, u16 proc_id, + u32 event_no, + notify_callback_fxn notify_callback_fxn, + void *cbck_arg); + +/* Function to unregister an event */ +int notify_unregister_event(void *notify_driver_handle, u16 proc_id, + u32 event_no, + notify_callback_fxn notify_callback_fxn, + void *cbck_arg); + +/* Function to send an event to other processor */ +int notify_sendevent(void *notify_driver_handle, u16 proc_id, + u32 event_no, u32 payload, bool wait_clear); + +/* Function to disable Notify module */ +u32 notify_disable(u16 procId); + +/* Function to restore Notify module state */ +void notify_restore(u32 key, u16 proc_id); + +/* Function to disable particular event */ +void notify_disable_event(void *notify_driver_handle, u16 proc_id, + u32 event_no); + +/* Function to enable particular event */ +void notify_enable_event(void *notify_driver_handle, u16 proc_id, u32 event_no); + +#endif /* !defined NOTIFY_H */ + diff --git a/arch/arm/plat-omap/include/syslink/notify_dispatcher.h b/arch/arm/plat-omap/include/syslink/notify_dispatcher.h new file mode 100644 index 000000000000..efd87315815e --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/notify_dispatcher.h @@ -0,0 +1,158 @@ +/* + * notify_dispatcher.h + * + * Notify driver support for OMAP Processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + + +#ifndef __TMBX_H__ +#define __TMBX_H__ + + +#include <syslink/notifydefs.h> +#include <linux/interrupt.h> + +#include <syslink/notifyerr.h> + +#define MAX_MBOX_MODULES 2 +#define MAX_MBOX_ISRS 32 +#define KErrNone 0 +#define KErrNotSupported 1 +#define KErrNotReady 2 +#define KErrArgument 2 + +typedef void (*isr_call_back)(void *); + +struct mbox_config { + unsigned long int mbox_linear_addr; + unsigned long int mbox_modules; + signed long int interrupt_lines[MAX_MBOX_MODULES]; + signed long int mailboxes[MAX_MBOX_MODULES]; +}; + +struct mbox_isrs { + signed long int isrNo[MAX_MBOX_MODULES]; + /* TODO: Remove this - seems to be unused.*/ + isr_call_back isrs[MAX_MBOX_MODULES][MAX_MBOX_ISRS]; + void *isr_params[MAX_MBOX_MODULES][MAX_MBOX_ISRS]; +}; + +extern const unsigned long *linear_address; + +irqreturn_t notify_mailbx0_user0_isr(int temp, void *anArg, struct pt_regs *p); + +/* + *func ntfy_disp_bind_interrupt + * + * desc Bind an ISR to the HW interrupt line coming into the processor + */ +int ntfy_disp_bind_interrupt(int interrupt_no, + isr_call_back hw_isr, + void *isr_arg); + + +/* + * desc Print the mailbox registers and other useful debug information + * + */ +void ntfy_disp_debug(void); + + +/* + * func ntfy_disp_deinit + * desc Uninitialize the Mailbox Manager module + */ +int ntfy_disp_deinit(void); + + +/* + * desc Return the pointer to the Mailbox Manager's configuration object + */ +struct mbox_config *ntfy_disp_get_config(void); + + +/* + * desc Initialize the Mailbox Manager module + */ +int ntfy_disp_init(void); + + +/* + * desc Disable a particular IRQ bit on a Mailbox IRQ Enable Register + */ +int ntfy_disp_interrupt_disable(unsigned long int mbox_module_no, + int a_irq_bit); + + +/* + * desc Enable a particular IRQ bit on a Mailbox IRQ Enable Register + */ +int ntfy_disp_interrupt_enable(unsigned long int mbox_module_no, + int a_irq_bit); + + +/* + * desc Read a message on a Mailbox FIFO queue + */ +int ntfy_disp_read(unsigned long int mbox_module_no, + int a_mbox_no, + int *messages, + int *num_messages, + short int read_all); + + +/* + * func ntfy_disp_register + * desc Register a ISR callback associated with a particular IRQ bit on a + * Mailbox IRQ Enable Register + */ +int ntfy_disp_register(unsigned long int mbox_module_no, + int a_irq_bit, + isr_call_back isr_cbck_fn, + void *isrCallbackArgs); + + +/* + * func ntfy_disp_send + * desc Send a message on a Mailbox FIFO queue + */ +int ntfy_disp_send(unsigned long int mbox_module_no, + int a_mbox_no, + int message); + + +/* + * func ntfy_disp_unbind_interrupt + * desc Remove the ISR to the HW interrupt line coming into the processor + */ +int ntfy_disp_unbind_interrupt(int interrupt_no); + + +/* + * func ntfy_disp_unregister + * desc Unregister a ISR callback associated with a particular IRQ bit on a + * Mailbox IRQ Enable Register + */ +int ntfy_disp_unregister(unsigned long int mbox_module_no, + int a_irq_bit); + +/* + * func notify_mailbx0_user0_isr + * desc mail ISR + * + */ + +irqreturn_t notify_mailbx0_user0_isr(int temp, void *anArg, struct pt_regs *p); + + +#endif diff --git a/arch/arm/plat-omap/include/syslink/notify_driver.h b/arch/arm/plat-omap/include/syslink/notify_driver.h new file mode 100644 index 000000000000..30a150174654 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/notify_driver.h @@ -0,0 +1,44 @@ +/* + * notify_driver.h + * + * Notify driver support for OMAP Processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + + +#if !defined NOTIFYDRIVER_H +#define NOTIFYDRIVER_H + +#include<linux/list.h> + +/* ----------------------------------- Notify */ +#include <syslink/notifyerr.h> + +/* ----------------------------------- Notify driver */ +#include <syslink/notify_driverdefs.h> + +/* Function to register notify driver */ +int notify_register_driver(char *driver_name, + struct notify_interface *fn_table, + struct notify_driver_attrs *drv_attrs, + struct notify_driver_object **driver_handle); + + +/* Function to unregister notify driver */ +int notify_unregister_driver(struct notify_driver_object *drv_handle); + +/* Function to find the driver in the list of drivers */ +int notify_get_driver_handle(char *driver_name, + struct notify_driver_object **handle); + +#endif /* !defined (NOTIFYDRIVER_H) */ + diff --git a/arch/arm/plat-omap/include/syslink/notify_driverdefs.h b/arch/arm/plat-omap/include/syslink/notify_driverdefs.h new file mode 100644 index 000000000000..0e79562d0867 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/notify_driverdefs.h @@ -0,0 +1,440 @@ +/* + * notify_driverdefs.h + * + * Notify driver support for OMAP Processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + + +#if !defined NOTIFYDRIVERDEFS_H +#define NOTIFYDRIVERDEFS_H + + +#include <syslink/host_os.h> + +/* ----------------------------------- Notify */ +#include <syslink/notify.h> +#include <syslink/notify_shmdriver.h> +#include <syslink/notifydefs.h> +#include <syslink/multiproc.h> + +#define NOTIFY_BASE_CMD (0x100) + +/* + * Command for Notify_getConfig + */ +#define CMD_NOTIFY_GETCONFIG (NOTIFY_BASE_CMD + 1u) + +/* + * Command for Notify_setup + */ +#define CMD_NOTIFY_SETUP (NOTIFY_BASE_CMD + 2u) + +/* + * Command for Notify_destroy + */ +#define CMD_NOTIFY_DESTROY (NOTIFY_BASE_CMD + 3u) + +/* + * Command for Notify_registerEvent + */ +#define CMD_NOTIFY_REGISTEREVENT (NOTIFY_BASE_CMD + 4u) + +/* + * Command for Notify_unregisterEvent + */ +#define CMD_NOTIFY_UNREGISTEREVENT (NOTIFY_BASE_CMD + 5u) + +/* + * Command for Notify_sendEvent + */ +#define CMD_NOTIFY_SENDEVENT (NOTIFY_BASE_CMD + 6u) + +/* + * Command for Notify_disable + */ +#define CMD_NOTIFY_DISABLE (NOTIFY_BASE_CMD + 7u) + +/* + * Command for Notify_restore + */ +#define CMD_NOTIFY_RESTORE (NOTIFY_BASE_CMD + 8u) + +/* + * Command for Notify_disableEvent + */ +#define CMD_NOTIFY_DISABLEEVENT (NOTIFY_BASE_CMD + 9u) + +/* + * Command for Notify_enableEvent + */ +#define CMD_NOTIFY_ENABLEEVENT (NOTIFY_BASE_CMD + 10u) + +/*! + * @brief Command for Notify_attach + */ +#define CMD_NOTIFY_ATTACH (NOTIFY_BASE_CMD + 11u) + +/*! + * @brief Command for Notify_detach + */ +#define CMD_NOTIFY_DETACH (NOTIFY_BASE_CMD + 12u) + +/* + * const NOTIFY_SYSTEM_KEY_MASK + * + * desc Mask to check for system key. + * + */ + +#define NOTIFY_SYSTEM_KEY_MASK (unsigned short int) 0xFFFF0000 + +/* + * const NOTIFY_EVENT_MASK + * + * desc Mask to check for event ID. + * + */ + +#define NOTIFY_EVENT_MASK (unsigned short int) 0x0000FFFF + +struct notify_cmd_args { + int apiStatus; + /* Status of the API being called. */ +}; + +/* + * Command arguments for Notify_getConfig + */ +struct notify_cmd_args_get_config { + struct notify_cmd_args commonArgs; + struct notify_config *cfg; +}; + +/* + * Command arguments for Notify_setup + */ +struct notify_cmd_args_setup { + struct notify_cmd_args commonArgs; + struct notify_config *cfg; +}; + +/* + * Command arguments for Notify_destroy + */ +struct notify_cmd_args_destroy { + struct notify_cmd_args commonArgs; +}; + +/* + * Command arguments for Notify_registerEvent + */ +struct notify_cmd_args_register_event { + struct notify_cmd_args commonArgs; + struct notify_driver_object *handle; + u16 procId; + u32 eventNo; + notify_callback_fxn fnNotifyCbck; + void *cbckArg; + u32 pid; +}; + +/* + * Command arguments for Notify_unregisterEvent + */ +struct notify_cmd_args_unregister_event { + struct notify_cmd_args commonArgs; + struct notify_driver_object *handle; + u16 procId; + u32 eventNo; + notify_callback_fxn fnNotifyCbck; + void *cbckArg; + u32 pid; +}; + +/* + * Command arguments for Notify_sendEvent + */ +struct notify_cmd_args_send_event { + struct notify_cmd_args commonArgs; + struct notify_driver_object *handle; + u16 procId; + u32 eventNo; + u32 payload; + bool waitClear; +}; + +/* + * Command arguments for Notify_disable + */ +struct notify_cmd_args_disable { + struct notify_cmd_args commonArgs; + u16 procId; + u32 flags; +}; + +/* + * Command arguments for Notify_restore + */ +struct notify_cmd_args_restore { + struct notify_cmd_args commonArgs; + u32 key; + u16 procId; +}; + +/* + * Command arguments for Notify_disableEvent + */ +struct notify_cmd_args_disable_event { + struct notify_cmd_args commonArgs; + struct notify_driver_object *handle; + u16 procId; + u32 eventNo; +}; + +/* + * Command arguments for Notify_enableEvent + */ +struct notify_cmd_args_enable_event { + struct notify_cmd_args commonArgs; + void *notify_driver_handle; + u16 procId; + u32 eventNo; +}; + +/* + * Command arguments for Notify_exit + */ +struct notify_cmd_args_exit { + struct notify_cmd_args commonArgs; +}; + + +enum { + NOTIFY_DRIVERINITSTATUS_NOTDONE = 0, + /* Driver initialization is not done. */ + NOTIFY_DRIVERINITSTATUS_DONE = 1, + /* Driver initialization is complete. */ + NOTIFY_DRIVERINITSTATUS_INPROGRESS = 2, + /* Driver initialization is in progress. */ + NOTIFY_DRIVERINITSTATUS_ENDVALUE = 3 + /* End delimiter indicating start of invalid values for this enum */ +}; + +/* + *This structure defines information for all processors supported by + *the Notify driver. + *An instance of this object is provided for each processor handled by + *the Notify driver, when registering itself with the Notify module. + * + */ +struct notify_driver_proc_info { + u32 max_events; + u32 reserved_events; + bool event_priority; + u32 payload_size; + u16 proc_id; +}; + +/* + * This structure defines the structure for specifying Notify driver + * attributes to the Notify module. + * This structure provides information about the Notify driver to the + * Notify module. The information is used by the Notify module mainly + * for parameter validation. It may also be used by the Notify module + * to take appropriate action if required, based on the characteristics + * of the Notify driver. + */ +struct notify_driver_attrs { + u32 numProc; + struct notify_driver_proc_info + proc_info[MULTIPROC_MAXPROCESSORS]; +}; + + +/* ======================================== + * Function pointer types + * ======================================== + */ +/* + * This type defines the function to register a callback for an event + * with the Notify driver. + * This function gets called internally from the Notify_registerEvent + * API. The Notify_registerEvent () function passes on the + * request into the Notify driver identified by the Notify Handle. + * + */ +typedef int(*NotifyDriver_RegisterEvent)(struct notify_driver_object *handle, + u16 procId, u32 eventNo, notify_callback_fxn cbckFxn, + void *cbckArg); +/* + * This type defines the function to unregister a callback for an event + * with the Notify driver. + * This function gets called internally from the Notify_unregisterEvent + * API. The Notify_unregisterEvent () function passes on the + * request into the Notify driver identified by the Notify Handle. + * + */ +typedef int(*NotifyDriver_UnregisterEvent) (struct notify_driver_object *handle, + u16 procId, u32 eventNo, notify_callback_fxn cbckFxn, + void *cbckArg); + +/* + * This type defines the function to send a notification event to the + * registered users for this notification on the specified processor. + * This function gets called internally from the Notify_sendEvent () + * API. The Notify_sendEvent () function passes on the initialization + * request into the Notify driver identified by the Notify Handle. + */ +typedef int(*NotifyDriver_SendEvent) (struct notify_driver_object *handle, + u16 procId, u32 eventNo, u32 payload, bool waitClear); + +/* + * This type defines the function to disable all events for the + * specified processor ID. + * This function gets called internally from the Notify_disable () + * API. The Notify_disable () function passes on the request into the + * Notify driver identified by the Notify Handle. + */ +typedef u32(*NotifyDriver_Disable) (struct notify_driver_object *handle, + u16 procId); + +/* + * This type defines the function to restore all events for the + * specified processor ID. + * This function gets called internally from the Notify_restore () + * API. The Notify_restore () function passes on the request into the + * Notify driver identified by the Notify Handle. + */ +typedef void (*NotifyDriver_Restore) (struct notify_driver_object *handle, + u32 key, u16 procId); + +/* + * This type defines the function to disable specified event for the + * specified processor ID. + * This function gets called internally from the Notify_disableEvent () + * API. The Notify_disableEvent () function passes on the request into + * the Notify driver identified by the Notify Handle. + */ +typedef void (*NotifyDriver_DisableEvent) (struct notify_driver_object *handle, + u16 procId, u32 eventNo); + +/* + * This type defines the function to enable specified event for the + * specified processor ID. + * This function gets called internally from the Notify_enableEvent () + * API. The Notify_enableEvent () function passes on the request into + * the Notify driver identified by the Notify Handle. + * + */ +typedef void (*NotifyDriver_EnableEvent) (struct notify_driver_object *handle, + u16 procId, u32 eventNo); + + +/* + * This structure defines the function table interface for the Notify + * driver. + * This function table interface must be implemented by each Notify + * driver and registered with the Notify module. + * + */ +struct notify_interface { + NotifyDriver_RegisterEvent register_event; + /* interface function registerEvent */ + NotifyDriver_UnregisterEvent unregister_event; + /* interface function unregisterEvent */ + NotifyDriver_SendEvent send_event; + /* interface function sendEvent */ + NotifyDriver_Disable disable; + /* interface function disable */ + NotifyDriver_Restore restore; + /* interface function restore */ + NotifyDriver_DisableEvent disable_event; + /* interface function disableEvent */ + NotifyDriver_EnableEvent enable_event; +}; + + +union notify_drv_procevents{ + struct { + struct notify_shmdrv_attrs attrs; + struct notify_shmdrv_ctrl *ctrl_ptr; + } shm_events; + + struct { + /*Attributes */ + unsigned long int num_events; + unsigned long int send_event_pollcount; + /*Control Paramters */ + unsigned long int send_init_status ; + struct notify_shmdrv_eventreg_mask reg_mask ; + } non_shm_events; +}; + + +/* + * This structure defines the Notify driver object and handle used + * internally to contain all information required for the Notify driver + * This object contains all information for the Notify module to be + * able to identify and interact with the Notify driver. + */ +struct notify_driver_object { + int is_init; + struct notify_interface fn_table; + char name[NOTIFY_MAX_NAMELEN]; + struct notify_driver_attrs attrs; + u32 *disable_flag[NOTIFY_MAXNESTDEPTH]; + void *driver_object; +}; + + +struct notify_drv_eventlist { + unsigned long int event_handler_count; + struct list_head listeners; +}; + + + +struct notify_drv_eventlistner{ + struct list_head element; + fn_notify_cbck fn_notify_cbck; + void *cbck_arg; +}; + + +struct notify_drv_proc_module { + + unsigned long int proc_id; + struct notify_drv_eventlist *event_list; + struct notify_shmdrv_eventreg *reg_chart; + union notify_drv_procevents events_obj; +}; + +/* + * Defines the Notify state object, which contains all the module + * specific information. + */ +struct notify_module_object { + atomic_t ref_count; + struct notify_config cfg; + /* Notify configuration structure */ + struct notify_config def_cfg; + /* Default module configuration */ + struct mutex *gate_handle; + /* Handle of gate to be used for local thread safety */ + struct notify_driver_object drivers[NOTIFY_MAX_DRIVERS]; + /* Array of configured drivers. */ + u32 disable_depth; + /* Current disable depth for Notify module. */ +}; +#endif /* !defined (NOTIFYDRIVERDEFS_H) */ + diff --git a/arch/arm/plat-omap/include/syslink/notify_ducatidriver.h b/arch/arm/plat-omap/include/syslink/notify_ducatidriver.h new file mode 100644 index 000000000000..16ad80e425a7 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/notify_ducatidriver.h @@ -0,0 +1,200 @@ +/* + * notify_ducatidriver.h + * + * Syslink driver support for OMAP Processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef NOTIFY_DUCATIDRIVER_H_ +#define NOTIFY_DUCATIDRIVER_H_ + + + +/* Notify*/ +#include <syslink/GlobalTypes.h> +#include <syslink/notifyerr.h> +#include <syslink/notify_driverdefs.h> + +/* + * const NOTIFYDUCATI_DRIVERNAME + * + * desc Name of the ducati driver. + * + */ + +#define IPC_BUF_ALIGN 128 +#define IPC_ALIGN(x, y) (unsigned long int)\ +((unsigned long int)((x + y - 1) / y) * y) + + +#define NOTIFYDUCATI_DRIVERNAME "NOTIFY_DUCATIDRV" + +#define REG volatile + + +extern u32 get_ducati_virt_mem(); +extern void unmap_ducati_virt_mem(u32 shm_virt_addr); + +/* +* func notify_mbxdrv_register_event +* +* desc Register a callback for an event with the Notify driver. +* +* +*/ + +int notify_ducatidrv_register_event( + struct notify_driver_object *handle, + short int proc_id, + int event_no, + fn_notify_cbck fn_notify_cbck, + void *cbck_arg) ; + +/* +* func notify_mbxdrv_unregevent +* +* desc Unregister a callback for an event with the Notify driver. +* +* +*/ + +int notify_ducatidrv_unregister_event( + struct notify_driver_object *handle, + short int proc_id, + int event_no, + fn_notify_cbck fn_notify_cbck, + void *cbck_arg) ; + +/* +* func notify_mbxdrv_sendevent +* +* desc Send a notification event to the registered users for this +* notification on the specified processor. +* +* +*/ + +int notify_ducatidrv_sendevent(struct notify_driver_object *handle, + short int proc_id, + int event_no, + int payload, + short int wait_clear) ; + +/* +* func notify_mbxdrv_disable +* +* desc Disable all events for this Notify driver. +* +* +*/ + +void *notify_ducatidrv_disable(struct notify_driver_object *handle); + +/* +* func notify_mbxdrv_restore +* +* desc Restore the Notify driver to the state before the last disable was +* called. +* +* +*/ + +int notify_ducatidrv_restore(struct notify_driver_object *handle, + void *flags) ; + +/* +* func notify_mbxdrv_disable_event +* +* desc Disable a specific event for this Notify driver. +* +* +*/ + +int notify_ducatidrv_disable_event( + struct notify_driver_object *handle, + short int proc_id, + int event_no) ; + +/* +* func notify_mbxdrv_enable_event +* +* desc Enable a specific event for this Notify driver. +* +* +*/ + +int notify_ducatidrv_enable_event( + struct notify_driver_object *handle, + short int proc_id, + int event_no) ; + + +/* +* func notify_mbxdrv_debug +* +* desc Print debug information for the Notify driver. +* +* +*/ + +int notify_ducatidrv_debug(struct notify_driver_object *handle) ; + +struct notify_ducatidrv_params { + int shared_addr; + int shared_addr_size; + int num_events; + int recv_int_id; + int send_int_id; + int remote_proc_id; + int num_reserved_events; + int send_event_poll_count; +} ; + +/* + * struct notify_ducatidrv_config + * + */ + +struct notify_ducatidrv_config { + u32 reserved; +}; + +/* Function to get the default configuration for the Notify module. */ +void notify_ducatidrv_getconfig(struct notify_ducatidrv_config *cfg); + +/* Function to setup the notify ducati driver with the given configuration*/ +int notify_ducatidrv_setup(struct notify_ducatidrv_config *cfg); + +/* Function to destroy the notify ducati driver*/ +int notify_ducatidrv_destroy(void); + +/* Function to create the ducati driver handle and performs initialization. */ + +struct notify_driver_object *notify_ducatidrv_create(char *driver_name, + const struct notify_ducatidrv_params *params); + +/* Function to delete the ducati driver handle and performs de initialization.*/ +int notify_ducatidrv_delete(struct notify_driver_object **handle_ptr); + +/*Function to open the ducati driver */ +int notify_ducatidrv_open(char *driver_name, + struct notify_driver_object **handle_ptr); + +/*Function to close the ducati driver */ +int notify_ducatidrv_close(struct notify_driver_object **handle_ptr); + +/*Function to initialize the given parameters */ +void notify_ducatidrv_params_init(struct notify_driver_object *handle, + struct notify_ducatidrv_params *params); + +#endif /* !defined NOTIFY_SHMDRIVER_H_ */ + diff --git a/arch/arm/plat-omap/include/syslink/notify_ducatidriver_defs.h b/arch/arm/plat-omap/include/syslink/notify_ducatidriver_defs.h new file mode 100644 index 000000000000..6d7b508ae533 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/notify_ducatidriver_defs.h @@ -0,0 +1,152 @@ +/* + * notify_ducati_driverdefs.h + * + * Notify driver support for OMAP Processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + + +#ifndef NOTIFY_DUCATIDRV_DEFS +#define NOTIFY_DUCATIDRV_DEFS + +#include <syslink/notify_ducatidriver.h> + +/* + * brief Base structure for NotifyDriverShm command args. This needs to be + * the first field in all command args structures. + */ +struct notify_ducatidrv_cmdargs { + int api_status; +}; + + +/* + * ioctl command IDs for NotifyDriverShm + * + */ +/* + * brief Base command ID for NotifyDriverShm + */ +#define NOTIFYDRIVERSHM_BASE_CMD 0x100 + +/* + * brief Command for NotifyDriverShm_getConfig + */ +#define CMD_NOTIFYDRIVERSHM_GETCONFIG (NOTIFYDRIVERSHM_BASE_CMD + 1u) + +/* + * brief Command for NotifyDriverShm_setup + */ +#define CMD_NOTIFYDRIVERSHM_SETUP (NOTIFYDRIVERSHM_BASE_CMD + 2u) + +/* + * brief Command for NotifyDriverShm_setup + */ +#define CMD_NOTIFYDRIVERSHM_DESTROY (NOTIFYDRIVERSHM_BASE_CMD + 3u) + +/* + * brief Command for NotifyDriverShm_destroy + */ +#define CMD_NOTIFYDRIVERSHM_PARAMS_INIT (NOTIFYDRIVERSHM_BASE_CMD + 4u) + +/* + * brief Command for NotifyDriverShm_create + */ +#define CMD_NOTIFYDRIVERSHM_CREATE (NOTIFYDRIVERSHM_BASE_CMD + 5u) + +/* + * brief Command for NotifyDriverShm_delete + */ +#define CMD_NOTIFYDRIVERSHM_DELETE (NOTIFYDRIVERSHM_BASE_CMD + 6u) + +/* + * brief Command for NotifyDriverShm_open + */ +#define CMD_NOTIFYDRIVERSHM_OPEN (NOTIFYDRIVERSHM_BASE_CMD + 7u) + +/* + * brief Command for NotifyDriverShm_close + */ +#define CMD_NOTIFYDRIVERSHM_CLOSE (NOTIFYDRIVERSHM_BASE_CMD + 8u) + + +/* + * @brief Command arguments for NotifyDriverShm_getConfig + */ +struct notify_ducatidrv_cmdargs_getconfig { + struct notify_ducatidrv_cmdargs common_args; + struct notify_ducatidrv_config *cfg; +}; + +/* + * brief Command arguments for NotifyDriverShm_setup + */ +struct notify_ducatidrv_cmdargs_setup { + struct notify_ducatidrv_cmdargs common_args; + struct notify_ducatidrv_config *cfg; +}; + +/* + * brief Command arguments for NotifyDriverShm_destroy + */ +struct notify_ducatidrv_cmdargs_destroy { + struct notify_ducatidrv_cmdargs common_args; +} ; + +/* + * brief Command arguments for NotifyDriverShm_Params_init + */ + +struct notify_ducatidrv_cmdargs_paramsinit { + struct notify_ducatidrv_cmdargs common_args; + struct notify_driver_object *handle; + struct notify_ducatidrv_params *params; +}; + +/*! + * @brief Command arguments for NotifyDriverShm_create + */ +struct notify_ducatidrv_cmdargs_create { + struct notify_ducatidrv_cmdargs common_args; + char driverName[NOTIFY_MAX_NAMELEN]; + struct notify_ducatidrv_params params; + struct notify_driver_object *handle; +}; + +/* + * brief Command arguments for NotifyDriverShm_delete + */ +struct notify_ducatidrv_cmdargs_delete { + struct notify_ducatidrv_cmdargs common_args; + struct notify_driver_object *handle; +}; + +/* + * brief Command arguments for NotifyDriverShm_open + */ +struct notify_ducatidrv_cmdargs_open { + struct notify_ducatidrv_cmdargs common_args; + char driverName[NOTIFY_MAX_NAMELEN]; + struct notify_driver_object *handle; + +}; + +/* + * brief Command arguments for NotifyDriverShm_close + */ +struct notify_ducatidrv_cmdargs_close { + struct notify_ducatidrv_cmdargs common_args; + struct notify_driver_object *handle; + +}; + +#endif /*NOTIFY_DUCATIDRV_DEFS*/ diff --git a/arch/arm/plat-omap/include/syslink/notify_shmdriver.h b/arch/arm/plat-omap/include/syslink/notify_shmdriver.h new file mode 100644 index 000000000000..450896160bdf --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/notify_shmdriver.h @@ -0,0 +1,108 @@ + +/* + * notify_shmdriver.h + * + * Notify driver support for OMAP Processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + + +#if !defined NOTIFY_SHMDRIVER_H_ +#define NOTIFY_SHMDRIVER_H_ + +/* + * const NOTIFYSHMDRV_DRIVERNAME + * + * desc Name of the Notify Shared Memory Mailbox driver. + * + */ +#define NOTIFYSHMDRV_DRIVERNAME "NOTIFYSHMDRV" + +/* + * const NOTIFYSHMDRV_RESERVED_EVENTS + * + * desc Maximum number of events marked as reserved events by the + * NotiyShmDrv driver. + * If required, this value can be changed by the system integrator. + * + */ + +#define NOTIFYSHMDRV_RESERVED_EVENTS 3 + + +/* + * name notify_shmdrv_attrs + * + */ +struct notify_shmdrv_attrs { + unsigned long int shm_base_addr; + unsigned long int shm_size; + unsigned long int num_events; + unsigned long int send_event_pollcount; +}; + + +/* +* name notify_shmdrv_event_entry +*/ +struct notify_shmdrv_event_entry { + REG unsigned long int flag; + REG unsigned long int payload; + REG unsigned long int reserved; + unsigned long int padding[29]; +}; + +/* +* name notify_shmdrv_eventreg_mask +* +*/ +struct notify_shmdrv_eventreg_mask { + REG unsigned long int mask; + REG unsigned long int enable_mask; + unsigned long int padding[30]; +}; + +/* +* name notify_shmdrv_eventreg +* +*/ +struct notify_shmdrv_eventreg { + unsigned long int reg_event_no; + unsigned long int reserved; +}; + +/* +* name notify_shmdrv_proc_ctrl +* +*/ +struct notify_shmdrv_proc_ctrl { + struct notify_shmdrv_event_entry *self_event_chart; + struct notify_shmdrv_event_entry *other_event_chart; + unsigned long int recv_init_status; + unsigned long int send_init_status; + unsigned long int padding[28]; + struct notify_shmdrv_eventreg_mask reg_mask; + struct notify_shmdrv_eventreg *reg_chart; +}; + +/* + * brief Defines the notify_shmdrv_ctrl structure, which contains all + * information shared between the two connected processors + * This structure is shared between the two processors. + */ +struct notify_shmdrv_ctrl { + struct notify_shmdrv_proc_ctrl proc_ctrl[2]; +}; + +#endif /* !defined NOTIFY_SHMDRIVER_H_ */ + + diff --git a/arch/arm/plat-omap/include/syslink/notifydefs.h b/arch/arm/plat-omap/include/syslink/notifydefs.h new file mode 100644 index 000000000000..7f37346a7f75 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/notifydefs.h @@ -0,0 +1,25 @@ +/* + * notifydefs.h + * + * Notify driver support for OMAP Processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + + +#if !defined NOTIFYDEFS_H +#define NOTIFYDEFS_H +typedef void (*fn_notify_cbck) (unsigned long int procId, + u32 eventNo, + void *arg, + u32 payload) ; + +#endif /* !defined (NOTIFYDEFS_H) */ diff --git a/arch/arm/plat-omap/include/syslink/notifyerr.h b/arch/arm/plat-omap/include/syslink/notifyerr.h new file mode 100644 index 000000000000..9bbaa238fa3a --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/notifyerr.h @@ -0,0 +1,198 @@ +/* + * notifyerr.h + * + * Notify driver support for OMAP Processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + + +#if !defined NOTIFYERR_H +#define NOTIFYERR_H + + +/* + * name NOTIFY_SUCCEEDED + * + * desc Check if the provided status code indicates a success code. + * + * arg status + * Status code to be checked + * + * ret TRUE + * If status code indicates success + * FALSE + * If status code indicates failure + * + * enter None. + * + * leave None. + * + * see NOTIFY_FAILED + * + */ +#define NOTIFY_SUCCEEDED(status)\ +(((signed long int) (status) >= (NOTIFY_SBASE)) \ +&& ((signed long int) (status) <= (NOTIFY_SLAST))) + + +/* + * @name NOTIFY_FAILED + * + * @desc Check if the provided status code indicates a failure code. + * + * @arg status + * Status code to be checked + * + * @ret TRUE + * If status code indicates failure + * FALSE + * If status code indicates success + * + * @enter None. + * + * @leave None. + * + * @see NOTIFY_FAILED + * + */ +#define NOTIFY_FAILED(status) (!NOTIFY_SUCCEEDED(status)) + + + +/* + * name NOTIFY_SBASE, NOTIFY_SLAST + * + * desc Defines the base and range for the success codes used by the + * Notify module + * + */ +#define NOTIFY_SBASE (signed long int)0x00002000l +#define NOTIFY_SLAST (signed long int)0x000020FFl + +/* + * name NOTIFY_EBASE, NOTIFY_ELAST + * + * desc Defines the base and range for the failure codes used by the + * Notify module + * + */ +#define NOTIFY_EBASE (signed long int)0x80002000l +#define NOTIFY_ELAST (signed long int)0x800020FFl + + +/* + * SUCCESS Codes + * + */ + +/* Generic success code for Notify module */ +#define NOTIFY_SOK (NOTIFY_SBASE + 0x01l) + +/* Indicates that the Notify module (or driver) has already been initialized + * by another client, and this process has now successfully acquired the right + * to use the Notify module. + */ +#define NOTIFY_SALREADYINIT (NOTIFY_SBASE + 0x02l) + +/* Indicates that the Notify module (or driver) is now being finalized, since + * the calling client is the last one finalizing the module, and all open + * handles to it have been closed. + */ +#define NOTIFY_SEXIT (NOTIFY_SBASE + 0x03l) + + +/* + * FAILURE Codes + * + */ + +/* Generic failure code for Notify module */ +#define NOTIFY_EFAIL (NOTIFY_EBASE + 0x01l) + +/* This failure code indicates that an operation has timed out. */ +#define NOTIFY_ETIMEOUT (NOTIFY_EBASE + 0x02l) + +/* This failure code indicates a configuration error */ +#define NOTIFY_ECONFIG (NOTIFY_EBASE + 0x03l) + +/* This failure code indicates that the Notify module has already been + * initialized from the calling client (process). + */ +#define NOTIFY_EALREADYINIT (NOTIFY_EBASE + 0x04l) + +/* This failure code indicates that the specified entity was not found + * The interpretation of this error code depends on the function from which it + * was returned. + */ +#define NOTIFY_ENOTFOUND (NOTIFY_EBASE + 0x05l) + +/* This failure code indicates that the specified feature is not supported + * The interpretation of this error code depends on the function from which it + * was returned. + */ +#define NOTIFY_ENOTSUPPORTED (NOTIFY_EBASE + 0x06l) + +/* This failure code indicates that the specified event number is + * not supported + */ +#define NOTIFY_EINVALIDEVENT (NOTIFY_EBASE + 0x07l) + +/* This failure code indicates that the specified pointer is invalid */ +#define NOTIFY_EPOINTER (NOTIFY_EBASE + 0x08l) + +/* This failure code indicates that a provided parameter was outside its valid + * range. + * The interpretation of this error code depends on the function from which it + * was returned. + */ +#define NOTIFY_ERANGE (NOTIFY_EBASE + 0x09l) + +/* This failure code indicates that the specified handle is invalid */ +#define NOTIFY_EHANDLE (NOTIFY_EBASE + 0x0Al) + +/* This failure code indicates that an invalid argument was specified */ +#define NOTIFY_EINVALIDARG (NOTIFY_EBASE + 0x0Bl) + +/* This failure code indicates a memory related failure */ +#define NOTIFY_EMEMORY (NOTIFY_EBASE + 0x0Cl) + +/* This failure code indicates that the Notify module has not been initialized*/ +#define NOTIFY_EINIT (NOTIFY_EBASE + 0x0Dl) + +/* This failure code indicates that a resource was not available. + * The interpretation of this error code depends on the function from which it + * was returned. + */ +#define NOTIFY_ERESOURCE (NOTIFY_EBASE + 0x0El) + +/* This failure code indicates that there was an attempt to register for a + * reserved event. + */ +#define NOTIFY_ERESERVEDEVENT (NOTIFY_EBASE + 0x0Fl) + +/* This failure code indicates that the specified entity already exists. + * The interpretation of this error code depends on the function from which it + * was returned. + */ +#define NOTIFY_EALREADYEXISTS (NOTIFY_EBASE + 0x10l) + +/* This failure code indicates that the Notify driver has not been fully + * initialized + */ +#define NOTIFY_EDRIVERINIT (NOTIFY_EBASE + 0x11l) + +/* This failure code indicates that the other side is not ready to receive + * notifications. + */ +#define NOTIFY_ENOTREADY (NOTIFY_EBASE + 0x12l) + +#endif /* !defined (NOTIFYERR_H) */ diff --git a/arch/arm/plat-omap/include/syslink/platform.h b/arch/arm/plat-omap/include/syslink/platform.h new file mode 100644 index 000000000000..298d20f7ab5d --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/platform.h @@ -0,0 +1,45 @@ +/* + * platform.h + * + * Defines the platform functions to be used by SysMgr module. + * + * Copyright (C) 2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef _PLATFORM_H_ +#define _PLATFORM_H_ + +/* Module headers */ +#include <sysmgr.h> + +/* ============================================================================= + * APIs + * ============================================================================= + */ +/* Function to setup the platform */ +s32 platform_setup(struct sysmgr_config *config); + +/* Function to destroy the platform */ +s32 platform_destroy(void); + +/* Function called when slave is loaded with executable */ +void platform_load_callback(void *arg); + +/* Function called when slave is in started state*/ +void platform_start_callback(void *arg); + +/* Function called when slave is stopped state */ +void platform_stop_callback(void *arg); + +s32 platform_override_config(struct sysmgr_config *config); + +#endif /* ifndef _PLATFORM_H_ */ diff --git a/arch/arm/plat-omap/include/syslink/platform_mem.h b/arch/arm/plat-omap/include/syslink/platform_mem.h new file mode 100644 index 000000000000..874a1153fc21 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/platform_mem.h @@ -0,0 +1,137 @@ +/* + * platform_mem.c + * + * Target memory management interface implementation. + * + * This abstracts the Memory management interface in the kernel + * code. Allocation, Freeing-up, copy and address translate are + * supported for the kernel memory management. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef _PLATFORM_MEM_H_ +#define _PLATFORM_MEM_H_ + +#include <linux/types.h> + +/* + * MEMORYOS_MODULEID + * Module ID for platform mem module + */ +#define PLATFORM_MEM_MODULEID (u16) 0x97D2 + +/* + * Enumerates the types of caching for memory regions + */ +enum platform_mem_cache_flags { + PLATFORM_MEM_CACHE_FLAGS_DEFAULT = 0x00000000, + /* Default flags - Cached */ + PLATFORM_MEM_CACHE_FLAGS_CACHED = 0x00010000, + /* Cached memory */ + PLATFORM_MEM_CACHE_FLAGS_UNCACHED = 0x00020000, + /* Uncached memory */ + PLATFORM_MEM_CACHE_FLAGS_END_VALUE = 0x00030000 + /* End delimiter indicating start of invalid values for this enum */ +}; + +/* + * Enumerates the types of memory allocation + */ +enum platform_mem_mtype_flags{ + PLATFORM_MEM_MTYPE_FLAGS_DEFAULT = 0x00000000, + /* Default flags - virtually contiguous */ + PLATFORM_MEM_MTYPE_FLAGS_PHYSICAL = 0x00000001, + /* Physically contiguous */ + PLATFORM_MEM_MTYPE_FLAGS_DMA = 0x00000002, + /* Physically contiguous */ + PLATFORM_MEM_MTYPE_FLAGS_END_VALUE = 0x00000003 + /* End delimiter indicating start of invalid values for this enum */ +}; + +/* + * Enumerates the types of translation + */ +enum memory_xlt_flags{ + PLATFORM_MEM_XLT_FLAGS_VIRT2PHYS = 0x00000000, + /* Virtual to physical */ + PLATFORM_MEM_XLT_FLAGS_PHYS2VIRT = 0x00000001, + /* Virtual to physical */ + PLATFORM_MEM_XLT_FLAGS_END_VALUE = 0x00000002 + /* End delimiter indicating start of invalid values for this enum */ +}; + +/* + * Structure containing information required for mapping a + * memory region. + */ +struct platform_mem_map_info { + u32 src; + /* Address to be mapped. */ + u32 size; + /* Size of memory region to be mapped. */ + u32 dst; + /* Mapped address. */ + bool is_cached; + /* Whether the mapping is to a cached area or uncached area. */ + void *drv_handle; + /* Handle to the driver that is implementing the mmap call. Ignored for + Kernel-side version. */ +}; + +/* + * Structure containing information required for unmapping a + * memory region. + */ +struct platform_mem_unmap_info { + u32 addr; + /* Address to be unmapped.*/ + u32 size; + /* Size of memory region to be unmapped.*/ + bool is_cached; + /* Whether the mapping is to a cached area or uncached area. */ +}; + +/* + * Structure containing information required for mapping a + * memory region. + */ +#define memory_map_info struct platform_mem_map_info + +/* + * Structure containing information required for unmapping a + * memory region. + */ +#define memory_unmap_info struct platform_mem_unmap_info + + +/* ============================================================================= + * APIs + * ============================================================================= + */ +/* Initialize the platform mem module. */ +int platform_mem_setup(void); + +/* Finalize the platform mem module. */ +int platform_mem_destroy(void); + +/* Maps a memory area into virtual space. */ +int platform_mem_map(memory_map_info *map_info); + +/* Unmaps a memory area into virtual space. */ +int platform_mem_unmap(memory_unmap_info *unmap_info); + +/* Translate API */ +void *platform_mem_translate(void *srcAddr, enum memory_xlt_flags flags); + +#endif /* ifndef _PLATFORM_MEM_H_ */ + diff --git a/arch/arm/plat-omap/include/syslink/procmgr.h b/arch/arm/plat-omap/include/syslink/procmgr.h new file mode 100644 index 000000000000..4d113c9fa90d --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/procmgr.h @@ -0,0 +1,280 @@ +/* + * procmgr.h + * + * Syslink driver support functions for TI OMAP processors. + * + * Copyright (C) 2009-2010 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ +#ifndef SYSLINK_PROC_MGR_H +#define SYSLINK_PROC_MGR_H + +#include <linux/types.h> +#include <syslink/multiproc.h> + + + +#define PROCMGR_MODULEID 0xf2ba + +/* + * Maximum name length for ProcMgr module strings. + */ +#define PROCMGR_MAX_STRLEN 32 + +/* + * Maximum number of memory regions supported by ProcMgr module. + */ +#define PROCMGR_MAX_MEMORY_REGIONS 32 + +/* + * IS_VALID_PROCID + * Checks if the Processor ID is valid + */ +#define IS_VALID_PROCID(id) (id < MULTIPROC_MAXPROCESSORS) + + +/* + * Enumerations to indicate Processor states. + */ +enum proc_mgr_state { + PROC_MGR_STATE_UNKNOWN = 0, + /* Unknown Processor state (e.g. at startup or error). */ + PROC_MGR_STATE_POWERED = 1, + /* Indicates the Processor is powered up. */ + PROC_MGR_STATE_RESET = 2, + /* Indicates the Processor is reset. */ + PROC_MGR_STATE_LOADED = 3, + /* Indicates the Processor is loaded. */ + PROC_MGR_STATE_RUNNNING = 4, + /* Indicates the Processor is running. */ + PROC_MGR_STATE_UNAVAILABLE = 5, + /* Indicates the Processor is unavailable to the physical transport. */ + PROC_MGR_STATE_ENDVALUE = 6 + /* End delimiter indicating start of invalid values for this enum */ +}; + +/* + * Enumerations to indicate different types of slave boot modes. + */ +enum proc_mgr_boot_mode { + PROC_MGR_BOOTMODE_BOOT = 0, + /* ProcMgr is responsible for loading the slave and its reset control */ + PROC_MGR_BOOTMODE_NOLOAD = 1, + /* ProcMgr is not responsible for loading the slave. It is responsible + for reset control of the slave. */ + PROC_MGR_BOOTMODE_NOBOOT = 2, + /* ProcMgr is not responsible for loading or reset control of the slave. + The slave either self-boots, or this is done by some entity outside of + the ProcMgr module. */ + PROC_MGR_BOOTMODE_ENDVALUE = 3 + /* End delimiter indicating start of invalid values for this enum */ +} ; + +/* + * Enumerations to indicate address types used for translation + */ +enum proc_mgr_addr_type{ + PROC_MGR_ADDRTYPE_MASTERKNLVIRT = 0, + /* Kernel Virtual address on master processor */ + PROC_MGR_ADDRTYPE_MASTERUSRVIRT = 1, + /* User Virtual address on master processor */ + PROC_MGR_ADDRTYPE_SLAVEVIRT = 2, + /* Virtual address on slave processor */ + PROC_MGR_ADDRTYPE_ENDVALUE = 3 + /* End delimiter indicating start of invalid values for this enum */ +}; + +/* + * Enumerations to indicate types of address mapping + */ +enum proc_mgr_map_type { + PROC_MGR_MAPTYPE_VIRT = 0, + /* Map/unmap to virtual address space (kernel/user) */ + PROC_MGR_MAPTYPE_SLAVE = 1, + /* Map/unmap to slave address space */ + PROC_MGR_MAPTYPE_ENDVALUE = 2 + /* End delimiter indicating start of invalid values for this enum */ +}; + +/* + * Module configuration structure. + */ +struct proc_mgr_config { + void *gate_handle; +} ; + +/* + * Configuration parameters specific to the slave ProcMgr instance. + */ +struct proc_mgr_params { + void *proc_handle; + /* void * to the Processor object associated with this ProcMgr. */ + void *loader_handle; + /*!< Handle to the Loader object associated with this ProcMgr. */ + void *pwr_handle; + /*!< Handle to the PwrMgr object associated with this ProcMgr. */ +}; + +/* + * Configuration parameters specific to the slave ProcMgr instance. + */ +struct proc_mgr_attach_params { + enum proc_mgr_boot_mode boot_mode; + /* Boot mode for the slave processor. */ +} ; + +/* + * Configuration parameters to be provided while starting the slave + * processor. + */ +struct proc_mgr_start_params { + u32 proc_id; +}; + +/* + * Configuration parameters to be provided while stopping the slave + * processor. + */ +struct proc_mgr_stop_params { + u32 proc_id; +}; + +/* + * This structure defines information about memory regions mapped by + * the ProcMgr module. + */ +struct proc_mgr_addr_info { +/* bool is_init; */ + unsigned short is_init; + /* Is this memory region initialized? */ + u32 addr[PROC_MGR_ADDRTYPE_ENDVALUE]; + /* Addresses for each type of address space */ + u32 size; + /* Size of the memory region in bytes */ +}; + +/* + * Characteristics of the slave processor + */ +struct proc_mgr_proc_info { + enum proc_mgr_boot_mode boot_mode; + /* Boot mode of the processor. */ + u16 num_mem_entries; + /* Number of valid memory entries */ + struct proc_mgr_addr_info mem_entries[PROCMGR_MAX_MEMORY_REGIONS]; + /* Configuration of memory regions */ +}; + + +/* + * Function pointer type that is passed to the proc_mgr_registerNotify function +*/ +typedef int (*proc_mgr_callback_fxn)(u16 proc_id, void *handle, + enum proc_mgr_state from_state, enum proc_mgr_state to_state); + +/* Function to get the default configuration for the ProcMgr module. */ +void proc_mgr_get_config(struct proc_mgr_config *cfg); + +/* Function to setup the ProcMgr module. */ +int proc_mgr_setup(struct proc_mgr_config *cfg); + +/* Function to destroy the ProcMgr module. */ +int proc_mgr_destroy(void); + +/* Function to initialize the parameters for the ProcMgr instance. */ +void proc_mgr_params_init(void *handle, struct proc_mgr_params *params); + +/* Function to create a ProcMgr object for a specific slave processor. */ +void *proc_mgr_create(u16 proc_id, const struct proc_mgr_params *params); + +/* Function to delete a ProcMgr object for a specific slave processor. */ +int proc_mgr_delete(void **handle_ptr); + +/* Function to open a handle to an existing ProcMgr object handling the + * proc_id. + */ +int proc_mgr_open(void **handle, u16 proc_id); + +/* Function to close this handle to the ProcMgr instance. */ +int proc_mgr_close(void *handle); + +/* Function to initialize the parameters for the ProcMgr attach function. */ +void proc_mgr_get_attach_params(void *handle, + struct proc_mgr_attach_params *params); + +/* Function to attach the client to the specified slave and also initialize the + * slave(if required). + */ +int proc_mgr_attach(void *handle, struct proc_mgr_attach_params *params); + +/* Function to detach the client from the specified slave and also finalze the + * slave(if required). + */ +int proc_mgr_detach(void *handle); + +/* Function to initialize the parameters for the ProcMgr start function. */ +void proc_mgr_get_start_params(void *handle, + struct proc_mgr_start_params *params); + +/* Function to starts execution of the loaded code on the slave from the + * starting point specified in the slave executable loaded earlier by call to + * proc_mgr_load(). + */ +int proc_mgr_start(void *handle, u32 entry_point, + struct proc_mgr_start_params *params); + +/* Function to stop execution of the slave Processor. */ +int proc_mgr_stop(void *handle, struct proc_mgr_stop_params *params); + +/* Function to get the current state of the slave Processor as maintained on + * the master Processor state machine. + */ +enum proc_mgr_state proc_mgr_get_state(void *handle); + +/* Function to read from the slave Processor's memory space. */ +int proc_mgr_read(void *handle, u32 proc_addr, u32 *num_bytes, + void *buffer); + +/* Function to read from the slave Processor's memory space. */ +int proc_mgr_write(void *handle, u32 proc_addr, u32 *num_bytes, void *buffer); + +/* Function that provides a hook for performing device dependent operations on + * the slave Processor. + */ +int proc_mgr_control(void *handle, int cmd, void *arg); + +int proc_mgr_translate_addr(void *handle, void **dst_addr, + enum proc_mgr_addr_type dst_addr_type, void *src_addr, + enum proc_mgr_addr_type src_addr_type); + +/* Function that maps the specified slave address to master address space. */ +int proc_mgr_map(void *handle, u32 proc_addr, u32 size, + u32 *mappedAddr, u32 *mapped_size, u32 map_attribs); + +/* Function that unmaps the specified slave address to master address space. */ +int proc_mgr_unmap(void *handle, u32 mapped_addr); + +/* Function that registers for notification when the slave processor + * transitions to any of the states specified. + */ +int proc_mgr_register_notify(void *handle, proc_mgr_callback_fxn fxn, + void *args, enum proc_mgr_state state[]); + +/* Function that returns information about the characteristics of the slave + * processor. + */ +int proc_mgr_get_proc_info(void *handle, struct proc_mgr_proc_info *proc_info); + +/* Function that returns virtual to physical translations + */ +int proc_mgr_virt_to_phys(void *handle, u32 da, u32 *mapped_entries, + u32 num_of_entries); + +#endif diff --git a/arch/arm/plat-omap/include/syslink/sharedregion.h b/arch/arm/plat-omap/include/syslink/sharedregion.h new file mode 100644 index 000000000000..75fe48049b5e --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/sharedregion.h @@ -0,0 +1,110 @@ +/* + * sharedregion.h + * + * The SharedRegion module is designed to be used in a + * multi-processor environment where there are memory regions + * that are shared and accessed across different processors + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef _SHAREDREGION_H_ +#define _SHAREDREGION_H_ + +#include <linux/types.h> + +/* + * SHAREDREGION_MODULEID + * Module ID for Shared region manager + */ +#define SHAREDREGION_MODULEID (0x5D8A) + +/* + * Name of the reserved nameserver used for application + */ +#define SHAREDREGION_NAMESERVER "SHAREDREGION" + +/* + * Name of the reserved nameserver used for application + */ +#define SHAREDREGION_INVALIDSRPTR ((u32 *)0xFFFFFFFF) + + +struct sharedregion_info { + bool is_valid; /* table entry is valid or not? */ + void *base; /* Ptr to the base address of a table entry */ + u32 len; /* The length of a table entry */ +}; + +/* + * Module configuration structure + */ +struct sharedregion_config { + void *gate_handle; + void *heap_handle; + u32 max_regions; +}; + +/* + * Function to get the configuration + */ +int sharedregion_get_config(struct sharedregion_config *config); + +/* + * Function to setup the SharedRegion module + */ +int sharedregion_setup(const struct sharedregion_config *config); + +/* + * Function to destroy the SharedRegion module + */ +int sharedregion_destroy(void); + +/* Fucntion to Add a memory segment to the lookup table during + * runtime by base and length + */ +int sharedregion_add(u32 index, void *base, u32 len); + +/* Removes the memory segment at the specified index from the lookup + * table at runtime + */ +int sharedregion_remove(u32 index); + +/* + * Returns the index for the specified address pointer + */ +int sharedregion_get_index(void *addr); + +/* + * Returns the address pointer associated with the shared region pointer + */ +void *sharedregion_get_ptr(u32 *srptr); + +/* + * Returns the shared region pointer + */ +u32 *sharedregion_get_srptr(void *addr, int index); + +/* + * Gets the table entry information for the specified index and processor id + */ +int sharedregion_get_table_info(u32 index, u16 proc_id, + struct sharedregion_info *info); + +/* + * Sets the base address of the entry in the table + */ +int sharedregion_set_table_info(u32 index, u16 proc_id, + struct sharedregion_info *info); + +#endif /* _SHAREDREGION_H */ + diff --git a/arch/arm/plat-omap/include/syslink/sharedregion_ioctl.h b/arch/arm/plat-omap/include/syslink/sharedregion_ioctl.h new file mode 100644 index 000000000000..0b2857110991 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/sharedregion_ioctl.h @@ -0,0 +1,181 @@ +/* + * sharedregion_ioctl.h + * + * The sharedregion module is designed to be used in a + * multi-processor environment where there are memory regions + * that are shared and accessed across different processors + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef _SHAREDREGION_IOCTL_H +#define _SHAREDREGION_IOCTL_H + +#include <linux/ioctl.h> +#include <linux/types.h> + +#include <ipc_ioctl.h> +#include <sharedregion.h> + +enum CMD_SHAREDREGION { + SHAREDREGION_GETCONFIG = SHAREDREGION_BASE_CMD, + SHAREDREGION_SETUP, + SHAREDREGION_DESTROY, + SHAREDREGION_ADD, + SHAREDREGION_GETPTR, + SHAREDREGION_GETSRPTR, + SHAREDREGION_GETTABLEINFO, + SHAREDREGION_REMOVE, + SHAREDREGION_SETTABLEINFO, + SHAREDREGION_GETINDEX, +}; + +/* + * IOCTL command IDs for sharedregion + * + */ + +/* + * Command for sharedregion_get_config + */ +#define CMD_SHAREDREGION_GETCONFIG _IOWR(IPC_IOC_MAGIC, \ + SHAREDREGION_GETCONFIG, \ + struct sharedregion_cmd_args) +/* + * Command for sharedregion_setup + */ +#define CMD_SHAREDREGION_SETUP _IOWR(IPC_IOC_MAGIC, \ + SHAREDREGION_SETUP, \ + struct sharedregion_cmd_args) +/* + * Command for sharedregion_setup + */ +#define CMD_SHAREDREGION_DESTROY _IOWR(IPC_IOC_MAGIC, \ + SHAREDREGION_DESTROY, \ + struct sharedregion_cmd_args) +/* + * Command for sharedregion_ADD + */ +#define CMD_SHAREDREGION_ADD _IOWR(IPC_IOC_MAGIC, \ + SHAREDREGION_ADD, \ + struct sharedregion_cmd_args) +/* + * Command for sharedregion_get_ptr + */ +#define CMD_SHAREDREGION_GETPTR _IOWR(IPC_IOC_MAGIC, \ + SHAREDREGION_GETPTR, \ + struct sharedregion_cmd_args) + +/* + * Command for sharedregion_get_srptr + */ +#define CMD_SHAREDREGION_GETSRPTR _IOWR(IPC_IOC_MAGIC, \ + SHAREDREGION_GETSRPTR, \ + struct sharedregion_cmd_args) + +/* + * Command for sharedregion_get_table_info + */ +#define CMD_SHAREDREGION_GETTABLEINFO _IOWR(IPC_IOC_MAGIC, \ + SHAREDREGION_GETTABLEINFO, \ + struct sharedregion_cmd_args) + +/* + * Command for sharedregion_remove + */ +#define CMD_SHAREDREGION_REMOVE _IOWR(IPC_IOC_MAGIC, \ + SHAREDREGION_REMOVE, \ + struct sharedregion_cmd_args) +/* + * Command for sharedregion_set_table_info + */ +#define CMD_SHAREDREGION_SETTABLEINFO _IOWR(IPC_IOC_MAGIC, \ + SHAREDREGION_SETTABLEINFO, \ + struct sharedregion_cmd_args) + +/* + * Command for sharedregion_get_index + */ +#define CMD_SHAREDREGION_GETINDEX _IOWR(IPC_IOC_MAGIC, \ + SHAREDREGION_GETINDEX, \ + struct sharedregion_cmd_args) + +/* + * Command arguments for sharedregion + */ +union sharedregion_arg { + struct { + struct sharedregion_config *config; + } get_config; + + struct { + struct sharedregion_config *config; + struct sharedregion_config *default_cfg; + struct sharedregion_info *table; + } setup; + + struct { + u32 index; + void *base; + u32 len; + } add; + + struct { + void *addr; + s32 index; + } get_index; + + struct { + u32 *srptr; + void *addr; + } get_ptr; + + struct { + u32 *srptr; + void *addr; + s32 index; + } get_srptr; + + struct { + u32 index; + u16 proc_id; + struct sharedregion_info *info; + } get_table_info; + + struct { + u32 index; + } remove; + + struct { + u32 index; + u16 proc_id; + struct sharedregion_info *info; + } set_table_info; +} ; + +/* + * Command arguments for sharedregion + */ +struct sharedregion_cmd_args { + union sharedregion_arg args; + s32 api_status; +}; + +/* + * This ioctl interface for sharedregion module + */ +int sharedregion_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long args); + +#endif /* _SHAREDREGION_IOCTL_H */ + + diff --git a/arch/arm/plat-omap/include/syslink/sysmemmgr.h b/arch/arm/plat-omap/include/syslink/sysmemmgr.h new file mode 100644 index 000000000000..34c3b4182288 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/sysmemmgr.h @@ -0,0 +1,179 @@ +/* + * sysmemmgr.h + * + * Manager for the Slave system memory. Slave system level memory is allocated + * through this module. + * + * Copyright (C) 2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + + +#ifndef _SYSTEMMEMORYMANAGER_H_ +#define _SYSTEMMEMORYMANAGER_H_ + + +/*! + * @def SYSMEMMGR_MODULEID + * @brief Module identifier for System memory manager. + */ +#define SYSMEMMGR_MODULEID (0xb53d) + +/*! + * @def SYSMEMMGR_STATUSCODEBASE + * @brief Error code base for system memory manager module. + */ +#define SYSMEMMGR_STATUSCODEBASE (SYSMEMMGR_MODULEID << 12u) + +/*! + * @def SYSMEMMGR_MAKE_ERROR + * @brief Macro to make error code. + */ +#define SYSMEMMGR_MAKE_ERROR(x) ((int)(0x80000000 + \ + (SYSMEMMGR_STATUSCODEBASE + \ + (x)))) + +/*! + * @def SYSMEMMGR_MAKE_SUCCESS + * @brief Macro to make success code. + */ +#define SYSMEMMGR_MAKE_SUCCESS(x) (SYSMEMMGR_STATUSCODEBASE + (x)) + +/*! + * @def SYSMEMMGR_E_CREATEALLOCATOR + * @brief Static allocator creation failed. + */ +#define SYSMEMMGR_E_CREATEALLOCATOR SYSMEMMGR_MAKE_ERROR(1) + +/*! + * @def SYSMEMMGR_E_CREATELOCK + * @brief Mutex lock creation failed. + */ +#define SYSMEMMGR_E_CREATELOCK SYSMEMMGR_MAKE_ERROR(2) + +/*! + * @def SYSMEMMGR_E_INVALIDSTATE + * @brief Module is not initialized. + */ +#define SYSMEMMGR_E_INVALIDSTATE SYSMEMMGR_MAKE_ERROR(3) + +/*! + * @def SYSMEMMGR_E_INVALIDARG + * @brief Argument passed to a function is invalid. + */ +#define SYSMEMMGR_E_INVALIDARG SYSMEMMGR_MAKE_ERROR(4) + +/*! + * @def SYSMEMMGR_E_BPAFREE + * @brief Freeing to buddy allocator failed. + */ +#define SYSMEMMGR_E_BPAFREE SYSMEMMGR_MAKE_ERROR(5) + +/*! + * @def SYSMEMMGR_E_MEMORY + * @brief Memory allocation failed. + */ +#define SYSMEMMGR_E_MEMORY SYSMEMMGR_MAKE_ERROR(6) + +/*! + * @def SYSMEMMGR_SUCCESS + * @brief Operation successful. + */ +#define SYSMEMMGR_SUCCESS SYSMEMMGR_MAKE_SUCCESS(0) + +/*! + * @def SYSMEMMGR_S_ALREADYSETUP + * @brief Module already initialized. + */ +#define SYSMEMMGR_S_ALREADYSETUP SYSMEMMGR_MAKE_SUCCESS(1) + +/*! + * @def SYSMEMMGR_S_DRVALREADYOPENED + * @brief Internal OS Driver is already opened. + */ +#define SYSMEMMGR_S_DRVALREADYOPENED SYSMEMMGR_MAKE_SUCCESS(2) + +/*! + * @brief Configuration data structure of system memory manager. + */ +struct sysmemmgr_config { + u32 sizeof_valloc; + /* Total size for virtual memory allocation */ + u32 sizeof_palloc; + /* Total size for physical memory allocation */ + u32 static_phys_base_addr; + /* Physical address of static memory region */ + u32 static_virt_base_addr; + /* Virtual address of static memory region */ + u32 static_mem_size; + /* size of static memory region */ + u32 page_size; + /* Page size */ + u32 event_no; + /* Event number to be used */ +}; + +/*! + * @brief Flag used for allocating memory blocks. + */ +enum sysmemmgr_allocflag { + sysmemmgr_allocflag_uncached = 0u, + /* Flag used for allocating uncacheable block */ + sysmemmgr_allocflag_cached = 1u, + /* Flag used for allocating cacheable block */ + sysmemmgr_allocflag_physical = 2u, + /* Flag used for allocating physically contiguous block */ + sysmemmgr_allocflag_virtual = 3u, + /* Flag used for allocating virtually contiguous block */ + sysmemmgr_allocflag_dma = 4u + /* Flag used for allocating DMAable (physically contiguous) block */ +}; + +/*! + * @brief Flag used for translating address. + */ +enum sysmemmgr_xltflag { + sysmemmgr_xltflag_kvirt2phys = 0x0001u, + /* Flag used for converting Kernel virtual address to physical + * address */ + sysmemmgr_xltflag_kvirt2uvirt = 0x0002u, + /* Flag used for converting Kernel virtual address to user virtual + * address */ + sysmemmgr_xltflag_uvirt2phys = 0x0003u, + /* Flag used for converting user virtual address to physical address */ + sysmemmgr_xltflag_uvirt2kvirt = 0x0004u, + /* Flag used for converting user virtual address to Kernel virtual + * address */ + sysmemmgr_xltflag_phys2kvirt = 0x0005u, + /* Flag used for converting physical address to user virtual address */ + sysmemmgr_xltflag_phys2uvirt = 0x0006u + /* Flag used for converting physical address to Kernel virtual + * address */ +}; + + +/* Function prototypes */ +void sysmemmgr_get_config(struct sysmemmgr_config *config); + +int sysmemmgr_setup(struct sysmemmgr_config *params); + +int sysmemmgr_destroy(void); + +int sysmemmgr_attach(u16 slave_id); + +void *sysmemmgr_alloc(u32 size, enum sysmemmgr_allocflag flag); + +int sysmemmgr_free(void *blk, u32 size, enum sysmemmgr_allocflag flag); + +void *sysmemmgr_translate(void *srcAddr, enum sysmemmgr_xltflag flag); + + +#endif /* _SYSTEMMEMORYMANAGER_H_ */ diff --git a/arch/arm/plat-omap/include/syslink/sysmemmgr_ioctl.h b/arch/arm/plat-omap/include/syslink/sysmemmgr_ioctl.h new file mode 100644 index 000000000000..4b0d99615560 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/sysmemmgr_ioctl.h @@ -0,0 +1,130 @@ +/* + * sysmemmgr_ioctl.h + * + * Definitions of sysmemmgr driver types and structures.. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef _SYSMEMMGR_IOCTL_H_ +#define _SYSMEMMGR_IOCTL_H_ + +/* Standard headers */ +#include <linux/types.h> + +/* Syslink headers */ +#include <ipc_ioctl.h> +#include <sysmgr.h> + + +/* ============================================================================= + * Macros and types + * ============================================================================= + */ +/* ---------------------------------------------------------------------------- + * IOCTL command IDs for sysmemmgr + * ---------------------------------------------------------------------------- + */ +/* IOC Magic Number for sysmemmgr */ +#define SYSMEMMGR_IOC_MAGIC IPC_IOC_MAGIC + +/* IOCTL command numbers for sysmemmgr */ +enum sysmemmgr_drv_cmd { + SYSMEMMGR_GETCONFIG = SYSMEMMGR_BASE_CMD, + SYSMEMMGR_SETUP, + SYSMEMMGR_DESTROY, + SYSMEMMGR_ALLOC, + SYSMEMMGR_FREE, + SYSMEMMGR_TRANSLATE +}; + +/* Command for sysmemmgr_getConfig */ +#define CMD_SYSMEMMGR_GETCONFIG \ + _IOWR(SYSMEMMGR_IOC_MAGIC, SYSMEMMGR_GETCONFIG, \ + struct sysmemmgr_cmd_args) + +/* Command for sysmemmgr_setup */ +#define CMD_SYSMEMMGR_SETUP \ + _IOWR(SYSMEMMGR_IOC_MAGIC, SYSMEMMGR_SETUP, \ + struct sysmemmgr_cmd_args) + +/* Command for sysmemmgr_destroy */ +#define CMD_SYSMEMMGR_DESTROY \ + _IOWR(SYSMEMMGR_IOC_MAGIC, SYSMEMMGR_DESTROY, \ + struct sysmemmgr_cmd_args) + +/* Command for sysmemmgr_alloc */ +#define CMD_SYSMEMMGR_ALLOC \ + _IOWR(SYSMEMMGR_IOC_MAGIC, SYSMEMMGR_ALLOC, \ + struct sysmemmgr_cmd_args) + +/* Command for sysmemmgr_free */ +#define CMD_SYSMEMMGR_FREE \ + _IOWR(SYSMEMMGR_IOC_MAGIC, SYSMEMMGR_FREE, \ + struct sysmemmgr_cmd_args) + +/* Command for sysmemmgr_translate */ +#define CMD_SYSMEMMGR_TRANSLATE \ + _IOWR(SYSMEMMGR_IOC_MAGIC, SYSMEMMGR_TRANSLATE, \ + struct sysmemmgr_cmd_args) + + +/* ---------------------------------------------------------------------------- + * Command arguments for sysmemmgr + * ---------------------------------------------------------------------------- + */ +/* Command arguments for sysmemmgr */ +struct sysmemmgr_cmd_args { + union { + struct { + struct sysmemmgr_config *config; + } get_config; + + struct { + struct sysmemmgr_config *config; + } setup; + + struct { + u32 size; + void *buf; + void *phys; + void *kbuf; + enum sysmemmgr_allocflag flags; + } alloc; + + struct { + u32 size; + void *buf; + void *phys; + void *kbuf; + enum sysmemmgr_allocflag flags; + } free; + + struct { + void *buf; + void *ret_ptr; + enum sysmemmgr_xltflag flags; + } translate; + } args; + + s32 api_status; +}; + +/* ---------------------------------------------------------------------------- + * IOCTL functions for sysmemmgr module + * ---------------------------------------------------------------------------- + */ +/* ioctl interface function for sysmemmgr */ +int sysmemmgr_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long args); + +#endif /* SYSMEMMGR_DRVDEFS_H_0xF414 */ diff --git a/arch/arm/plat-omap/include/syslink/sysmgr.h b/arch/arm/plat-omap/include/syslink/sysmgr.h new file mode 100644 index 000000000000..19fab220b2c4 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/sysmgr.h @@ -0,0 +1,182 @@ +/* + * sysmgr.h + * + * Defines for System manager. + * + * Copyright (C) 2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef _SYSMGR_H_ +#define _SYSMGR_H_ + + +/* Module headers */ +#include <multiproc.h> +#include <gatepeterson.h> +#include <sharedregion.h> +#include <listmp.h> +#include <listmp_sharedmemory.h> +#include <messageq.h> +#include <messageq_transportshm.h> +#include <notify.h> +#include <notify_ducatidriver.h> +#include <nameserver.h> +#include <nameserver_remote.h> +#include <nameserver_remotenotify.h> +#include <procmgr.h> +#include <heap.h> +#include <heapbuf.h> +#include <sysmemmgr.h> + + +/*! + * @def SYSMGR_MODULEID + * @brief Unique module ID. + */ +#define SYSMGR_MODULEID (0xF086) + + +/* ============================================================================= + * Module Success and Failure codes + * ============================================================================= + */ +/*! + * @def SYSMGR_STATUSCODEBASE + * @brief Error code base for System manager. + */ +#define SYSMGR_STATUSCODEBASE (SYSMGR_MODULEID << 12u) + +/*! + * @def SYSMGR_MAKE_FAILURE + * @brief Macro to make error code. + */ +#define SYSMGR_MAKE_FAILURE(x) ((s32)(0x80000000 + \ + (SYSMGR_STATUSCODEBASE + \ + (x)))) + +/*! + * @def SYSMGR_MAKE_SUCCESS + * @brief Macro to make success code. + */ +#define SYSMGR_MAKE_SUCCESS(x) (SYSMGR_STATUSCODEBASE + (x)) + +/*! + * @def SYSMGR_E_INVALIDARG + * @brief Argument passed to a function is invalid. + */ +#define SYSMGR_E_INVALIDARG SYSMGR_MAKE_FAILURE(1) + +/*! + * @def SYSMGR_E_MEMORY + * @brief Memory allocation failed. + */ +#define SYSMGR_E_MEMORY SYSMGR_MAKE_FAILURE(2) + +/*! + * @def SYSMGR_E_FAIL + * @brief General failure. + */ +#define SYSMGR_E_FAIL SYSMGR_MAKE_FAILURE(3) + +/*! + * @def SYSMGR_E_INVALIDSTATE + * @brief Module is in invalid state. + */ +#define SYSMGR_E_INVALIDSTATE SYSMGR_MAKE_FAILURE(4) + +/*! + * @def SYSMGR_E_OSFAILURE + * @brief Failure in OS call. + */ +#define SYSMGR_E_OSFAILURE SYSMGR_MAKE_FAILURE(5) + +/*! + * @def SYSMGR_S_ALREADYSETUP + * @brief Module is already initialized. + */ +#define SYSMGR_S_ALREADYSETUP SYSMGR_MAKE_SUCCESS(1) + +/*! + * @def SYSMGR_CMD_SCALABILITY + * @brief Command ID for scalability info. + */ +#define SYSMGR_CMD_SCALABILITY (0x00000000) + +/*! + * @def SYSMGR_CMD_SHAREDREGION_ENTRY_BASE + * @brief Base of command IDs for entries used by Shared region. + */ +#define SYSMGR_CMD_SHAREDREGION_ENTRY_START (0x00000001) +#define SYSMGR_CMD_SHAREDREGION_ENTRY_END (0x00001000) + + +/* ============================================================================= + * Structures & Enums + * ============================================================================= + */ +/*! + * @brief Structure defining config parameters for overall System. + */ +struct sysmgr_config { + struct sysmemmgr_config sysmemmgr_cfg; + /*!< System memory manager config parameter */ + + struct multiproc_config multiproc_cfg; + /*!< Multiproc config parameter */ + + struct gatepeterson_config gatepeterson_cfg; + /*!< Gatepeterson config parameter */ + + struct sharedregion_config sharedregion_cfg; + /*!< SharedRegion config parameter */ + + struct messageq_config messageq_cfg; + /*!< MessageQ config parameter */ + + struct notify_config notify_cfg; + /*!< Notify config parameter */ + + struct proc_mgr_config proc_mgr_cfg; + /*!< Processor manager config parameter */ + + struct heapbuf_config heapbuf_cfg; + /*!< Heap Buf config parameter */ + + struct listmp_config listmp_sharedmemory_cfg; + /*!< ListMPSharedMemory config parameter */ + + struct messageq_transportshm_config messageq_transportshm_cfg; + /*!< MessageQTransportShm config parameter */ + + struct notify_ducatidrv_config notify_ducatidrv_cfg; + /*!< NotifyDriverShm config parameter */ + + struct nameserver_remotenotify_config nameserver_remotenotify_cfg; + /*!< NameServerRemoteNotify config parameter */ +}; + + +/* ============================================================================= + * APIs + * ============================================================================= + */ +/* Function to initialize the parameter structure */ +void sysmgr_get_config(struct sysmgr_config *config); + +/* Function to initialize sysmgr module */ +s32 sysmgr_setup(const struct sysmgr_config *config); + +/* Function to Finalize sysmgr module */ +s32 sysmgr_destroy(void); + + +#endif /* ifndef SYSMGR_H_0xF086 */ diff --git a/arch/arm/plat-omap/include/syslink/sysmgr_ioctl.h b/arch/arm/plat-omap/include/syslink/sysmgr_ioctl.h new file mode 100644 index 000000000000..03db7b9511a2 --- /dev/null +++ b/arch/arm/plat-omap/include/syslink/sysmgr_ioctl.h @@ -0,0 +1,100 @@ +/* + * sysmgr_ioctl.h + * + * Definitions of sysmgr driver types and structures.. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef _SYSMGR_IOCTL_H_ +#define _SYSMGR_IOCTL_H_ + +/* Standard headers */ +#include <linux/types.h> + +/* Syslink headers */ +#include <ipc_ioctl.h> +#include <sysmgr.h> + + +/* ============================================================================= + * Macros and types + * ============================================================================= + */ +/* ---------------------------------------------------------------------------- + * IOCTL command IDs for sysmgr + * ---------------------------------------------------------------------------- + */ +/* IOC Magic Number for sysmgr */ +#define SYSMGR_IOC_MAGIC IPC_IOC_MAGIC + +/* IOCTL command numbers for sysmgr */ +enum sysmgr_drv_cmd { + SYSMGR_SETUP = SYSMGR_BASE_CMD, + SYSMGR_DESTROY, + SYSMGR_LOADCALLBACK, + SYSMGR_STARTCALLBACK, + SYSMGR_STOPCALLBACK +}; + +/* Command for sysmgr_setup */ +#define CMD_SYSMGR_SETUP \ + _IOWR(SYSMGR_IOC_MAGIC, SYSMGR_SETUP, \ + struct sysmgr_cmd_args) + +/* Command for sysmgr_destroy */ +#define CMD_SYSMGR_DESTROY \ + _IOWR(SYSMGR_IOC_MAGIC, SYSMGR_DESTROY, \ + struct sysmgr_cmd_args) + +/* Command for load callback */ +#define CMD_SYSMGR_LOADCALLBACK \ + _IOWR(SYSMGR_IOC_MAGIC, SYSMGR_LOADCALLBACK, \ + struct sysmgr_cmd_args) + +/* Command for load callback */ +#define CMD_SYSMGR_STARTCALLBACK \ + _IOWR(SYSMGR_IOC_MAGIC, SYSMGR_STARTCALLBACK, \ + struct sysmgr_cmd_args) + +/* Command for stop callback */ +#define CMD_SYSMGR_STOPCALLBACK \ + _IOWR(SYSMGR_IOC_MAGIC, SYSMGR_STOPCALLBACK, \ + struct sysmgr_cmd_args) + + +/* ---------------------------------------------------------------------------- + * Command arguments for sysmgr + * ---------------------------------------------------------------------------- + */ +/* Command arguments for sysmgr */ +struct sysmgr_cmd_args { + union { + struct { + struct sysmgr_config *config; + } setup; + + int proc_id; + } args; + + s32 api_status; +}; + +/* ---------------------------------------------------------------------------- + * IOCTL functions for sysmgr module + * ---------------------------------------------------------------------------- + */ +/* ioctl interface function for sysmgr */ +int sysmgr_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long args); + +#endif /* _SYSMGR_IOCTL_H_ */ diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index c0ff1e39d893..761df23150fd 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c @@ -171,15 +171,12 @@ static void iotlb_lock_get(struct iommu *obj, struct iotlb_lock *l) l->base = MMU_LOCK_BASE(val); l->vict = MMU_LOCK_VICT(val); - BUG_ON(l->base != 0); /* Currently no preservation is used */ } static void iotlb_lock_set(struct iommu *obj, struct iotlb_lock *l) { u32 val; - BUG_ON(l->base != 0); /* Currently no preservation is used */ - val = (l->base << MMU_LOCK_BASE_SHIFT); val |= (l->vict << MMU_LOCK_VICT_SHIFT); @@ -241,7 +238,7 @@ int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e) break; } - if (i == obj->nr_tlb_entries) { + if (i == obj->nr_tlb_entries || (l.base == obj->nr_tlb_entries)) { dev_dbg(obj->dev, "%s: full: no entry\n", __func__); err = -EBUSY; goto out; @@ -252,13 +249,18 @@ int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e) clk_disable(obj->clk); return PTR_ERR(cr); } - iotlb_load_cr(obj, cr); kfree(cr); + /* Increment base number if preservation is set */ + if (e->prsvd) + l.base++; /* increment victim for next tlb load */ - if (++l.vict == obj->nr_tlb_entries) - l.vict = 0; + if (++l.vict == obj->nr_tlb_entries) { + l.vict = l.base; + goto out; + } + iotlb_lock_set(obj, &l); out: clk_disable(obj->clk); @@ -862,10 +864,12 @@ static int __devinit omap_iommu_probe(struct platform_device *pdev) if (!obj) return -ENOMEM; - obj->clk = clk_get(&pdev->dev, pdata->clk_name); - if (IS_ERR(obj->clk)) - goto err_clk; - + /* FIX ME: OMAP4 PM framework not ready */ + if (!cpu_is_omap44xx()) { + obj->clk = clk_get(&pdev->dev, pdata->clk_name); + if (IS_ERR(obj->clk)) + goto err_clk; + } obj->nr_tlb_entries = pdata->nr_tlb_entries; obj->name = pdata->name; obj->dev = &pdev->dev; diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index 8e90633e4cb9..bf239b682053 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -28,6 +28,7 @@ #include <plat/mailbox.h> +static struct workqueue_struct *mboxd; static struct omap_mbox *mboxes; static DEFINE_RWLOCK(mboxes_lock); @@ -70,11 +71,10 @@ static int __mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg) int ret = 0, i = 1000; while (mbox_fifo_full(mbox)) { - if (mbox->ops->type == OMAP_MBOX_TYPE2) - return -1; if (--i == 0) return -1; udelay(1); + printk(KERN_ERR "Mailbox FIFO full %d\n", i); } mbox_fifo_write(mbox, msg); return ret; @@ -83,7 +83,13 @@ static int __mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg) int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg) { + /* Directly calling __mbox_msg_send since Tesla is already running + in a tasklet */ + return __mbox_msg_send(mbox, msg); + /* FIXME Work queue is not used to send mailbox messages. + Directly calling __mbox_msg_send().*/ +#if 0 struct request *rq; struct request_queue *q = mbox->txq->queue; @@ -95,6 +101,7 @@ int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg) tasklet_schedule(&mbox->txq->tasklet); return 0; +#endif } EXPORT_SYMBOL(omap_mbox_msg_send); @@ -135,6 +142,7 @@ static void mbox_rx_work(struct work_struct *work) mbox_msg_t msg; unsigned long flags; + while (1) { spin_lock_irqsave(q->queue_lock, flags); rq = blk_fetch_request(q); @@ -146,6 +154,7 @@ static void mbox_rx_work(struct work_struct *work) blk_end_request_all(rq, 0); mbox->rxq->callback((void *)msg); } + } /* @@ -179,7 +188,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox) msg = mbox_fifo_read(mbox); - + rq->special = (void *)msg; blk_insert_request(q, rq, 0, (void *)msg); if (mbox->ops->type == OMAP_MBOX_TYPE1) break; @@ -188,7 +197,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox) /* no more messages in the fifo. clear IRQ source. */ ack_mbox_irq(mbox, IRQ_RX); nomem: - schedule_work(&mbox->rxq->work); + queue_work(mboxd, &mbox->rxq->work); } static irqreturn_t mbox_interrupt(int irq, void *p) @@ -401,12 +410,17 @@ EXPORT_SYMBOL(omap_mbox_unregister); static int __init omap_mbox_init(void) { + mboxd = create_workqueue("mboxd"); + if (!mboxd) + return -ENOMEM; + return 0; } module_init(omap_mbox_init); static void __exit omap_mbox_exit(void) { + destroy_workqueue(mboxd); } module_exit(omap_mbox_exit); diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index 8eb8fb8654e6..5671c3f9444a 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -37,6 +37,7 @@ void omap_mcbsp_write(void __iomem *io_base, u16 reg, u32 val) else __raw_writel(val, io_base + reg); } +EXPORT_SYMBOL(omap_mcbsp_write); int omap_mcbsp_read(void __iomem *io_base, u16 reg) { @@ -45,6 +46,7 @@ int omap_mcbsp_read(void __iomem *io_base, u16 reg) else return __raw_readl(io_base + reg); } +EXPORT_SYMBOL(omap_mcbsp_read); #define OMAP_MCBSP_READ(base, reg) \ omap_mcbsp_read(base, OMAP_MCBSP_REG_##reg) diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index f60a5400a25b..bf4734bf50fa 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -525,7 +525,7 @@ static int __init vfp_init(void) */ elf_hwcap |= HWCAP_VFP; #ifdef CONFIG_VFPv3 - if (VFP_arch >= 3) { + if (VFP_arch >= 2) { elf_hwcap |= HWCAP_VFPv3; /* diff --git a/drivers/Kconfig b/drivers/Kconfig index 960708d2eae9..5f74e0e182e9 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -118,4 +118,6 @@ source "drivers/media/video/dmm/Kconfig" source "drivers/media/video/tiler/Kconfig" +source "drivers/dsp/syslink/Kconfig" + endmenu diff --git a/drivers/Makefile b/drivers/Makefile index 6165649b4fa9..1b398f902259 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -112,4 +112,9 @@ obj-$(CONFIG_STAGING) += staging/ obj-y += platform/ obj-y += ieee802154/ obj-$(CONFIG_DMM_OMAP) += media/ -obj-$(CONFIG_TILER_OMAP) += media/ +obj-$(CONFIG_TILER_OMAP) += media/ +obj-$(CONFIG_MPU_SYSLINK_IPC) += dsp/syslink/multicore_ipc/ +obj-$(CONFIG_MPU_BRIDGE_NOTIFY) += dsp/syslink/omap_notify/ +obj-$(CONFIG_NOTIFY_DUCATI) += dsp/syslink/notify_ducatidriver/ +obj-$(CONFIG_SYSLINK_PROC) += dsp/syslink/procmgr/ +obj-$(CONFIG_SYSLINK_PROC4430) += dsp/syslink/procmgr/proc4430/ diff --git a/drivers/dsp/syslink/Kconfig b/drivers/dsp/syslink/Kconfig new file mode 100755 index 000000000000..63752e2f2a5d --- /dev/null +++ b/drivers/dsp/syslink/Kconfig @@ -0,0 +1,62 @@ +menuconfig Sys_Link + bool "Sys_Link" + default y +if Sys_Link + +config SYSLINK_PROC + tristate "Syslink ProcMgr" + default y + help + Syslink Proc manager + +config SYSLINK_PROC4430 + tristate "Proc 4430" + depends on SYSLINK_PROC + default y + help + Ducati Proc implementation + +config MPU_BRIDGE_NOTIFY + tristate "OMAP Notify Module" + default y + select OMAP_MBOX_FWK + help + Notify Module + + +config NOTIFY_DUCATI + tristate "OMAP Notify Ducati Module" + depends on MPU_BRIDGE_NOTIFY && SYSLINK_PROC4430 + default y + help + Notify Ducati Module + +config MPU_SYSLINK_IPC + tristate "Syslink IPC Module" + depends on MPU_BRIDGE_NOTIFY && NOTIFY_DUCATI + default y + help + Syslink IPC Module + +config SYSLINK_USE_SYSMGR + bool "Enable SYS MGR setup" + depends on MPU_SYSLINK_IPC && SYSLINK_PROC + default y + help + This is the experimental option to enable SYS manager setup + +config OMAP_IOMMU + tristate "IOMMU" + default y + help + Select IOMMU module for managing ducati mmu + +config OMAP_IOMMU_DEBUG_MODULE + bool "IOMMU debugging" + depends on OMAP_IOMMU + default y +endif + + + + diff --git a/drivers/dsp/syslink/multicore_ipc/Kbuild b/drivers/dsp/syslink/multicore_ipc/Kbuild new file mode 100644 index 000000000000..2377e20c76b1 --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/Kbuild @@ -0,0 +1,25 @@ +libsyslink_ipc = multiproc.o multiproc_ioctl.o nameserver.o \ +nameserver_ioctl.o heap.o heapbuf.o heapbuf_ioctl.o \ +gatepeterson.o gatepeterson_ioctl.o sharedregion.o sharedregion_ioctl.o \ +nameserver_remote.o nameserver_remotenotify.o listmp_sharedmemory.o \ +listmp.o listmp_sharedmemory_ioctl.o messageq.o messageq_ioctl.o \ +messageq_transportshm.o messageq_transportshm_ioctl.o \ +nameserver_remotenotify_ioctl.o platform_mem.o sysmgr.o sysmgr_ioctl.o \ +sysmemmgr.o sysmemmgr_ioctl.o platformcfg.o platform.o ipc_ioctl.o ipc_drv.o + +obj-$(CONFIG_MPU_SYSLINK_IPC) += syslink_ipc.o +syslink_ipc-objs = $(libservices) $(libsyslink_ipc) + +ccflags-y += -Wno-strict-prototypes + +#Machine dependent +ccflags-y += -D_TI_ -D_DB_TIOMAP -DTMS32060 \ + -DTICFG_PROC_VER -DTICFG_EVM_TYPE -DCHNL_SMCLASS \ + -DCHNL_MESSAGES -DUSE_LEVEL_1_MACROS \ + -DCONFIG_DISABLE_BRIDGE_PM -DDSP_TRACEBUF_DISABLED + +#Header files +ccflags-y += -Iarch/arm/plat-omap/include +ccflags-y += -Iarch/arm/plat-omap/include/syslink +ccflags-y += -Iarch/arm/plat-omap/include/dspbridge + diff --git a/drivers/dsp/syslink/multicore_ipc/_listmp.h b/drivers/dsp/syslink/multicore_ipc/_listmp.h new file mode 100644 index 000000000000..13223dc2610b --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/_listmp.h @@ -0,0 +1,48 @@ +/* + * _listmp.h + * + * Internal definitions for Internal Defines for shared memory + * doubly linked list. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef __LISTMP_H_ +#define __LISTMP_H_ + +/* Standard headers */ +#include <linux/types.h> + +/*! + * @brief Structure defining attribute parameters for the + * ListMP module. + */ +struct listmp_attrs { + u32 version; + /*!< Version of module */ + u32 status; + /*!< Status of module */ + u32 shared_addr_size; + /*!< Shared address size of module */ +}; + +/*! + * @brief Structure defining processor related information for the + * ListMP module. + */ +struct listmp_proc_attrs { + bool creator; /*!< Creator or opener */ + u16 proc_id; /*!< Processor Identifier */ + u32 open_count; /*!< How many times it is opened on a processor */ +}; + +#endif /* __LISTMP_H_ */ diff --git a/drivers/dsp/syslink/multicore_ipc/gate_remote.c b/drivers/dsp/syslink/multicore_ipc/gate_remote.c new file mode 100644 index 000000000000..b5cf6871c8b9 --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/gate_remote.c @@ -0,0 +1,40 @@ +/* + * gate_remote.c + * + * This includes the functions to handle remote gates + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#include <linux/types.h> + +/* + * ======== gate_remote_enter ======== + * Purpose: + * This function is used to enter in to a remote gate + */ +int gate_remote_enter(void *ghandle) +{ + return 0; +} + +/* + * ======== gate_remote_leave ======== + * Purpose: + * This function is used to leave from a remote gate + */ +int gate_remote_leave(void *ghandle, u32 key) +{ + key = 0; + return 0; +} + diff --git a/drivers/dsp/syslink/multicore_ipc/gatepeterson.c b/drivers/dsp/syslink/multicore_ipc/gatepeterson.c new file mode 100755 index 000000000000..d885f12b6a84 --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/gatepeterson.c @@ -0,0 +1,964 @@ +/* + * gatepeterson.c + * + * The Gate Peterson Algorithm for mutual exclusion of shared memory. + * Current implementation works for 2 processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#include <linux/module.h> +#include <linux/types.h> +#include <linux/string.h> +#include <linux/list.h> +#include <linux/mutex.h> +#include <linux/slab.h> + +#include <syslink/atomic_linux.h> +#include <multiproc.h> +#include <nameserver.h> +#include <sharedregion.h> +#include <gatepeterson.h> + + +/* IPC stubs */ + +/* + * Name of the reserved NameServer used for gatepeterson + */ +#define GATEPETERSON_NAMESERVER "GatePeterson" +#define GATEPETERSON_BUSY 1 +#define GATEPETERSON_FREE 0 +#define GATEPETERSON_VERSION 1 +#define GATEPETERSON_CREATED 0x08201997 /* Stamp to indicate GP + was created here */ +#define MAX_GATEPETERSON_NAME_LEN 32 + +/* Cache line size */ +#define GATEPETERSON_CACHESIZE 128 + +/* Macro to make a correct module magic number with ref_count */ +#define GATEPETERSON_MAKE_MAGICSTAMP(x) ((GATEPETERSON_MODULEID << 12) | (x)) + +/* + * structure for gatepeterson module state + */ +struct gatepeterson_moduleobject { + atomic_t ref_count; /* Reference count */ + void *nshandle; + struct list_head obj_list; + struct mutex *mod_lock; /* Lock for obj list */ + struct gatepeterson_config cfg; + struct gatepeterson_config default_cfg; + struct gatepeterson_params def_inst_params; /* default instance + paramters */ +}; + +/* + * Structure defining attribute parameters for the Gate Peterson module + */ +struct gatepeterson_attrs { + VOLATILE u32 version; + VOLATILE u32 status; + VOLATILE u16 creator_proc_id; + VOLATILE u16 opener_proc_id; +}; + +/* + * Structure defining internal object for the Gate Peterson + */ +struct gatepeterson_obj { + struct list_head elem; + VOLATILE struct gatepeterson_attrs *attrs; /* Instance attr */ + VOLATILE u32 *flag[2]; /* Falgs for processors */ + VOLATILE u32 *turn; /* Indicates whoes turn it is now? */ + u8 self_id; /* Self identifier */ + u8 other_id; /* Other's identifier */ + u32 nested; /* Counter to track nesting */ + void *local_gate; /* Local lock handle */ + void *ns_key; /* NameServer key received in create */ + enum gatepeterson_protect local_protection; /* Type of local protection + to be used */ + struct gatepeterson_params params; + void *top; /* Pointer to the top Object */ + u32 ref_count; /* Local reference count */ +}; + +/* + * Structure defining object for the Gate Peterson + */ +struct gatepeterson_object { + void *(*lock_get_knl_handle)(void **handle); /* Pointer to + Kernl object will be returned */ + u32 (*enter)(void *handle); /* Function to enter GP */ + void (*leave)(void *handle, u32 key); /* Function to leave GP */ + struct gatepeterson_obj *obj; /* Pointer to GP internal object */ +}; + +/* + * Variable for holding state of the gatepeterson module + */ +struct gatepeterson_moduleobject gatepeterson_state = { + .obj_list = LIST_HEAD_INIT(gatepeterson_state.obj_list), + .default_cfg.max_name_len = MAX_GATEPETERSON_NAME_LEN, + .default_cfg.default_protection = GATEPETERSON_PROTECT_PROCESS, + .default_cfg.use_nameserver = true, + .def_inst_params.shared_addr = 0x0, + .def_inst_params.shared_addr_size = 0x0, + .def_inst_params.name = NULL, + .def_inst_params.local_protection = GATEPETERSON_PROTECT_DEFAULT + +}; + +static void *_gatepeterson_create(const struct gatepeterson_params *params, + bool create_flag); + +/* + * ======== gatepeterson_get_config ======== + * Purpose: + * This will get the default configuration parameters for gatepeterson + * module + */ +void gatepeterson_get_config(struct gatepeterson_config *config) +{ + if (WARN_ON(config == NULL)) + goto exit; + + if (atomic_cmpmask_and_lt(&(gatepeterson_state.ref_count), + GATEPETERSON_MAKE_MAGICSTAMP(0), + GATEPETERSON_MAKE_MAGICSTAMP(1)) == true) + memcpy(config, &gatepeterson_state.default_cfg, + sizeof(struct gatepeterson_config)); + else + memcpy(config, &gatepeterson_state.cfg, + sizeof(struct gatepeterson_config)); + +exit: + return; +} +EXPORT_SYMBOL(gatepeterson_get_config); + +/* + * ======== gatepeterson_setup ======== + * Purpose: + * This will setup the gatepeterson module + */ +int gatepeterson_setup(const struct gatepeterson_config *config) +{ + struct nameserver_params params; + struct gatepeterson_config tmp_cfg; + void *nshandle = NULL; + s32 retval = 0; + s32 ret; + + /* This sets the ref_count variable not initialized, upper 16 bits is + * written with module Id to ensure correctness of ref_count variable + */ + atomic_cmpmask_and_set(&gatepeterson_state.ref_count, + GATEPETERSON_MAKE_MAGICSTAMP(0), + GATEPETERSON_MAKE_MAGICSTAMP(0)); + + if (atomic_inc_return(&gatepeterson_state.ref_count) + != GATEPETERSON_MAKE_MAGICSTAMP(1)) { + return 1; + } + + if (config == NULL) { + gatepeterson_get_config(&tmp_cfg); + config = &tmp_cfg; + } + + if (WARN_ON(config->max_name_len == 0)) { + retval = -EINVAL; + goto exit; + } + + if (likely((config->use_nameserver == true))) { + retval = nameserver_params_init(¶ms); + params.max_value_len = sizeof(u32); + params.max_name_len = config->max_name_len; + /* Create the nameserver for modules */ + nshandle = nameserver_create(GATEPETERSON_NAMESERVER, ¶ms); + if (nshandle == NULL) + goto exit; + + gatepeterson_state.nshandle = nshandle; + } + + memcpy(&gatepeterson_state.cfg, config, + sizeof(struct gatepeterson_config)); + gatepeterson_state.mod_lock = kmalloc(sizeof(struct mutex), + GFP_KERNEL); + if (gatepeterson_state.mod_lock == NULL) { + retval = -ENOMEM; + goto lock_create_fail; + } + + mutex_init(gatepeterson_state.mod_lock); + return 0; + +lock_create_fail: + if ((likely(config->use_nameserver == true))) + ret = nameserver_delete(&gatepeterson_state.nshandle); + +exit: + atomic_set(&gatepeterson_state.ref_count, + GATEPETERSON_MAKE_MAGICSTAMP(0)); + + printk(KERN_ERR "gatepeterson_setup failed status: %x\n", + retval); + return retval; +} +EXPORT_SYMBOL(gatepeterson_setup); + +/* + * ======== gatepeterson_destroy ======== + * Purpose: + * This will destroy the gatepeterson module + */ +int gatepeterson_destroy(void) + +{ + struct gatepeterson_obj *obj = NULL; + struct mutex *lock = NULL; + s32 retval = 0; + + if (atomic_cmpmask_and_lt(&(gatepeterson_state.ref_count), + GATEPETERSON_MAKE_MAGICSTAMP(0), + GATEPETERSON_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto exit; + } + + if (!(atomic_dec_return(&gatepeterson_state.ref_count) + == GATEPETERSON_MAKE_MAGICSTAMP(0))) { + retval = 1; + goto exit; + } + + /* Temporarily increment ref_count here. */ + atomic_set(&gatepeterson_state.ref_count, + GATEPETERSON_MAKE_MAGICSTAMP(1)); + /* Check if any gatepeterson instances have not been + * ideleted/closed so far, if there any, delete or close them + */ + list_for_each_entry(obj, &gatepeterson_state.obj_list, elem) { + if (obj->attrs->creator_proc_id == + multiproc_get_id(NULL)) + gatepeterson_delete(&obj->top); + else + gatepeterson_close(&obj->top); + + if (list_empty(&gatepeterson_state.obj_list)) + break; + } + + /* Again reset ref_count. */ + atomic_set(&gatepeterson_state.ref_count, + GATEPETERSON_MAKE_MAGICSTAMP(0)); + + retval = mutex_lock_interruptible(gatepeterson_state.mod_lock); + if (retval != 0) + goto exit; + + if (likely(gatepeterson_state.cfg.use_nameserver == true)) { + retval = nameserver_delete(&gatepeterson_state.nshandle); + if (unlikely(retval != 0)) + goto exit; + } + + lock = gatepeterson_state.mod_lock; + gatepeterson_state.mod_lock = NULL; + memset(&gatepeterson_state.cfg, 0, sizeof(struct gatepeterson_config)); + mutex_unlock(lock); + kfree(lock); + /* Decrease the ref_count */ + atomic_set(&gatepeterson_state.ref_count, + GATEPETERSON_MAKE_MAGICSTAMP(0)); + return 0; + +exit:; + if (retval < 0) { + printk(KERN_ERR "gatepeterson_destroy failed status:%x\n", + retval); + } + return retval; + +} +EXPORT_SYMBOL(gatepeterson_destroy); + +/* + * ======== gatepeterson_params_init ======== + * Purpose: + * This will Initialize this config-params structure with + * supplier-specified defaults before instance creation + */ +void gatepeterson_params_init(void *handle, + struct gatepeterson_params *params) +{ + if (WARN_ON(atomic_cmpmask_and_lt(&(gatepeterson_state.ref_count), + GATEPETERSON_MAKE_MAGICSTAMP(0), + GATEPETERSON_MAKE_MAGICSTAMP(1)) == true)) + goto exit; + + if (WARN_ON(params == NULL)) + goto exit; + + if (handle == NULL) + memcpy(params, &(gatepeterson_state.def_inst_params), + sizeof(struct gatepeterson_params)); + else { + struct gatepeterson_obj *obj = + (struct gatepeterson_obj *)handle; + /* Return updated gatepeterson instance specific parameters. */ + memcpy(params, &(obj->params), + sizeof(struct gatepeterson_params)); + } + +exit: + return; +} +EXPORT_SYMBOL(gatepeterson_params_init); + +/* + * ======== gatepeterson_create ======== + * Purpose: + * This will creates a new instance of gatepeterson module + */ +void *gatepeterson_create(const struct gatepeterson_params *params) +{ + void *handle = NULL; + s32 retval = 0; + u32 shaddrsize; + + BUG_ON(params == NULL); + if (atomic_cmpmask_and_lt(&(gatepeterson_state.ref_count), + GATEPETERSON_MAKE_MAGICSTAMP(0), + GATEPETERSON_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto exit; + } + + shaddrsize = gatepeterson_shared_memreq(params); + if (WARN_ON(params->shared_addr == NULL || + params->shared_addr_size < shaddrsize)) { + retval = -EINVAL; + goto exit; + } + + if (params->local_protection >= GATEPETERSON_PROTECT_END_VALUE) { + retval = -EINVAL; + goto exit; + } + + handle = _gatepeterson_create(params, true); + return handle; + +exit: + return NULL; +} +EXPORT_SYMBOL(gatepeterson_create); + +/* + * ======== gatepeterson_delete ======== + * Purpose: + * This will deletes an instance of gatepeterson module + */ +int gatepeterson_delete(void **gphandle) + +{ + struct gatepeterson_object *handle = NULL; + struct gatepeterson_obj *obj = NULL; + struct gatepeterson_params *params = NULL; + s32 retval; + + BUG_ON(gphandle == NULL); + BUG_ON(*gphandle == NULL); + if (atomic_cmpmask_and_lt(&(gatepeterson_state.ref_count), + GATEPETERSON_MAKE_MAGICSTAMP(0), + GATEPETERSON_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto exit; + } + + handle = (struct gatepeterson_object *)(*gphandle); + obj = (struct gatepeterson_obj *)handle->obj; + if (unlikely(obj == NULL)) { + retval = -EINVAL; + goto exit; + } + + if (unlikely(obj->attrs == NULL)) { + retval = -EINVAL; + goto exit; + } + + /* Check if we have created the GP or not */ + if (unlikely(obj->attrs->creator_proc_id != multiproc_get_id(NULL))) { + retval = -EACCES; + goto exit; + } + + retval = mutex_lock_interruptible(obj->local_gate); + if (retval) + goto exit; + + if (obj->ref_count != 0) { + retval = -EBUSY; + goto error_handle; + } + + obj->attrs->status = !GATEPETERSON_CREATED; + retval = mutex_lock_interruptible(gatepeterson_state.mod_lock); + if (retval) + goto exit; + + list_del(&obj->elem); /* Remove the GP instance from the GP list */ + mutex_unlock(gatepeterson_state.mod_lock); + params = &obj->params; + /* Remove from the name server */ + if (likely(gatepeterson_state.cfg.use_nameserver) && + params->name != NULL) { + retval = nameserver_remove_entry(gatepeterson_state.nshandle, + obj->ns_key); + if (unlikely(retval != 0)) + goto error_handle; + kfree(params->name); + obj->ns_key = NULL; + } + + mutex_unlock(obj->local_gate); + /* If the lock handle was created internally */ + switch (obj->params.local_protection) { + case GATEPETERSON_PROTECT_NONE: /* Fall through */ + obj->local_gate = NULL; /* TBD: Fixme */ + break; + case GATEPETERSON_PROTECT_INTERRUPT: /* Fall through */ + /* FIXME: Add a spinlock protection */ + case GATEPETERSON_PROTECT_TASKLET: /* Fall through */ + case GATEPETERSON_PROTECT_THREAD: /* Fall through */ + case GATEPETERSON_PROTECT_PROCESS: + kfree(obj->local_gate); + break; + default: + /* An invalid protection level was supplied, FIXME */ + break; + } + + kfree(obj); + kfree(handle); + *gphandle = NULL; + return 0; + +error_handle: + mutex_unlock(obj->local_gate); + +exit: + printk(KERN_ERR "gatepeterson_create failed status: %x\n", + retval); + return retval; +} +EXPORT_SYMBOL(gatepeterson_delete); + +/* + * ======== gatepeterson_inc_refcount ======== + * Purpose: + * This will increment the reference count while opening + * a GP instance if it is already opened from local processor + */ +static bool gatepeterson_inc_refcount(const struct gatepeterson_params *params, + void **handle) +{ + struct gatepeterson_obj *obj = NULL; + s32 retval = 0; + bool done = false; + + list_for_each_entry(obj, &gatepeterson_state.obj_list, elem) { + if (params->shared_addr != NULL) { + if (obj->params.shared_addr == params->shared_addr) { + retval = mutex_lock_interruptible( + gatepeterson_state.mod_lock); + if (retval) + break; + + obj->ref_count++; + *handle = obj->top; + mutex_unlock(gatepeterson_state.mod_lock); + done = true; + break; + } + } else if (params->name != NULL && obj->params.name != NULL) { + if (strcmp(obj->params.name, params->name) == 0) { + retval = mutex_lock_interruptible( + gatepeterson_state.mod_lock); + if (retval) + break; + + obj->ref_count++; + *handle = obj->top; + mutex_unlock(gatepeterson_state.mod_lock); + done = true; + break; + } + } + } + + return done; +} + +/* + * ======== gatepeterson_open ======== + * Purpose: + * This will opens a created instance of gatepeterson + * module. + */ +int gatepeterson_open(void **gphandle, + struct gatepeterson_params *params) +{ + void *temp = NULL; + s32 retval = 0; + u32 sharedaddr; + + BUG_ON(params == NULL); + BUG_ON(gphandle == NULL); + if (atomic_cmpmask_and_lt(&(gatepeterson_state.ref_count), + GATEPETERSON_MAKE_MAGICSTAMP(0), + GATEPETERSON_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto exit; + } + + if (gatepeterson_state.cfg.use_nameserver == false && + params->shared_addr == NULL) { + retval = -EINVAL; + goto exit; + } + + if (gatepeterson_state.cfg.use_nameserver == true && + params->shared_addr == NULL && params->name == NULL) { + retval = -EINVAL; + goto exit; + } + if (params->shared_addr != NULL && params->shared_addr_size < + gatepeterson_shared_memreq(params)) { + retval = -EINVAL; + goto exit; + } + + if (gatepeterson_inc_refcount(params, &temp)) { + retval = -EBUSY; + goto exit; /* It's already opened from local processor */ + } + + if (unlikely(params->shared_addr == NULL)) { + if (likely(gatepeterson_state.cfg.use_nameserver == true && + params->name != NULL)) { + /* Find in name server */ + retval = nameserver_get(gatepeterson_state.nshandle, + params->name, &sharedaddr, + sizeof(u32), NULL); + if (retval < 0) + goto noentry_fail; /* Entry not found */ + + params->shared_addr = sharedregion_get_ptr( + (u32 *)sharedaddr); + if (params->shared_addr == NULL) + goto noentry_fail; + } + } else + sharedaddr = (u32) params->shared_addr; + + if (unlikely(((struct gatepeterson_attrs *)sharedaddr)->status != + GATEPETERSON_CREATED)) { + retval = -ENXIO; /* Not created */ + goto exit; + } + + if (unlikely(((struct gatepeterson_attrs *)sharedaddr)->version != + GATEPETERSON_VERSION)) { + retval = -ENXIO; /* FIXME Version mismatch, + need to change retval */ + goto exit; + } + + *gphandle = _gatepeterson_create(params, false); + return 0; + +noentry_fail: /* Fall through */ + retval = -ENOENT; +exit: + printk(KERN_ERR "gatepeterson_open failed status: %x\n", retval); + return retval; +} +EXPORT_SYMBOL(gatepeterson_open); + +/* + * ======== gatepeterson_close ======== + * Purpose: + * This will closes previously opened/created instance + * of gatepeterson module + */ +int gatepeterson_close(void **gphandle) +{ + struct gatepeterson_object *handle = NULL; + struct gatepeterson_obj *obj = NULL; + struct gatepeterson_params *params = NULL; + s32 retval = 0; + + BUG_ON(gphandle == NULL); + if (atomic_cmpmask_and_lt(&(gatepeterson_state.ref_count), + GATEPETERSON_MAKE_MAGICSTAMP(0), + GATEPETERSON_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto exit; + } + + if (WARN_ON(*gphandle == NULL)) { + retval = -EINVAL; + goto exit; + } + + handle = (struct gatepeterson_object *)(*gphandle); + obj = (struct gatepeterson_obj *) handle->obj; + if (unlikely(obj == NULL)) { + retval = -EINVAL; + goto exit; + } + + retval = mutex_lock_interruptible(obj->local_gate); + if (retval) + goto exit; + + if (obj->ref_count > 1) { + obj->ref_count--; + mutex_unlock(obj->local_gate); + goto exit; + } + + retval = mutex_lock_interruptible(gatepeterson_state.mod_lock); + if (retval) + goto error_handle; + + list_del(&obj->elem); + mutex_unlock(gatepeterson_state.mod_lock); + params = &obj->params; + if (likely(params->name != NULL)) + kfree(params->name); + + mutex_unlock(obj->local_gate); + /* If the lock handle was created internally */ + switch (obj->params.local_protection) { + case GATEPETERSON_PROTECT_NONE: /* Fall through */ + obj->local_gate = NULL; /* TBD: Fixme */ + break; + case GATEPETERSON_PROTECT_INTERRUPT: /* Fall through */ + /* FIXME: Add a spinlock protection */ + case GATEPETERSON_PROTECT_TASKLET: /* Fall through */ + case GATEPETERSON_PROTECT_THREAD: /* Fall through */ + case GATEPETERSON_PROTECT_PROCESS: + kfree(obj->local_gate); + break; + default: + /* An invalid protection level was supplied */ + break; + } + + kfree(obj); + kfree(handle); + *gphandle = NULL; + return 0; + +error_handle: + mutex_unlock(obj->local_gate); + +exit: + printk(KERN_ERR "gatepeterson_close failed status: %x\n", retval); + return retval; +} +EXPORT_SYMBOL(gatepeterson_close); + +/* + * ======== gatepeterson_enter ======== + * Purpose: + * This will enters the gatepeterson instance + */ +u32 gatepeterson_enter(void *gphandle) +{ + struct gatepeterson_object *handle = NULL; + struct gatepeterson_obj *obj = NULL; + s32 retval = 0; + + BUG_ON(gphandle == NULL); + if (WARN_ON(atomic_cmpmask_and_lt(&(gatepeterson_state.ref_count), + GATEPETERSON_MAKE_MAGICSTAMP(0), + GATEPETERSON_MAKE_MAGICSTAMP(1)) == true)) { + retval = -ENODEV; + goto exit; + } + + + handle = (struct gatepeterson_object *)gphandle; + obj = (struct gatepeterson_obj *) handle->obj; + if (obj->local_gate != NULL) + retval = mutex_lock_interruptible(obj->local_gate); + if (retval) + goto exit; + + obj->nested++; + if (obj->nested == 1) { + /* indicate, needs to use the resource. */ + *((u32 *)obj->flag[obj->self_id]) = GATEPETERSON_BUSY ; + /* Give away the turn. */ + *((u32 *)(obj->turn)) = obj->other_id; + /* Wait while other processor is using the resource and has + * the turn + */ + while ((*((VOLATILE u32 *) obj->flag[obj->other_id]) + == GATEPETERSON_BUSY) && + (*((VOLATILE u32 *)obj->turn) == obj->other_id)) + ; /* Empty body loop */ + } + + return 0; + +exit: + return retval; +} +EXPORT_SYMBOL(gatepeterson_enter); + +/* + * ======== gatepeterson_leave ======== + * Purpose: + * This will leaves the gatepeterson instance + */ +void gatepeterson_leave(void *gphandle, u32 flag) +{ + struct gatepeterson_object *handle = NULL; + struct gatepeterson_obj *obj = NULL; + + if (WARN_ON(atomic_cmpmask_and_lt(&(gatepeterson_state.ref_count), + GATEPETERSON_MAKE_MAGICSTAMP(0), + GATEPETERSON_MAKE_MAGICSTAMP(1)) == true)) + goto exit; + + BUG_ON(gphandle == NULL); + + handle = (struct gatepeterson_object *)gphandle; + (void) flag; + obj = (struct gatepeterson_obj *)handle->obj; + obj->nested--; + if (obj->nested == 0) + *((VOLATILE u32 *)obj->flag[obj->self_id]) = GATEPETERSON_FREE; + + if (obj->local_gate != NULL) + mutex_unlock(obj->local_gate); + +exit: + return; +} +EXPORT_SYMBOL(gatepeterson_leave); + +/* + * ======== gatepeterson_get_knl_handle ======== + * Purpose: + * This will gatepeterson kernel object pointer + */ +void *gatepeterson_get_knl_handle(void **gphandle) +{ + BUG_ON(gphandle == NULL); + return gphandle; +} +EXPORT_SYMBOL(gatepeterson_get_knl_handle); + +/* + * ======== gatepeterson_shared_memreq ======== + * Purpose: + * This will give the amount of shared memory required + * for creation of each instance + */ +u32 gatepeterson_shared_memreq(const struct gatepeterson_params *params) +{ + u32 retval = 0; + + retval = (GATEPETERSON_CACHESIZE * 4) ; + return retval; +} +EXPORT_SYMBOL(gatepeterson_shared_memreq); + +/* + * ======== gatepeterson_create ======== + * Purpose: + * Creates a new instance of gatepeterson module. + * This is an internal function because both + * gatepeterson_create and gatepeterson_open + * call use the same functionality. + */ +static void *_gatepeterson_create(const struct gatepeterson_params *params, + bool create_flag) +{ + int status = 0; + struct gatepeterson_object *handle = NULL; + struct gatepeterson_obj *obj = NULL; + u32 len; + u32 shm_index; + u32 shared_shm_base; + s32 retval = 0; + + + handle = kmalloc(sizeof(struct gatepeterson_object), GFP_KERNEL); + if (handle == NULL) { + retval = -ENOMEM; + goto exit; + } + + obj = kmalloc(sizeof(struct gatepeterson_obj), GFP_KERNEL); + if (obj == NULL) { + retval = -ENOMEM; + goto obj_alloc_fail; + } + + if (likely(gatepeterson_state.cfg.use_nameserver == true && + params->name != NULL)) { + len = strlen(params->name) + 1; + obj->params.name = kmalloc(len, GFP_KERNEL); + if (obj->params.name == NULL) { + retval = -ENOMEM; + goto name_alloc_fail; + } + + if (create_flag == true) { + shm_index = sharedregion_get_index( + params->shared_addr); + shared_shm_base = (u32)sharedregion_get_srptr( + (void *)params->shared_addr, + shm_index); + obj->ns_key = nameserver_add_uint32( + gatepeterson_state.nshandle, + params->name, + (u32) (shared_shm_base)); + if (obj->ns_key == NULL) { + status = -ENOMEM; /* FIXME */ + goto ns_add32_fail; + } + } + + } + + handle->obj = obj; + handle->enter = &gatepeterson_enter; + handle->leave = &gatepeterson_leave; + handle->lock_get_knl_handle = &gatepeterson_get_knl_handle; + /* assign the memory with proper cache line padding */ + obj->attrs = (struct gatepeterson_attrs *) params->shared_addr; + obj->flag[0] = ((void *)(((u32) obj->attrs) + + GATEPETERSON_CACHESIZE)); + obj->flag[1] = ((void *)(((u32) obj->flag[0]) + + GATEPETERSON_CACHESIZE)); + obj->turn = ((void *)(((u32) obj->flag[1]) + + GATEPETERSON_CACHESIZE)); /* TBD: Fixme */ + + /* Creator always has selfid set to 0 */ + if (create_flag == true) { + obj->self_id = 0; + obj->other_id = 1; + obj->attrs->creator_proc_id = multiproc_get_id(NULL); + obj->attrs->opener_proc_id = MULTIPROC_INVALIDID; + obj->attrs->status = GATEPETERSON_CREATED; + obj->attrs->version = GATEPETERSON_VERSION; + + /* Set up shared memory */ + *(obj->turn) = 0x0; + *(obj->flag[0]) = 0x0; + *(obj->flag[1]) = 0x0; + obj->ref_count = 0; + } else { + obj->self_id = 1; + obj->other_id = 0; + obj->attrs->opener_proc_id = multiproc_get_id(NULL); + obj->ref_count = 1; + } + obj->nested = 0; + obj->top = handle; + + /* Populate the params member */ + memcpy(&obj->params, params, sizeof(struct gatepeterson_params)); + + /* Create the local lock if not provided */ + if (likely(params->local_protection == GATEPETERSON_PROTECT_DEFAULT)) + obj->params.local_protection = + gatepeterson_state.cfg.default_protection; + else + obj->params.local_protection = params->local_protection; + + switch (obj->params.local_protection) { + case GATEPETERSON_PROTECT_NONE: /* Fall through */ + obj->local_gate = NULL; /* TBD: Fixme */ + break; + /* In syslink ; for interrupt protect gatespinlock is used, that + * internally uses the mutex. So we added mutex for interrupt + * protection here also + */ + case GATEPETERSON_PROTECT_INTERRUPT: /* Fall through */ + /* FIXME: Add a spinlock protection */ + case GATEPETERSON_PROTECT_TASKLET: /* Fall through */ + case GATEPETERSON_PROTECT_THREAD: /* Fall through */ + case GATEPETERSON_PROTECT_PROCESS: + obj->local_gate = kmalloc(sizeof(struct mutex), GFP_KERNEL); + if (obj->local_gate == NULL) { + retval = -ENOMEM; + goto gate_create_fail; + } + + mutex_init(obj->local_gate); + break; + default: + /* An invalid protection level was supplied, FIXME */ + obj->local_gate = NULL; + break; + } + + /* Put in the local list */ + retval = mutex_lock_interruptible(gatepeterson_state.mod_lock); + if (retval) + goto mod_lock_fail; + + list_add_tail(&obj->elem, &gatepeterson_state.obj_list); + mutex_unlock(gatepeterson_state.mod_lock); + return (void *)handle; + +mod_lock_fail: + kfree(obj->local_gate); + +gate_create_fail: + status = nameserver_remove_entry(gatepeterson_state.nshandle, + obj->ns_key); + +ns_add32_fail: + kfree(obj->params.name); + +name_alloc_fail: + kfree(obj); + +obj_alloc_fail: + kfree(handle); + handle = NULL; + +exit: + if (create_flag == true) + printk(KERN_ERR "_gatepeterson_create (create) failed status: %x\n", + retval); + else + printk(KERN_ERR "_gatepeterson_create (open) failed status: %x\n", + retval); + + return NULL; +} diff --git a/drivers/dsp/syslink/multicore_ipc/gatepeterson_ioctl.c b/drivers/dsp/syslink/multicore_ipc/gatepeterson_ioctl.c new file mode 100644 index 000000000000..f0d34d1084c8 --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/gatepeterson_ioctl.c @@ -0,0 +1,392 @@ +/* + * gatepeterson_ioctl.c + * + * The Gate Peterson Algorithm for mutual exclusion of shared memory. + * Current implementation works for 2 processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#include <linux/uaccess.h> +#include <linux/types.h> +#include <linux/bug.h> +#include <linux/fs.h> +#include <linux/mm.h> +#include <gatepeterson.h> +#include <gatepeterson_ioctl.h> +#include <sharedregion.h> + +/* + * ======== gatepeterson_ioctl_get_config ======== + * Purpose: + * This ioctl interface to gatepeterson_get_config function + */ +static int gatepeterson_ioctl_get_config(struct gatepeterson_cmd_args *cargs) +{ + struct gatepeterson_config config; + s32 status = 0; + s32 size; + + gatepeterson_get_config(&config); + size = copy_to_user(cargs->args.get_config.config, &config, + sizeof(struct gatepeterson_config)); + if (size) + status = -EFAULT; + + cargs->api_status = 0; + return status; +} + +/* + * ======== gatepeterson_ioctl_setup ======== + * Purpose: + * This ioctl interface to gatepeterson_setup function + */ +static int gatepeterson_ioctl_setup(struct gatepeterson_cmd_args *cargs) +{ + struct gatepeterson_config config; + s32 status = 0; + s32 size; + + size = copy_from_user(&config, cargs->args.setup.config, + sizeof(struct gatepeterson_config)); + if (size) { + status = -EFAULT; + goto exit; + } + + cargs->api_status = gatepeterson_setup(&config); + +exit: + return status; +} + +/* + * ======== gatepeterson_ioctl_destroy ======== + * Purpose: + * This ioctl interface to gatepeterson_destroy function + */ +static int gatepeterson_ioctl_destroy( + struct gatepeterson_cmd_args *cargs) +{ + cargs->api_status = gatepeterson_destroy(); + return 0; +} + +/* + * ======== gatepeterson_ioctl_params_init ======== + * Purpose: + * This ioctl interface to gatepeterson_params_init function + */ +static int gatepeterson_ioctl_params_init(struct gatepeterson_cmd_args *cargs) +{ + struct gatepeterson_params params; + s32 status = 0; + s32 size; + + gatepeterson_params_init(cargs->args.params_init.handle, + ¶ms); + size = copy_to_user(cargs->args.params_init.params, ¶ms, + sizeof(struct gatepeterson_params)); + if (size) + status = -EFAULT; + + cargs->api_status = 0; + return status; +} + +/* + * ======== gatepeterson_ioctl_create ======== + * Purpose: + * This ioctl interface to gatepeterson_create function + */ +static int gatepeterson_ioctl_create(struct gatepeterson_cmd_args *cargs) +{ + struct gatepeterson_params params; + void *handle = NULL; + s32 status = 0; + s32 size; + + size = copy_from_user(¶ms, cargs->args.create.params, + sizeof(struct gatepeterson_params)); + if (size) { + status = -EFAULT; + goto exit; + } + + if (cargs->args.create.name_len > 0) { + params.name = kmalloc(cargs->args.create.name_len + 1, + GFP_KERNEL); + if (params.name == NULL) { + status = -ENOMEM; + goto exit; + } + + params.name[cargs->args.create.name_len] = '\0'; + size = copy_from_user(params.name, + cargs->args.create.params->name, + cargs->args.create.name_len); + if (size) { + status = -EFAULT; + goto name_from_usr_error; + } + + } + + params.shared_addr = sharedregion_get_ptr( + (u32 *)cargs->args.create.shared_addr_srptr); + handle = gatepeterson_create(¶ms); + /* Here we are not validating the return from the module. + Even it is nul, we pass it to user and user has to pass + proper return to application + */ + cargs->args.create.handle = handle; + cargs->api_status = 0; + +name_from_usr_error: + if (cargs->args.open.name_len > 0) + kfree(params.name); + +exit: + return status; +} + +/* + * ======== gatepeterson_ioctl_delete ======== + * Purpose: + * This ioctl interface to gatepeterson_ioctl_delete function + */ +static int gatepeterson_ioctl_delete(struct gatepeterson_cmd_args *cargs) + +{ + cargs->api_status = gatepeterson_delete(&cargs->args.delete.handle); + return 0; +} + +/* + * ======== gatepeterson_ioctl_open ======== + * Purpose: + * This ioctl interface to gatepeterson_open function + */ +static int gatepeterson_ioctl_open(struct gatepeterson_cmd_args *cargs) +{ + struct gatepeterson_params params; + void *handle = NULL; + s32 status = 0; + s32 size; + + size = copy_from_user(¶ms, cargs->args.open.params, + sizeof(struct gatepeterson_params)); + if (size) { + status = -EFAULT; + goto exit; + } + + if (cargs->args.open.name_len > 0) { + params.name = kmalloc(cargs->args.open.name_len + 1, + GFP_KERNEL); + if (params.name == NULL) { + status = -ENOMEM; + goto exit; + } + + params.name[cargs->args.open.name_len] = '\0'; + size = copy_from_user(params.name, + cargs->args.open.params->name, + cargs->args.open.name_len); + if (size) { + status = -EFAULT; + goto name_from_usr_error; + } + } + + /* For open by name, the shared_add_srptr may be invalid */ + if (cargs->args.open.shared_addr_srptr != \ + (u32) SHAREDREGION_INVALIDSRPTR) { + params.shared_addr = sharedregion_get_ptr( + (u32 *)cargs->args.open.shared_addr_srptr); + } + cargs->api_status = gatepeterson_open(&handle, ¶ms); + cargs->args.open.handle = handle; + +name_from_usr_error: + if (cargs->args.open.name_len > 0) + kfree(params.name); + +exit: + return status; +} + +/* + * ======== gatepeterson_ioctl_close ======== + * Purpose: + * This ioctl interface to gatepeterson_close function + */ +static int gatepeterson_ioctl_close(struct gatepeterson_cmd_args *cargs) +{ + cargs->api_status = gatepeterson_close(&cargs->args.close.handle); + return 0; +} + +/* + * ======== gatepeterson_ioctl_enter ======== + * Purpose: + * This ioctl interface to gatepeterson_enter function + */ +static int gatepeterson_ioctl_enter(struct gatepeterson_cmd_args *cargs) +{ + cargs->api_status = gatepeterson_enter(cargs->args.enter.handle); + return 0; +} + +/* + * ======== gatepeterson_ioctl_leave ======== + * Purpose: + * This ioctl interface to gatepeterson_leave function + */ +static int gatepeterson_ioctl_leave(struct gatepeterson_cmd_args *cargs) +{ + gatepeterson_leave(cargs->args.enter.handle, + cargs->args.enter.flags); + cargs->api_status = 0; + return 0; +} + +/* + * ======== gatepeterson_ioctl_shared_memreq ======== + * Purpose: + * This ioctl interface to gatepeterson_shared_memreq function + */ +static int gatepeterson_ioctl_shared_memreq(struct gatepeterson_cmd_args *cargs) +{ + struct gatepeterson_params params; + s32 status = 0; + s32 size; + + + size = copy_from_user(¶ms, cargs->args.shared_memreq.params, + sizeof(struct gatepeterson_params)); + if (size) { + status = -EFAULT; + goto exit; + } + + cargs->args.shared_memreq.bytes = + gatepeterson_shared_memreq(cargs->args.shared_memreq.params); + cargs->api_status = 0; + +exit: + return status; +} + +/* + * ======== gatepeterson_ioctl ======== + * Purpose: + * This ioctl interface for gatepeterson module + */ +int gatepeterson_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long args) +{ + s32 status = 0; + s32 size = 0; + struct gatepeterson_cmd_args __user *uarg = + (struct gatepeterson_cmd_args __user *)args; + struct gatepeterson_cmd_args cargs; + + + if (_IOC_DIR(cmd) & _IOC_READ) + status = !access_ok(VERIFY_WRITE, uarg, _IOC_SIZE(cmd)); + else if (_IOC_DIR(cmd) & _IOC_WRITE) + status = !access_ok(VERIFY_READ, uarg, _IOC_SIZE(cmd)); + + if (status) { + status = -EFAULT; + goto exit; + } + + /* Copy the full args from user-side */ + size = copy_from_user(&cargs, uarg, + sizeof(struct gatepeterson_cmd_args)); + if (size) { + status = -EFAULT; + goto exit; + } + + switch (cmd) { + case CMD_GATEPETERSON_GETCONFIG: + status = gatepeterson_ioctl_get_config(&cargs); + break; + + case CMD_GATEPETERSON_SETUP: + status = gatepeterson_ioctl_setup(&cargs); + break; + + case CMD_GATEPETERSON_DESTROY: + status = gatepeterson_ioctl_destroy(&cargs); + break; + + case CMD_GATEPETERSON_PARAMS_INIT: + status = gatepeterson_ioctl_params_init(&cargs); + break; + + case CMD_GATEPETERSON_CREATE: + status = gatepeterson_ioctl_create(&cargs); + break; + + case CMD_GATEPETERSON_DELETE: + status = gatepeterson_ioctl_delete(&cargs); + break; + + case CMD_GATEPETERSON_OPEN: + status = gatepeterson_ioctl_open(&cargs); + break; + + case CMD_GATEPETERSON_CLOSE: + status = gatepeterson_ioctl_close(&cargs); + break; + + case CMD_GATEPETERSON_ENTER: + status = gatepeterson_ioctl_enter(&cargs); + break; + + case CMD_GATEPETERSON_LEAVE: + status = gatepeterson_ioctl_leave(&cargs); + break; + + case CMD_GATEPETERSON_SHAREDMEMREQ: + status = gatepeterson_ioctl_shared_memreq(&cargs); + break; + + default: + WARN_ON(cmd); + status = -ENOTTY; + break; + } + + if ((cargs.api_status == -ERESTARTSYS) || (cargs.api_status == -EINTR)) + status = -ERESTARTSYS; + + if (status < 0) + goto exit; + + /* Copy the full args to the user-side. */ + size = copy_to_user(uarg, &cargs, + sizeof(struct gatepeterson_cmd_args)); + if (size) { + status = -EFAULT; + goto exit; + } + +exit: + return status; +} + diff --git a/drivers/dsp/syslink/multicore_ipc/heap.c b/drivers/dsp/syslink/multicore_ipc/heap.c new file mode 100755 index 000000000000..11df26c11c88 --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/heap.c @@ -0,0 +1,101 @@ +/* + * heap.c + * + * Heap module manages fixed size buffers that can be used + * in a multiprocessor system with shared memory + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +#include <linux/types.h> +#include <linux/bug.h> + + +#include <heap.h> + + +/* + * ======== heap_alloc ======== + * Purpose: + * This will allocate a block of memory of specified + * size + */ +void *heap_alloc(void *hphandle, u32 size, u32 align) +{ + char *block = NULL; + struct heap_object *obj = NULL; + + BUG_ON(hphandle == NULL); + + obj = (struct heap_object *)hphandle; + BUG_ON(obj->alloc == NULL); + block = obj->alloc(hphandle, size, align); + return block; +} + +/* + * ======== heap_free ======== + * Purpose: + * This will frees a block of memory allocated + * rom heap + */ +int heap_free(void *hphandle, void *block, u32 size) +{ + struct heap_object *obj = NULL; + s32 retval = 0; + + BUG_ON(hphandle == NULL); + + obj = (struct heap_object *)hphandle; + BUG_ON(obj->free == NULL); + retval = obj->free(hphandle, block, size); + return retval; +} + +/* + * ======== heap_get_stats ======== + * Purpose: + * This will get the heap memory statistics + */ +int heap_get_stats(void *hphandle, struct memory_stats *stats) +{ + struct heap_object *obj = NULL; + s32 retval = 0; + + BUG_ON(hphandle == NULL); + BUG_ON(stats == NULL); + + obj = (struct heap_object *)hphandle; + BUG_ON(obj->get_stats == NULL); + retval = obj->get_stats(hphandle, stats); + return retval; +} + +/* + * ======== heap_get_extended_stats ======== + * Purpose: + * This will get the heap memory extended statistics + */ +int heap_get_extended_stats(void *hphandle, + struct heap_extended_stats *stats) +{ + struct heap_object *obj = NULL; + s32 retval = 0; + + BUG_ON(hphandle == NULL); + BUG_ON(stats == NULL); + + obj = (struct heap_object *)hphandle; + BUG_ON(obj->get_extended_stats == NULL); + retval = obj->get_extended_stats(hphandle, stats); + return retval; +} + diff --git a/drivers/dsp/syslink/multicore_ipc/heapbuf.c b/drivers/dsp/syslink/multicore_ipc/heapbuf.c new file mode 100755 index 000000000000..e7d75f640976 --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/heapbuf.c @@ -0,0 +1,1173 @@ +/* + * heapbuf.c + * + * Heap module manages fixed size buffers that can be used + * in a multiprocessor system with shared memory. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#include <linux/module.h> +#include <linux/types.h> +#include <linux/string.h> +#include <linux/list.h> +#include <linux/mutex.h> +#include <linux/slab.h> + +#include <atomic_linux.h> +#include <multiproc.h> +#include <nameserver.h> +#include <sharedregion.h> +#include <gatepeterson.h> +#include <heapbuf.h> +#include <listmp.h> +#include <listmp_sharedmemory.h> + +/* + * Name of the reserved nameserver used for heapbuf. + */ +#define HEAPBUF_NAMESERVER "HeapBuf" +#define HEAPBUF_MAX_NAME_LEN 32 +#define HEAPBUF_CACHESIZE 128 +/* brief Macro to make a correct module magic number with refCount */ +#define HEAPBUF_MAKE_MAGICSTAMP(x) ((HEAPBUF_MODULEID << 12) | (x)) + + +/* + * Structure defining attribute parameters for the heapbuf module + */ +struct heapbuf_attrs { + VOLATILE u32 version; + VOLATILE u32 status; + VOLATILE u32 num_free_blocks; + VOLATILE u32 min_free_blocks; + VOLATILE u32 block_size; + VOLATILE u32 align; + VOLATILE u32 num_blocks; + VOLATILE u32 buf_size; + VOLATILE char *buf; +}; + +/* + * Structure defining processor related information for the + * heapbuf module + */ +struct heapbuf_proc_attrs { + bool creator; /* Creator or opener */ + u16 proc_id; /* Processor identifier */ + u32 open_count; /* open count in a processor */ +}; + +/* + * Structure for heapbuf module state + */ +struct heapbuf_module_object { + atomic_t ref_count; /* Reference count */ + void *ns_handle; + struct list_head obj_list; /* List holding created objects */ + struct mutex *local_lock; /* lock for protecting obj_list */ + struct heapbuf_config cfg; + struct heapbuf_config default_cfg; /* Default config values */ + struct heapbuf_params default_inst_params; /* Default instance + creation parameters */ +}; + +struct heapbuf_module_object heapbuf_state = { + .obj_list = LIST_HEAD_INIT(heapbuf_state.obj_list), + .default_cfg.max_name_len = HEAPBUF_MAX_NAME_LEN, + .default_cfg.use_nameserver = true, + .default_cfg.track_max_allocs = false, + .default_inst_params.gate = NULL, + .default_inst_params.exact = false, + .default_inst_params.name = NULL, + .default_inst_params.resource_id = 0, + .default_inst_params.cache_flag = false, + .default_inst_params.align = 1, + .default_inst_params.num_blocks = 0, + .default_inst_params.block_size = 0, + .default_inst_params.shared_addr = NULL, + .default_inst_params.shared_addr_size = 0, + .default_inst_params.shared_buf = NULL, + .default_inst_params.shared_buf_size = 0 +}; + +/* + * Structure for the handle for the heapbuf + */ +struct heapbuf_obj { + struct list_head list_elem; /* Used for creating a linked list */ + struct heapbuf_params params; /* The creation parameter structure */ + struct heapbuf_attrs *attrs; /* The shared attributes structure */ + void *free_list; /* List of free buffers */ + struct mutex *gate; /* Lock used for critical region management */ + void *ns_key; /* nameserver key required for remove */ + struct heapbuf_proc_attrs owner; /* owner processor info */ + void *top; /* Pointer to the top object */ + bool cacheFlag; /* added for future use */ +}; + +/* + * ======== heapbuf_get_config ======== + * Purpose: + * This will get default configuration for the + * heapbuf module + */ +int heapbuf_get_config(struct heapbuf_config *cfgparams) +{ + BUG_ON(cfgparams == NULL); + + if (atomic_cmpmask_and_lt(&(heapbuf_state.ref_count), + HEAPBUF_MAKE_MAGICSTAMP(0), + HEAPBUF_MAKE_MAGICSTAMP(1)) == true) + memcpy(cfgparams, &heapbuf_state.default_cfg, + sizeof(struct heapbuf_config)); + else + memcpy(cfgparams, &heapbuf_state.cfg, + sizeof(struct heapbuf_config)); + return 0; +} +EXPORT_SYMBOL(heapbuf_get_config); + +/* + * ======== heapbuf_setup ======== + * Purpose: + * This will setup the heapbuf module + * + * This function sets up the HeapBuf module. This function + * must be called before any other instance-level APIs can be + * invoked. + * Module-level configuration needs to be provided to this + * function. If the user wishes to change some specific config + * parameters, then heapbuf_getconfig can be called to get + * the configuration filled with the default values. After this, + * only the required configuration values can be changed. If the + * user does not wish to make any change in the default parameters, + * the application can simply call HeapBuf_setup with NULL + * parameters. The default parameters would get automatically used. + */ +int heapbuf_setup(const struct heapbuf_config *cfg) +{ + struct nameserver_params params; + struct heapbuf_config tmp_cfg; + void *ns_handle = NULL; + s32 retval = 0; + + /* This sets the ref_count variable not initialized, upper 16 bits is + * written with module Id to ensure correctness of ref_count variable + */ + atomic_cmpmask_and_set(&heapbuf_state.ref_count, + HEAPBUF_MAKE_MAGICSTAMP(0), + HEAPBUF_MAKE_MAGICSTAMP(0)); + + if (atomic_inc_return(&heapbuf_state.ref_count) + != HEAPBUF_MAKE_MAGICSTAMP(1)) { + return 1; + } + + if (cfg == NULL) { + heapbuf_get_config(&tmp_cfg); + cfg = &tmp_cfg; + } + + if (cfg->max_name_len == 0 || + cfg->max_name_len > HEAPBUF_MAX_NAME_LEN) { + retval = -EINVAL; + goto error; + } + + heapbuf_state.local_lock = kmalloc(sizeof(struct mutex), GFP_KERNEL); + if (heapbuf_state.local_lock == NULL) { + retval = -ENOMEM; + goto error; + } + + if (likely((cfg->use_nameserver == true))) { + retval = nameserver_get_params(NULL, ¶ms); + params.max_value_len = sizeof(u32); + params.max_name_len = cfg->max_name_len; + ns_handle = nameserver_create(HEAPBUF_NAMESERVER, ¶ms); + if (ns_handle == NULL) { + retval = -EFAULT; + goto ns_create_fail; + } + heapbuf_state.ns_handle = ns_handle; + } + + memcpy(&heapbuf_state.cfg, cfg, sizeof(struct heapbuf_config)); + mutex_init(heapbuf_state.local_lock); + return 0; + +ns_create_fail: + kfree(heapbuf_state.local_lock); + +error: + atomic_set(&heapbuf_state.ref_count, + HEAPBUF_MAKE_MAGICSTAMP(0)); + + printk(KERN_ERR "heapbuf_setup failed status: %x\n", retval); + return retval; +} +EXPORT_SYMBOL(heapbuf_setup); + +/* + * ======== heapbuf_destroy ======== + * Purpose: + * This will destroy the heapbuf module + */ +int heapbuf_destroy(void) +{ + s32 retval = 0; + struct mutex *lock = NULL; + struct heapbuf_obj *obj = NULL; + + if (atomic_cmpmask_and_lt(&(heapbuf_state.ref_count), + HEAPBUF_MAKE_MAGICSTAMP(0), + HEAPBUF_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto error; + } + + if (atomic_dec_return(&heapbuf_state.ref_count) + == HEAPBUF_MAKE_MAGICSTAMP(0)) { + /* Temporarily increment ref_count here. */ + atomic_set(&heapbuf_state.ref_count, + HEAPBUF_MAKE_MAGICSTAMP(1)); + + /* Check if any heapbuf instances have not been deleted/closed + * so far. if there any, delete or close them + */ + list_for_each_entry(obj, &heapbuf_state.obj_list, list_elem) { + if (obj->owner.proc_id == multiproc_get_id(NULL)) + heapbuf_delete(&obj->top); + else + heapbuf_close(obj->top); + + if (list_empty(&heapbuf_state.obj_list)) + break; + } + + /* Again reset ref_count. */ + atomic_set(&heapbuf_state.ref_count, + HEAPBUF_MAKE_MAGICSTAMP(0)); + + if (likely(heapbuf_state.cfg.use_nameserver == true)) { + retval = nameserver_delete(&heapbuf_state.ns_handle); + if (unlikely(retval != 0)) + goto error; + } + + retval = mutex_lock_interruptible(heapbuf_state.local_lock); + if (retval) + goto error; + + lock = heapbuf_state.local_lock; + heapbuf_state.local_lock = NULL; + mutex_unlock(lock); + kfree(lock); + memset(&heapbuf_state.cfg, 0, sizeof(struct heap_config)); + + atomic_set(&heapbuf_state.ref_count, + HEAPBUF_MAKE_MAGICSTAMP(0)); + } + + return 0; + +error: + printk(KERN_ERR "heapbuf_destroy failed status: %x\n", retval); + return retval; +} +EXPORT_SYMBOL(heapbuf_destroy); + +/* + * ======== heapbuf_params_init ======== + * Purpose: + * This will get the intialization prams for a heapbuf + * module instance + */ +void heapbuf_params_init(void *handle, + struct heapbuf_params *params) +{ + struct heapbuf_obj *obj = NULL; + s32 retval = 0; + + if (atomic_cmpmask_and_lt(&(heapbuf_state.ref_count), + HEAPBUF_MAKE_MAGICSTAMP(0), + HEAPBUF_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto error; + } + + BUG_ON(params == NULL); + + if (handle == NULL) + memcpy(params, &heapbuf_state.default_inst_params, + sizeof(struct heapbuf_params)); + else { + obj = (struct heapbuf_obj *)handle; + memcpy(params, (void *)&obj->params, + sizeof(struct heapbuf_params)); + } + return; +error: + printk(KERN_ERR "heapbuf_params_init failed status: %x\n", retval); +} +EXPORT_SYMBOL(heapbuf_params_init); + +/* + * ======== _heapbuf_create ======== + * Purpose: + * This will create a new instance of heapbuf module + * This is an internal function as both heapbuf_create + * and heapbuf_open use the functionality + * + * NOTE: The lock to protect the shared memory area + * used by heapbuf is provided by the consumer of + * heapbuf module + */ +int _heapbuf_create(void **handle_ptr, const struct heapbuf_params *params, + u32 create_flag) +{ + struct heap_object *handle = NULL; + struct heapbuf_obj *obj = NULL; + char *buf = NULL; + listmp_sharedmemory_params listmp_params; + s32 retval = 0; + u32 i; + s32 align; + s32 shm_index; + u32 shared_shm_base; + void *entry = NULL; + + if (atomic_cmpmask_and_lt(&(heapbuf_state.ref_count), + HEAPBUF_MAKE_MAGICSTAMP(0), + HEAPBUF_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto error; + } + + BUG_ON(handle_ptr == NULL); + + BUG_ON(params == NULL); + + /* No need for parameter checks, since this is an internal function. */ + + /* Initialize return parameter. */ + *handle_ptr = NULL; + + handle = kmalloc(sizeof(struct heap_object), GFP_KERNEL); + if (handle == NULL) { + retval = -ENOMEM; + goto error; + } + + obj = kmalloc(sizeof(struct heapbuf_obj), GFP_KERNEL); + if (obj == NULL) { + retval = -ENOMEM; + goto obj_alloc_error; + } + + handle->obj = (struct heapbuf_obj *)obj; + handle->alloc = &heapbuf_alloc; + handle->free = &heapbuf_free; + handle->get_stats = &heapbuf_get_stats; + /* FIXME: handle->is_blocking = &heapbuf_isblocking; */ + /* Create the shared list */ + listmp_sharedmemory_params_init(NULL, &listmp_params); + listmp_params.shared_addr = (u32 *)((u32) (params->shared_addr) + + ((sizeof(struct heapbuf_attrs) + + (HEAPBUF_CACHESIZE - 1)) + & ~(HEAPBUF_CACHESIZE - 1))); + listmp_params.shared_addr_size = + listmp_sharedmemory_shared_memreq(&listmp_params); + listmp_params.gate = NULL; + /* Assign the memory with proper cache line padding */ + obj->attrs = (struct heapbuf_attrs *) params->shared_addr; + + if (create_flag == false) + listmp_sharedmemory_open(&obj->free_list, &listmp_params); + else { + obj->free_list = listmp_sharedmemory_create(&listmp_params); + + if (obj->free_list == NULL) { + retval = -ENOMEM; + goto listmp_error; + } + + obj->attrs->version = HEAPBUF_VERSION; + obj->attrs->num_free_blocks = params->num_blocks; + obj->attrs->min_free_blocks = params->num_blocks; + obj->attrs->block_size = params->block_size; + obj->attrs->align = params->align; + obj->attrs->num_blocks = params->num_blocks; + obj->attrs->buf_size = params->shared_buf_size; + buf = params->shared_buf; + align = obj->attrs->align; + buf = (char *)(((u32)buf + (align - 1)) & ~(align - 1)); + obj->attrs->buf = buf; + + /* + * Split the buffer into blocks that are length + * block_size" and add into the free_list Queue + */ + for (i = 0; i < obj->attrs->num_blocks; i++) { + listmp_put_tail((struct listmp_object *) + obj->free_list, + (struct listmp_elem *)buf); + buf += obj->attrs->block_size; + } + } + + obj->gate = params->gate; + + /* Populate the params member */ + memcpy(&obj->params, params, sizeof(struct heapbuf_params)); + if (params->name != NULL) { + obj->params.name = kmalloc(strlen(params->name) + 1, + GFP_KERNEL); + if (obj->params.name == NULL) { + retval = -ENOMEM; + goto name_alloc_error; + } + strncpy(obj->params.name, params->name, + strlen(params->name) + 1); + } + + if (create_flag == true) { + obj->owner.creator = true; + obj->owner.open_count = 1; + obj->owner.proc_id = multiproc_get_id(NULL); + obj->top = handle; + obj->attrs->status = HEAPBUF_CREATED; + } else { + obj->owner.creator = false; + obj->owner.open_count = 0; + obj->owner.proc_id = MULTIPROC_INVALIDID; + obj->top = handle; + } + + retval = mutex_lock_interruptible(heapbuf_state.local_lock); + if (retval) + goto lock_error; + + INIT_LIST_HEAD(&obj->list_elem); + list_add_tail(&obj->list_elem, &heapbuf_state.obj_list); + mutex_unlock(heapbuf_state.local_lock); + + if ((likely(heapbuf_state.cfg.use_nameserver == true)) + && (create_flag == true)) { + /* We will store a shared pointer in the nameserver */ + shm_index = sharedregion_get_index(params->shared_addr); + shared_shm_base = (u32)sharedregion_get_srptr( + params->shared_addr, shm_index); + if (obj->params.name != NULL) { + entry = nameserver_add_uint32(heapbuf_state.ns_handle, + params->name, + (u32)(shared_shm_base)); + if (entry == NULL) { + retval = -EFAULT; + goto ns_add_error; + } + } + } + + *handle_ptr = (void *)handle; + return retval; + +ns_add_error: + retval = mutex_lock_interruptible(heapbuf_state.local_lock); + list_del(&obj->list_elem); + mutex_unlock(heapbuf_state.local_lock); + +lock_error: + if (obj->params.name != NULL) { + if (obj->ns_key != NULL) { + nameserver_remove_entry(heapbuf_state.ns_handle, + obj->ns_key); + obj->ns_key = NULL; + } + kfree(obj->params.name); + } + +name_alloc_error: /* Fall through */ + if (create_flag == true) + listmp_sharedmemory_delete((listmp_sharedmemory_handle *) + &obj->free_list); + else + listmp_sharedmemory_close((listmp_sharedmemory_handle *) + &obj->free_list); + +listmp_error: + kfree(obj); + +obj_alloc_error: + kfree(handle); + +error: + printk(KERN_ERR "_heapbuf_create failed status: %x\n", retval); + return retval; +} + +/* + * ======== heapbuf_create ======== + * Purpose: + * This will create a new instance of heapbuf module + */ +void *heapbuf_create(const struct heapbuf_params *params) +{ + s32 retval = 0; + void *handle = NULL; + u32 buf_size; + + if (atomic_cmpmask_and_lt(&(heapbuf_state.ref_count), + HEAPBUF_MAKE_MAGICSTAMP(0), + HEAPBUF_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto error; + } + + BUG_ON(params == NULL); + + if ((params->shared_addr) == NULL || + params->shared_buf == NULL) { + retval = -EINVAL; + goto error; + } + + if ((params->shared_addr_size) + < heapbuf_shared_memreq(params, &buf_size)) { + /* if Shared memory size is less than required */ + retval = -EINVAL; + goto error; + } + + if (params->shared_buf_size < buf_size) { + /* if shared memory size is less than required */ + retval = -EINVAL; + goto error; + } + + retval = _heapbuf_create((void **)&handle, params, true); + if (retval < 0) + goto error; + + return (void *)handle; + +error: + printk(KERN_ERR "heapbuf_create failed status: %x\n", retval); + return (void *)handle; +} +EXPORT_SYMBOL(heapbuf_create); + +/* + * ======== heapbuf_delete ======== + * Purpose: + * This will delete an instance of heapbuf module + */ +int heapbuf_delete(void **handle_ptr) +{ + int status = 0; + struct heap_object *handle = NULL; + struct heapbuf_obj *obj = NULL; + struct heapbuf_params *params = NULL; + s32 retval = 0; + u16 myproc_id; + + BUG_ON(handle_ptr == NULL); + handle = (struct heap_object *)(*handle_ptr); + if (WARN_ON(handle == NULL)) { + retval = -EINVAL; + goto error; + } + + if (atomic_cmpmask_and_lt(&(heapbuf_state.ref_count), + HEAPBUF_MAKE_MAGICSTAMP(0), + HEAPBUF_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto error; + } + + obj = (struct heapbuf_obj *)handle->obj; + if (obj == NULL) { + retval = -EINVAL; + goto error; + } + + myproc_id = multiproc_get_id(NULL); + + if (obj->owner.proc_id != myproc_id) { + retval = -EPERM; + goto error; + } + + if (likely(obj->gate != NULL)) { + status = gatepeterson_enter(obj->gate); + if (status < 0) { + retval = -EINVAL; + goto gate_error; + } + } + + if (obj->owner.open_count > 1) { + retval = -EBUSY; + goto device_busy_error;; + } + + if (obj->owner.open_count != 1) { + retval = -EBUSY; + goto device_busy_error;; + } + + retval = mutex_lock_interruptible(heapbuf_state.local_lock); + if (retval) + goto local_lock_error; + + list_del(&obj->list_elem); + mutex_unlock(heapbuf_state.local_lock); + params = (struct heapbuf_params *) &obj->params; + if (likely(params->name != NULL)) { + if (likely(heapbuf_state.cfg.use_nameserver == true)) { + retval = nameserver_remove(heapbuf_state.ns_handle, + params->name); + if (retval != 0) + goto ns_remove_error; + obj->ns_key = NULL; + } + kfree(params->name); + } + + if (likely(obj->gate != NULL)) + gatepeterson_leave(obj->gate, 0); + retval = listmp_sharedmemory_delete(&obj->free_list); + kfree(obj); + kfree(handle); + *handle_ptr = NULL; + return 0; + +ns_remove_error: /* Fall through */ +gate_error: /* Fall through */ +local_lock_error: /* Fall through */ +device_busy_error: + if (likely(obj->gate != NULL)) + gatepeterson_leave(obj->gate, 0); + +error: + printk(KERN_ERR "heapbuf_delete failed status: %x\n", retval); + return retval; +} +EXPORT_SYMBOL(heapbuf_delete); + +/* + * ======== heapbuf_open ======== + * Purpose: + * This will opens a created instance of heapbuf + * module + */ +int heapbuf_open(void **handle_ptr, + struct heapbuf_params *params) +{ + struct heapbuf_obj *obj = NULL; + bool found = false; + s32 retval = 0; + u16 myproc_id; + u32 shared_shm_base; + struct heapbuf_attrs *attrs; + + BUG_ON(handle_ptr == NULL); + BUG_ON(params == NULL); + + if (atomic_cmpmask_and_lt(&(heapbuf_state.ref_count), + HEAPBUF_MAKE_MAGICSTAMP(0), + HEAPBUF_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto error; + } + + if ((heapbuf_state.cfg.use_nameserver == false) + && (params->shared_addr == (u32)NULL)) { + retval = -EINVAL; + goto error; + } + + if ((heapbuf_state.cfg.use_nameserver == true) + && (params->shared_addr == (u32)NULL) + && (params->name == NULL)) { + retval = -EINVAL; + goto error; + } + + myproc_id = multiproc_get_id(NULL); + list_for_each_entry(obj, &heapbuf_state.obj_list, list_elem) { + if (obj->params.shared_addr == params->shared_addr) + found = true; + else if (params->name != NULL) { + if (strcmp(obj->params.name, params->name) == 0) + found = true; + } + + if (found == true) { + retval = mutex_lock_interruptible( + heapbuf_state.local_lock); + if (retval) + goto error; + if (obj->owner.proc_id == myproc_id) + obj->owner.open_count++; + *handle_ptr = obj->top; + mutex_unlock(heapbuf_state.local_lock); + } + } + + if (likely(found == false)) { + if (unlikely(params->shared_addr == NULL)) { + if (likely(heapbuf_state.cfg.use_nameserver == true)) { + /* Find in name server */ + retval = nameserver_get(heapbuf_state.ns_handle, + params->name, + &shared_shm_base, + sizeof(u32), + NULL); + if (retval < 0) + goto error; + + /* + * Convert from shared region pointer + * to local address + */ + params->shared_addr = sharedregion_get_ptr + (&shared_shm_base); + if (params->shared_addr == NULL) { + retval = -EINVAL; + goto error; + } + } + } + + attrs = (struct heapbuf_attrs *)(params->shared_addr); + if (unlikely(attrs->status != (HEAPBUF_CREATED))) + retval = -ENXIO; /* Not created */ + else if (unlikely(attrs->version != (HEAPBUF_VERSION))) { + retval = -EINVAL; + goto error; + } + + retval = _heapbuf_create((void **)handle_ptr, params, false); + if (retval < 0) + goto error; + + } + + return 0; + +error: + printk(KERN_ERR "heapbuf_open failed status: %x\n", retval); + return retval; +} +EXPORT_SYMBOL(heapbuf_open); + +/* + * ======== heapbuf_close ======== + * Purpose: + * This will closes previously opened/created instance + * of heapbuf module + */ +int heapbuf_close(void *handle_ptr) +{ + int status = 0; + struct heap_object *handle = NULL; + struct heapbuf_obj *obj = NULL; + struct heapbuf_params *params = NULL; + s32 retval = 0; + u16 myproc_id = 0; + + if (atomic_cmpmask_and_lt(&(heapbuf_state.ref_count), + HEAPBUF_MAKE_MAGICSTAMP(0), + HEAPBUF_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto error; + } + + if (WARN_ON(handle_ptr == NULL)) { + retval = -EINVAL; + goto error; + } + + handle = (struct heap_object *)(handle_ptr); + obj = (struct heapbuf_obj *)handle->obj; + + if (obj != NULL) { + retval = mutex_lock_interruptible(heapbuf_state.local_lock); + if (retval) + goto error; + + myproc_id = multiproc_get_id(NULL); + /* opening an instance created locally */ + if (obj->owner.proc_id == myproc_id) { + if (obj->owner.open_count > 1) + obj->owner.open_count--; + } + + /* Check if HeapBuf is opened on same processor*/ + if ((((struct heapbuf_obj *)obj)->owner.creator == false) + && (obj->owner.open_count == 0)) { + list_del(&obj->list_elem); + + /* Take the local lock */ + if (likely(obj->gate != NULL)) { + status = gatepeterson_enter(obj->gate); + if (status < 0) { + retval = -EINVAL; + goto error; + } + } + + params = (struct heapbuf_params *)&obj->params; + if (likely((params->name) != NULL)) + kfree(params->name); /* Free memory */ + + /* Release the local lock */ + if (likely(obj->gate != NULL)) + gatepeterson_leave(obj->gate, 0); + + /* Delete the list */ + listmp_sharedmemory_close((listmp_sharedmemory_handle *) + obj->free_list); + kfree(obj); + kfree(handle); + handle = NULL; + } + mutex_unlock(heapbuf_state.local_lock); + } + return 0; + +error: + printk(KERN_ERR "heapbuf_close failed status: %x\n", retval); + return retval; +} +EXPORT_SYMBOL(heapbuf_close); + +/* + * ======== heapbuf_alloc ======== + * Purpose: + * This will allocs a block of memory + */ +void *heapbuf_alloc(void *hphandle, u32 size, u32 align) +{ + int status = 0; + struct heap_object *handle = NULL; + struct heapbuf_obj *obj = NULL; + char *block = NULL; + s32 retval = 0; + + if (atomic_cmpmask_and_lt(&(heapbuf_state.ref_count), + HEAPBUF_MAKE_MAGICSTAMP(0), + HEAPBUF_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto error; + } + + if (WARN_ON(hphandle == NULL)) { + retval = -EINVAL; + goto error; + } + + if (WARN_ON(size == 0)) { + retval = -EINVAL; + goto error; + } + + handle = (struct heap_object *)(hphandle); + obj = (struct heapbuf_obj *)handle->obj; + + if ((obj->params.exact == true) + && (size != obj->attrs->block_size)) { + retval = -EINVAL; + goto error; + } + + if (size > obj->attrs->block_size) { + retval = -EINVAL; + goto error; + } + + if (likely(obj->gate != NULL)) { + status = gatepeterson_enter(obj->gate); + if (status < 0) { + retval = -EINVAL; + goto error; + } + } + + block = listmp_get_head((void *)obj->free_list); + if (block == NULL) { + retval = -ENOMEM; + goto error; + } + + obj->attrs->num_free_blocks--; + /* + * Keep track of the min number of free for this heapbuf, if user + * has set the config variable trackMaxAllocs to true. + * + * The min number of free blocks, 'min_free_blocks', will be used to + * compute the "all time" maximum number of allocated blocks in + * getExtendedStats(). + */ + if (heapbuf_state.cfg.track_max_allocs) { + if (obj->attrs->num_free_blocks < obj->attrs->min_free_blocks) + /* save the new minimum */ + obj->attrs->min_free_blocks = + obj->attrs->num_free_blocks; + } + + if (likely(obj->gate != NULL)) + gatepeterson_leave(obj->gate, 0); + return block; +error: + printk(KERN_ERR "heapbuf_alloc failed status: %x\n", retval); + return NULL; +} +EXPORT_SYMBOL(heapbuf_alloc); + +/* + * ======== heapbuf_free ======== + * Purpose: + * This will free a block of memory + */ +int heapbuf_free(void *hphandle, void *block, u32 size) +{ + int status = 0; + struct heap_object *handle = NULL; + struct heapbuf_obj *obj = NULL; + s32 retval = 0; + + if (atomic_cmpmask_and_lt(&(heapbuf_state.ref_count), + HEAPBUF_MAKE_MAGICSTAMP(0), + HEAPBUF_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto error; + } + + if (WARN_ON(hphandle == NULL)) { + retval = -EINVAL; + goto error; + } + + if (WARN_ON(block == NULL)) { + retval = -EINVAL; + goto error; + } + + handle = (struct heap_object *)(hphandle); + obj = (struct heapbuf_obj *)handle->obj; + if (likely(obj->gate != NULL)) { + status = gatepeterson_enter(obj->gate); + if (status < 0) { + retval = -EINVAL; + goto error; + } + } + + retval = listmp_put_tail((void *)obj->free_list, block); + obj->attrs->num_free_blocks++; + if (likely(obj->gate != NULL)) + gatepeterson_leave(obj->gate, 0); + return 0; + +error: + printk(KERN_ERR "heapbuf_free failed status: %x\n", retval); + return retval; +} +EXPORT_SYMBOL(heapbuf_free); + +/* + * ======== heapbuf_get_stats ======== + * Purpose: + * This will get memory statistics + */ +int heapbuf_get_stats(void *hphandle, struct memory_stats *stats) +{ + int status = 0; + struct heap_object *object = NULL; + struct heapbuf_obj *obj = NULL; + u32 block_size; + s32 retval = 0; + + if (atomic_cmpmask_and_lt(&(heapbuf_state.ref_count), + HEAPBUF_MAKE_MAGICSTAMP(0), + HEAPBUF_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto error; + } + + BUG_ON(stats == NULL); + + if (WARN_ON(hphandle == NULL)) { + retval = -EINVAL; + goto error; + } + + object = (struct heap_object *)(hphandle); + obj = (struct heapbuf_obj *)object->obj; + + if (likely(obj->gate != NULL)) { + status = gatepeterson_enter(obj->gate); + if (status < 0) { + retval = -EINVAL; + goto error; + } + } + + block_size = obj->attrs->block_size; + stats->total_size = (u32 *)(block_size * obj->attrs->num_blocks); + stats->total_free_size = (u32 *)(block_size * + obj->attrs->num_free_blocks); + if (obj->attrs->num_free_blocks) + stats->largest_free_size = (u32 *)block_size; + else + stats->largest_free_size = (u32 *)0; + + if (likely(obj->gate != NULL)) + gatepeterson_leave(obj->gate, 0); + return 0; + +error: + printk(KERN_ERR "heapbuf_get_stats failed status: %x\n", retval); + return retval; +} +EXPORT_SYMBOL(heapbuf_get_stats); + +/* + * ======== heapbuf_isblocking ======== + * Purpose: + * Indicate whether the heap may block during an alloc or free call + */ +bool heapbuf_isblocking(void *handle) +{ + bool isblocking = false; + s32 retval = 0; + + if (WARN_ON(handle == NULL)) { + retval = -EINVAL; + goto error; + } + + /* TBD: Figure out how to determine whether the gate is blocking */ + isblocking = true; + + /* retval true Heap blocks during alloc/free calls */ + /* retval false Heap does not block during alloc/free calls */ + return isblocking; + +error: + printk(KERN_ERR "heapbuf_isblocking status: %x\n", retval); + return isblocking; +} +EXPORT_SYMBOL(heapbuf_isblocking); + +/* + * ======== heapbuf_get_extended_stats ======== + * Purpose: + * This will get extended statistics + */ +int heapbuf_get_extended_stats(void *hphandle, + struct heapbuf_extended_stats *stats) +{ + int status = 0; + struct heap_object *object = NULL; + struct heapbuf_obj *obj = NULL; + s32 retval = 0; + + if (atomic_cmpmask_and_lt(&(heapbuf_state.ref_count), + HEAPBUF_MAKE_MAGICSTAMP(0), + HEAPBUF_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto error; + } + + BUG_ON(stats == NULL); + if (WARN_ON(heapbuf_state.ns_handle == NULL)) { + retval = -EINVAL; + goto error; + } + + if (WARN_ON(hphandle == NULL)) { + retval = -EINVAL; + goto error; + } + + object = (struct heap_object *)(hphandle); + obj = (struct heapbuf_obj *)object->obj; + if (likely(obj->gate != NULL)) { + status = gatepeterson_enter(obj->gate); + if (status < 0) { + retval = -EINVAL; + goto error; + } + } + + /* + * The maximum number of allocations for this heapbuf (for any given + * instance of time during its liftime) is computed as follows: + * + * max_allocated_blocks = obj->num_blocks - obj->min_free_blocks + * + * Note that max_allocated_blocks is *not* the maximum allocation count, + * but rather the maximum allocations seen at any snapshot of time in + * the heapbuf instance. + */ + /* if nothing has been alloc'ed yet, return 0 */ + if ((u32)(obj->attrs->min_free_blocks) == -1) /* FIX THIS */ + stats->max_allocated_blocks = 0; + else + stats->max_allocated_blocks = obj->attrs->num_blocks + - obj->attrs->min_free_blocks; + /* current number of alloc'ed blocks is computed using curr # free + * blocks + */ + stats->num_allocated_blocks = obj->attrs->num_blocks + - obj->attrs->num_free_blocks; + if (likely(obj->gate != NULL)) + gatepeterson_leave(obj->gate, 0); + +error: + printk(KERN_ERR "heapbuf_get_extended_stats status: %x\n", + retval); + return retval; +} +EXPORT_SYMBOL(heapbuf_get_extended_stats); + +/* + * ======== heapbuf_shared_memreq ======== + * Purpose: + * This will get amount of shared memory required for + * creation of each instance + */ +int heapbuf_shared_memreq(const struct heapbuf_params *params, u32 *buf_size) +{ + int state_size = 0; + listmp_sharedmemory_params listmp_params; + + BUG_ON(params == NULL); + + /* Size for attrs */ + state_size = (sizeof(struct heapbuf_attrs) + (HEAPBUF_CACHESIZE - 1)) + & ~(HEAPBUF_CACHESIZE - 1); + + listmp_params_init(NULL, &listmp_params); + listmp_params.resource_id = params->resource_id; + state_size += listmp_shared_memreq(&listmp_params); + + /* Determine size for the buffer */ + *buf_size = params->num_blocks * params->block_size; + + return state_size; +} +EXPORT_SYMBOL(heapbuf_shared_memreq); diff --git a/drivers/dsp/syslink/multicore_ipc/heapbuf_ioctl.c b/drivers/dsp/syslink/multicore_ipc/heapbuf_ioctl.c new file mode 100755 index 000000000000..62928088fd65 --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/heapbuf_ioctl.c @@ -0,0 +1,485 @@ +/* + * heapbuf_ioctl.c + * + * Heap module manages fixed size buffers that can be used + * in a multiprocessor system with shared memory. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#include <linux/uaccess.h> +#include <linux/types.h> +#include <linux/bug.h> +#include <linux/fs.h> +#include <linux/mm.h> +#include <heap.h> +#include <heapbuf.h> +#include <heapbuf_ioctl.h> +#include <sharedregion.h> + +/* + * ======== heapbuf_ioctl_alloc ======== + * Purpose: + * This ioctl interface to heapbuf_alloc function + */ +static int heapbuf_ioctl_alloc(struct heapbuf_cmd_args *cargs) +{ + u32 *block_srptr = SHAREDREGION_INVALIDSRPTR; + void *block; + s32 index; + s32 status = 0; + + block = heapbuf_alloc(cargs->args.alloc.handle, + cargs->args.alloc.size, + cargs->args.alloc.align); + if (block != NULL) { + index = sharedregion_get_index(block); + block_srptr = sharedregion_get_srptr(block, index); + } + /* The error on above fn will be a null ptr. We are not + checking that condition here. We are passing whatever + we are getting from the heapbuf module. So IOCTL will succed, + but the actual fn might be failed inside heapbuf + */ + cargs->args.alloc.block_srptr = block_srptr; + cargs->api_status = 0; + return status; +} + +/* + * ======== heapbuf_ioctl_free ======== + * Purpose: + * This ioctl interface to heapbuf_free function + */ +static int heapbuf_ioctl_free(struct heapbuf_cmd_args *cargs) +{ + char *block; + + block = sharedregion_get_ptr(cargs->args.free.block_srptr); + cargs->api_status = heapbuf_free(cargs->args.free.handle, block, + cargs->args.free.size); + return 0; +} + +/* + * ======== heapbuf_ioctl_params_init ======== + * Purpose: + * This ioctl interface to heapbuf_params_init function + */ +static int heapbuf_ioctl_params_init(struct heapbuf_cmd_args *cargs) +{ + struct heapbuf_params params; + s32 status = 0; + u32 size; + + heapbuf_params_init(cargs->args.params_init.handle, ¶ms); + cargs->api_status = 0; + size = copy_to_user(cargs->args.params_init.params, ¶ms, + sizeof(struct heapbuf_params)); + if (size) + status = -EFAULT; + + return status; +} + +/* + * ======== heapbuf_ioctl_create ======== + * Purpose: + * This ioctl interface to heapbuf_create function + */ +static int heapbuf_ioctl_create(struct heapbuf_cmd_args *cargs) +{ + struct heapbuf_params params; + s32 status = 0; + u32 size; + void *handle = NULL; + + size = copy_from_user(¶ms, cargs->args.create.params, + sizeof(struct heapbuf_params)); + if (size) { + status = -EFAULT; + goto exit; + } + + if (cargs->args.create.name_len > 0) { + params.name = kmalloc(cargs->args.create.name_len, GFP_KERNEL); + if (params.name == NULL) { + status = -ENOMEM; + goto exit; + } + + params.name[cargs->args.create.name_len] = '\0'; + size = copy_from_user(params.name, + cargs->args.create.params->name, + cargs->args.create.name_len); + if (size) { + status = -EFAULT; + goto name_from_usr_error; + } + } + + params.shared_addr = sharedregion_get_ptr((u32 *) + cargs->args.create.shared_addr_srptr); + params.shared_buf = sharedregion_get_ptr((u32 *) + cargs->args.create.shared_buf_srptr); + params.gate = cargs->args.create.knl_gate; + handle = heapbuf_create(¶ms); + cargs->args.create.handle = handle; + cargs->api_status = 0; + +name_from_usr_error: + if (cargs->args.open.name_len > 0) + kfree(params.name); + +exit: + return status; +} + + +/* + * ======== heapbuf_ioctl_delete ======== + * Purpose: + * This ioctl interface to heapbuf_delete function + */ +static int heapbuf_ioctl_delete(struct heapbuf_cmd_args *cargs) +{ + cargs->api_status = heapbuf_delete(&cargs->args.delete.handle); + return 0; +} + +/* + * ======== heapbuf_ioctl_open ======== + * Purpose: + * This ioctl interface to heapbuf_open function + */ +static int heapbuf_ioctl_open(struct heapbuf_cmd_args *cargs) +{ + struct heapbuf_params params; + void *handle = NULL; + s32 status = 0; + ulong size; + + size = copy_from_user(¶ms, cargs->args.open.params, + sizeof(struct heapbuf_params)); + if (size) { + status = -EFAULT; + goto exit; + } + + if (cargs->args.open.name_len > 0) { + params.name = kmalloc(cargs->args.open.name_len, GFP_KERNEL); + if (params.name == NULL) { + status = -ENOMEM; + goto exit; + } + + params.name[cargs->args.create.name_len] = '\0'; + size = copy_from_user(params.name, + cargs->args.open.params->name, + cargs->args.open.name_len); + if (size) { + status = -EFAULT; + goto free_name; + } + } + + /* For open by name, the shared_add_srptr may be invalid */ + if (cargs->args.open.shared_addr_srptr != SHAREDREGION_INVALIDSRPTR) { + params.shared_addr = sharedregion_get_ptr( + (u32 *)cargs->args.open.shared_addr_srptr); + } + params.gate = cargs->args.open.knl_gate; + + cargs->api_status = heapbuf_open(&handle, ¶ms); + if (cargs->api_status < 0) + goto free_name; + + cargs->args.open.handle = handle; + size = copy_to_user(cargs->args.open.params, ¶ms, + sizeof(struct heapbuf_params)); + if (size) { + status = -EFAULT; + goto copy_to_usr_error; + } + + goto free_name; + +copy_to_usr_error: + if (handle) { + heapbuf_close(handle); + cargs->args.open.handle = NULL; + } + +free_name: + if (cargs->args.open.name_len > 0) + kfree(params.name); + +exit: + return status; +} + + +/* + * ======== heapbuf_ioctl_close ======== + * Purpose: + * This ioctl interface to heapbuf_close function + */ +static int heapbuf_ioctl_close(struct heapbuf_cmd_args *cargs) +{ + cargs->api_status = heapbuf_close(cargs->args.close.handle); + return 0; +} + +/* + * ======== heapbuf_ioctl_shared_memreq ======== + * Purpose: + * This ioctl interface to heapbuf_shared_memreq function + */ +static int heapbuf_ioctl_shared_memreq(struct heapbuf_cmd_args *cargs) +{ + struct heapbuf_params params; + s32 status = 0; + ulong size; + u32 bytes; + + size = copy_from_user(¶ms, cargs->args.shared_memreq.params, + sizeof(struct heapbuf_params)); + if (size) { + status = -EFAULT; + goto exit; + } + + bytes = heapbuf_shared_memreq(¶ms, + &cargs->args.shared_memreq.buf_size); + cargs->args.shared_memreq.bytes = bytes; + cargs->api_status = 0; + +exit: + return status; +} + + +/* + * ======== heapbuf_ioctl_get_config ======== + * Purpose: + * This ioctl interface to heapbuf_get_config function + */ +static int heapbuf_ioctl_get_config(struct heapbuf_cmd_args *cargs) +{ + struct heapbuf_config config; + s32 status = 0; + ulong size; + + cargs->api_status = heapbuf_get_config(&config); + size = copy_to_user(cargs->args.get_config.config, &config, + sizeof(struct heapbuf_config)); + if (size) + status = -EFAULT; + + return status; +} + +/* + * ======== heapbuf_ioctl_setup ======== + * Purpose: + * This ioctl interface to heapbuf_setup function + */ +static int heapbuf_ioctl_setup(struct heapbuf_cmd_args *cargs) +{ + struct heapbuf_config config; + s32 status = 0; + ulong size; + + size = copy_from_user(&config, cargs->args.setup.config, + sizeof(struct heapbuf_config)); + if (size) { + status = -EFAULT; + goto exit; + } + + cargs->api_status = heapbuf_setup(&config); + +exit: + return status; +} +/* + * ======== heapbuf_ioctl_destroy ======== + * Purpose: + * This ioctl interface to heapbuf_destroy function + */ +static int heapbuf_ioctl_destroy(struct heapbuf_cmd_args *cargs) +{ + cargs->api_status = heapbuf_destroy(); + return 0; +} + + +/* + * ======== heapbuf_ioctl_get_stats ======== + * Purpose: + * This ioctl interface to heapbuf_get_stats function + */ +static int heapbuf_ioctl_get_stats(struct heapbuf_cmd_args *cargs) +{ + struct memory_stats stats; + s32 status = 0; + ulong size; + + cargs->api_status = heapbuf_get_stats(cargs->args.get_stats.handle, + &stats); + if (status) + goto exit; + + size = copy_to_user(cargs->args.get_stats.stats, &stats, + sizeof(struct memory_stats)); + if (size) + status = -EFAULT; + +exit: + return status; +} + +/* + * ======== heapbuf_ioctl_get_extended_stats ======== + * Purpose: + * This ioctl interface to heapbuf_get_extended_stats function + */ +static int heapbuf_ioctl_get_extended_stats(struct heapbuf_cmd_args *cargs) +{ + struct heapbuf_extended_stats stats; + s32 status = 0; + ulong size; + + cargs->api_status = heapbuf_get_extended_stats( + cargs->args.get_extended_stats.handle, &stats); + if (cargs->api_status != 0) + goto exit; + + size = copy_to_user(cargs->args.get_extended_stats.stats, &stats, + sizeof(struct heapbuf_extended_stats)); + if (size) + status = -EFAULT; + +exit: + return status; +} + +/* + * ======== heapbuf_ioctl ======== + * Purpose: + * This ioctl interface for heapbuf module + */ +int heapbuf_ioctl(struct inode *pinode, struct file *filp, + unsigned int cmd, unsigned long args) +{ + s32 status = 0; + s32 size = 0; + struct heapbuf_cmd_args __user *uarg = + (struct heapbuf_cmd_args __user *)args; + struct heapbuf_cmd_args cargs; + + if (_IOC_DIR(cmd) & _IOC_READ) + status = !access_ok(VERIFY_WRITE, uarg, _IOC_SIZE(cmd)); + else if (_IOC_DIR(cmd) & _IOC_WRITE) + status = !access_ok(VERIFY_READ, uarg, _IOC_SIZE(cmd)); + + if (status) { + status = -EFAULT; + goto exit; + } + + /* Copy the full args from user-side */ + size = copy_from_user(&cargs, uarg, + sizeof(struct heapbuf_cmd_args)); + if (size) { + status = -EFAULT; + goto exit; + } + + switch (cmd) { + case CMD_HEAPBUF_ALLOC: + status = heapbuf_ioctl_alloc(&cargs); + break; + + case CMD_HEAPBUF_FREE: + status = heapbuf_ioctl_free(&cargs); + break; + + case CMD_HEAPBUF_PARAMS_INIT: + status = heapbuf_ioctl_params_init(&cargs); + break; + + case CMD_HEAPBUF_CREATE: + status = heapbuf_ioctl_create(&cargs); + break; + + case CMD_HEAPBUF_DELETE: + status = heapbuf_ioctl_delete(&cargs); + break; + + case CMD_HEAPBUF_OPEN: + status = heapbuf_ioctl_open(&cargs); + break; + + case CMD_HEAPBUF_CLOSE: + status = heapbuf_ioctl_close(&cargs); + break; + + case CMD_HEAPBUF_SHAREDMEMREQ: + status = heapbuf_ioctl_shared_memreq(&cargs); + break; + + case CMD_HEAPBUF_GETCONFIG: + status = heapbuf_ioctl_get_config(&cargs); + break; + + case CMD_HEAPBUF_SETUP: + status = heapbuf_ioctl_setup(&cargs); + break; + + case CMD_HEAPBUF_DESTROY: + status = heapbuf_ioctl_destroy(&cargs); + break; + + case CMD_HEAPBUF_GETSTATS: + status = heapbuf_ioctl_get_stats(&cargs); + break; + + case CMD_HEAPBUF_GETEXTENDEDSTATS: + status = heapbuf_ioctl_get_extended_stats(&cargs); + break; + + default: + WARN_ON(cmd); + status = -ENOTTY; + break; + } + + if ((cargs.api_status == -ERESTARTSYS) || (cargs.api_status == -EINTR)) + status = -ERESTARTSYS; + + if (status < 0) + goto exit; + + /* Copy the full args to the user-side. */ + size = copy_to_user(uarg, &cargs, + sizeof(struct heapbuf_cmd_args)); + if (size) { + status = -EFAULT; + goto exit; + } + +exit: + return status; + +} + diff --git a/drivers/dsp/syslink/multicore_ipc/ipc_drv.c b/drivers/dsp/syslink/multicore_ipc/ipc_drv.c new file mode 100755 index 000000000000..2e9a36f53592 --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/ipc_drv.c @@ -0,0 +1,242 @@ +/* + * ipc_drv.c + * + * IPC driver module. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +/*#ifdef MODULE*/ +#include <linux/module.h> +/*#endif*/ +#include <linux/device.h> +#include <linux/init.h> +#include <linux/types.h> +#include <linux/kdev_t.h> +#include <linux/fs.h> +#include <linux/moduleparam.h> +#include <linux/cdev.h> +#include <linux/uaccess.h> + +#include <ipc_ioctl.h> +#include <nameserver.h> + +#define IPC_NAME "syslink_ipc" +#define IPC_MAJOR 0 +#define IPC_MINOR 0 +#define IPC_DEVICES 1 + +struct ipc_device { + struct cdev cdev; +}; + +struct ipc_device *ipc_device; +static struct class *ipc_class; + +s32 ipc_major = IPC_MAJOR; +s32 ipc_minor = IPC_MINOR; +char *ipc_name = IPC_NAME; + +module_param(ipc_name, charp, 0); +MODULE_PARM_DESC(ipc_name, "Device name, default = syslink_ipc"); + +module_param(ipc_major, int, 0); /* Driver's major number */ +MODULE_PARM_DESC(ipc_major, "Major device number, default = 0 (auto)"); + +module_param(ipc_minor, int, 0); /* Driver's minor number */ +MODULE_PARM_DESC(ipc_minor, "Minor device number, default = 0 (auto)"); + +MODULE_AUTHOR("Texas Instruments"); +MODULE_LICENSE("GPL"); + +/* + * ======== ipc_open ======== + * This function is invoked when an application + * opens handle to the ipc driver + */ +int ipc_open(struct inode *inode, struct file *filp) +{ + s32 retval = 0; + struct ipc_device *dev; + + dev = container_of(inode->i_cdev, struct ipc_device, cdev); + filp->private_data = dev; + return retval; +} + +/* + * ======== ipc_release ======== + * This function is invoked when an application + * closes handle to the ipc driver + */ +int ipc_release(struct inode *inode, struct file *filp) +{ + return 0; +} + +/* + * ======== ipc_ioctl ======== + * This function provides IO interface to the + * ipc driver + */ +int ipc_ioctl(struct inode *ip, struct file *filp, u32 cmd, ulong arg) +{ + s32 retval = 0; + void __user *argp = (void __user *)arg; + + /* Verify the memory and ensure that it is not is kernel + address space + */ + if (_IOC_DIR(cmd) & _IOC_READ) + retval = !access_ok(VERIFY_WRITE, argp, _IOC_SIZE(cmd)); + else if (_IOC_DIR(cmd) & _IOC_WRITE) + retval = !access_ok(VERIFY_READ, argp, _IOC_SIZE(cmd)); + + if (retval) { + retval = -EFAULT; + goto exit; + } + + retval = ipc_ioc_router(cmd, (ulong)argp); + return retval; + +exit: + return retval; +} + +const struct file_operations ipc_fops = { +open: ipc_open, +release : ipc_release, +ioctl : ipc_ioctl, +}; + +/* + * ======== ipc_modules_Init ======== + * IPC Initialization routine. will initialize various + * sub components (modules) of IPC. + */ +static int ipc_modules_init(void) +{ + return 0; +} + +/* + * ======== ipc_modules_Init ======== + * IPC cleanup routine. will cleanup of various + * sub components (modules) of IPC. + */ +static void ipc_modules_exit(void) +{ + +} + +/* + * ======== ipc_init ======== + * Initialization routine. Executed when the driver is + * loaded (as a kernel module), or when the system + * is booted (when included as part of the kernel + * image). + */ +static int __init ipc_init(void) +{ + dev_t dev ; + s32 retval = 0; + + /* 2.6 device model */ + if (ipc_major) { + dev = MKDEV(ipc_major, ipc_minor); + retval = register_chrdev_region(dev, IPC_DEVICES, ipc_name); + } else { + retval = alloc_chrdev_region(&dev, ipc_minor, IPC_DEVICES, + ipc_name); + ipc_major = MAJOR(dev); + } + + if (retval < 0) { + printk(KERN_ERR "ipc_init: can't get major %x \n", ipc_major); + goto exit; + } + + ipc_device = kmalloc(sizeof(struct ipc_device), GFP_KERNEL); + if (!ipc_device) { + printk(KERN_ERR "ipc_init: memory allocation failed for " + "ipc_device \n"); + retval = -ENOMEM; + goto unreg_exit; + } + + memset(ipc_device, 0, sizeof(struct ipc_device)); + retval = ipc_modules_init(); + if (retval) { + printk(KERN_ERR "ipc_init: ipc initialization failed \n"); + goto unreg_exit; + + } + /* TO DO : NEED TO LOOK IN TO THIS */ + ipc_class = class_create(THIS_MODULE, "syslink_ipc"); + if (IS_ERR(ipc_class)) { + printk(KERN_ERR "ipc_init: error creating ipc class \n"); + retval = PTR_ERR(ipc_class); + goto unreg_exit; + } + + device_create(ipc_class, NULL, MKDEV(ipc_major, ipc_minor), NULL, + ipc_name); + cdev_init(&ipc_device->cdev, &ipc_fops); + ipc_device->cdev.owner = THIS_MODULE; + retval = cdev_add(&ipc_device->cdev, dev, IPC_DEVICES); + if (retval) { + printk(KERN_ERR "ipc_init: failed to add the ipc device \n"); + goto class_exit; + } + return retval; + +class_exit: + class_destroy(ipc_class); + +unreg_exit: + unregister_chrdev_region(dev, IPC_DEVICES); + kfree(ipc_device); + +exit: + return retval; +} + +/* + * ======== ipc_init ======== + * This function is invoked during unlinking of ipc + * module from the kernel. ipc resources are + * freed in this function. + */ +static void __exit ipc_exit(void) +{ + dev_t devno; + + ipc_modules_exit(); + devno = MKDEV(ipc_major, ipc_minor); + if (ipc_device) { + cdev_del(&ipc_device->cdev); + kfree(ipc_device); + } + unregister_chrdev_region(devno, IPC_DEVICES); + if (ipc_class) { + /* remove the device from sysfs */ + device_destroy(ipc_class, MKDEV(ipc_major, ipc_minor)); + class_destroy(ipc_class); + } +} + +/* + * ipc driver initialization and de-initialization functions + */ +module_init(ipc_init); +module_exit(ipc_exit); diff --git a/drivers/dsp/syslink/multicore_ipc/ipc_ioctl.c b/drivers/dsp/syslink/multicore_ipc/ipc_ioctl.c new file mode 100755 index 000000000000..b40a1e192e76 --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/ipc_ioctl.c @@ -0,0 +1,80 @@ +/* + * ipc_ioctl.c + * + * This is the collection of ioctl functions that will invoke various ipc + * module level functions based on user comands + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#include <linux/uaccess.h> + +#include <ipc_ioctl.h> +#include <multiproc_ioctl.h> +#include <nameserver_ioctl.h> +#include <heapbuf_ioctl.h> +#include <sharedregion_ioctl.h> +#include <gatepeterson_ioctl.h> +#include <listmp_sharedmemory_ioctl.h> +#include <messageq_ioctl.h> +#include <messageq_transportshm_ioctl.h> +#include <nameserver_remotenotify_ioctl.h> +#include <sysmgr_ioctl.h> +#include <sysmemmgr_ioctl.h> + +/* + * ======== ipc_ioctl_router ======== + * Purpose: + * This will route the ioctl commands to proper + * modules + */ +int ipc_ioc_router(u32 cmd, ulong arg) +{ + s32 retval = 0; + u32 ioc_nr = _IOC_NR(cmd); + + if (ioc_nr >= MULTIPROC_BASE_CMD && ioc_nr <= MULTIPROC_END_CMD) + retval = multiproc_ioctl(NULL, NULL, cmd, arg); + else if (ioc_nr >= NAMESERVER_BASE_CMD && + ioc_nr <= NAMESERVER_END_CMD) + retval = nameserver_ioctl(NULL, NULL, cmd, arg); + else if (ioc_nr >= HEAPBUF_BASE_CMD && ioc_nr <= HEAPBUF_END_CMD) + retval = heapbuf_ioctl(NULL, NULL, cmd, arg); + else if (ioc_nr >= SHAREDREGION_BASE_CMD && + ioc_nr <= SHAREDREGION_END_CMD) + retval = sharedregion_ioctl(NULL, NULL, cmd, arg); + else if (ioc_nr >= GATEPETERSON_BASE_CMD && + ioc_nr <= GATEPETERSON_END_CMD) + retval = gatepeterson_ioctl(NULL, NULL, cmd, arg); + else if (ioc_nr >= LISTMP_SHAREDMEMORY_BASE_CMD && + ioc_nr <= LISTMP_SHAREDMEMORY_END_CMD) + retval = listmp_sharedmemory_ioctl(NULL, NULL, cmd, arg); + else if (ioc_nr >= MESSAGEQ_BASE_CMD && + ioc_nr <= MESSAGEQ_END_CMD) + retval = messageq_ioctl(NULL, NULL, cmd, arg); + else if (ioc_nr >= MESSAGEQ_TRANSPORTSHM_BASE_CMD && + ioc_nr <= MESSAGEQ_TRANSPORTSHM_END_CMD) + retval = messageq_transportshm_ioctl(NULL, NULL, cmd, arg); + else if (ioc_nr >= NAMESERVERREMOTENOTIFY_BASE_CMD && + ioc_nr <= NAMESERVERREMOTENOTIFY_END_CMD) + retval = nameserver_remotenotify_ioctl(NULL, NULL, cmd, arg); + else if (ioc_nr >= SYSMGR_BASE_CMD && + ioc_nr <= SYSMGR_END_CMD) + retval = sysmgr_ioctl(NULL, NULL, cmd, arg); + else if (ioc_nr >= SYSMEMMGR_BASE_CMD && + ioc_nr <= SYSMEMMGR_END_CMD) + retval = sysmemmgr_ioctl(NULL, NULL, cmd, arg); + else + retval = -ENOTTY; + + return retval; +} diff --git a/drivers/dsp/syslink/multicore_ipc/listmp.c b/drivers/dsp/syslink/multicore_ipc/listmp.c new file mode 100644 index 000000000000..742c67f58f4c --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/listmp.c @@ -0,0 +1,440 @@ +/* + * listmp_sharedmemory.c + * + * The listmp_sharedmemory is a linked-list based module designed to be + * used in a multi-processor environment. It is designed to + * provide a means of communication between different processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +/*! + * + * This module implements the ListMP. + * This module is instance based. Each instance requires a small + * piece of shared memory. This is specified via the #shared_addr + * parameter to the create. The proper #shared_addr_size parameter + * can be determined via the #sharedMemReq call. Note: the + * parameters to this function must be the same that will used to + * create or open the instance. + * The ListMP module uses a #ti.sdo.utils.NameServer instance + * to store instance information when an instance is created and + * the name parameter is non-NULL. If a name is supplied, it must + * be unique for all ListMP instances. + * The #create also initializes the shared memory as needed. The + * shared memory must be initialized to 0 or all ones + * (e.g. 0xFFFFFFFFF) before the ListMP instance is created. + * Once an instance is created, an open can be performed. The #open + * is used to gain access to the same ListMP instance. + * Generally an instance is created on one processor and opened + * on the other processor. + * The open returns a ListMP instance handle like the create, + * however the open does not modify the shared memory. Generally an + * instance is created on one processor and opened on the other + * processor. + * There are two options when opening the instance: + * @li Supply the same name as specified in the create. The + * ListMP module queries the NameServer to get the needed + * information. + * @li Supply the same #shared_addr value as specified in the + * create. If the open is called before the instance is created, + * open returns NULL. + * There is currently a list of restrictions for the module: + * @li Both processors must have the same endianness. Endianness + * conversion may supported in a future version of ListMP. + * @li The module will be made a gated module + */ + + +/* Standard headers */ +#include <linux/types.h> +#include <linux/module.h> + +/* Utilities headers */ +#include <linux/string.h> +#include <linux/list.h> + +/* Module level headers */ +#include <nameserver.h> +#include <listmp.h> +#include <listmp_sharedmemory.h> + + +/* + * ======== listmp_params_init ======== + * Purpose: + * Function initializes listmp parameters + */ +void listmp_params_init(void *listmp_handle, struct listmp_params *params) +{ + BUG_ON(params == NULL); + listmp_sharedmemory_params_init(listmp_handle, params); +} + +/* + * ======== listmp_shared_memreq ======== + * Purpose: + * Function to get shared memory requirement for the module + */ +int listmp_shared_memreq(struct listmp_params *params) +{ + int shared_memreq = 0; + + if (WARN_ON(params == NULL)) + goto exit; + + shared_memreq = listmp_sharedmemory_shared_memreq(params); +exit: + return shared_memreq; +} + +/* + * ======== listmp_create ======== + * Purpose: + * Creates a new instance of listmp_sharedmemory module. + */ +void *listmp_create(struct listmp_params *params) +{ + struct listmp_object *handle = NULL; + + if (WARN_ON(params == NULL)) + goto exit; + + if (params->list_type == listmp_type_SHARED) + handle = (struct listmp_object *) + listmp_sharedmemory_create(params); + return (void *)handle; + +exit: + printk(KERN_ERR "listmp_create: listmp_params passed are NULL!\n"); + return NULL; +} + +/* + * ======== listmp_delete ======== + * Purpose: + * Deletes an instance of listmp_sharedmemory module. + */ +int listmp_delete(void **listmp_handle_ptr) +{ + int status = 0; + + if (WARN_ON(*listmp_handle_ptr == NULL)) { + status = -EINVAL; + goto exit; + } + + if (((struct listmp_object *)(*listmp_handle_ptr))->list_type == \ + listmp_type_SHARED) + status = listmp_sharedmemory_delete(listmp_handle_ptr); + +exit: + if (status < 0) { + printk(KERN_ERR "listmp_delete failed! status = 0x%x\n", + status); + } + return status; +} + +/* + * ======== listmp_open ======== + * Purpose: + * Opens an instance ofa previously created listmp_sharedmemory module. + */ +int listmp_open(void **listmp_handle_ptr, struct listmp_params *params) +{ + int status = 0; + + if (WARN_ON(listmp_handle_ptr == NULL)) { + status = -EINVAL; + goto exit; + } + if (WARN_ON(params == NULL)) { + status = -EINVAL; + goto exit; + } + + if (params->list_type == listmp_type_SHARED) + status = listmp_sharedmemory_open(listmp_handle_ptr, params); + +exit: + if (status < 0) + printk(KERN_ERR "listmp_open failed! status = 0x%x\n", status); + return status; +} + +/* + * ======== listmp_close ======== + * Purpose: + * Closes an instance of a previously opened listmp_sharedmemory module. + */ +int listmp_close(void *listmp_handle) +{ + int status = 0; + + if (WARN_ON(listmp_handle == NULL)) { + status = -EINVAL; + goto exit; + } + + if (((struct listmp_object *)listmp_handle)->list_type == \ + listmp_type_SHARED) + status = listmp_sharedmemory_close(listmp_handle); + +exit: + if (status < 0) + printk(KERN_ERR "listmp_close failed! status = 0x%x\n", status); + return status; +} + +/* + * ======== listmp_empty ======== + * Purpose: + * Function to check if list is empty + */ +bool listmp_empty(void *listmp_handle) +{ + bool isEmpty = false; + struct listmp_object *handle = NULL; + + if (WARN_ON(listmp_handle == NULL)) + goto exit; + + handle = (struct listmp_object *)listmp_handle; + + BUG_ON(handle->empty == NULL); + isEmpty = handle->empty(listmp_handle); + +exit: + return isEmpty; +} + +/* + * ======== listmp_get_head ======== + * Purpose: + * Function to get head element from a listmp_sharedmemory list + */ +void *listmp_get_head(void *listmp_handle) +{ + struct listmp_object *handle = NULL; + struct listmp_elem *elem = NULL; + + if (WARN_ON(listmp_handle == NULL)) + goto exit; + + handle = (struct listmp_object *)listmp_handle; + + BUG_ON(handle->get_head == NULL); + elem = handle->get_head(listmp_handle); + +exit: + return elem; +} + +/* + * ======== listmp_get_tail ===== + * Purpose: + * Function to get tailement from a listmp_sharedmemory list + */ +void *listmp_get_tail(void *listmp_handle) +{ + struct listmp_object *handle = NULL; + struct listmp_elem *elem = NULL; + + if (WARN_ON(listmp_handle == NULL)) + goto exit; + + handle = (struct listmp_object *)listmp_handle; + + BUG_ON(handle->get_tail == NULL); + elem = handle->get_tail(listmp_handle); + +exit: + return elem; +} + +/* + * ======== listmp_put_head ======== + * Purpose: + * Function to put head element into a listmp_sharedmemory list + */ +int listmp_put_head(void *listmp_handle, struct listmp_elem *elem) +{ + int status = 0; + struct listmp_object *handle = NULL; + + if (WARN_ON(listmp_handle == NULL)) { + status = -EINVAL; + goto exit; + } + if (WARN_ON(elem == NULL)) { + status = -EINVAL; + goto exit; + } + + handle = (struct listmp_object *) listmp_handle; + + BUG_ON(handle->put_head == NULL); + status = handle->put_head(listmp_handle, elem); + +exit: + if (status < 0) { + printk(KERN_ERR "listmp_put_head failed! status = 0x%x\n", + status); + } + return status; +} + +/* + * ======== listmp_put_tail ======== + * Purpose: + * Function to put tail element into a listmp_sharedmemory list + */ +int listmp_put_tail(void *listmp_handle, struct listmp_elem *elem) +{ + int status = 0; + struct listmp_object *handle = NULL; + + if (WARN_ON(listmp_handle == NULL)) { + status = -EINVAL; + goto exit; + } + if (WARN_ON(elem == NULL)) { + status = -EINVAL; + goto exit; + } + + handle = (struct listmp_object *)listmp_handle; + + BUG_ON(handle->put_tail == NULL); + status = handle->put_tail(listmp_handle, elem); + +exit: + if (status < 0) { + printk(KERN_ERR "listmp_put_tail failed! status = 0x%x\n", + status); + } + return status; +} + +/* + * ======== listmp_insert ======== + * Purpose: + * Function to insert element into a listmp_sharedmemory list + */ +int listmp_insert(void *listmp_handle, struct listmp_elem *elem, + struct listmp_elem *curElem) +{ + int status = 0; + struct listmp_object *handle = NULL; + + if (WARN_ON(listmp_handle == NULL)) { + status = -EINVAL; + goto exit; + } + if (WARN_ON(elem == NULL)) { + status = -EINVAL; + goto exit; + } + if (WARN_ON(curElem == NULL)) { + status = -EINVAL; + goto exit; + } + + handle = (struct listmp_object *)listmp_handle; + + BUG_ON(handle->insert == NULL); + status = handle->insert(listmp_handle, elem, curElem); + +exit: + if (status < 0) { + printk(KERN_ERR "listmp_insert failed! status = 0x%x\n", + status); + } + return status; +} + +/* + * ======== listmp_remove ======== + * Purpose: + * Function to remove an element from a listmp_sharedmemory list + */ +int listmp_remove(void *listmp_handle, struct listmp_elem *elem) +{ + int status = LISTMP_SUCCESS; + struct listmp_object *handle = NULL; + + if (WARN_ON(listmp_handle == NULL)) { + status = -EINVAL; + goto exit; + } + if (WARN_ON(elem == NULL)) { + status = -EINVAL; + goto exit; + } + + handle = (struct listmp_object *)listmp_handle; + + BUG_ON(handle->remove == NULL); + status = handle->remove(listmp_handle, elem); + +exit: + if (status < 0) { + printk(KERN_ERR "listmp_remove failed! status = 0x%x\n", + status); + } + return status ; +} + +/* + * ======== listmp_next ======== + * Purpose: + * Function to return the next element from a listmp_sharedmemory list + */ +void *listmp_next(void *listmp_handle, struct listmp_elem *elem) +{ + struct listmp_object *handle = NULL; + struct listmp_elem *nextElem = NULL; + + if (WARN_ON(listmp_handle == NULL)) + goto exit; + + handle = (struct listmp_object *)listmp_handle; + + BUG_ON(handle->next == NULL); + nextElem = handle->next(listmp_handle, elem); + +exit: + return nextElem; +} + +/* + * ======== listmp_next ======== + * Purpose: + * Function to return the prev element from a listmp_sharedmemory list + */ +void *listmp_prev(void *listmp_handle, struct listmp_elem *elem) +{ + struct listmp_object *handle = NULL; + struct listmp_elem *prevElem = NULL; + + if (WARN_ON(listmp_handle == NULL)) + goto exit; + + handle = (struct listmp_object *)listmp_handle; + + BUG_ON(handle->prev == NULL); + prevElem = handle->prev(listmp_handle, elem); + +exit: + return prevElem; +} diff --git a/drivers/dsp/syslink/multicore_ipc/listmp_sharedmemory.c b/drivers/dsp/syslink/multicore_ipc/listmp_sharedmemory.c new file mode 100755 index 000000000000..1e49d832c91d --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/listmp_sharedmemory.c @@ -0,0 +1,1487 @@ +/* + * listmp_sharedmemory.c + * + * The listmp_sharedmemory is a linked-list based module designed to be + * used in a multi-processor environment. It is designed to + * provide a means of communication between different processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +/*! + * This module is instance based. Each instance requires a small + * piece of shared memory. This is specified via the #shared_addr + * parameter to the create. The proper #shared_addr_size parameter + * can be determined via the #shared_memreq call. Note: the + * parameters to this function must be the same that will used to + * create or open the instance. + * The listmp_sharedmemory module uses a #NameServer instance + * to store instance information when an instance is created and + * the name parameter is non-NULL. If a name is supplied, it must + * be unique for all listmp_sharedmemory instances. + * The #create also initializes the shared memory as needed. The + * shared memory must be initialized to 0 or all ones + * (e.g. 0xFFFFFFFFF) before the listmp_sharedmemory instance + * is created. + * Once an instance is created, an open can be performed. The #open + * is used to gain access to the same listmp_sharedmemory instance. + * Generally an instance is created on one processor and opened + * on the other processor. + * The open returns a listmp_sharedmemory instance handle like the + * create, however the open does not modify the shared memory. + * Generally an instance is created on one processor and opened + * on the other processor. + * There are two options when opening the instance: + * @li Supply the same name as specified in the create. The + * listmp_sharedmemory module queries the NameServer to get the + * needed information. + * @li Supply the same #shared_addr value as specified in the + * create. + * If the open is called before the instance is created, open + * returns NULL. + * There is currently a list of restrictions for the module: + * @li Both processors must have the same endianness. Endianness + * conversion may supported in a future version of + * listmp_sharedmemory. + * @li The module will be made a gated module + */ + + +/* Standard headers */ +#include <linux/types.h> +#include <linux/module.h> + +/* Utilities headers */ +#include <linux/list.h> +#include <linux/slab.h> +#include <linux/string.h> + +/* Syslink headers */ +#include <syslink/atomic_linux.h> + +/* Module level headers */ +#include <nameserver.h> +#include <sharedregion.h> +#include <multiproc.h> +#include "_listmp.h" +#include <listmp.h> +#include <gatepeterson.h> +#include <listmp_sharedmemory.h> + + +/* ============================================================================= + * Globals + * ============================================================================= + */ +/*! @brief Macro to make a correct module magic number with refCount */ +#define LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(x) \ + ((LISTMPSHAREDMEMORY_MODULEID << 12u) | (x)) + +/*! + * @brief Name of the reserved NameServer used for listmp_sharedmemory. + */ +#define LISTMP_SHAREDMEMORY_NAMESERVER "ListMPSharedMemory" + +/*! + * @brief Cache size + */ +#define LISTMP_SHAREDMEMORY_CACHESIZE 128 + + + +/* ============================================================================= + * Structures and Enums + * ============================================================================= + */ +/*! @brief structure for listmp_sharedmemory module state */ +struct listmp_sharedmemory_module_object { + atomic_t ref_count; + /*!< Reference count */ + void *ns_handle; + /*!< Handle to the local NameServer used for storing GP objects */ + struct list_head obj_list; + /*!< List holding created listmp_sharedmemory objects */ + struct mutex *local_gate; + /*!< Handle to lock for protecting obj_list */ + struct listmp_config cfg; + /*!< Current config values */ + struct listmp_config default_cfg; + /*!< Default config values */ + listmp_sharedmemory_params default_inst_params; + /*!< Default instance creation parameters */ +}; + +/*! + * @var listmp_sharedmemory_nameServer + * + * @brief Name of the reserved NameServer used for listmp_sharedmemory. + */ +static +struct listmp_sharedmemory_module_object listmp_sharedmemory_state = { + .default_cfg.max_name_len = 32, + .default_cfg.use_name_server = true, + .default_inst_params.shared_addr = 0, + .default_inst_params.shared_addr_size = 0, + .default_inst_params.name = NULL, + .default_inst_params.gate = NULL, + .default_inst_params.list_type = listmp_type_SHARED}; + +/*! + * @brief Structure for the internal Handle for the listmp_sharedmemory. + */ +struct listmp_sharedmemory_obj{ + struct list_head list_elem; + /*!< Used for creating a linked list */ + VOLATILE struct listmp_elem *listmp_elem; + /*!< Used for storing listmp_sharedmemory element */ + struct listmp_proc_attrs *owner; + /*!< Creator's attributes associated with an instance */ + listmp_sharedmemory_params params; + /*!< the parameter structure */ + void *ns_key; + u32 index; + /*!< the index for SrPtr */ + VOLATILE struct listmp_attrs *attrs; + /*!< Shared memory attributes */ + void *top; + /*!< Pointer to the top Object */ +}; + + +/* ============================================================================= + * Function definitions + * ============================================================================= + */ +/* + * ======== _listmp_sharedmemory_create ======== + * Purpose: + * Creates a new instance of listmp_sharedmemory module. This is an internal + * function because both listmp_sharedmemory_create and + * listmp_sharedmemory_open call use the same functionality. + */ +static listmp_sharedmemory_handle +_listmp_sharedmemory_create(listmp_sharedmemory_params *params, + u32 create_flag); + + +/* ============================================================================= + * Function API's + * ============================================================================= + */ +/* + * ======== listmp_sharedmemory_get_config ======== + * Purpose: + * Function to get configuration parameters to setup the + * the listmp_sharedmemory module. + */ +int listmp_sharedmemory_get_config(struct listmp_config *cfgParams) +{ + int status = 0; + + if (WARN_ON(cfgParams == NULL)) { + status = -EINVAL; + goto exit; + } + + if (atomic_cmpmask_and_lt(&(listmp_sharedmemory_state.ref_count), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(0), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(1)) == true) + /* If setup has not yet been called) */ + memcpy(cfgParams, &listmp_sharedmemory_state.default_cfg, + sizeof(struct listmp_config)); + else + memcpy(cfgParams, &listmp_sharedmemory_state.cfg, + sizeof(struct listmp_config)); + return 0; + +exit: + printk(KERN_ERR "listmp_sharedmemory_get_config failed: " + "status = 0x%x\n", status); + return status; +} + +/* + * ======== listmp_sharedmemory_setup ======== + * Purpose: + * Function to setup the listmp_sharedmemory module. + */ +int listmp_sharedmemory_setup(struct listmp_config *config) +{ + int status = 0; + int status1 = 0; + void *nshandle = NULL; + struct nameserver_params params; + struct listmp_config tmp_cfg; + + /* This sets the refCount variable is not initialized, upper 16 bits is + * written with module Id to ensure correctness of refCount variable. + */ + atomic_cmpmask_and_set(&listmp_sharedmemory_state.ref_count, + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(0), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(0)); + + if (atomic_inc_return(&listmp_sharedmemory_state.ref_count) + != LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(1)) { + return 1; + } + + if (config == NULL) { + listmp_sharedmemory_get_config(&tmp_cfg); + config = &tmp_cfg; + } + + if (WARN_ON(config->max_name_len == 0)) { + status = -EINVAL; + goto exit; + } + + if (likely((config->use_name_server == true))) { + /* Initialize the parameters */ + nameserver_params_init(¶ms); + params.max_value_len = 4; + params.max_name_len = config->max_name_len; + /* Create the nameserver for modules */ + nshandle = nameserver_create( + LISTMP_SHAREDMEMORY_NAMESERVER, ¶ms); + if (unlikely(nshandle == NULL)) { + status = LISTMPSHAREDMEMORY_E_FAIL; + goto exit; + } + } + + listmp_sharedmemory_state.ns_handle = nshandle; + /* Construct the list object */ + INIT_LIST_HEAD(&listmp_sharedmemory_state.obj_list); + /* Create a lock for protecting list object */ + listmp_sharedmemory_state.local_gate = \ + kmalloc(sizeof(struct mutex), GFP_KERNEL); + if (listmp_sharedmemory_state.local_gate == NULL) { + status = -ENOMEM; + goto clean_nameserver; + } + + mutex_init(listmp_sharedmemory_state.local_gate); + /* Copy the cfg */ + memcpy(&listmp_sharedmemory_state.cfg, config, + sizeof(struct listmp_config)); + return 0; + +clean_nameserver: + printk(KERN_ERR "listmp_sharedmemory_setup: Failed to create the local " + "gate! status = 0x%x\n", status); + atomic_set(&listmp_sharedmemory_state.ref_count, + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(0)); + status1 = nameserver_delete + (&(listmp_sharedmemory_state.ns_handle)); + BUG_ON(status1 < 0); + +exit: + printk(KERN_ERR "listmp_sharedmemory_setup failed! status = 0x%x\n", + status); + return status; +} + +/* + * ======== listmp_sharedmemory_destroy ======== + * Purpose: + * Function to destroy the listmp_sharedmemory module. + */ +int listmp_sharedmemory_destroy(void) +{ + int status = 0; + int status1 = 0; + struct list_head *elem = NULL; + struct list_head *head = &listmp_sharedmemory_state.obj_list; + struct list_head *next; + + if (atomic_cmpmask_and_lt(&(listmp_sharedmemory_state.ref_count), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(0), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(1)) == true) { + status = -ENODEV; + goto exit; + } + + if (atomic_dec_return(&listmp_sharedmemory_state.ref_count) + == LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(0)) { + /* Temporarily increment refCount here. */ + atomic_set(&listmp_sharedmemory_state.ref_count, + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(1)); + /* Check if any listmp_sharedmemory instances have not been + * deleted so far. If not, delete them. */ + for (elem = (head)->next; elem != (head); elem = next) { + /* Retain the next pointer so it doesn't + get overwritten */ + next = elem->next; + if (((struct listmp_sharedmemory_obj *) elem)->owner + ->proc_id == multiproc_get_id(NULL)) { + status1 = listmp_sharedmemory_delete( + (listmp_sharedmemory_handle *) + &(((struct listmp_sharedmemory_obj *) \ + elem)->top)); + WARN_ON(status1 < 0); + } else { + status1 = listmp_sharedmemory_close( + (listmp_sharedmemory_handle) + (((struct listmp_sharedmemory_obj *) \ + elem)->top)); + WARN_ON(status1 < 0); + } + } + + /* Again reset refCount. */ + atomic_set(&listmp_sharedmemory_state.ref_count, + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(0)); + if (likely(listmp_sharedmemory_state.cfg.use_name_server + == true)) { + /* Delete the nameserver for modules */ + status = nameserver_delete( + &(listmp_sharedmemory_state.ns_handle)); + BUG_ON(status < 0); + } + + /* Destruct the list object */ + list_del(&listmp_sharedmemory_state.obj_list); + /* Delete the list lock */ + kfree(listmp_sharedmemory_state.local_gate); + listmp_sharedmemory_state.local_gate = NULL; + memset(&listmp_sharedmemory_state.cfg, 0, + sizeof(struct listmp_config)); + /* Decrease the refCount */ + atomic_set(&listmp_sharedmemory_state.ref_count, + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(0)); + } + +exit: + if (status < 0) { + printk(KERN_ERR "listmp_sharedmemory_destroy failed! " + "status = 0x%x\n", status); + } + return status; +} + +/* + * ======== listmp_sharedmemory_params_init ======== + * Purpose: + * Function to initialize the config-params structure with supplier-specified + * defaults before instance creation. + */ +void listmp_sharedmemory_params_init(listmp_sharedmemory_handle handle, + listmp_sharedmemory_params *params) +{ + s32 status = 0; + struct listmp_sharedmemory_obj *obj = NULL; + + if (atomic_cmpmask_and_lt(&(listmp_sharedmemory_state.ref_count), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(0), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(1)) == true) { + status = -ENODEV; + goto exit; + } + + if (WARN_ON(params == NULL)) { + status = -EINVAL; + goto exit; + } + + if (handle == NULL) { + memcpy(params, + &(listmp_sharedmemory_state.default_inst_params), + sizeof(listmp_sharedmemory_params)); + } else { + obj = (struct listmp_sharedmemory_obj *) + (((listmp_sharedmemory_object *) handle)->obj); + + memcpy((void *)&obj->params, + (void *)params, + sizeof(listmp_sharedmemory_params)); + } + return; + +exit: + printk(KERN_ERR "listmp_sharedmemory_params_init failed! " + "status = 0x%x\n", status); + return; +} + +/* + * ======== listmp_sharedmemory_create ======== + * Purpose: + * Creates a new instance of listmp_sharedmemory module. + */ +listmp_sharedmemory_handle listmp_sharedmemory_create( + listmp_sharedmemory_params *params) +{ + s32 status = 0; + listmp_sharedmemory_object *handle = NULL; + + if (atomic_cmpmask_and_lt(&(listmp_sharedmemory_state.ref_count), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(0), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(1)) == true) { + status = -ENODEV; + goto exit; + } + + if (WARN_ON(params == NULL)) { + status = -EINVAL; + goto exit; + } + + if (WARN_ON((params->shared_addr == (u32)NULL) + && (params->list_type != listmp_type_FAST))) { + status = -EINVAL; + goto exit; + } + if (WARN_ON(params->shared_addr_size + < listmp_sharedmemory_shared_memreq(params))) { + status = -EINVAL; + goto exit; + } + + handle = (listmp_sharedmemory_object *) + _listmp_sharedmemory_create(params, true); + +exit: + if (status < 0) { + printk(KERN_ERR "listmp_sharedmemory_create failed! " + "status = 0x%x\n", status); + } + return (listmp_sharedmemory_handle) handle; +} + +/* + * ======== listmp_sharedmemory_delete ======== + * Purpose: + * Deletes a instance of listmp_sharedmemory instance object. + */ +int listmp_sharedmemory_delete(listmp_sharedmemory_handle *listmp_handleptr) +{ + int status = 0; + listmp_sharedmemory_object *handle = NULL; + struct listmp_sharedmemory_obj *obj = NULL; + listmp_sharedmemory_params *params = NULL; + + if (atomic_cmpmask_and_lt(&(listmp_sharedmemory_state.ref_count), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(0), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(1)) == true) { + status = -ENODEV; + goto exit; + } + if (WARN_ON(listmp_handleptr == NULL)) { + status = -EINVAL; + goto exit; + } + if (WARN_ON(*listmp_handleptr == NULL)) { + status = -EINVAL; + goto exit; + } + + handle = (listmp_sharedmemory_object *) (*listmp_handleptr); + obj = (struct listmp_sharedmemory_obj *) handle->obj; + params = (listmp_sharedmemory_params *) &obj->params; + + if (obj->owner->proc_id != multiproc_get_id(NULL)) { + status = -EPERM; + goto exit; + } + + if (obj->owner->open_count > 1) { + status = -EBUSY; + goto exit; + } + + if (obj->owner->open_count != 1) { + status = -EBUSY; + goto exit; + } + + /* Remove from the local list */ + status = mutex_lock_interruptible( + listmp_sharedmemory_state.local_gate); + if (status) + goto exit; + list_del(&obj->list_elem); + mutex_unlock(listmp_sharedmemory_state.local_gate); + + if (likely(params->name != NULL)) { + /* Free memory for the name */ + kfree(params->name); + /* Remove from the name server */ + if (likely(listmp_sharedmemory_state.cfg.use_name_server)) { + if (obj->ns_key != NULL) { + nameserver_remove_entry( + listmp_sharedmemory_state.ns_handle, + obj->ns_key); + obj->ns_key = NULL; + } + } + } + + /* Free memory for the processor info's */ + if (obj) + kfree(obj->owner); + /* Now free the handle */ + kfree(obj); + obj = NULL; + + /* Now free the handle */ + kfree(handle); + handle = NULL; + *listmp_handleptr = NULL; + +exit: + if (status < 0) { + printk(KERN_ERR "listmp_sharedmemory_delete failed! " + "status = 0x%x\n", status); + } + return status; + +} + + +/* + * ======== listmp_sharedmemory_shared_memreq ======== + * Purpose: + * Function to return the amount of shared memory required for creation of + * each instance. + */ +int listmp_sharedmemory_shared_memreq(listmp_sharedmemory_params *params) +{ + int retval = 0; + + if (WARN_ON(params == NULL)) { + retval = -EINVAL; + goto exit; + } + + if (params->list_type == listmp_type_SHARED) + retval = (LISTMP_SHAREDMEMORY_CACHESIZE * 2); + +exit: + if (retval < 0) { + printk(KERN_ERR "listmp_sharedmemory_shared_memreq failed! " + "retval = 0x%x\n", retval); + } + /*! @retval ((1 * sizeof(struct listmp_elem)) + *! + 1 * sizeof(struct listmp_attrs)) if params is null */ + /*! @retval (2 * cacheSize) if params is provided */ + /*! @retval (0) if hardware queue */ + return retval; +} + +/* + * ======== listmp_sharedmemory_open ======== + * Purpose: + * Function to open a listmp_sharedmemory instance + */ +int listmp_sharedmemory_open(listmp_sharedmemory_handle *listmp_handleptr, + listmp_sharedmemory_params *params) +{ + int status = 0; + bool done_flag = false; + struct list_head *elem; + u32 shared_shm_base; + struct listmp_attrs *attrs; + + if (atomic_cmpmask_and_lt(&(listmp_sharedmemory_state.ref_count), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(0), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(1)) == true) { + status = -ENODEV; + goto exit; + } + if (WARN_ON(listmp_handleptr == NULL)) { + status = -EINVAL; + goto exit; + } + if (WARN_ON(params == NULL)) { + status = -EINVAL; + goto exit; + } + + if (WARN_ON((listmp_sharedmemory_state.cfg.use_name_server == false) + && (params->shared_addr == (u32)NULL))) { + status = -EINVAL; + goto exit; + } + + if (WARN_ON((listmp_sharedmemory_state.cfg.use_name_server == true) + && (params->shared_addr == (u32)NULL)) + && (params->name == NULL)) { + status = -EINVAL; + goto exit; + } + + /* First check in the local list */ + list_for_each(elem, &listmp_sharedmemory_state.obj_list) { + if (((struct listmp_sharedmemory_obj *)elem)->params.shared_addr + == params->shared_addr) { + status = mutex_lock_interruptible( + listmp_sharedmemory_state.local_gate); + if (status) + goto exit; + if (((struct listmp_sharedmemory_obj *)elem) + ->owner->proc_id + == multiproc_get_id(NULL)) + ((struct listmp_sharedmemory_obj *)elem) + ->owner->open_count++; + mutex_unlock( + listmp_sharedmemory_state.local_gate); + *listmp_handleptr = \ + (((struct listmp_sharedmemory_obj *) + elem)->top); + done_flag = true; + break; + } else if ((params->name != NULL) + && (((struct listmp_sharedmemory_obj *)elem) \ + ->params.name != NULL)){ + if (strcmp(((struct listmp_sharedmemory_obj *)elem) + ->params.name, params->name) == 0) { + status = mutex_lock_interruptible( + listmp_sharedmemory_state.local_gate); + if (status) + goto exit; + if (((struct listmp_sharedmemory_obj *)elem) + ->owner->proc_id + == multiproc_get_id(NULL)) + ((struct listmp_sharedmemory_obj *)elem) + ->owner->open_count++; + mutex_unlock( + listmp_sharedmemory_state.local_gate); + *listmp_handleptr = \ + (((struct listmp_sharedmemory_obj *) + elem)->top); + done_flag = true; + break; + } + } + } + + if (likely(done_flag == false)) { + if (unlikely(params->shared_addr == NULL)) { + if (likely(listmp_sharedmemory_state.cfg.use_name_server + == true)){ + /* Find in name server */ + status = + nameserver_get( + listmp_sharedmemory_state.ns_handle, + params->name, + &shared_shm_base, + sizeof(u32), + NULL); + if (status >= 0) + params->shared_addr = + sharedregion_get_ptr( + (u32 *)shared_shm_base); + if (params->shared_addr == NULL) { + status = + LISTMPSHAREDMEMORY_E_NOTCREATED; + goto exit; + } + } + } + } + + if (status >= 0) { + attrs = (struct listmp_attrs *) (params->shared_addr); + if (unlikely(attrs->status != (LISTMP_SHAREDMEMORY_CREATED))) + status = LISTMPSHAREDMEMORY_E_NOTCREATED; + else if (unlikely(attrs->version != + (LISTMP_SHAREDMEMORY_VERSION))) + status = LISTMPSHAREDMEMORY_E_VERSION; + } + + if (likely(status >= 0)) + *listmp_handleptr = (listmp_sharedmemory_handle) + _listmp_sharedmemory_create(params, false); + +exit: + if (status < 0) { + printk(KERN_ERR "listmp_sharedmemory_open failed! " + "status = 0x%x\n", status); + } + return status; +} + +/* + * ======== listmp_sharedmemory_close ======== + * Purpose: + * Function to close a previously opened instance + */ +int listmp_sharedmemory_close(listmp_sharedmemory_handle listmp_handle) +{ + int status = 0; + listmp_sharedmemory_object *handle = NULL; + struct listmp_sharedmemory_obj *obj = NULL; + listmp_sharedmemory_params *params = NULL; + + if (atomic_cmpmask_and_lt(&(listmp_sharedmemory_state.ref_count), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(0), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(1)) == true) { + status = -ENODEV; + goto exit; + } + + if (WARN_ON(listmp_handle == NULL)) { + status = -EINVAL; + goto exit; + } + + handle = (listmp_sharedmemory_object *)listmp_handle; + obj = (struct listmp_sharedmemory_obj *) handle->obj; + if (obj == NULL) { + status = -EINVAL; + goto exit; + } + + status = mutex_lock_interruptible( + listmp_sharedmemory_state.local_gate); + if (status) + goto exit; + if (obj->owner->proc_id == multiproc_get_id(NULL)) + (obj)->owner->open_count--; + + params = (listmp_sharedmemory_params *) &obj->params; + /* Check if ListMP is opened on same processor*/ + if (((struct listmp_sharedmemory_obj *)obj)->owner->creator == false) { + list_del(&obj->list_elem); + /* remove from the name server */ + if (params->name != NULL) + /* Free memory for the name */ + kfree(params->name); + + kfree(obj->owner); + kfree(obj); + obj = NULL; + kfree(handle); + handle = NULL; + } + + mutex_unlock(listmp_sharedmemory_state.local_gate); + +exit: + if (status < 0) { + printk(KERN_ERR "listmp_sharedmemory_close failed! " + "status = 0x%x\n", status); + } + return status; +} + +/* + * ======== listmp_sharedmemory_empty ======== + * Purpose: + * Function to check if the shared memory list is empty + */ +bool listmp_sharedmemory_empty(listmp_sharedmemory_handle listmp_handle) +{ + + int status = 0; + bool is_empty = false; + listmp_sharedmemory_object *handle = NULL; + struct listmp_sharedmemory_obj *obj = NULL; + s32 retval = 0; + struct listmp_elem *sharedHead; + + if (atomic_cmpmask_and_lt(&(listmp_sharedmemory_state.ref_count), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(0), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(1)) == true) { + status = -ENODEV; + goto exit; + } + + if (WARN_ON(listmp_handle == NULL)) { + status = -EINVAL; + goto exit; + } + + handle = (listmp_sharedmemory_object *)listmp_handle; + obj = (struct listmp_sharedmemory_obj *) handle->obj; + + if (obj->params.gate != NULL) { + retval = gatepeterson_enter(obj->params.gate); + if (retval < 0) { + status = -EINVAL; + goto exit; + } + } + + /*! @retval true if list is empty */ + sharedHead = (struct listmp_elem *)(sharedregion_get_srptr( + (void *)obj->listmp_elem, obj->index)); + dsb(); + if (obj->listmp_elem->next == sharedHead) + is_empty = true; + + if (obj->params.gate != NULL) + gatepeterson_leave(obj->params.gate, 0); + +exit: + return is_empty; +} + +/* + * ======== listmp_sharedmemory_get_head ======== + * Purpose: + * Function to get head element from a shared memory list + */ +void *listmp_sharedmemory_get_head(listmp_sharedmemory_handle listmp_handle) +{ + listmp_sharedmemory_object *handle = NULL; + struct listmp_sharedmemory_obj *obj = NULL; + struct listmp_elem *elem = NULL; + struct listmp_elem *localHeadNext = NULL; + struct listmp_elem *localNext = NULL; + struct listmp_elem *sharedHead = NULL; + s32 retval = 0; + + if (atomic_cmpmask_and_lt(&(listmp_sharedmemory_state.ref_count), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(0), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(1)) == true) + goto exit; + + if (WARN_ON(listmp_handle == NULL)) { + /*! @retval NULL if listmp_handle passed is NULL */ + elem = NULL; + goto exit; + } + + handle = (listmp_sharedmemory_object *)listmp_handle; + obj = (struct listmp_sharedmemory_obj *) handle->obj; + + if (obj->params.gate != NULL) { + retval = gatepeterson_enter(obj->params.gate); + if (retval < 0) + goto exit; + } + + localHeadNext = sharedregion_get_ptr((u32 *)obj->listmp_elem->next); + dsb(); + /* See if the listmp_sharedmemory_object was empty */ + if (localHeadNext == (struct listmp_elem *)obj->listmp_elem) { + /*! @retval NULL if list is empty */ + elem = NULL ; + } else { + /* Elem to return */ + elem = localHeadNext; + dsb(); + localNext = sharedregion_get_ptr((u32 *)elem->next); + sharedHead = (struct listmp_elem *) sharedregion_get_srptr( + (void *)obj->listmp_elem, obj->index); + + /* Fix the head of the list next pointer */ + obj->listmp_elem->next = elem->next; + dsb(); + /* Fix the prev pointer of the new first elem on the + list */ + localNext->prev = sharedHead; + } + + if (obj->params.gate != NULL) + gatepeterson_leave(obj->params.gate, 0); + +exit: + return elem; +} + +/* + * ======== listmp_sharedmemory_get_tail ======== + * Purpose: + * Function to get tail element from a shared memory list + */ +void *listmp_sharedmemory_get_tail(listmp_sharedmemory_handle listmp_handle) +{ + listmp_sharedmemory_object *handle = NULL; + struct listmp_sharedmemory_obj *obj = NULL; + struct listmp_elem *elem = NULL; + struct listmp_elem *localHeadNext = NULL; + struct listmp_elem *localHeadPrev = NULL; + struct listmp_elem *localPrev = NULL; + struct listmp_elem *sharedHead = NULL; + s32 retval = 0; + + if (atomic_cmpmask_and_lt(&(listmp_sharedmemory_state.ref_count), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(0), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(1)) == true) + goto exit; + + if (WARN_ON(listmp_sharedmemory_state.ns_handle == NULL)) { + /*! @retval NULL if Module was not initialized */ + elem = NULL; + goto exit; + } + if (WARN_ON(listmp_handle == NULL)) { + /*! @retval NULL if listmp_handle passed is NULL */ + elem = NULL; + goto exit; + } + + handle = (listmp_sharedmemory_object *)listmp_handle; + obj = (struct listmp_sharedmemory_obj *) handle->obj; + + if (obj->params.gate != NULL) { + retval = gatepeterson_enter(obj->params.gate); + if (retval < 0) + goto exit; + } + + localHeadNext = sharedregion_get_ptr((u32 *)obj->listmp_elem->next); + localHeadPrev = sharedregion_get_ptr((u32 *)obj->listmp_elem->prev); + + /* See if the listmp_sharedmemory_object was empty */ + if (localHeadNext == (struct listmp_elem *)obj->listmp_elem) { + /* Empty, return NULL */ + elem = NULL ; + } else { + /* Elem to return */ + elem = localHeadPrev; + localPrev = sharedregion_get_ptr((u32 *)elem->prev); + sharedHead = (struct listmp_elem *) sharedregion_get_srptr( + (void *)obj->listmp_elem, obj->index); + obj->listmp_elem->prev = elem->prev; + localPrev->next = sharedHead; + } + + if (obj->params.gate != NULL) + gatepeterson_leave(obj->params.gate, 0); + +exit: + return elem; +} + +/* + * ======== listmp_sharedmemory_put_head ======== + * Purpose: + * Function to put head element into a shared memory list + */ +int listmp_sharedmemory_put_head(listmp_sharedmemory_handle listmp_handle, + struct listmp_elem *elem) +{ + int status = 0; + listmp_sharedmemory_object *handle = NULL; + struct listmp_sharedmemory_obj *obj = NULL; + struct listmp_elem *localNextElem = NULL; + struct listmp_elem *sharedElem = NULL; + struct listmp_elem *sharedHead = NULL; + s32 retval = 0; + u32 index; + + if (atomic_cmpmask_and_lt(&(listmp_sharedmemory_state.ref_count), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(0), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(1)) == true) { + status = -ENODEV; + goto exit; + } + + if (WARN_ON(listmp_handle == NULL)) { + status = -EINVAL; + goto exit; + } + + handle = (listmp_sharedmemory_object *)listmp_handle; + obj = (struct listmp_sharedmemory_obj *) handle->obj; + dsb(); + index = sharedregion_get_index(elem); + sharedElem = (struct listmp_elem *) sharedregion_get_srptr(elem, index); + sharedHead = (struct listmp_elem *)sharedregion_get_srptr( + (void *)obj->listmp_elem, obj->index); + dsb(); + if (obj->params.gate != NULL) { + retval = gatepeterson_enter(obj->params.gate); + if (retval < 0) { + status = -EINVAL; + goto exit; + } + } + /* Add the new elem into the list */ + elem->next = obj->listmp_elem->next; + elem->prev = sharedHead; + dsb(); + localNextElem = sharedregion_get_ptr((u32 *)elem->next); + localNextElem->prev = sharedElem; + obj->listmp_elem->next = sharedElem; + + if (obj->params.gate != NULL) + gatepeterson_leave(obj->params.gate, 0); + +exit: + if (status < 0) { + printk(KERN_ERR "listmp_sharedmemory_put_head failed! " + "status = 0x%x\n", status); + } + return status; +} + +/* + * ======== listmp_sharedmemory_put_tail ======== + * Purpose: + * Function to put tail element into a shared memory list + */ +int listmp_sharedmemory_put_tail(listmp_sharedmemory_handle listmp_handle, + struct listmp_elem *elem) +{ + int status = 0; + listmp_sharedmemory_object *handle = NULL; + struct listmp_sharedmemory_obj *obj = NULL; + struct listmp_elem *localPrevElem = NULL; + struct listmp_elem *sharedElem = NULL; + struct listmp_elem *sharedHead = NULL; + s32 retval = 0; + u32 index; + + if (atomic_cmpmask_and_lt(&(listmp_sharedmemory_state.ref_count), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(0), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(1)) == true) { + status = -ENODEV; + goto exit; + } + + if (WARN_ON(elem == NULL)) { + status = -EINVAL; + goto exit; + } + + handle = (listmp_sharedmemory_object *)listmp_handle; + obj = (struct listmp_sharedmemory_obj *) handle->obj; + dsb(); + /* Safe to do outside the gate */ + index = sharedregion_get_index(elem); + sharedElem = (struct listmp_elem *) + sharedregion_get_srptr(elem, index); + sharedHead = (struct listmp_elem *)sharedregion_get_srptr + ((void *)obj->listmp_elem, + obj->index); + + if (obj->params.gate != NULL) { + retval = gatepeterson_enter(obj->params.gate); + if (retval < 0) { + status = -EINVAL; + goto exit; + } + } + /* Add the new elem into the list */ + elem->next = sharedHead; + elem->prev = obj->listmp_elem->prev; + dsb(); + localPrevElem = sharedregion_get_ptr((u32 *)elem->prev); + dsb(); + localPrevElem->next = sharedElem; + obj->listmp_elem->prev = sharedElem; + + if (obj->params.gate != NULL) + gatepeterson_leave(obj->params.gate, 0); + +exit: + if (status < 0) { + printk(KERN_ERR "listmp_sharedmemory_put_tail failed! " + "status = 0x%x\n", status); + } + return status; +} + +/* + * ======== listmp_sharedmemory_insert ======== + * Purpose: + * Function to insert an element into a shared memory list + */ +int listmp_sharedmemory_insert(listmp_sharedmemory_handle listmp_handle, + struct listmp_elem *new_elem, + struct listmp_elem *cur_elem) +{ + int status = 0; + listmp_sharedmemory_object *handle = NULL; + struct listmp_sharedmemory_obj *obj = NULL; + struct listmp_elem *localPrevElem = NULL; + struct listmp_elem *sharedNewElem = NULL; + struct listmp_elem *sharedCurElem = NULL; + s32 retval = 0; + u32 index; + + if (atomic_cmpmask_and_lt(&(listmp_sharedmemory_state.ref_count), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(0), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(1)) == true) { + status = -ENODEV; + goto exit; + } + + if (WARN_ON(new_elem == NULL)) { + status = -EINVAL; + goto exit; + } + + handle = (listmp_sharedmemory_object *)listmp_handle; + obj = (struct listmp_sharedmemory_obj *) handle->obj; + + if (obj->params.gate != NULL) { + retval = gatepeterson_enter(obj->params.gate); + if (retval < 0) { + status = -EINVAL; + goto exit; + } + } + + /* If NULL change cur_elem to the obj */ + if (cur_elem == NULL) + cur_elem = (struct listmp_elem *)obj->listmp_elem->next; + + /* Get SRPtr for new_elem */ + index = sharedregion_get_index(new_elem); + sharedNewElem = (struct listmp_elem *) + sharedregion_get_srptr(new_elem, index); + dsb(); + /* Get SRPtr for cur_elem */ + index = sharedregion_get_index(cur_elem); + sharedCurElem = (struct listmp_elem *) + sharedregion_get_srptr(cur_elem, index); + + /* Get SRPtr for cur_elem->prev */ + localPrevElem = sharedregion_get_ptr((u32 *)cur_elem->prev); + dsb(); + new_elem->next = sharedCurElem; + new_elem->prev = cur_elem->prev; + localPrevElem->next = sharedNewElem; + dsb(); + cur_elem->prev = sharedNewElem; + + if (obj->params.gate != NULL) + gatepeterson_leave(obj->params.gate, 0); + +exit: + if (status < 0) { + printk(KERN_ERR "listmp_sharedmemory_insert failed! " + "status = 0x%x\n", status); + } + return status; +} + +/* + * ======== listmp_sharedmemory_remove ======== + * Purpose: + * Function to remove a element from a shared memory list + */ +int listmp_sharedmemory_remove(listmp_sharedmemory_handle listmp_handle, + struct listmp_elem *elem) +{ + int status = 0; + listmp_sharedmemory_object *handle = NULL; + struct listmp_sharedmemory_obj *obj = NULL; + struct listmp_elem *localPrevElem = NULL; + struct listmp_elem *localNextElem = NULL; + s32 retval = 0; + + if (atomic_cmpmask_and_lt(&(listmp_sharedmemory_state.ref_count), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(0), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(1)) == true) { + status = -ENODEV; + goto exit; + } + + if (WARN_ON(elem == NULL)) { + status = -EINVAL; + goto exit; + } + + handle = (listmp_sharedmemory_object *)listmp_handle; + obj = (struct listmp_sharedmemory_obj *) handle->obj; + + if (obj->params.gate != NULL) { + retval = gatepeterson_enter(obj->params.gate); + if (retval < 0) { + status = -EINVAL; + goto exit; + } + } + + localPrevElem = sharedregion_get_ptr((u32 *)elem->prev); + localNextElem = sharedregion_get_ptr((u32 *)elem->next); + dsb(); + localPrevElem->next = elem->next; + localNextElem->prev = elem->prev; + + if (obj->params.gate != NULL) + gatepeterson_leave(obj->params.gate, 0); + +exit: + if (status < 0) { + printk(KERN_ERR "listmp_sharedmemory_remove failed! " + "status = 0x%x\n", status); + } + return status; +} + +/* + * ======== listmp_sharedmemory_next ======== + * Purpose: + * Function to traverse to next element in shared memory list + */ +void *listmp_sharedmemory_next(listmp_sharedmemory_handle listmp_handle, + struct listmp_elem *elem) +{ + listmp_sharedmemory_object *handle = NULL; + struct listmp_sharedmemory_obj *obj = NULL; + struct listmp_elem *retElem = NULL; + struct listmp_elem *sharedNextElem = NULL; + s32 retval = 0; + + if (atomic_cmpmask_and_lt(&(listmp_sharedmemory_state.ref_count), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(0), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(1)) == true) + goto exit; + + handle = (listmp_sharedmemory_object *)listmp_handle; + obj = (struct listmp_sharedmemory_obj *) handle->obj; + + if (obj->params.gate != NULL) { + retval = gatepeterson_enter(obj->params.gate); + if (retval < 0) + goto exit; + } + + /* If element is NULL start at head */ + if (elem == NULL) + sharedNextElem = (struct listmp_elem *) obj->listmp_elem->next; + else + sharedNextElem = (struct listmp_elem *)elem->next; + + retElem = sharedregion_get_ptr((u32 *)sharedNextElem); + + /*! @retval NULL if list is empty */ + if (retElem == (struct listmp_elem *)obj->listmp_elem) + retElem = NULL; + if (obj->params.gate != NULL) + gatepeterson_leave(obj->params.gate, 0); + +exit: + return retElem; +} + +/* + * ======== listmp_sharedmemory_prev ======== + * Purpose: + * Function to traverse to prev element in shared memory list + */ +void *listmp_sharedmemory_prev(listmp_sharedmemory_handle listmp_handle, + struct listmp_elem *elem) +{ + listmp_sharedmemory_object *handle = NULL; + struct listmp_sharedmemory_obj *obj = NULL; + struct listmp_elem *retElem = NULL; + struct listmp_elem *sharedPrevElem = NULL; + s32 retval = 0; + + if (atomic_cmpmask_and_lt(&(listmp_sharedmemory_state.ref_count), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(0), + LISTMPSHAREDMEMORY_MAKE_MAGICSTAMP(1)) == true) + goto exit; + + handle = (listmp_sharedmemory_object *)listmp_handle; + obj = (struct listmp_sharedmemory_obj *) handle->obj; + + if (obj->params.gate != NULL) { + retval = gatepeterson_enter(obj->params.gate); + if (retval < 0) + goto exit; + } + + /* If elem is NULL use head */ + if (elem == NULL) + sharedPrevElem = (struct listmp_elem *) + obj->listmp_elem->prev; + else + sharedPrevElem = (struct listmp_elem *)elem->prev; + + retElem = sharedregion_get_ptr((u32 *)sharedPrevElem); + + /*! @retval NULL if list is empty */ + if (retElem == (struct listmp_elem *)(obj->listmp_elem)) + retElem = NULL; + + if (obj->params.gate != NULL) + gatepeterson_leave(obj->params.gate, 0); + +exit: + return retElem; +} + +/* + * ======== _listmp_sharedmemory_create ======== + * Purpose: + * Creates a new instance of listmp_sharedmemory module. This is an internal + * function because both listmp_sharedmemory_create and + * listmp_sharedmemory_open call use the same functionality. + */ +listmp_sharedmemory_handle _listmp_sharedmemory_create( + listmp_sharedmemory_params *params, u32 create_flag) +{ + int status = 0; + listmp_sharedmemory_object *handle = NULL; + struct listmp_sharedmemory_obj *obj = NULL; + u32 key; + u32 shm_index; + u32 *shared_shm_base; + + BUG_ON(params == NULL); + + /* Allow local lock not being provided. Don't do protection if local + * lock is not provided. + */ + /* Create the handle */ + handle = kzalloc(sizeof(listmp_sharedmemory_object), GFP_KERNEL); + if (handle == NULL) { + status = -ENOMEM; + goto exit; + } + + obj = kzalloc(sizeof(struct listmp_sharedmemory_obj), + GFP_KERNEL); + if (obj == NULL) { + /*! @retval NULL if Memory allocation failed for + * internal object "Memory allocation failed for handle" + * "of type struct listmp_sharedmemory_obj"); */ + status = -ENOMEM; + goto exit; + } + + handle->obj = (struct listmp_sharedmemory_obj *)obj ; + handle->empty = &listmp_sharedmemory_empty; + handle->get_head = &listmp_sharedmemory_get_head; + handle->get_tail = &listmp_sharedmemory_get_tail; + handle->put_head = &listmp_sharedmemory_put_head; + handle->put_tail = &listmp_sharedmemory_put_tail; + handle->insert = &listmp_sharedmemory_insert; + handle->remove = &listmp_sharedmemory_remove; + handle->next = &listmp_sharedmemory_next; + handle->prev = &listmp_sharedmemory_prev; + + /* Update attrs */ + obj->attrs = (struct listmp_attrs *) params->shared_addr; + /* Assign the memory with proper cache line padding */ + obj->listmp_elem = (void *) ((u32)obj->attrs + \ + LISTMP_SHAREDMEMORY_CACHESIZE); + obj->index = sharedregion_get_index(params->shared_addr); + + if (create_flag == true) { + obj->attrs->shared_addr_size = params->shared_addr_size; + obj->attrs->version = LISTMP_SHAREDMEMORY_VERSION; + obj->listmp_elem->next = obj->listmp_elem->prev = + (struct listmp_elem *) + (sharedregion_get_srptr((void *)obj->listmp_elem, + obj->index)); + } + + /* Populate the params member */ + memcpy((void *)&obj->params, (void *)params, + sizeof(listmp_sharedmemory_params)); + + if (likely(listmp_sharedmemory_state.cfg.use_name_server + == true)) { + if (obj->params.name != NULL) { + /* Copy the name */ + obj->params.name = kmalloc(strlen(params->name) + 1, + GFP_KERNEL); + + if (obj->params.name == NULL) { + /*! @retval NULL if Memory allocation failed for + name */ + status = -ENOMEM; + } else { + strncpy(obj->params.name, params->name, + strlen(params->name) + 1); + } + } + } + + /* Update processor information */ + obj->owner = kmalloc(sizeof(struct listmp_proc_attrs), + GFP_KERNEL); + if (obj->owner == NULL) { + printk(KERN_ERR "_listmp_sharedmemory_create: Memory " + "allocation failed for processor information!\n"); + status = -ENOMEM; + } else { + /* Update owner and opener details */ + if (create_flag == true) { + obj->owner->creator = true; + obj->owner->open_count = 1; + obj->owner->proc_id = multiproc_get_id(NULL); + obj->top = handle; + obj->attrs->status = \ + LISTMP_SHAREDMEMORY_CREATED; + } else { + obj->owner->creator = false; + obj->owner->open_count = 0; + obj->owner->proc_id = MULTIPROC_INVALIDID; + obj->top = handle; + } + + /* Put in the local list */ + key = mutex_lock_interruptible( + listmp_sharedmemory_state.local_gate); + INIT_LIST_HEAD(&obj->list_elem); + list_add_tail((&obj->list_elem), + &listmp_sharedmemory_state.obj_list); + mutex_unlock(listmp_sharedmemory_state.local_gate); + + if (create_flag == true) { + + /* We will store a shared pointer in the + * NameServer + */ + shm_index = sharedregion_get_index(params->shared_addr); + shared_shm_base = sharedregion_get_srptr( + params->shared_addr, shm_index); + /* Add list instance to name server */ + if (obj->params.name != NULL) { + obj->ns_key = nameserver_add_uint32( + listmp_sharedmemory_state.ns_handle, + params->name, + (u32) (shared_shm_base)); + if (obj->ns_key == NULL) + status = -EFAULT; + } + } + } + + if (status < 0) { + /* Remove from the local list */ + key = mutex_lock_interruptible( + listmp_sharedmemory_state.local_gate); + list_del(&obj->list_elem); + mutex_unlock(listmp_sharedmemory_state.local_gate); + + if (likely(listmp_sharedmemory_state.cfg.use_name_server + == true)) { + if ((obj->params.name != NULL) && (status != -EFAULT)) + nameserver_remove_entry( + listmp_sharedmemory_state.ns_handle, + obj->ns_key); + } + if (obj->owner != NULL) + kfree(obj->owner); + + if (obj->params.name != NULL) + kfree(obj->params.name); + + if (obj != NULL) { + kfree(obj); + obj = NULL; + } + if (handle != NULL) { + kfree(handle); + handle = NULL; + } + } + +exit: + if (status < 0) { + printk(KERN_ERR "_listmp_sharedmemory_create failed! " + "status = 0x%x\n", status); + } + return (listmp_sharedmemory_handle) handle; +} diff --git a/drivers/dsp/syslink/multicore_ipc/listmp_sharedmemory_ioctl.c b/drivers/dsp/syslink/multicore_ipc/listmp_sharedmemory_ioctl.c new file mode 100644 index 000000000000..292881665788 --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/listmp_sharedmemory_ioctl.c @@ -0,0 +1,701 @@ +/* + * listmp_sharedmemory_ioctl.c + * + * This file implements all the ioctl operations required on the + * listmp_sharedmemory module. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +/* Standard headers */ +#include <linux/types.h> + +/* Linux headers */ +#include <linux/uaccess.h> +#include <linux/bug.h> +#include <linux/fs.h> +#include <linux/mm.h> + +/* Module Headers */ +#include <listmp.h> +#include <listmp_sharedmemory.h> +#include <listmp_sharedmemory_ioctl.h> +#include <sharedregion.h> + +/* + * ======== listmp_sharedmemory_ioctl_get_config ======== + * Purpose: + * This ioctl interface to listmp_sharedmemory_get_config function + */ +static inline int listmp_sharedmemory_ioctl_get_config( + struct listmp_sharedmemory_cmd_args *cargs) +{ + s32 retval = 0; + int status = 0; + unsigned long size; + struct listmp_config config; + + status = listmp_sharedmemory_get_config(&config); + if (unlikely(status)) + goto exit; + + size = copy_to_user(cargs->args.get_config.config, &config, + sizeof(struct listmp_config)); + if (size) { + retval = -EFAULT; + goto exit; + } + + cargs->api_status = 0; +exit: + return retval; +} + +/* + * ======== listmp_sharedmemory_ioctl_setup ======== + * Purpose: + * This ioctl interface to listmp_sharedmemory_setup function + */ +static inline int listmp_sharedmemory_ioctl_setup( + struct listmp_sharedmemory_cmd_args *cargs) +{ + s32 retval = 0; + int status = 0; + unsigned long size; + struct listmp_config config; + + size = copy_from_user(&config, cargs->args.setup.config, + sizeof(struct listmp_config)); + if (size) { + retval = -EFAULT; + goto exit; + } + + status = listmp_sharedmemory_setup(&config); + cargs->api_status = status; + if (unlikely(status)) + goto exit; +exit: + return retval; +} + +/* + * ======== listmp_sharedmemory_ioctl_destroy ======== + * Purpose: + * This ioctl interface to listmp_sharedmemory_destroy function + */ +static inline int listmp_sharedmemory_ioctl_destroy( + struct listmp_sharedmemory_cmd_args *cargs) +{ + cargs->api_status = listmp_sharedmemory_destroy(); + return 0; +} + +/* + * ======== listmp_sharedmemory_ioctl_params_init ======== + * Purpose: + * This ioctl interface to listmp_sharedmemory_params_init function + */ +static inline int listmp_sharedmemory_ioctl_params_init( + struct listmp_sharedmemory_cmd_args *cargs) +{ + s32 retval = 0; + int status = 0; + unsigned long size; + listmp_sharedmemory_params params; + + size = copy_from_user(¶ms, + cargs->args.params_init.params, + sizeof(listmp_sharedmemory_params)); + if (size) { + retval = -EFAULT; + goto exit; + } + + listmp_sharedmemory_params_init( + cargs->args.params_init.listmp_handle, ¶ms); + size = copy_to_user(cargs->args.params_init.params, ¶ms, + sizeof(listmp_sharedmemory_params)); + if (size) { + retval = -EFAULT; + goto exit; + } + +exit: + cargs->api_status = status; + return retval; +} + +/* + * ======== listmp_sharedmemory_ioctl_create ======== + * Purpose: + * This ioctl interface to listmp_sharedmemory_create function + */ +static inline int listmp_sharedmemory_ioctl_create( + struct listmp_sharedmemory_cmd_args *cargs) +{ + s32 retval = 0; + unsigned long size; + listmp_sharedmemory_params params; + + size = copy_from_user(¶ms, cargs->args.create.params, + sizeof(listmp_sharedmemory_params)); + if (size) { + retval = -EFAULT; + goto exit; + } + + /* Allocate memory for the name */ + if (cargs->args.create.name_len > 0) { + params.name = kmalloc(cargs->args.create.name_len, GFP_KERNEL); + if (params.name == NULL) { + retval = -ENOMEM; + goto exit; + } + /* Copy the name */ + size = copy_from_user(params.name, + cargs->args.create.params->name, + cargs->args.create.name_len); + if (size) { + retval = -EFAULT; + goto free_name; + } + } + + params.shared_addr = sharedregion_get_ptr( + (u32 *)cargs->args.create.shared_addr_srptr); + if (unlikely(params.shared_addr == NULL)) + goto free_name; + + /* Update gate in params. */ + params.gate = cargs->args.create.knl_gate; + cargs->args.create.listmp_handle = listmp_sharedmemory_create(¶ms); + + size = copy_to_user(cargs->args.create.params, ¶ms, + sizeof(listmp_sharedmemory_params)); + if (!size) + goto free_name; + + /* Error copying, so delete the handle */ + retval = -EFAULT; + if (cargs->args.create.listmp_handle) + listmp_sharedmemory_delete(&cargs->args.create.listmp_handle); + +free_name: + if (cargs->args.create.name_len > 0) + kfree(params.name); + + cargs->api_status = 0; +exit: + return retval; +} + +/* + * ======== listmp_sharedmemory_ioctl_delete ======== + * Purpose: + * This ioctl interface to listmp_sharedmemory_delete function + */ +static inline int listmp_sharedmemory_ioctl_delete( + struct listmp_sharedmemory_cmd_args *cargs) +{ + cargs->api_status = listmp_sharedmemory_delete( + &(cargs->args.delete_listmp.listmp_handle)); + return 0; +} + +/* + * ======== listmp_sharedmemory_ioctl_open ======== + * Purpose: + * This ioctl interface to listmp_sharedmemory_open function + */ +static inline int listmp_sharedmemory_ioctl_open( + struct listmp_sharedmemory_cmd_args *cargs) +{ + s32 retval = 0; + int status = 0; + unsigned long size; + listmp_sharedmemory_params params; + void *listmp_handle = NULL; + + if (unlikely(cargs->args.open.params == NULL)) { + retval = -EFAULT; + goto exit; + } + + size = copy_from_user(¶ms, cargs->args.open.params, + sizeof(listmp_sharedmemory_params)); + if (size) { + retval = -EFAULT; + goto exit; + } + + if ((cargs->args.open.name_len > 0) && + (cargs->args.open.params->name != NULL)) { + params.name = kmalloc(cargs->args.open.name_len, GFP_KERNEL); + if (params.name == NULL) { + retval = -ENOMEM; + goto exit; + } + /* Copy the name */ + size = copy_from_user(params.name, + cargs->args.open.params->name, + cargs->args.open.name_len); + if (size) { + retval = -EFAULT; + goto free_name; + } + } + + /* For open by name, the shared_add_srptr may be invalid */ + if (cargs->args.open.shared_addr_srptr != \ + (u32)SHAREDREGION_INVALIDSRPTR) { + params.shared_addr = sharedregion_get_ptr( + (u32 *)cargs->args.open.shared_addr_srptr); + } + if (unlikely(params.shared_addr == NULL)) + goto free_name; + + /* Update gate in params. */ + params.gate = cargs->args.open.knl_gate; + status = listmp_sharedmemory_open(&listmp_handle, ¶ms); + if (status < 0) + goto free_name; + cargs->args.open.listmp_handle = listmp_handle; + + size = copy_to_user(cargs->args.open.params, ¶ms, + sizeof(listmp_sharedmemory_params)); + if (!size) + goto free_name; + + /* Error copying, so close the handle */ + retval = -EFAULT; + if (cargs->args.open.listmp_handle) { + listmp_sharedmemory_close(cargs->args.open.listmp_handle); + cargs->args.open.listmp_handle = NULL; + } + +free_name: + if (cargs->args.open.name_len > 0) + kfree(params.name); + + cargs->api_status = status; +exit: + return retval; +} + +/* + * ======== listmp_sharedmemory_ioctl_close ======== + * Purpose: + * This ioctl interface to listmp_sharedmemory_close function + */ +static inline int listmp_sharedmemory_ioctl_close( + struct listmp_sharedmemory_cmd_args *cargs) +{ + cargs->api_status = \ + listmp_sharedmemory_close(cargs->args.close.listmp_handle); + return 0; +} + +/* + * ======== listmp_sharedmemory_ioctl_is_empty ======== + * Purpose: + * This ioctl interface to listmp_sharedmemory_empty function + */ +static inline int listmp_sharedmemory_ioctl_empty( + struct listmp_sharedmemory_cmd_args *cargs) +{ + cargs->args.is_empty.is_empty = \ + listmp_sharedmemory_empty(cargs->args.is_empty.listmp_handle); + cargs->api_status = 0; + return 0; +} + +/* + * ======== listmp_sharedmemory_ioctl_get_head ======== + * Purpose: + * This ioctl interface to listmp_sharedmemory_get_head function + */ +static inline int listmp_sharedmemory_ioctl_get_head( + struct listmp_sharedmemory_cmd_args *cargs) +{ + struct listmp_elem *elem; + u32 *elem_srptr = SHAREDREGION_INVALIDSRPTR; + int index; + + cargs->api_status = LISTMPSHAREDMEMORY_E_FAIL; + + elem = listmp_sharedmemory_get_head(cargs->args.get_head.listmp_handle); + if (unlikely(elem == NULL)) + goto exit; + + index = sharedregion_get_index(elem); + if (unlikely(index < 0)) + goto exit; + + elem_srptr = sharedregion_get_srptr((void *)elem, index); + + cargs->api_status = 0; +exit: + cargs->args.get_head.elem_srptr = elem_srptr; + return 0; +} + +/* + * ======== listmp_sharedmemory_ioctl_get_tail ======== + * Purpose: + * This ioctl interface to listmp_sharedmemory_get_tail function + */ +static inline int listmp_sharedmemory_ioctl_get_tail( + struct listmp_sharedmemory_cmd_args *cargs) +{ + struct listmp_elem *elem; + u32 *elem_srptr = SHAREDREGION_INVALIDSRPTR; + int index; + + cargs->api_status = LISTMPSHAREDMEMORY_E_FAIL; + + elem = listmp_sharedmemory_get_tail(cargs->args.get_tail.listmp_handle); + if (unlikely(elem == NULL)) + goto exit; + + index = sharedregion_get_index(elem); + if (unlikely(index < 0)) + goto exit; + + elem_srptr = sharedregion_get_srptr((void *)elem, index); + + cargs->api_status = 0; +exit: + cargs->args.get_tail.elem_srptr = elem_srptr; + return 0; +} + +/* + * ======== listmp_sharedmemory_ioctl_put_head ======== + * Purpose: + * This ioctl interface to listmp_sharedmemory_put_head function + */ +static inline int listmp_sharedmemory_ioctl_put_head( + struct listmp_sharedmemory_cmd_args *cargs) +{ + struct listmp_elem *elem; + + cargs->api_status = LISTMPSHAREDMEMORY_E_FAIL; + + elem = (struct listmp_elem *) sharedregion_get_ptr( + cargs->args.put_head.elem_srptr); + if (unlikely(elem == NULL)) + goto exit; + + cargs->api_status = listmp_sharedmemory_put_head( + cargs->args.put_head.listmp_handle, elem); +exit: + return 0; +} + +/* + * ======== listmp_sharedmemory_ioctl_put_tail ======== + * Purpose: + * This ioctl interface to listmp_sharedmemory_put_tail function + */ +static inline int listmp_sharedmemory_ioctl_put_tail( + struct listmp_sharedmemory_cmd_args *cargs) +{ + struct listmp_elem *elem; + + cargs->api_status = LISTMPSHAREDMEMORY_E_FAIL; + + elem = (struct listmp_elem *) sharedregion_get_ptr( + cargs->args.put_tail.elem_srptr); + if (unlikely(elem == NULL)) + goto exit; + + cargs->api_status = listmp_sharedmemory_put_tail( + cargs->args.put_head.listmp_handle, elem); +exit: + return 0; +} + +/* + * ======== listmp_sharedmemory_ioctl_insert ======== + * Purpose: + * This ioctl interface to listmp_sharedmemory_insert function + */ +static inline int listmp_sharedmemory_ioctl_insert( + struct listmp_sharedmemory_cmd_args *cargs) +{ + struct listmp_elem *new_elem; + struct listmp_elem *cur_elem; + + new_elem = (struct listmp_elem *) sharedregion_get_ptr( + cargs->args.insert.new_elem_srptr); + if (unlikely(new_elem == NULL)) + goto exit; + + cur_elem = (struct listmp_elem *) sharedregion_get_ptr( + cargs->args.insert.cur_elem_srptr); + if (unlikely(cur_elem == NULL)) + goto exit; + + cargs->api_status = listmp_sharedmemory_insert( + cargs->args.insert.listmp_handle, new_elem, cur_elem); +exit: + return 0; +} + +/* + * ======== listmp_sharedmemory_ioctl_remove ======== + * Purpose: + * This ioctl interface to listmp_sharedmemory_remove function + */ +static inline int listmp_sharedmemory_ioctl_remove( + struct listmp_sharedmemory_cmd_args *cargs) +{ + struct listmp_elem *elem; + + elem = (struct listmp_elem *) sharedregion_get_ptr( + cargs->args.remove.elem_srptr); + if (unlikely(elem == NULL)) + goto exit; + + cargs->api_status = listmp_sharedmemory_remove( + cargs->args.get_head.listmp_handle, elem); + +exit: + return 0; +} + +/* + * ======== listmp_sharedmemory_ioctl_next ======== + * Purpose: + * This ioctl interface to listmp_sharedmemory_next function + */ +static inline int listmp_sharedmemory_ioctl_next( + struct listmp_sharedmemory_cmd_args *cargs) +{ + struct listmp_elem *elem = NULL; + struct listmp_elem *ret_elem = NULL; + u32 *next_elem_srptr = SHAREDREGION_INVALIDSRPTR; + int index; + + if (cargs->args.next.elem_srptr != NULL) { + elem = (struct listmp_elem *) sharedregion_get_ptr( + cargs->args.next.elem_srptr); + } + ret_elem = (struct listmp_elem *) listmp_sharedmemory_next( + cargs->args.next.listmp_handle, elem); + if (unlikely(ret_elem == NULL)) + goto exit; + + index = sharedregion_get_index(ret_elem); + if (unlikely(index < 0)) + goto exit; + + next_elem_srptr = sharedregion_get_srptr((void *)ret_elem, index); + + cargs->api_status = 0; +exit: + cargs->args.next.next_elem_srptr = next_elem_srptr; + return 0; +} + +/* + * ======== listmp_sharedmemory_ioctl_prev ======== + * Purpose: + * This ioctl interface to listmp_sharedmemory_prev function + */ +static inline int listmp_sharedmemory_ioctl_prev( + struct listmp_sharedmemory_cmd_args *cargs) +{ + struct listmp_elem *elem = NULL; + struct listmp_elem *ret_elem = NULL; + u32 *prev_elem_srptr = SHAREDREGION_INVALIDSRPTR; + int index; + + if (cargs->args.next.elem_srptr != NULL) { + elem = (struct listmp_elem *) sharedregion_get_ptr( + cargs->args.prev.elem_srptr); + } + ret_elem = (struct listmp_elem *) listmp_sharedmemory_prev( + cargs->args.prev.listmp_handle, elem); + if (unlikely(ret_elem == NULL)) + goto exit; + + index = sharedregion_get_index(ret_elem); + if (unlikely(index < 0)) + goto exit; + + prev_elem_srptr = sharedregion_get_srptr((void *)ret_elem, index); + + cargs->api_status = 0; +exit: + cargs->args.prev.prev_elem_srptr = prev_elem_srptr; + return 0; + +} + +/* + * ======== listmp_sharedmemory_ioctl_shared_memreq ======== + * Purpose: + * This ioctl interface to listmp_sharedmemory_shared_memreq function + */ +static inline int listmp_sharedmemory_ioctl_shared_memreq( + struct listmp_sharedmemory_cmd_args *cargs) +{ + s32 retval = 0; + unsigned long size; + listmp_sharedmemory_params params; + + size = copy_from_user(¶ms, cargs->args.shared_memreq.params, + sizeof(listmp_sharedmemory_params)); + if (size) { + retval = -EFAULT; + goto exit; + } + + cargs->args.shared_memreq.bytes = + listmp_sharedmemory_shared_memreq(¶ms); + + cargs->api_status = 0; +exit: + return retval; +} + +/* + * ======== listmp_sharedmemory_ioctl ======== + * Purpose: + * ioctl interface function for listmp_sharedmemory module + */ +int listmp_sharedmemory_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long args) +{ + int os_status = 0; + struct listmp_sharedmemory_cmd_args __user *uarg = + (struct listmp_sharedmemory_cmd_args __user *)args; + struct listmp_sharedmemory_cmd_args cargs; + unsigned long size; + + if (_IOC_DIR(cmd) & _IOC_READ) + os_status = !access_ok(VERIFY_WRITE, uarg, _IOC_SIZE(cmd)); + else if (_IOC_DIR(cmd) & _IOC_WRITE) + os_status = !access_ok(VERIFY_READ, uarg, _IOC_SIZE(cmd)); + if (os_status) { + os_status = -EFAULT; + goto exit; + } + + /* Copy the full args from user-side */ + size = copy_from_user(&cargs, uarg, + sizeof(struct listmp_sharedmemory_cmd_args)); + if (size) { + os_status = -EFAULT; + goto exit; + } + + switch (cmd) { + case CMD_LISTMP_SHAREDMEMORY_GETCONFIG: + os_status = listmp_sharedmemory_ioctl_get_config(&cargs); + break; + + case CMD_LISTMP_SHAREDMEMORY_SETUP: + os_status = listmp_sharedmemory_ioctl_setup(&cargs); + break; + + case CMD_LISTMP_SHAREDMEMORY_DESTROY: + os_status = listmp_sharedmemory_ioctl_destroy(&cargs); + break; + + case CMD_LISTMP_SHAREDMEMORY_PARAMS_INIT: + os_status = listmp_sharedmemory_ioctl_params_init(&cargs); + break; + + case CMD_LISTMP_SHAREDMEMORY_CREATE: + os_status = listmp_sharedmemory_ioctl_create(&cargs); + break; + + case CMD_LISTMP_SHAREDMEMORY_DELETE: + os_status = listmp_sharedmemory_ioctl_delete(&cargs); + break; + + case CMD_LISTMP_SHAREDMEMORY_OPEN: + os_status = listmp_sharedmemory_ioctl_open(&cargs); + break; + + case CMD_LISTMP_SHAREDMEMORY_CLOSE: + os_status = listmp_sharedmemory_ioctl_close(&cargs); + break; + + case CMD_LISTMP_SHAREDMEMORY_ISEMPTY: + os_status = listmp_sharedmemory_ioctl_empty(&cargs); + break; + + case CMD_LISTMP_SHAREDMEMORY_GETHEAD: + os_status = listmp_sharedmemory_ioctl_get_head(&cargs); + break; + + case CMD_LISTMP_SHAREDMEMORY_GETTAIL: + os_status = listmp_sharedmemory_ioctl_get_tail(&cargs); + break; + + case CMD_LISTMP_SHAREDMEMORY_PUTHEAD: + os_status = listmp_sharedmemory_ioctl_put_head(&cargs); + break; + + case CMD_LISTMP_SHAREDMEMORY_PUTTAIL: + os_status = listmp_sharedmemory_ioctl_put_tail(&cargs); + break; + + case CMD_LISTMP_SHAREDMEMORY_INSERT: + os_status = listmp_sharedmemory_ioctl_insert(&cargs); + break; + + case CMD_LISTMP_SHAREDMEMORY_REMOVE: + os_status = listmp_sharedmemory_ioctl_remove(&cargs); + break; + + case CMD_LISTMP_SHAREDMEMORY_NEXT: + os_status = listmp_sharedmemory_ioctl_next(&cargs); + break; + + case CMD_LISTMP_SHAREDMEMORY_PREV: + os_status = listmp_sharedmemory_ioctl_prev(&cargs); + break; + + case CMD_LISTMP_SHAREDMEMORY_SHAREDMEMREQ: + os_status = listmp_sharedmemory_ioctl_shared_memreq(&cargs); + break; + + default: + WARN_ON(cmd); + os_status = -ENOTTY; + break; + } + + if ((cargs.api_status == -ERESTARTSYS) || (cargs.api_status == -EINTR)) + os_status = -ERESTARTSYS; + + if (os_status < 0) + goto exit; + + /* Copy the full args to the user-side. */ + size = copy_to_user(uarg, &cargs, + sizeof(struct listmp_sharedmemory_cmd_args)); + if (size) { + os_status = -EFAULT; + goto exit; + } + return os_status; + +exit: + printk(KERN_ERR "listmp_sharedmemory_ioctl failed: status = 0x%x\n", + os_status); + return os_status; +} diff --git a/drivers/dsp/syslink/multicore_ipc/messageq.c b/drivers/dsp/syslink/multicore_ipc/messageq.c new file mode 100755 index 000000000000..cc2eeca21ef5 --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/messageq.c @@ -0,0 +1,1597 @@ +/* + * messageq.c + * + * The messageQ module supports the structured sending and receiving of + * variable length messages. This module can be used for homogeneous or + * heterogeneous multi-processor messaging. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +/*! + * MessageQ provides more sophisticated messaging than other modules. It is + * typically used for complex situations such as multi-processor messaging. + * + * The following are key features of the MessageQ module: + * -Writers and readers can be relocated to another processor with no + * runtime code changes. + * -Timeouts are allowed when receiving messages. + * -Readers can determine the writer and reply back. + * -Receiving a message is deterministic when the timeout is zero. + * -Messages can reside on any message queue. + * -Supports zero-copy transfers. + * -Can send and receive from any type of thread. + * -Notification mechanism is specified by application. + * -Allows QoS (quality of service) on message buffer pools. For example, + * using specific buffer pools for specific message queues. + * + * Messages are sent and received via a message queue. A reader is a thread + * that gets (reads) messages from a message queue. A writer is a thread that + * puts (writes) a message to a message queue. Each message queue has one + * reader and can have many writers. A thread may read from or write to + * multiple message queues. + * + * Conceptually, the reader thread owns a message queue. The reader thread + * creates a message queue. Writer threads a created message queues to + * get access to them. + * + * Message queues are identified by a system-wide unique name. Internally, + * MessageQ uses the NameServer module for managing + * these names. The names are used for opening a message queue. Using + * names is not required. + * + * Messages must be allocated from the MessageQ module. Once a message is + * allocated, it can be sent on any message queue. Once a message is sent, the + * writer loses ownership of the message and should not attempt to modify the + * message. Once the reader receives the message, it owns the message. It + * may either free the message or re-use the message. + * + * Messages in a message queue can be of variable length. The only + * requirement is that the first field in the definition of a message must be a + * MsgHeader structure. For example: + * typedef struct MyMsg { + * messageq_MsgHeader header; + * ... + * } MyMsg; + * + * The MessageQ API uses the messageq_MsgHeader internally. Your application + * should not modify or directly access the fields in the messageq_MsgHeader. + * + * All messages sent via the MessageQ module must be allocated from a + * Heap implementation. The heap can be used for + * other memory allocation not related to MessageQ. + * + * An application can use multiple heaps. The purpose of having multiple + * heaps is to allow an application to regulate its message usage. For + * example, an application can allocate critical messages from one heap of fast + * on-chip memory and non-critical messages from another heap of slower + * external memory + * + * MessageQ does support the usage of messages that allocated via the + * alloc function. Please refer to the static_msg_init + * function description for more details. + * + * In a multiple processor system, MessageQ communications to other + * processors via MessageQ_transport} instances. There must be one and + * only one IMessageQ_transport instance for each processor where communication + * is desired. + * So on a four processor system, each processor must have three + * IMessageQ_transport instance. + * + * The user only needs to create the IMessageQ_transport instances. The + * instances are responsible for registering themselves with MessageQ. + * This is accomplished via the register_transport function. + */ + + + +/* Standard headers */ +#include <linux/types.h> +#include <linux/module.h> + +/* Utilities headers */ +#include <linux/string.h> +#include <linux/list.h> +#include <linux/slab.h> +#include <linux/semaphore.h> + +/* Syslink headers */ +#include <syslink/atomic_linux.h> + +/* Module level headers */ +#include <nameserver.h> +#include <multiproc.h> +#include <messageq_transportshm.h> +#include <heap.h> +#include <messageq.h> + + +/* Macro to make a correct module magic number with refCount */ +#define MESSAGEQ_MAKE_MAGICSTAMP(x) ((MESSAGEQ_MODULEID << 12u) | (x)) + +/* ============================================================================= + * Globals + * ============================================================================= + */ +/*! + * @brief Name of the reserved NameServer used for MessageQ. + */ +#define MESSAGEQ_NAMESERVER "MessageQ" + + +/* ============================================================================= + * Structures & Enums + * ============================================================================= + */ +/* structure for MessageQ module state */ +struct messageq_module_object { + atomic_t ref_count; + /*!< Reference count */ + void *ns_handle; + /*!< Handle to the local NameServer used for storing GP objects */ + struct mutex *gate_handle; + /*!< Handle of gate to be used for local thread safety */ + struct messageq_config cfg; + /*!< Current config values */ + struct messageq_config default_cfg; + /*!< Default config values */ + struct messageq_params default_inst_params; + /*!< Default instance creation parameters */ + void *transports[MULTIPROC_MAXPROCESSORS][MESSAGEQ_NUM_PRIORITY_QUEUES]; + /*!< Transport to be set in messageq_register_transport */ + void **queues; /*messageq_handle *queues;*/ + /*!< Grow option */ + void **heaps; /*Heap_Handle *heaps; */ + /*!< Heap to be set in messageq_registerHeap */ + u16 num_queues; + /*!< Heap to be set in messageq_registerHeap */ + u16 num_heaps; + /*!< Number of Heaps */ + bool can_free_queues; + /*!< Grow option */ +}; + +/*! + * @brief Structure for the Handle for the MessageQ. + */ +struct messageq_object { + struct messageq_params params; + /*! Instance specific creation parameters */ + char *name; + /*! MessageQ name */ + u32 queue; + /* Unique id */ + struct list_head normal_list; + /* Embedded List objects */ + struct list_head high_list; + /* Embedded List objects */ + /*OsalSemaphore_Handle synchronizer;*/ + struct semaphore *synchronizer; + /* Semaphore used for synchronizing message events */ +}; + + +static struct messageq_module_object messageq_state = { + .ns_handle = NULL, + .gate_handle = NULL, + .queues = NULL, + .heaps = NULL, + .num_queues = 1, + .num_heaps = 1, + .can_free_queues = false, + .default_cfg.num_heaps = 1, + .default_cfg.max_runtime_entries = 32, + .default_cfg.name_table_gate = NULL, + .default_cfg.max_name_len = 32, + .default_inst_params.reserved = 0 +}; + + +/* ============================================================================= + * Constants + * ============================================================================= + */ +/* + * Used to denote a message that was initialized + * with the messageq_static_msg_init function. + */ +#define MESSAGEQ_STATICMSG 0xFFFF + + +/* ============================================================================= + * Forward declarations of internal functions + * ============================================================================= + */ +/* + * @brief Grow the MessageQ table + * + * @sa messageq_create + */ +static u16 _messageq_grow(struct messageq_object *obj); + +/* ============================================================================= + * APIS + * ============================================================================= + */ +/* + * ======== messageq_get_config ======== + * Purpose: + * Function to get the default configuration for the MessageQ + * module. + * + * This function can be called by the application to get their + * configuration parameter to MessageQ_setup filled in by the + * MessageQ module with the default parameters. If the user does + * not wish to make any change in the default parameters, this API + * is not required to be called. + * the listmp_sharedmemory module. + */ +void messageq_get_config(struct messageq_config *cfg) +{ + if (WARN_ON(cfg == NULL)) + goto exit; + + if (atomic_cmpmask_and_lt(&(messageq_state.ref_count), + MESSAGEQ_MAKE_MAGICSTAMP(0), + MESSAGEQ_MAKE_MAGICSTAMP(1)) == true) { + /* (If setup has not yet been called) */ + memcpy(cfg, &messageq_state.default_cfg, + sizeof(struct messageq_config)); + } else { + memcpy(cfg, &messageq_state.cfg, + sizeof(struct messageq_config)); + } + return; + +exit: + printk(KERN_ERR "messageq_get_config: Argument of type " + "(struct messageq_config *) passed is null!\n"); +} +EXPORT_SYMBOL(messageq_get_config); + +/* + * ======== messageq_setup ======== + * Purpose: + * Function to setup the MessageQ module. + * + * This function sets up the MessageQ module. This function must + * be called before any other instance-level APIs can be invoked. + * Module-level configuration needs to be provided to this + * function. If the user wishes to change some specific config + * parameters, then MessageQ_getConfig can be called to get the + * configuration filled with the default values. After this, only + * the required configuration values can be changed. If the user + * does not wish to make any change in the default parameters, the + * application can simply call MessageQ with NULL parameters. + * The default parameters would get automatically used. + */ +int messageq_setup(const struct messageq_config *cfg) +{ + int status = MESSAGEQ_SUCCESS; + struct nameserver_params params; + struct messageq_config tmpcfg; + + /* This sets the ref_count variable is not initialized, upper 16 bits is + * written with module Id to ensure correctness of refCount variable. + */ + atomic_cmpmask_and_set(&messageq_state.ref_count, + MESSAGEQ_MAKE_MAGICSTAMP(0), + MESSAGEQ_MAKE_MAGICSTAMP(0)); + if (atomic_inc_return(&messageq_state.ref_count) + != MESSAGEQ_MAKE_MAGICSTAMP(1)) { + return 1; + } + + if (cfg == NULL) { + messageq_get_config(&tmpcfg); + cfg = &tmpcfg; + } + + if (WARN_ON(cfg->max_name_len == 0)) { + status = -EINVAL; + goto exit; + } + if (WARN_ON(cfg->max_name_len == 0)) { + status = -EINVAL; + goto exit; + } + + if (cfg->name_table_gate != NULL) { + messageq_state.gate_handle = cfg->name_table_gate; + } else { + /* User has not provided any gate handle, so create a default + * handle for protecting list object */ + messageq_state.gate_handle = kmalloc(sizeof(struct mutex), + GFP_KERNEL); + if (messageq_state.gate_handle == NULL) { + /*! @retval MESSAGEQ_E_FAIL Failed to create lock! */ + status = MESSAGEQ_E_FAIL; + printk(KERN_ERR "messageq_setup: Failed to create a " + "mutex.\n"); + status = -ENOMEM; + goto exit; + } + mutex_init(messageq_state.gate_handle); + } + + /* Initialize the parameters */ + nameserver_params_init(¶ms); + params.max_value_len = 4; + params.max_name_len = cfg->max_name_len; + + /* Create the nameserver for modules */ + messageq_state.ns_handle = nameserver_create(MESSAGEQ_NAMESERVER, + ¶ms); + if (messageq_state.ns_handle == NULL) { + /*! @retval MESSAGEQ_E_FAIL Failed to create the + * MessageQ nameserver*/ + status = MESSAGEQ_E_FAIL; + printk(KERN_ERR "messageq_setup: Failed to create the messageq" + "nameserver!\n"); + goto nameserver_create_fail; + } + + messageq_state.num_heaps = cfg->num_heaps; + messageq_state.heaps = kzalloc(sizeof(void *) * \ + messageq_state.num_heaps, GFP_KERNEL); + if (messageq_state.heaps == NULL) { + status = -ENOMEM; + goto heaps_alloc_fail; + } + + messageq_state.num_queues = cfg->max_runtime_entries; + messageq_state.queues = kzalloc(sizeof(struct messageq_object *) * \ + messageq_state.num_queues, GFP_KERNEL); + if (messageq_state.queues == NULL) { + status = -ENOMEM; + goto queues_alloc_fail; + } + + memset(&(messageq_state.transports), 0, (sizeof(void *) * \ + MULTIPROC_MAXPROCESSORS * \ + MESSAGEQ_NUM_PRIORITY_QUEUES)); + + BUG_ON(status < 0); + return status; + +queues_alloc_fail: + if (messageq_state.queues != NULL) + kfree(messageq_state.queues); +heaps_alloc_fail: + if (messageq_state.heaps != NULL) + kfree(messageq_state.heaps); + if (messageq_state.ns_handle != NULL) + nameserver_delete(&messageq_state.ns_handle); +nameserver_create_fail: + if (cfg->name_table_gate != NULL) { + if (messageq_state.gate_handle != NULL) { + kfree(messageq_state.gate_handle); + messageq_state.gate_handle = NULL; + } + } + + memset(&messageq_state.cfg, 0, sizeof(struct messageq_config)); + messageq_state.queues = NULL; + messageq_state.heaps = NULL; + messageq_state.num_queues = 0; + messageq_state.num_heaps = 1; + messageq_state.can_free_queues = true; + +exit: + if (status < 0) { + atomic_set(&messageq_state.ref_count, + MESSAGEQ_MAKE_MAGICSTAMP(0)); + printk(KERN_ERR "messageq_setup failed! status = 0x%x\n", + status); + } + return status; +} +EXPORT_SYMBOL(messageq_setup); + +/* + * ======== messageq_destroy ======== + * Purpose: + * Function to destroy the MessageQ module. + */ +int messageq_destroy(void) +{ + int status = MESSAGEQ_SUCCESS; + u32 i; + + if (atomic_cmpmask_and_lt(&(messageq_state.ref_count), + MESSAGEQ_MAKE_MAGICSTAMP(0), + MESSAGEQ_MAKE_MAGICSTAMP(1)) == true) { + status = -ENODEV; + goto exit; + } + + if (!(atomic_dec_return(&messageq_state.ref_count) + == MESSAGEQ_MAKE_MAGICSTAMP(0))) { + status = 1; + goto exit; + } + + if (WARN_ON(messageq_state.ns_handle == NULL)) { + status = -ENODEV; + goto exit; + } + + /* Delete any Message Queues that have not been deleted so far. */ + for (i = 0; i < messageq_state.num_queues; i++) { + if (messageq_state.queues[i] != NULL) + messageq_delete(&(messageq_state.queues[i])); + } + + /* Delete the nameserver for modules */ + status = nameserver_delete(&messageq_state.ns_handle); + BUG_ON(status < 0); + + /* Delete the gate if created internally */ + if (messageq_state.cfg.name_table_gate == NULL) { + kfree(messageq_state.gate_handle); + messageq_state.gate_handle = NULL; + BUG_ON(status < 0); + } + + memset(&(messageq_state.transports), 0, (sizeof(void *) * \ + MULTIPROC_MAXPROCESSORS * MESSAGEQ_NUM_PRIORITY_QUEUES)); + if (messageq_state.heaps != NULL) { + kfree(messageq_state.heaps); + messageq_state.heaps = NULL; + } + if (messageq_state.queues != NULL) { + kfree(messageq_state.queues); + messageq_state.queues = NULL; + } + + memset(&messageq_state.cfg, 0, sizeof(struct messageq_config)); + messageq_state.num_queues = 0; + messageq_state.num_heaps = 1; + messageq_state.can_free_queues = true; + atomic_set(&messageq_state.ref_count, + MESSAGEQ_MAKE_MAGICSTAMP(0)); + +exit: + if (status < 0) { + printk(KERN_ERR "messageq_destroy failed! status = 0x%x\n", + status); + } + return status; +} +EXPORT_SYMBOL(messageq_destroy); + +/* + * ======== messageq_params_init ======== + * Purpose: + * Initialize this config-params structure with supplier-specified + * defaults before instance creation. + */ +void messageq_params_init(void *messageq_handle, + struct messageq_params *params) +{ + struct messageq_object *object = NULL; + + if (atomic_cmpmask_and_lt(&(messageq_state.ref_count), + MESSAGEQ_MAKE_MAGICSTAMP(0), + MESSAGEQ_MAKE_MAGICSTAMP(1)) == true) + goto exit; + + if (WARN_ON(params == NULL)) { + printk(KERN_ERR "messageq_params_init failed:Argument of " + "type(messageq_params *) is NULL!\n"); + goto exit; + } + + if (messageq_handle == NULL) { + memcpy(params, &(messageq_state.default_inst_params), + sizeof(struct messageq_params)); + } else { + object = (struct messageq_object *) messageq_handle; + memcpy((void *)params, (void *)&object->params, + sizeof(struct messageq_params)); + } + +exit: + return; +} +EXPORT_SYMBOL(messageq_params_init); + +/* + * ======== messageq_create ======== + * Purpose: + * Creates a new instance of MessageQ module. + */ +void *messageq_create(char *name, const struct messageq_params *params) +{ + int status = 0; + struct messageq_object *handle = NULL; + bool found = false; + u16 count = 0; + int i; + u16 start; + u16 queueIndex = 0; + + if (atomic_cmpmask_and_lt(&(messageq_state.ref_count), + MESSAGEQ_MAKE_MAGICSTAMP(0), + MESSAGEQ_MAKE_MAGICSTAMP(1)) == true) { + status = -ENODEV; + goto exit; + } + if (WARN_ON(params == NULL)) { + status = -EINVAL; + goto exit; + } + + /* Create the generic handle */ + handle = kzalloc(sizeof(struct messageq_object), 0); + if (handle == NULL) { + status = -ENOMEM; + goto exit; + } + + status = mutex_lock_interruptible(messageq_state.gate_handle); + if (status) + goto exit; + start = 0; /* Statically allocated objects not supported */ + count = messageq_state.num_queues; + /* Search the dynamic array for any holes */ + for (i = start; i < count ; i++) { + if (messageq_state.queues[i] == NULL) { + messageq_state.queues[i] = (void *) handle; + queueIndex = i; + found = true; + break; + } + } + /* + * If no free slot was found: + * - if no growth allowed, raise an error + * - if growth is allowed, grow the array + */ + if (found == false) { + if (messageq_state.cfg.max_runtime_entries + != MESSAGEQ_ALLOWGROWTH) { + mutex_unlock(messageq_state.gate_handle); + status = MESSAGEQ_E_MAXREACHED; + printk(KERN_ERR "messageq_create: All message queues " + "are full!\n"); + goto free_slot_fail; + } else { + queueIndex = _messageq_grow(handle); + if (queueIndex == MESSAGEQ_INVALIDMESSAGEQ) { + mutex_unlock(messageq_state.gate_handle); + status = MESSAGEQ_E_MAXREACHED; + printk(KERN_ERR "messageq_create: All message " + "queues are full!\n"); + goto free_slot_fail; + } + } + } + + BUG_ON(status < 0); + mutex_unlock(messageq_state.gate_handle); + + /* Construct the list object */ + INIT_LIST_HEAD(&handle->normal_list); + INIT_LIST_HEAD(&handle->high_list); + + /* Copy the name */ + if (name != NULL) { + handle->name = kmalloc((strlen(name) + 1), GFP_KERNEL); + if (handle->name == NULL) { + status = -ENOMEM; + goto handle_name_alloc_fail; + } + strncpy(handle->name, name, strlen(name) + 1); + } + + /* Update processor information */ + handle->queue = ((u32)(multiproc_get_id(NULL)) << 16) | queueIndex; + /*handle->synchronizer = OsalSemaphore_create(OsalSemaphore_Type_Binary + | OsalSemaphore_IntType_Interruptible);*/ + handle->synchronizer = kzalloc(sizeof(struct semaphore), GFP_KERNEL); + if (handle->synchronizer == NULL) { + status = MESSAGEQ_E_FAIL; + printk(KERN_ERR "messageq_create: Failed to create " + "synchronizer semaphore!\n"); + goto semaphore_create_fail; + } else { + sema_init(handle->synchronizer, 0); + } + + if (name != NULL) { + nameserver_add_uint32(messageq_state.ns_handle, name, + handle->queue); + } + goto exit; + +semaphore_create_fail: + if (handle->name != NULL) + kfree(handle->name); + +handle_name_alloc_fail: + list_del(&handle->high_list); + list_del(&handle->normal_list); + +free_slot_fail: + /* Now free the handle */ + if (handle != NULL) { + kfree(handle); + handle = NULL; + } + +exit: + if (status < 0) { + printk(KERN_ERR "messageq_create failed! status = 0x%x\n", + status); + } + return (void *) handle; +} +EXPORT_SYMBOL(messageq_create); + +/* + * ======== messageq_delete ======== + * Purpose: + * Deletes a instance of MessageQ module. + */ +int messageq_delete(void **msg_handleptr) +{ + int status = 0; + struct messageq_object *handle = NULL; + + if (atomic_cmpmask_and_lt(&(messageq_state.ref_count), + MESSAGEQ_MAKE_MAGICSTAMP(0), + MESSAGEQ_MAKE_MAGICSTAMP(1)) == true) { + status = -ENODEV; + goto exit; + } + if (WARN_ON(msg_handleptr == NULL)) { + status = -EINVAL; + goto exit; + } + if (WARN_ON(*msg_handleptr == NULL)) { + status = -EINVAL; + goto exit; + } + + handle = (struct messageq_object *) (*msg_handleptr); + + /* Take the local lock */ + status = mutex_lock_interruptible(messageq_state.gate_handle); + if (status) + goto exit; + + if (handle->name != NULL) { + /* remove from the name serve */ + nameserver_remove(messageq_state.ns_handle, handle->name); + /* Free memory for the name */ + kfree(handle->name); + } + + /* Release the local lock */ + mutex_unlock(messageq_state.gate_handle); + + /* Free the list */ + list_del(&handle->high_list); + list_del(&handle->normal_list); + + /*if (handle->synchronizer != NULL) + status = OsalSemaphore_delete(&handle->synchronizer);*/ + if (handle->synchronizer != NULL) { + kfree(handle->synchronizer); + handle->synchronizer = NULL; + } + /* Clear the MessageQ handle from array. */ + messageq_state.queues[handle->queue] = NULL; + + /* Now free the handle */ + kfree(handle); + *msg_handleptr = NULL; + +exit: + if (status < 0) { + printk(KERN_ERR "messageq_delete failed! status = 0x%x\n", + status);; + } + return status; +} +EXPORT_SYMBOL(messageq_delete); + +/* + * ======== messageq_open ======== + * Purpose: + * Opens a created instance of MessageQ module. + */ +int messageq_open(char *name, u32 *queue_id) +{ + int status = 0; + int len = 0; + + if (atomic_cmpmask_and_lt(&(messageq_state.ref_count), + MESSAGEQ_MAKE_MAGICSTAMP(0), + MESSAGEQ_MAKE_MAGICSTAMP(1)) == true) { + status = -ENODEV; + goto exit; + } + if (WARN_ON(queue_id == NULL)) { + status = -EINVAL; + goto exit; + } + + /* Initialize return queue ID to invalid. */ + *queue_id = MESSAGEQ_INVALIDMESSAGEQ; + len = nameserver_get(messageq_state.ns_handle, name, queue_id, + sizeof(u32), NULL); + if (len < 0) { + if (len == -ENOENT) { + /* Name not found */ + status = -ENOENT; + } else { + /* Any other error from nameserver */ + status = len; + } + } + +exit: + if (status < 0) { + printk(KERN_ERR "messageq_open failed! status = 0x%x\n", + status); + } + return status; +} +EXPORT_SYMBOL(messageq_open); + +/* + * ======== messageq_close ======== + * Purpose: + * Closes previously opened/created instance of MessageQ module. + */ +void messageq_close(u32 *queue_id) +{ + if (WARN_ON(atomic_cmpmask_and_lt(&(messageq_state.ref_count), + MESSAGEQ_MAKE_MAGICSTAMP(0), + MESSAGEQ_MAKE_MAGICSTAMP(1)) == true)) + goto exit; + + if (WARN_ON(queue_id == NULL)) { + printk(KERN_ERR "messageq_close: queue_id passed is NULL!\n"); + goto exit; + } + + *queue_id = MESSAGEQ_INVALIDMESSAGEQ; + +exit: + return; +} +EXPORT_SYMBOL(messageq_close); + +/* + * ======== messageq_get ======== + */ +int messageq_get(void *messageq_handle, messageq_msg *msg, + u32 timeout) +{ + int status = 0; + struct messageq_object *obj = (struct messageq_object *)messageq_handle; + + if (WARN_ON(atomic_cmpmask_and_lt(&(messageq_state.ref_count), + MESSAGEQ_MAKE_MAGICSTAMP(0), + MESSAGEQ_MAKE_MAGICSTAMP(1)) == true)) { + status = -ENODEV; + goto exit; + } + + if (WARN_ON(msg == NULL)) { + status = -EINVAL; + goto exit; + } + + if (WARN_ON(obj == NULL)) { + status = -EINVAL; + goto exit; + } + + /* Keep looping while there is no element in the list */ + /* Take the local lock */ + status = mutex_lock_interruptible(messageq_state.gate_handle); + if (status) + goto exit; + if (!list_empty(&obj->high_list)) { + *msg = (messageq_msg) (obj->high_list.next); + list_del_init(obj->high_list.next); + } + /* Leave the local lock */ + mutex_unlock(messageq_state.gate_handle); + while (*msg == NULL) { + status = mutex_lock_interruptible(messageq_state.gate_handle); + if (status) + goto exit; + if (!list_empty(&obj->normal_list)) { + *msg = (messageq_msg) (obj->normal_list.next); + list_del_init(obj->normal_list.next); + } + mutex_unlock(messageq_state.gate_handle); + + if (*msg == NULL) { + /* + * Block until notified. If pend times-out, no message + * should be returned to the caller + */ + /*! @retval NULL timeout has occurred */ + if (obj->synchronizer != NULL) { + /* TODO: cater to different timeout values */ + /*status = OsalSemaphore_pend( + obj->synchronizer, timeout); */ + if (timeout == MESSAGEQ_FOREVER) { + if (down_interruptible + (obj->synchronizer)) { + status = -ERESTARTSYS; + } + } else { + status = down_timeout(obj->synchronizer, + msecs_to_jiffies(timeout)); + } + if (status < 0) { + *msg = NULL; + break; + } + } + status = mutex_lock_interruptible( + messageq_state.gate_handle); + if (status) + goto exit; + if (!list_empty(&obj->high_list)) { + *msg = (messageq_msg) (obj->high_list.next); + list_del_init(obj->high_list.next); + } + mutex_unlock(messageq_state.gate_handle); + } + } + return status; + +exit: + if (status < 0) + printk(KERN_ERR "messageq_get failed! status = 0x%x\n", status); + return status; +} +EXPORT_SYMBOL(messageq_get); + +/* + * ======== messageq_count ======== + * Purpose: + * Count the number of messages in the queue + */ +int messageq_count(void *messageq_handle) +{ + struct messageq_object *obj = (struct messageq_object *)messageq_handle; + int count = 0; + struct list_head *elem; + int key; + + if (WARN_ON(atomic_cmpmask_and_lt(&(messageq_state.ref_count), + MESSAGEQ_MAKE_MAGICSTAMP(0), + MESSAGEQ_MAKE_MAGICSTAMP(1)) == true)) + goto exit; + + if (WARN_ON(obj == NULL)) { + printk(KERN_ERR "messageq_count: obj passed is NULL!\n"); + goto exit; + } + + key = mutex_lock_interruptible(messageq_state.gate_handle); + if (key < 0) + return key; + + list_for_each(elem, &obj->high_list) { + count++; + } + list_for_each(elem, &obj->normal_list) { + count++; + } + mutex_unlock(messageq_state.gate_handle); + +exit: + return count; +} +EXPORT_SYMBOL(messageq_count); + +/* + * ======== messageq_static_msg_init ======== + * Purpose: + * Initialize a static message + */ +void messageq_static_msg_init(messageq_msg msg, u32 size) +{ + if (WARN_ON(atomic_cmpmask_and_lt(&(messageq_state.ref_count), + MESSAGEQ_MAKE_MAGICSTAMP(0), + MESSAGEQ_MAKE_MAGICSTAMP(1)) == true)) + goto exit; + + if (WARN_ON(msg == NULL)) { + printk(KERN_ERR "messageq_static_msg_init: msg is invalid!\n"); + goto exit; + } + + /* Fill in the fields of the message */ + msg->heap_id = MESSAGEQ_STATICMSG; + msg->msg_size = size; + msg->reply_id = (u16)MESSAGEQ_INVALIDMESSAGEQ; + msg->msg_id = MESSAGEQ_INVALIDMSGID; + msg->dst_id = (u16)MESSAGEQ_INVALIDMESSAGEQ; + msg->flags = MESSAGEQ_HEADERVERSION | MESSAGEQ_NORMALPRI; + +exit: + return; +} +EXPORT_SYMBOL(messageq_static_msg_init); + +/* + * ======== messageq_alloc ======== + * Purpose: + * Allocate a message and initial the needed fields (note some + * of the fields in the header at set via other APIs or in the + * messageq_put function. + */ +messageq_msg messageq_alloc(u16 heap_id, u32 size) +{ + messageq_msg msg = NULL; + + if (WARN_ON(atomic_cmpmask_and_lt(&(messageq_state.ref_count), + MESSAGEQ_MAKE_MAGICSTAMP(0), + MESSAGEQ_MAKE_MAGICSTAMP(1)) == true)) + goto exit; + + if (WARN_ON(heap_id >= messageq_state.num_heaps)) { + printk(KERN_ERR "messageq_alloc: heap_id is invalid!\n"); + goto exit; + } + + if (messageq_state.heaps[heap_id] != NULL) { + /* Allocate the message. No alignment requested */ + msg = heap_alloc(messageq_state.heaps[heap_id], size, 0); + if (msg == NULL) { + printk(KERN_ERR "messageq_alloc: message allocation " + "failed!\n"); + goto exit; + } + + /* Fill in the fields of the message */ + msg->msg_size = size; + msg->heap_id = heap_id; + msg->reply_id = (u16)MESSAGEQ_INVALIDMESSAGEQ; + msg->dst_id = (u16)MESSAGEQ_INVALIDMESSAGEQ; + msg->msg_id = MESSAGEQ_INVALIDMSGID; + msg->flags = MESSAGEQ_HEADERVERSION | MESSAGEQ_NORMALPRI; + } else { + printk(KERN_ERR "messageq_alloc: heap_id was not " + "registered!\n"); + } + +exit: + return msg; +} +EXPORT_SYMBOL(messageq_alloc); + +/* + * ======== messageq_free ======== + * Purpose: + * Frees the message. + */ +int messageq_free(messageq_msg msg) +{ + u32 status = 0; + void *heap = NULL; + + if (WARN_ON(atomic_cmpmask_and_lt(&(messageq_state.ref_count), + MESSAGEQ_MAKE_MAGICSTAMP(0), + MESSAGEQ_MAKE_MAGICSTAMP(1)) == true)) { + status = -ENODEV; + goto exit; + } + + if (WARN_ON(msg == NULL)) { + status = -EINVAL; + goto exit; + } + if (msg->heap_id >= messageq_state.num_heaps) { + status = MESSAGEQ_E_INVALIDHEAPID; + goto exit; + } + if (msg->heap_id == MESSAGEQ_STATICMSG) { + status = MESSAGEQ_E_CANNOTFREESTATICMSG; + goto exit; + } + + heap = messageq_state.heaps[msg->heap_id]; + heap_free(heap, msg, msg->msg_size); + +exit: + if (status < 0) { + printk(KERN_ERR "messageq_free failed! status = 0x%x\n", + status); + } + return status; +} +EXPORT_SYMBOL(messageq_free); + +/* + * ======== messageq_put ======== + * Purpose: + * Put a message in the queue + */ +int messageq_put(u32 queue_id, messageq_msg msg) +{ + int status = 0; + u16 dst_proc_id = (u16)(queue_id >> 16); + struct messageq_object *obj = NULL; + void *transport = NULL; + u32 priority; + + if (WARN_ON(atomic_cmpmask_and_lt(&(messageq_state.ref_count), + MESSAGEQ_MAKE_MAGICSTAMP(0), + MESSAGEQ_MAKE_MAGICSTAMP(1)) == true)) { + status = -ENODEV; + goto exit; + } + if (WARN_ON(msg == NULL)) { + status = -EINVAL; + goto exit; + } + + msg->dst_id = (u16)(queue_id); + msg->dst_proc = (u16)(queue_id >> 16); + if (dst_proc_id != multiproc_get_id(NULL)) { + if (dst_proc_id >= multiproc_get_max_processors()) { + /* Invalid destination processor id */ + status = MESSAGEQ_E_INVALIDPROCID; + goto exit; + } + + priority = (u32)((msg->flags) & MESSAGEQ_TRANSPORTPRIORITYMASK); + /* Call the transport associated with this message queue */ + transport = messageq_state.transports[dst_proc_id][priority]; + if (transport == NULL) { + /* Try the other transport */ + priority = !priority; + transport = + messageq_state.transports[dst_proc_id][priority]; + } + + if (transport != NULL) + status = messageq_transportshm_put(transport, msg); + else { + status = -ENODEV; + goto exit; + } + } else { + /* It is a local MessageQ */ + obj = (struct messageq_object *) + (messageq_state.queues[(u16)(queue_id)]); + status = mutex_lock_interruptible(messageq_state.gate_handle); + if (status < 0) + goto exit; + if ((msg->flags & MESSAGEQ_PRIORITYMASK) == \ + MESSAGEQ_URGENTPRI) { + list_add((struct list_head *) msg, &obj->high_list); + } else { + if ((msg->flags & MESSAGEQ_PRIORITYMASK) == \ + MESSAGEQ_NORMALPRI) { + list_add_tail((struct list_head *) msg, + &obj->normal_list); + } else { + list_add_tail((struct list_head *) msg, + &obj->high_list); + } + } + mutex_unlock(messageq_state.gate_handle); + + /* Notify the reader. */ + if (obj->synchronizer != NULL) { + up(obj->synchronizer); + /*OsalSemaphore_post(obj->synchronizer);*/ + } + } + +exit: + if (status < 0) + printk(KERN_ERR "messageq_put failed! status = 0x%x\n", status); + return status; +} +EXPORT_SYMBOL(messageq_put); + +/* + * ======== messageq_register_heap ======== + * Purpose: + * register a heap + */ +int messageq_register_heap(void *heap_handle, u16 heap_id) +{ + int status = 0; + + if (WARN_ON(atomic_cmpmask_and_lt(&(messageq_state.ref_count), + MESSAGEQ_MAKE_MAGICSTAMP(0), + MESSAGEQ_MAKE_MAGICSTAMP(1)) == true)) { + status = -ENODEV; + goto exit; + } + /* Make sure the heap_id is valid */ + if (WARN_ON(heap_id >= messageq_state.num_heaps)) { + /*! @retval MESSAGEQ_E_HEAPIDINVALID Invalid heap_id */ + status = MESSAGEQ_E_HEAPIDINVALID; + goto exit; + } + + status = mutex_lock_interruptible(messageq_state.gate_handle); + if (status) + goto exit; + if (messageq_state.heaps[heap_id] == NULL) + messageq_state.heaps[heap_id] = heap_handle; + else { + /*! @retval MESSAGEQ_E_ALREADYEXISTS Specified heap is + already registered. */ + status = MESSAGEQ_E_ALREADYEXISTS; + } + mutex_unlock(messageq_state.gate_handle); + +exit: + if (status < 0) { + printk(KERN_ERR "messageq_register_heap failed! " + "status = 0x%x\n", status); + } + return status; +} +EXPORT_SYMBOL(messageq_register_heap); + +/* + * ======== messageq_unregister_heap ======== + * Purpose: + * Unregister a heap + */ +int messageq_unregister_heap(u16 heap_id) +{ + int status = 0; + + if (WARN_ON(atomic_cmpmask_and_lt(&(messageq_state.ref_count), + MESSAGEQ_MAKE_MAGICSTAMP(0), + MESSAGEQ_MAKE_MAGICSTAMP(1)) == true)) { + status = -ENODEV; + goto exit; + } + + /* Make sure the heap_id is valid */ + if (WARN_ON(heap_id > messageq_state.num_heaps)) { + /*! @retval MESSAGEQ_E_HEAPIDINVALID Invalid heap_id */ + status = MESSAGEQ_E_HEAPIDINVALID; + goto exit; + } + + status = mutex_lock_interruptible(messageq_state.gate_handle); + if (status) + goto exit; + if (messageq_state.heaps != NULL) + messageq_state.heaps[heap_id] = NULL; + mutex_unlock(messageq_state.gate_handle); + +exit: + if (status < 0) { + printk(KERN_ERR "messageq_unregister_heap failed! " + "status = 0x%x\n", status); + } + return status; +} +EXPORT_SYMBOL(messageq_unregister_heap); + +/* + * ======== messageq_register_transport ======== + * Purpose: + * register a transport + */ +int messageq_register_transport(void *messageq_transportshm_handle, + u16 proc_id, u32 priority) +{ + int status = 0; + + BUG_ON(messageq_transportshm_handle == NULL); + if (WARN_ON(atomic_cmpmask_and_lt(&(messageq_state.ref_count), + MESSAGEQ_MAKE_MAGICSTAMP(0), + MESSAGEQ_MAKE_MAGICSTAMP(1)) == true)) { + status = -ENODEV; + goto exit; + } + + /* Make sure the proc_id is valid */ + if (WARN_ON(proc_id >= multiproc_get_max_processors())) { + /*! @retval MESSAGEQ_E_PROCIDINVALID Invalid proc_id */ + status = MESSAGEQ_E_PROCIDINVALID; + goto exit; + } + + status = mutex_lock_interruptible(messageq_state.gate_handle); + if (status) + goto exit; + if (messageq_state.transports[proc_id][priority] == NULL) { + messageq_state.transports[proc_id][priority] = \ + messageq_transportshm_handle; + } else { + /*! @retval MESSAGEQ_E_ALREADYEXISTS Specified transport is + already registered. */ + status = MESSAGEQ_E_ALREADYEXISTS; + } + mutex_unlock(messageq_state.gate_handle); + +exit: + if (status < 0) { + printk(KERN_ERR "messageq_register_transport failed! " + "status = 0x%x\n", status); + } + return status; +} +EXPORT_SYMBOL(messageq_register_transport); + +/* + * ======== messageq_unregister_transport ======== + * Purpose: + * Unregister a transport + */ +int messageq_unregister_transport(u16 proc_id, u32 priority) +{ + int status = 0; + + if (WARN_ON(atomic_cmpmask_and_lt(&(messageq_state.ref_count), + MESSAGEQ_MAKE_MAGICSTAMP(0), + MESSAGEQ_MAKE_MAGICSTAMP(1)) == true)) { + status = -ENODEV; + goto exit; + } + + /* Make sure the proc_id is valid */ + if (WARN_ON(proc_id >= multiproc_get_max_processors())) { + /*! @retval MESSAGEQ_E_PROCIDINVALID Invalid proc_id */ + status = MESSAGEQ_E_PROCIDINVALID; + goto exit; + } + + status = mutex_lock_interruptible(messageq_state.gate_handle); + if (status) + goto exit; + if (messageq_state.transports[proc_id][priority] == NULL) + messageq_state.transports[proc_id][priority] = NULL; + mutex_unlock(messageq_state.gate_handle); + +exit: + if (status < 0) { + printk(KERN_ERR "messageq_unregister_transport failed! " + "status = 0x%x\n", status); + } + return status; +} +EXPORT_SYMBOL(messageq_unregister_transport); + +/* + * ======== messageq_set_reply_queue ======== + * Purpose: + * Set the destination queue of the message. + */ +void messageq_set_reply_queue(void *messageq_handle, messageq_msg msg) +{ + struct messageq_object *obj = \ + (struct messageq_object *) messageq_handle; + + BUG_ON(messageq_handle == NULL); + if (WARN_ON(atomic_cmpmask_and_lt(&(messageq_state.ref_count), + MESSAGEQ_MAKE_MAGICSTAMP(0), + MESSAGEQ_MAKE_MAGICSTAMP(1)) == true)) + goto exit; + + if (WARN_ON(msg == NULL)) { + printk(KERN_ERR "messageq_set_reply_queue: msg passed is " + "NULL!\n"); + goto exit; + } + + msg->reply_id = (u16)(obj->queue); + msg->reply_proc = (u16)(obj->queue >> 16); + +exit: + return; +} +EXPORT_SYMBOL(messageq_set_reply_queue); + +/* + * ======== messageq_get_queue_id ======== + * Purpose: + * Get the queue _id of the message. + */ +u32 messageq_get_queue_id(void *messageq_handle) +{ + struct messageq_object *obj = \ + (struct messageq_object *) messageq_handle; + u32 queue_id = MESSAGEQ_INVALIDMESSAGEQ; + + if (WARN_ON(atomic_cmpmask_and_lt(&(messageq_state.ref_count), + MESSAGEQ_MAKE_MAGICSTAMP(0), + MESSAGEQ_MAKE_MAGICSTAMP(1)) == true)) + goto exit; + + if (WARN_ON(obj == NULL)) { + printk(KERN_ERR "messageq_get_queue_id: obj passed is NULL!\n"); + goto exit; + } + + queue_id = (obj->queue); + +exit: + return queue_id; +} +EXPORT_SYMBOL(messageq_get_queue_id); + +/* + * ======== messageq_get_proc_id ======== + * Purpose: + * Get the proc _id of the message. + */ +u16 messageq_get_proc_id(void *messageq_handle) +{ + struct messageq_object *obj = \ + (struct messageq_object *) messageq_handle; + u16 proc_id = MULTIPROC_INVALIDID; + + if (WARN_ON(atomic_cmpmask_and_lt(&(messageq_state.ref_count), + MESSAGEQ_MAKE_MAGICSTAMP(0), + MESSAGEQ_MAKE_MAGICSTAMP(1)) == true)) + goto exit; + + if (WARN_ON(obj == NULL)) { + printk(KERN_ERR "messageq_get_proc_id: obj passed is NULL!\n"); + goto exit; + } + + proc_id = (u16)(obj->queue >> 16); + +exit: + return proc_id; +} +EXPORT_SYMBOL(messageq_get_proc_id); + +/* + * ======== messageq_get_dst_queue ======== + * Purpose: + * Get the destination queue of the message. + */ +u32 messageq_get_dst_queue(messageq_msg msg) +{ + u32 queue_id = MESSAGEQ_INVALIDMESSAGEQ; + + if (WARN_ON(atomic_cmpmask_and_lt(&(messageq_state.ref_count), + MESSAGEQ_MAKE_MAGICSTAMP(0), + MESSAGEQ_MAKE_MAGICSTAMP(1)) == true)) + goto exit; + + if (WARN_ON(msg == NULL)) { + printk(KERN_ERR "messageq_get_dst_queue: msg passed is " + "NULL!\n"); + goto exit; + } + + /*construct queue value */ + if (msg->dst_id != (u32)MESSAGEQ_INVALIDMESSAGEQ) + queue_id = ((u32) multiproc_get_id(NULL) << 16) | msg->dst_id; + +exit: + return queue_id; +} +EXPORT_SYMBOL(messageq_get_dst_queue); + +/* + * ======== messageq_get_msg_id ======== + * Purpose: + * Get the message id of the message. + */ +u16 messageq_get_msg_id(messageq_msg msg) +{ + u16 id = MESSAGEQ_INVALIDMSGID; + + if (WARN_ON(atomic_cmpmask_and_lt(&(messageq_state.ref_count), + MESSAGEQ_MAKE_MAGICSTAMP(0), + MESSAGEQ_MAKE_MAGICSTAMP(1)) == true)) + goto exit; + + if (WARN_ON(msg == NULL)) { + printk(KERN_ERR "messageq_get_msg_id: msg passed is NULL!\n"); + goto exit; + } + + id = msg->msg_id; + +exit: + return id; +} +EXPORT_SYMBOL(messageq_get_msg_id); + +/* + * ======== messageq_get_msg_size ======== + * Purpose: + * Get the message size of the message. + */ +u32 messageq_get_msg_size(messageq_msg msg) +{ + u32 size = 0; + + if (WARN_ON(atomic_cmpmask_and_lt(&(messageq_state.ref_count), + MESSAGEQ_MAKE_MAGICSTAMP(0), + MESSAGEQ_MAKE_MAGICSTAMP(1)) == true)) + goto exit; + + if (WARN_ON(msg == NULL)) { + printk(KERN_ERR "messageq_get_msg_size: msg passed is NULL!\n"); + goto exit; + } + + size = msg->msg_size; + +exit: + return size; +} +EXPORT_SYMBOL(messageq_get_msg_size); + +/* + * ======== messageq_get_msg_pri ======== + * Purpose: + * Get the message priority of the message. + */ +u32 messageq_get_msg_pri(messageq_msg msg) +{ + u32 priority = MESSAGEQ_NORMALPRI; + + BUG_ON(msg == NULL); + if (WARN_ON(atomic_cmpmask_and_lt(&(messageq_state.ref_count), + MESSAGEQ_MAKE_MAGICSTAMP(0), + MESSAGEQ_MAKE_MAGICSTAMP(1)) == true)) + goto exit; + + if (WARN_ON(msg == NULL)) { + printk(KERN_ERR "messageq_get_msg_pri: msg passed is NULL!\n"); + goto exit; + } + + priority = ((u32)(msg->flags & MESSAGEQ_PRIORITYMASK)); + +exit: + return priority; +} +EXPORT_SYMBOL(messageq_get_msg_pri); + +/* + * ======== messageq_get_reply_queue ======== + * Purpose: + * Get the embedded source message queue out of the message. + */ +u32 messageq_get_reply_queue(messageq_msg msg) +{ + u32 queue = MESSAGEQ_INVALIDMESSAGEQ; + + if (WARN_ON(atomic_cmpmask_and_lt(&(messageq_state.ref_count), + MESSAGEQ_MAKE_MAGICSTAMP(0), + MESSAGEQ_MAKE_MAGICSTAMP(1)) == true)) + goto exit; + + if (WARN_ON(msg == NULL)) { + printk(KERN_ERR "messageq_get_reply_queue: msg passed is " + "NULL!\n"); + goto exit; + } + + if (msg->reply_id != (u16)MESSAGEQ_INVALIDMESSAGEQ) + queue = ((u32)(msg->reply_proc) << 16) | msg->reply_id; + +exit: + return queue; +} +EXPORT_SYMBOL(messageq_get_reply_queue); + +/* + * ======== messageq_set_msg_id ======== + * Purpose: + * Set the message id of the message. + */ +void messageq_set_msg_id(messageq_msg msg, u16 msg_id) +{ + if (WARN_ON(atomic_cmpmask_and_lt(&(messageq_state.ref_count), + MESSAGEQ_MAKE_MAGICSTAMP(0), + MESSAGEQ_MAKE_MAGICSTAMP(1)) == true)) + goto exit; + + if (WARN_ON(msg == NULL)) { + printk(KERN_ERR "messageq_set_msg_id: msg passed is NULL!\n"); + goto exit; + } + + msg->msg_id = msg_id; + +exit: + return; +} +EXPORT_SYMBOL(messageq_set_msg_id); + +/* + * ======== messageq_set_msg_pri ======== + * Purpose: + * Set the priority of the message. + */ +void messageq_set_msg_pri(messageq_msg msg, u32 priority) +{ + if (WARN_ON(atomic_cmpmask_and_lt(&(messageq_state.ref_count), + MESSAGEQ_MAKE_MAGICSTAMP(0), + MESSAGEQ_MAKE_MAGICSTAMP(1)) == true)) + goto exit; + + if (WARN_ON(msg == NULL)) { + printk(KERN_ERR "messageq_set_msg_pri: msg passed is NULL!\n"); + goto exit; + } + + msg->flags = priority & MESSAGEQ_PRIORITYMASK; + +exit: + return; +} +EXPORT_SYMBOL(messageq_set_msg_pri); + +/* ============================================================================= + * Internal functions + * ============================================================================= + */ +/* + * ======== _messageq_grow ======== + * Purpose: + * Grow the MessageQ table + */ +u16 _messageq_grow(struct messageq_object *obj) +{ + u16 queue_index = messageq_state.num_queues; + int oldSize; + void **queues; + void **oldqueues; + + if (WARN_ON(obj == NULL)) { + printk(KERN_ERR "_messageq_grow: obj passed is NULL!\n"); + goto exit; + } + + oldSize = (messageq_state.num_queues) * \ + sizeof(struct messageq_object *); + queues = kmalloc(oldSize + sizeof(struct messageq_object *), + GFP_KERNEL); + if (queues == NULL) { + printk(KERN_ERR "_messageq_grow: Growing the messageq " + "failed!\n"); + goto exit; + } + + /* Copy contents into new table */ + memcpy(queues, messageq_state.queues, oldSize); + /* Fill in the new entry */ + queues[queue_index] = (void *)obj; + /* Hook-up new table */ + oldqueues = messageq_state.queues; + messageq_state.queues = queues; + messageq_state.num_queues++; + + /* Delete old table if not statically defined*/ + if (messageq_state.can_free_queues == true) + kfree(oldqueues); + else + messageq_state.can_free_queues = true; + +exit: + return queue_index; +} diff --git a/drivers/dsp/syslink/multicore_ipc/messageq_ioctl.c b/drivers/dsp/syslink/multicore_ipc/messageq_ioctl.c new file mode 100644 index 000000000000..12283479b5b3 --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/messageq_ioctl.c @@ -0,0 +1,490 @@ +/* + * messageq_ioctl.c + * + * This file implements all the ioctl operations required on the messageq + * module. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +/* Standard headers */ +#include <linux/types.h> + +/* Linux headers */ +#include <linux/uaccess.h> +#include <linux/bug.h> +#include <linux/fs.h> +#include <linux/mm.h> + +/* Module Headers */ +#include <messageq.h> +#include <messageq_ioctl.h> +#include <sharedregion.h> + +/* + * ======== messageq_ioctl_put ======== + * Purpose: + * This ioctl interface to messageq_put function + */ +static inline int messageq_ioctl_put(struct messageq_cmd_args *cargs) +{ + int status = 0; + messageq_msg msg; + + msg = (messageq_msg) sharedregion_get_ptr(cargs->args.put.msg_srptr); + if (unlikely(msg == NULL)) + goto exit; + + status = messageq_put(cargs->args.put.queue_id, msg); + + cargs->api_status = status; +exit: + return 0; +} + +/* + * ======== messageq_ioctl_get ======== + * Purpose: + * This ioctl interface to messageq_get function + */ +static inline int messageq_ioctl_get(struct messageq_cmd_args *cargs) +{ + messageq_msg msg = NULL; + u32 *msg_srptr = SHAREDREGION_INVALIDSRPTR; + int index; + + cargs->api_status = messageq_get(cargs->args.get.messageq_handle, + &msg, + cargs->args.get.timeout); + if (unlikely(cargs->api_status < 0)) + goto exit; + + index = sharedregion_get_index(msg); + if (unlikely(index < 0)) { + cargs->api_status = index; + goto exit; + } + + msg_srptr = sharedregion_get_srptr(msg, index); + +exit: + cargs->args.get.msg_srptr = msg_srptr; + return 0; +} + +/* + * ======== messageq_ioctl_count ======== + * Purpose: + * This ioctl interface to messageq_count function + */ +static inline int messageq_ioctl_count(struct messageq_cmd_args *cargs) +{ + int result = messageq_count(cargs->args.count.messageq_handle); + if (result < 0) + cargs->api_status = result; + else + cargs->args.count.count = result; + + return 0; +} + +/* + * ======== messageq_ioctl_alloc ======== + * Purpose: + * This ioctl interface to messageq_alloc function + */ +static inline int messageq_ioctl_alloc(struct messageq_cmd_args *cargs) +{ + messageq_msg msg; + u32 *msg_srptr = SHAREDREGION_INVALIDSRPTR; + int index; + + msg = messageq_alloc(cargs->args.alloc.heap_id, cargs->args.alloc.size); + if (unlikely(msg == NULL)) + goto exit; + + index = sharedregion_get_index(msg); + if (unlikely(index < 0)) + goto exit; + + msg_srptr = sharedregion_get_srptr(msg, index); + + cargs->api_status = 0; +exit: + cargs->args.alloc.msg_srptr = msg_srptr; + return 0; +} + +/* + * ======== messageq_ioctl_free ======== + * Purpose: + * This ioctl interface to messageq_free function + */ +static inline int messageq_ioctl_free(struct messageq_cmd_args *cargs) +{ + int status = 0; + messageq_msg msg; + + msg = sharedregion_get_ptr(cargs->args.free.msg_srptr); + if (unlikely(msg == NULL)) + goto exit; + status = messageq_free(msg); + + cargs->api_status = status; +exit: + return 0; +} + +/* + * ======== messageq_ioctl_params_init ======== + * Purpose: + * This ioctl interface to messageq_params_init function + */ +static inline int messageq_ioctl_params_init(struct messageq_cmd_args *cargs) +{ + s32 retval = 0; + int status = 0; + unsigned long size; + struct messageq_params params; + + messageq_params_init(cargs->args.params_init.messageq_handle, + ¶ms); + size = copy_to_user(cargs->args.params_init.params, ¶ms, + sizeof(struct messageq_params)); + if (size) { + retval = -EFAULT; + goto exit; + } + + cargs->api_status = status; +exit: + return retval; +} + +/* + * ======== messageq_ioctl_create ======== + * Purpose: + * This ioctl interface to messageq_create function + */ +static inline int messageq_ioctl_create(struct messageq_cmd_args *cargs) +{ + s32 retval = 0; + int status = 0; + unsigned long size; + struct messageq_params params; + char *name = NULL; + + size = copy_from_user(¶ms, cargs->args.create.params, + sizeof(struct messageq_params)); + if (size) { + retval = -EFAULT; + goto exit; + } + + /* Allocate memory for the name */ + if (cargs->args.create.name_len > 0) { + name = kmalloc(cargs->args.create.name_len, GFP_KERNEL); + if (name == NULL) { + retval = -ENOMEM; + goto exit; + } + size = copy_from_user(name, cargs->args.create.name, + cargs->args.create.name_len); + if (size) { + retval = -EFAULT; + goto free_name; + } + } + + cargs->args.create.messageq_handle = messageq_create(name, ¶ms); + if (cargs->args.create.messageq_handle != NULL) { + cargs->args.create.queue_id = messageq_get_queue_id( + cargs->args.create.messageq_handle); + } + +free_name: + if (cargs->args.create.name_len > 0) + kfree(name); + + cargs->api_status = status; +exit: + return retval; +} + +/* + * ======== messageq_ioctl_delete ======== + * Purpose: + * This ioctl interface to messageq_delete function + */ +static inline int messageq_ioctl_delete(struct messageq_cmd_args *cargs) +{ + cargs->api_status = + messageq_delete(&(cargs->args.delete_messageq.messageq_handle)); + return 0; +} + +/* + * ======== messageq_ioctl_open ======== + * Purpose: + * This ioctl interface to messageq_open function + */ +static inline int messageq_ioctl_open(struct messageq_cmd_args *cargs) +{ + s32 retval = 0; + int status = 0; + unsigned long size; + char *name = NULL; + u32 queue_id = MESSAGEQ_INVALIDMESSAGEQ; + + /* Allocate memory for the name */ + if (cargs->args.open.name_len > 0) { + name = kmalloc(cargs->args.open.name_len, GFP_KERNEL); + if (name == NULL) { + retval = -ENOMEM; + goto exit; + } + size = copy_from_user(name, cargs->args.open.name, + cargs->args.open.name_len); + if (size) { + retval = -EFAULT; + goto free_name; + } + } + + status = messageq_open(name, &queue_id); + cargs->args.open.queue_id = queue_id; + +free_name: + if (cargs->args.open.name_len > 0) + kfree(name); + + cargs->api_status = status; +exit: + return retval; +} + +/* + * ======== messageq_ioctl_close ======== + * Purpose: + * This ioctl interface to messageq_close function + */ +static inline int messageq_ioctl_close(struct messageq_cmd_args *cargs) +{ + u32 queue_id = cargs->args.close.queue_id; + messageq_close(&queue_id); + cargs->args.close.queue_id = queue_id; + + cargs->api_status = 0; + return 0; +} + +/* + * ======== messageq_ioctl_get_config ======== + * Purpose: + * This ioctl interface to messageq_get_config function + */ +static inline int messageq_ioctl_get_config(struct messageq_cmd_args *cargs) +{ + s32 retval = 0; + unsigned long size; + struct messageq_config config; + + messageq_get_config(&config); + size = copy_to_user(cargs->args.get_config.config, &config, + sizeof(struct messageq_config)); + if (size) { + retval = -EFAULT; + goto exit; + } + + cargs->api_status = 0; +exit: + return retval; +} + +/* + * ======== messageq_ioctl_setup ======== + * Purpose: + * This ioctl interface to messageq_setup function + */ +static inline int messageq_ioctl_setup(struct messageq_cmd_args *cargs) +{ + s32 retval = 0; + unsigned long size; + struct messageq_config config; + + size = copy_from_user(&config, cargs->args.setup.config, + sizeof(struct messageq_config)); + if (size) { + retval = -EFAULT; + goto exit; + } + + cargs->api_status = messageq_setup(&config); + +exit: + return retval; +} + +/* + * ======== messageq_ioctl_destroy ======== + * Purpose: + * This ioctl interface to messageq_destroy function + */ +static inline int messageq_ioctl_destroy(struct messageq_cmd_args *cargs) +{ + cargs->api_status = messageq_destroy(); + return 0; +} + + +/* + * ======== messageq_ioctl_register_heap ======== + * Purpose: + * This ioctl interface to messageq_register_heap function + */ +static inline int messageq_ioctl_register_heap(struct messageq_cmd_args *cargs) +{ + cargs->api_status = \ + messageq_register_heap(cargs->args.register_heap.heap_handle, + cargs->args.register_heap.heap_id); + return 0; +} + +/* + * ======== messageq_ioctl_unregister_heap ======== + * Purpose: + * This ioctl interface to messageq_unregister_heap function + */ +static inline int messageq_ioctl_unregister_heap( + struct messageq_cmd_args *cargs) +{ + cargs->api_status = messageq_unregister_heap( + cargs->args.unregister_heap.heap_id); + return 0; +} + +/* + * ======== messageq_ioctl ======== + * Purpose: + * ioctl interface function for messageq module + */ +int messageq_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long args) +{ + int os_status = 0; + struct messageq_cmd_args __user *uarg = + (struct messageq_cmd_args __user *)args; + struct messageq_cmd_args cargs; + unsigned long size; + + if (_IOC_DIR(cmd) & _IOC_READ) + os_status = !access_ok(VERIFY_WRITE, uarg, _IOC_SIZE(cmd)); + else if (_IOC_DIR(cmd) & _IOC_WRITE) + os_status = !access_ok(VERIFY_READ, uarg, _IOC_SIZE(cmd)); + if (os_status) { + os_status = -EFAULT; + goto exit; + } + + /* Copy the full args from user-side */ + size = copy_from_user(&cargs, uarg, sizeof(struct messageq_cmd_args)); + if (size) { + os_status = -EFAULT; + goto exit; + } + + switch (cmd) { + case CMD_MESSAGEQ_PUT: + os_status = messageq_ioctl_put(&cargs); + break; + + case CMD_MESSAGEQ_GET: + os_status = messageq_ioctl_get(&cargs); + break; + + case CMD_MESSAGEQ_COUNT: + os_status = messageq_ioctl_count(&cargs); + break; + + case CMD_MESSAGEQ_ALLOC: + os_status = messageq_ioctl_alloc(&cargs); + break; + + case CMD_MESSAGEQ_FREE: + os_status = messageq_ioctl_free(&cargs); + break; + + case CMD_MESSAGEQ_PARAMS_INIT: + os_status = messageq_ioctl_params_init(&cargs); + break; + + case CMD_MESSAGEQ_CREATE: + os_status = messageq_ioctl_create(&cargs); + break; + + case CMD_MESSAGEQ_DELETE: + os_status = messageq_ioctl_delete(&cargs); + break; + + case CMD_MESSAGEQ_OPEN: + os_status = messageq_ioctl_open(&cargs); + break; + + case CMD_MESSAGEQ_CLOSE: + os_status = messageq_ioctl_close(&cargs); + break; + + case CMD_MESSAGEQ_GETCONFIG: + os_status = messageq_ioctl_get_config(&cargs); + break; + + case CMD_MESSAGEQ_SETUP: + os_status = messageq_ioctl_setup(&cargs); + break; + + case CMD_MESSAGEQ_DESTROY: + os_status = messageq_ioctl_destroy(&cargs); + break; + + case CMD_MESSAGEQ_REGISTERHEAP: + os_status = messageq_ioctl_register_heap(&cargs); + break; + + case CMD_MESSAGEQ_UNREGISTERHEAP: + os_status = messageq_ioctl_unregister_heap(&cargs); + break; + + default: + WARN_ON(cmd); + os_status = -ENOTTY; + break; + } + + if ((cargs.api_status == -ERESTARTSYS) || (cargs.api_status == -EINTR)) + os_status = -ERESTARTSYS; + + if (os_status < 0) + goto exit; + + /* Copy the full args to the user-side. */ + size = copy_to_user(uarg, &cargs, sizeof(struct messageq_cmd_args)); + if (size) { + os_status = -EFAULT; + goto exit; + } + return os_status; + +exit: + printk(KERN_ERR "messageq_ioctl failed: status = 0x%x\n", os_status); + return os_status; +} diff --git a/drivers/dsp/syslink/multicore_ipc/messageq_transportshm.c b/drivers/dsp/syslink/multicore_ipc/messageq_transportshm.c new file mode 100644 index 000000000000..d07ca3479466 --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/messageq_transportshm.c @@ -0,0 +1,778 @@ +/* + * messageq_transportshm.c + * + * MessageQ Transport module + * + * Copyright (C) 2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +/* Standard headers */ +#include <linux/types.h> + +/* Utilities headers */ +#include <linux/string.h> +#include <linux/slab.h> + +/* Syslink headers */ +#include <syslink/atomic_linux.h> +/* Module level headers */ +#include <multiproc.h> +#include <nameserver.h> +#include <gatepeterson.h> +#include <notify.h> +#include <messageq.h> +#include <listmp_sharedmemory.h> +#include <messageq_transportshm.h> + +/* ============================================================================= + * Globals + * ============================================================================= + */ +/* Cache line size */ +#define MESSAGEQ_TRANSPORTSHM_CACHESIZE 128 + +/* Indicates that the transport is up. */ +#define MESSAGEQ_TRANSPORTSHM_UP 0xBADC0FFE + +/* messageq_transportshm Version. */ +#define MESSAGEQ_TRANSPORTSHM_VERSION 1 + +/*! + * @brief Macro to make a correct module magic number with refCount + */ +#define MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(x) \ + ((MESSAGEQ_TRANSPORTSHM_MODULEID << 12u) | (x)) + +/* ============================================================================= + * Structures & Enums + * ============================================================================= + */ +/* + * Defines the messageq_transportshm state object, which contains all the + * module specific information. + */ +struct messageq_transportshm_moduleobject { + atomic_t ref_count; + struct messageq_transportshm_config cfg; + /*< messageq_transportshm configuration structure */ + struct messageq_transportshm_config def_cfg; + /*< Default module configuration */ + struct messageq_transportshm_params def_inst_params; + /*< Default instance parameters */ + void *gate_handle; + /*< Handle to the gate for local thread safety */ + void *transports[MULTIPROC_MAXPROCESSORS][MESSAGEQ_NUM_PRIORITY_QUEUES]; + /*!< Transport to be set in messageq_register_transport */ + +}; + +/* + * Structure of attributes in shared memory + */ +struct messageq_transportshm_attrs { + VOLATILE u32 version; + VOLATILE u32 flag; +}; + +/* + * Structure defining config parameters for the MessageQ transport + * instances. + */ +struct messageq_transportshm_object { + VOLATILE struct messageq_transportshm_attrs *attrs[2]; + /* Attributes for both processors */ + void *my_listmp_handle; + /* List for this processor */ + void *remote_listmp_handle; + /* List for remote processor */ + VOLATILE int status; + /* Current status */ + int my_index; + /* 0 | 1 */ + int remote_index; + /* 1 | 0 */ + int notify_event_no; + /* Notify event to be used */ + void *notify_driver; + /* Notify driver to be used */ + u16 proc_id; + /* Dest proc id */ + void *gate; + /* Gate for critical regions */ + struct messageq_transportshm_params params; + /* Instance specific parameters */ + u32 priority; + /*!< Priority of messages supported by this transport */ +}; + +/* ============================================================================= + * Globals + * ============================================================================= + */ +/* + * @var messageq_transportshm_state + * + * messageq_transportshm state object variable + */ +static struct messageq_transportshm_moduleobject messageq_transportshm_state = { + .gate_handle = NULL, + .def_cfg.err_fxn = 0, + .def_inst_params.gate = NULL, + .def_inst_params.shared_addr = 0x0, + .def_inst_params.shared_addr_size = 0x0, + .def_inst_params.notify_event_no = (u32)(-1), + .def_inst_params.notify_driver = NULL, + .def_inst_params.priority = MESSAGEQ_NORMALPRI +}; + + +/* ============================================================================= + * Forward declarations of internal functions + * ============================================================================= + */ +/* Callback function registered with the Notify module. */ +static void _messageq_transportshm_notify_fxn(u16 proc_id, + u32 event_no, void *arg, u32 payload); + +/* ============================================================================= + * APIs called directly by applications + * ============================================================================= + */ +/* + * ======== messageq_transportshm_get_config ======== + * Purpose: + * Get the default configuration for the messageq_transportshm + * module. + * + * This function can be called by the application to get their + * configuration parameter to messageq_transportshm_setup filled in + * by the messageq_transportshm module with the default parameters. + * If the user does not wish to make any change in the default + * parameters, this API is not required to be called. + */ +void messageq_transportshm_get_config( + struct messageq_transportshm_config *cfg) +{ + if (WARN_ON(cfg == NULL)) + goto exit; + + if (atomic_cmpmask_and_lt(&(messageq_transportshm_state.ref_count), + MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(0), + MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(1)) == true) { + memcpy(cfg, &(messageq_transportshm_state.def_cfg), + sizeof(struct messageq_transportshm_config)); + } else { + memcpy(cfg, &(messageq_transportshm_state.cfg), + sizeof(struct messageq_transportshm_config)); + } + return; + +exit: + printk(KERN_ERR "messageq_transportshm_get_config: Argument of type" + "(struct messageq_transportshm_config *) passed is null!\n"); +} + + +/* + * ======== messageq_transportshm_setup ======== + * Purpose: + * Setup the messageq_transportshm module. + * + * This function sets up the messageq_transportshm module. This + * function must be called before any other instance-level APIs can + * be invoked. + * Module-level configuration needs to be provided to this + * function. If the user wishes to change some specific config + * parameters, then messageq_transportshm_getConfig can be called + * to get the configuration filled with the default values. After + * this, only the required configuration values can be changed. If + * the user does not wish to make any change in the default + * parameters, the application can simply call + * messageq_transportshm_setup with NULL parameters. The default + * parameters would get automatically used. + */ +int messageq_transportshm_setup(const struct messageq_transportshm_config *cfg) +{ + int status = MESSAGEQ_TRANSPORTSHM_SUCCESS; + struct messageq_transportshm_config tmpCfg; + + /* This sets the refCount variable is not initialized, upper 16 bits is + * written with module Id to ensure correctness of refCount variable. + */ + atomic_cmpmask_and_set(&messageq_transportshm_state.ref_count, + MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(0), + MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(0)); + + if (atomic_inc_return(&messageq_transportshm_state.ref_count) + != MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(1u)) { + return 1; + } + + if (cfg == NULL) { + messageq_transportshm_get_config(&tmpCfg); + cfg = &tmpCfg; + } + + messageq_transportshm_state.gate_handle = \ + kmalloc(sizeof(struct mutex), GFP_KERNEL); + if (messageq_transportshm_state.gate_handle == NULL) { + /* @retval MESSAGEQTRANSPORTSHM_E_FAIL Failed to create + GateMutex! */ + status = MESSAGEQ_TRANSPORTSHM_E_FAIL; + printk(KERN_ERR "messageq_transportshm_setup: Failed to create " + "mutex!\n"); + atomic_set(&messageq_transportshm_state.ref_count, + MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(0)); + goto exit; + } + mutex_init(messageq_transportshm_state.gate_handle); + + /* Copy the user provided values into the state object. */ + memcpy(&messageq_transportshm_state.cfg, cfg, + sizeof(struct messageq_transportshm_config)); + memset(&(messageq_transportshm_state.transports), 0, (sizeof(void *) * \ + MULTIPROC_MAXPROCESSORS * MESSAGEQ_NUM_PRIORITY_QUEUES)); + return status; + +exit: + printk(KERN_ERR "messageq_transportshm_setup failed: status = 0x%x", + status); + return status; +} + + +/* + * ======== messageq_transportshm_destroy ======== + * Purpose: + * Destroy the messageq_transportshm module. + * + * Once this function is called, other messageq_transportshm module + * APIs, except for the messageq_transportshm_getConfig API cannot + * be called anymore. + */ +int messageq_transportshm_destroy(void) +{ + int status = 0; + u16 i; + u16 j; + + if (WARN_ON(atomic_cmpmask_and_lt( + &(messageq_transportshm_state.ref_count), + MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(0), + MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(1)) == true)) { + status = -ENODEV; + goto exit; + } + + if (!(atomic_dec_return(&messageq_transportshm_state.ref_count) + == MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(0))) { + status = 1; + goto exit; + } + + /* Temporarily increment ref_count here. */ + atomic_set(&messageq_transportshm_state.ref_count, + MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(1)); + + /* Delete any Transports that have not been deleted so far. */ + for (i = 0; i < MULTIPROC_MAXPROCESSORS; i++) { + for (j = 0 ; j < MESSAGEQ_NUM_PRIORITY_QUEUES; j++) { + if (messageq_transportshm_state.transports[i][j] != \ + NULL) { + messageq_transportshm_delete(& + (messageq_transportshm_state.transports[i][j])); + } + } + } + if (messageq_transportshm_state.gate_handle != NULL) { + kfree(messageq_transportshm_state.gate_handle); + messageq_transportshm_state.gate_handle = NULL; + } + + /* Decrease the ref_count */ + atomic_set(&messageq_transportshm_state.ref_count, + MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(0)); + return 0; + +exit: + if (status < 0) { + printk(KERN_ERR "messageq_transportshm_destroy failed: " + "status = 0x%x\n", status); + } + return status; +} + + +/* + * ======== messageq_transportshm_params_init ======== + * Purpose: + * Get Instance parameters + */ +void messageq_transportshm_params_init(void *mqtshm_handle, + struct messageq_transportshm_params *params) +{ + struct messageq_transportshm_object *object = NULL; + + if (WARN_ON(atomic_cmpmask_and_lt( + &(messageq_transportshm_state.ref_count), + MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(0), + MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(1)) == true)) { + printk(KERN_ERR "messageq_transportshm_params_init: Module was " + " not initialized\n"); + goto exit; + } + + if (WARN_ON(params == NULL)) { + printk(KERN_ERR "messageq_transportshm_params_init: Argument of" + " type (struct messageq_transportshm_params *) " + "is NULL!"); + goto exit; + } + + if (mqtshm_handle == NULL) { + memcpy(params, &(messageq_transportshm_state.def_inst_params), + sizeof(struct messageq_transportshm_params)); + } else { + /* Return updated messageq_transportshm instance + specific parameters. */ + object = (struct messageq_transportshm_object *) mqtshm_handle; + memcpy(params, &(object->params), + sizeof(struct messageq_transportshm_params)); + } + +exit: + return; +} + +/* + * ======== messageq_transportshm_create ======== + * Purpose: + * Create a transport instance. This function waits for the remote + * processor to complete its transport creation. Hence it must be + * called only after the remote processor is running. + */ +void *messageq_transportshm_create(u16 proc_id, + const struct messageq_transportshm_params *params) +{ + struct messageq_transportshm_object *handle = NULL; + int status = 0; + int my_index; + int remote_index; + listmp_sharedmemory_params listmp_params[2]; + VOLATILE u32 *otherflag; + + if (WARN_ON(atomic_cmpmask_and_lt( + &(messageq_transportshm_state.ref_count), + MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(0), + MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(1)) == true)) { + status = -ENODEV; + goto exit; + } + + if (WARN_ON(params == NULL)) { + status = -EINVAL; + goto exit; + } + if (WARN_ON(params->shared_addr_size < \ + messageq_transportshm_shared_mem_req(params))) { + status = -EINVAL; + goto exit; + } + if (messageq_transportshm_state.transports[proc_id][params->priority] \ + != NULL) { + /* Specified transport is already registered. */ + status = MESSAGEQ_E_ALREADYEXISTS; + goto exit; + } + + /* + * Determine who gets the '0' slot and who gets the '1' slot + * The '0' slot is given to the lower multiproc id. + */ + if (multiproc_get_id(NULL) < proc_id) { + my_index = 0; + remote_index = 1; + } else { + my_index = 1; + remote_index = 0; + } + + handle = kzalloc(sizeof(struct messageq_transportshm_object), + GFP_KERNEL); + if (handle == NULL) { + status = -ENOMEM; + goto exit; + } + + handle->attrs[0] = (struct messageq_transportshm_attrs *) + params->shared_addr; + handle->attrs[1] = (struct messageq_transportshm_attrs *) + ((u32)(handle->attrs[0]) + \ + MESSAGEQ_TRANSPORTSHM_CACHESIZE); + handle->status = messageq_transportshm_status_INIT; + handle->gate = params->gate; + memcpy(&(handle->params), (void *)params, + sizeof(struct messageq_transportshm_params)); + + status = notify_register_event(params->notify_driver, proc_id, + params->notify_event_no, + _messageq_transportshm_notify_fxn, + (void *)handle); + if (status < 0) { + /* @retval NULL Notify register failed */ + printk(KERN_ERR "messageq_transportshm_create: " + "notify_register_event failed!\n"); + goto notify_register_fail; + } + + handle->notify_driver = params->notify_driver; + handle->notify_event_no = params->notify_event_no; + handle->priority = params->priority; + handle->proc_id = proc_id; + handle->my_index = my_index; + handle->remote_index = remote_index; + + /* Create the shared lists for the transport. */ + listmp_sharedmemory_params_init(NULL, &(listmp_params[0])); + listmp_params[0].shared_addr = (u32 *)((u32)(params->shared_addr) + \ + (2 * MESSAGEQ_TRANSPORTSHM_CACHESIZE)); + listmp_params[0].shared_addr_size = \ + listmp_sharedmemory_shared_memreq(&(listmp_params[0])); + listmp_params[0].gate = params->gate; + listmp_params[0].name = NULL; + listmp_params[0].list_type = listmp_type_SHARED; + + listmp_sharedmemory_params_init(NULL, &(listmp_params[1])); + listmp_params[1].shared_addr = \ + (u32 *)((u32)(listmp_params[0].shared_addr) + \ + listmp_params[0].shared_addr_size); + listmp_params[1].shared_addr_size = \ + listmp_sharedmemory_shared_memreq(&(listmp_params[1])); + listmp_params[1].name = NULL; + listmp_params[1].list_type = listmp_type_SHARED; + listmp_params[1].gate = params->gate; + + handle->my_listmp_handle = listmp_sharedmemory_create + (&(listmp_params[my_index])); + handle->attrs[my_index]->version = MESSAGEQ_TRANSPORTSHM_VERSION; + handle->attrs[my_index]->flag = MESSAGEQ_TRANSPORTSHM_UP; + + /* Store in VOLATILE to make sure it is not compiled out... */ + otherflag = &(handle->attrs[remote_index]->flag); + + /* Loop until the other side is up */ + while (*otherflag != MESSAGEQ_TRANSPORTSHM_UP) + ; + + if (handle->attrs[remote_index]->version + != MESSAGEQ_TRANSPORTSHM_VERSION) { + /* @retval NULL Versions do not match */ + printk(KERN_ERR "messageq_transportshm_create: " + "Incorrect version of remote transport!\n"); + goto exit; + } + + status = listmp_sharedmemory_open + ((listmp_sharedmemory_handle *) &(handle->remote_listmp_handle), + &listmp_params[remote_index]); + if (status < 0) { + /* @retval NULL List creation failed */ + goto listmp_open_fail; + } + + /* Register the transport with MessageQ */ + status = messageq_register_transport((void *)handle, proc_id, + (u32)params->priority); + if (status >= 0) { + messageq_transportshm_state.transports + [proc_id][params->priority] = (void *)handle; + handle->status = messageq_transportshm_status_UP; + } + return handle; + +listmp_open_fail: + printk(KERN_ERR "messageq_transportshm_create: " + "listmp_sharedmemory_open failed!\n"); +notify_register_fail: + if (status < 0) { + if (handle != NULL) + messageq_transportshm_delete((void **)(&handle)); + } + +exit: + printk(KERN_ERR "messageq_transportshm_create failed: status = 0x%x\n", + status); + return handle; +} + +/* + * ======== messageq_transportshm_delete ======== + * Purpose: + * Delete instance + */ +int messageq_transportshm_delete(void **mqtshm_handleptr) +{ + int status = 0; + int tmpstatus = 0; + struct messageq_transportshm_object *obj; + + if (WARN_ON(atomic_cmpmask_and_lt( + &(messageq_transportshm_state.ref_count), + MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(0), + MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(1)) == true)) { + status = -ENODEV; + goto exit; + } + + if (WARN_ON(mqtshm_handleptr == NULL)) { + status = -EINVAL; + goto exit; + } + if (WARN_ON(*mqtshm_handleptr == NULL)) { + /* @retval MESSAGEQTRANSPORTSHM_E_HANDLE Invalid NULL handle + specified */ + status = MESSAGEQ_TRANSPORTSHM_E_HANDLE; + printk(KERN_WARNING "messageq_transportshm_delete: Invalid NULL" + " mqtshm_handle specified! status = 0x%x\n", status); + goto exit; + } + + obj = (struct messageq_transportshm_object *) (*mqtshm_handleptr); + /* Clear handle in the local array */ + messageq_transportshm_state.transports[obj->proc_id][obj->priority] = \ + NULL; + obj->attrs[obj->my_index]->flag = 0; + status = listmp_sharedmemory_delete( + (listmp_sharedmemory_handle *)&obj->my_listmp_handle); + if (status < 0) { + printk(KERN_WARNING "messageq_transportshm_delete: Failed to " + "delete listmp_sharedmemory instance!\n"); + } + + tmpstatus = listmp_sharedmemory_close( + (listmp_sharedmemory_handle) obj->remote_listmp_handle); + if ((tmpstatus < 0) && (status >= 0)) { + status = tmpstatus; + printk(KERN_WARNING "messageq_transportshm_delete: Failed to " + "close listmp_sharedmemory instance!\n"); + } + + tmpstatus = messageq_unregister_transport(obj->proc_id, + obj->params.priority); + if ((tmpstatus < 0) && (status >= 0)) { + status = tmpstatus; + printk(KERN_WARNING "messageq_transportshm_delete: Failed to " + "unregister transport!\n"); + } + + tmpstatus = notify_unregister_event(obj->notify_driver, obj->proc_id, + obj->notify_event_no, + _messageq_transportshm_notify_fxn, + (void *)obj); + if ((tmpstatus < 0) && (status >= 0)) { + status = tmpstatus; + printk(KERN_WARNING "messageq_transportshm_delete: Failed to " + "unregister notify event!\n"); + } + + kfree(obj); + *mqtshm_handleptr = NULL; + +exit: + if (status < 0) + printk(KERN_ERR "messageq_transportshm_delete failed: " + "status = 0x%x\n", status); + return status; +} + +/* + * ======== messageq_transportshm_put ======== + * Purpose: + * Put msg to remote list +*/ +int messageq_transportshm_put(void *mqtshm_handle, + void *msg) +{ + int status = 0; + struct messageq_transportshm_object *obj = \ + (struct messageq_transportshm_object *) mqtshm_handle; + + if (WARN_ON(atomic_cmpmask_and_lt( + &(messageq_transportshm_state.ref_count), + MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(0), + MESSAGEQTRANSPORTSHM_MAKE_MAGICSTAMP(1)) == true)) { + status = -ENODEV; + goto exit; + } + + BUG_ON(mqtshm_handle == NULL); + if (WARN_ON(msg == NULL)) { + status = -EINVAL; + goto exit; + } + if (WARN_ON(obj == NULL)) { + status = -EINVAL; + goto exit; + } + + status = listmp_put_tail(obj->remote_listmp_handle, + (struct listmp_elem *) msg); + if (status < 0) { + /* @retval MESSAGEQ_TRANSPORTSHM_E_FAIL + * Notification to remote processor failed! + */ + status = MESSAGEQ_TRANSPORTSHM_E_FAIL; + printk(KERN_ERR "messageq_transportshm_put: Failed to put " + "message in the shared list! status = 0x%x\n", status); + goto exit; + } + + status = notify_sendevent(obj->notify_driver, obj->proc_id, + obj->notify_event_no, 0, true); + if (status < 0) + goto notify_send_fail; + else + goto exit; + +notify_send_fail: + printk(KERN_ERR "messageq_transportshm_put: Notification to remote " + "processor failed, status = 0x%x\n", status); + /* If sending the event failed, then remove the element from the list.*/ + /* Ignore the status of remove. */ + listmp_remove(obj->remote_listmp_handle, (struct listmp_elem *) msg); + +exit: + if (status < 0) + printk(KERN_ERR "messageq_transportshm_put failed: " + "status = 0x%x\n", status); + return status; +} + +/* + * ======== messageq_transportshm_control ======== + * Purpose: + * Control Function +*/ +int messageq_transportshm_control(void *mqtshm_handle, u32 cmd, u32 *cmdArg) +{ + BUG_ON(mqtshm_handle == NULL); + + printk(KERN_ALERT "messageq_transportshm_control not supported!\n"); + return MESSAGEQTRANSPORTSHM_E_NOTSUPPORTED; +} + +/* + * ======== messageq_transportshm_get_status ======== + * Purpose: + * Get status + */ +enum messageq_transportshm_status messageq_transportshm_get_status( + void *mqtshm_handle) +{ + struct messageq_transportshm_object *obj = \ + (struct messageq_transportshm_object *) mqtshm_handle; + + BUG_ON(obj == NULL); + + return obj->status; +} + +/* + * ======== messageq_transportshm_put ======== + * Purpose: + * Get shared memory requirements. + */ +u32 messageq_transportshm_shared_mem_req(const + struct messageq_transportshm_params *params) +{ + u32 totalSize; + listmp_sharedmemory_params listmp_params; + u32 listmp_size; + + /* There are two transport flags in shared memory */ + totalSize = 2 * MESSAGEQ_TRANSPORTSHM_CACHESIZE; + + listmp_sharedmemory_params_init(NULL, &listmp_params); + listmp_size = listmp_sharedmemory_shared_memreq(&listmp_params); + + /* MyList */ + totalSize += listmp_size; + + /* RemoteList */ + totalSize += listmp_size; + + return totalSize; +} + + +/* ============================================================================= + * internal functions + * ============================================================================= + */ +/* + * ======== _messageq_transportshm_notify_fxn ======== + * Purpose: + * Callback function registered with the Notify module. + */ +void _messageq_transportshm_notify_fxn(u16 proc_id, u32 event_no, + void *arg, u32 payload) +{ + struct messageq_transportshm_object *obj = NULL; + messageq_msg msg = NULL; + u32 queue_id; + + if (WARN_ON(arg == NULL)) + goto exit; + + obj = (struct messageq_transportshm_object *)arg; + /* While there is are messages, get them out and send them to + * their final destination. */ + while ((msg = (messageq_msg) listmp_get_head(obj->my_listmp_handle)) + != NULL) { + /* Get the destination message queue Id */ + queue_id = messageq_get_dst_queue(msg); + messageq_put(queue_id, msg); + } + return; + +exit: + printk(KERN_ERR "messageq_transportshm_notify_fxn: argument passed is " + "NULL!\n"); +} + + +/* + * ======== messageq_transportshm_delete ======== + * Purpose: + * This will set the asynchronous error function for the transport module + */ +void messageq_transportshm_set_err_fxn( + void (*err_fxn)( + enum MessageQTransportShm_Reason reason, + void *handle, + void *msg, + u32 info)) +{ + u32 key; + + key = mutex_lock_interruptible(messageq_transportshm_state.gate_handle); + if (key < 0) + goto exit; + + messageq_transportshm_state.cfg.err_fxn = err_fxn; + mutex_unlock(messageq_transportshm_state.gate_handle); + +exit: + return; +} + + diff --git a/drivers/dsp/syslink/multicore_ipc/messageq_transportshm_ioctl.c b/drivers/dsp/syslink/multicore_ipc/messageq_transportshm_ioctl.c new file mode 100644 index 000000000000..2b4af6192f27 --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/messageq_transportshm_ioctl.c @@ -0,0 +1,334 @@ +/* + * messageq_transportshm_ioctl.c + * + * This file implements all the ioctl operations required on the + * messageq_transportshm module. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +/* Standard headers */ +#include <linux/types.h> + +/* Linux headers */ +#include <linux/uaccess.h> +#include <linux/bug.h> +#include <linux/fs.h> + +/* Module Headers */ +#include <messageq.h> +#include <messageq_transportshm.h> +#include <messageq_transportshm_ioctl.h> +#include <sharedregion.h> + +/* + * ======== messageq_transportshm_ioctl_get_config ======== + * Purpose: + * This ioctl interface to messageq_transportshm_get_config function + */ +static inline int messageq_transportshm_ioctl_get_config( + struct messageq_transportshm_cmd_args *cargs) +{ + s32 retval = 0; + unsigned long size; + struct messageq_transportshm_config config; + + messageq_transportshm_get_config(&config); + size = copy_to_user(cargs->args.get_config.config, &config, + sizeof(struct messageq_transportshm_config)); + if (size) { + retval = -EFAULT; + goto exit; + } + + cargs->api_status = 0; +exit: + return retval; +} + +/* + * ======== messageq_transportshm_ioctl_setup ======== + * Purpose: + * This ioctl interface to messageq_transportshm_setup function + */ +static inline int messageq_transportshm_ioctl_setup( + struct messageq_transportshm_cmd_args *cargs) +{ + s32 retval = 0; + unsigned long size; + struct messageq_transportshm_config config; + + size = copy_from_user(&config, cargs->args.setup.config, + sizeof(struct messageq_transportshm_config)); + if (size) { + retval = -EFAULT; + goto exit; + } + + cargs->api_status = messageq_transportshm_setup(&config); + +exit: + return retval; +} + +/* + * ======== messageq_transportshm_ioctl_destroy ======== + * Purpose: + * This ioctl interface to messageq_transportshm_destroy function + */ +static inline int messageq_transportshm_ioctl_destroy( + struct messageq_transportshm_cmd_args *cargs) +{ + cargs->api_status = messageq_transportshm_destroy(); + return 0; +} + +/* + * ======== messageq_transportshm_ioctl_params_init ======== + * Purpose: + * This ioctl interface to messageq_transportshm_params_init function + */ +static inline int messageq_transportshm_ioctl_params_init( + struct messageq_transportshm_cmd_args *cargs) +{ + s32 retval = 0; + int status = 0; + unsigned long size; + struct messageq_transportshm_params params; + + messageq_transportshm_params_init( + cargs->args.params_init.messageq_transportshm_handle, ¶ms); + size = copy_to_user(cargs->args.params_init.params, ¶ms, + sizeof(struct messageq_transportshm_params)); + if (size) { + retval = -EFAULT; + goto exit; + } + + cargs->api_status = status; +exit: + return retval; +} + +/* + * ======== messageq_transportshm_ioctl_create ======== + * Purpose: + * This ioctl interface to messageq_transportshm_create function + */ +static inline int messageq_transportshm_ioctl_create( + struct messageq_transportshm_cmd_args *cargs) +{ + s32 retval = 0; + unsigned long size; + struct messageq_transportshm_params params; + + size = copy_from_user(¶ms, cargs->args.create.params, + sizeof(struct messageq_transportshm_params)); + if (size) { + retval = -EFAULT; + goto exit; + } + + params.shared_addr = sharedregion_get_ptr( + (u32 *)cargs->args.create.shared_addr_srptr); + if (unlikely(params.shared_addr == NULL)) + goto exit; + + params.gate = cargs->args.create.knl_lock_handle; + params.notify_driver = cargs->args.create.knl_notify_driver; + cargs->args.create.messageq_transportshm_handle = \ + messageq_transportshm_create(cargs->args.create.proc_id, + ¶ms); + + /* + * Here we are not validating the return from the module. + * Even it is NULL, we pass it to user and user has to pass + * proper return to application + */ + cargs->api_status = 0; +exit: + return retval; +} + +/* + * ======== messageq_transportshm_ioctl_delete ======== + * Purpose: + * This ioctl interface to messageq_transportshm_ioctl_delete function + */ +static inline int messageq_transportshm_ioctl_delete( + struct messageq_transportshm_cmd_args *cargs) +{ + cargs->api_status = messageq_transportshm_delete( + &(cargs->args.delete_transport.messageq_transportshm_handle)); + return 0; +} + +/* + * ======== messageq_transportshm_ioctl_put ======== + * Purpose: + * This ioctl interface to messageq_transportshm_put function + */ +static inline int messageq_transportshm_ioctl_put( + struct messageq_transportshm_cmd_args *cargs) +{ + int status = 0; + messageq_msg msg; + + msg = (messageq_msg) sharedregion_get_ptr(cargs->args.put.msg_srptr); + if (unlikely(msg == NULL)) + goto exit; + + status = messageq_transportshm_put( + cargs->args.put.messageq_transportshm_handle, msg); + + cargs->api_status = status; +exit: + return 0; +} + +/* + * ======== messageq_transportshm_ioctl_leave ======== + * Purpose: + * This ioctl interface to messageq_transportshm_leave function + */ +static inline int messageq_transportshm_ioctl_get_status( + struct messageq_transportshm_cmd_args *cargs) +{ + cargs->args.get_status.status = \ + messageq_transportshm_get_status( + cargs->args.get_status.messageq_transportshm_handle); + cargs->api_status = 0; + return 0; +} + +/* + * ======== messageq_transportshm_ioctl_shared_memreq ======== + * Purpose: + * This ioctl interface to messageq_transportshm_shared_memreq function + */ +static inline int messageq_transportshm_ioctl_shared_memreq( + struct messageq_transportshm_cmd_args *cargs) +{ + s32 retval = 0; + unsigned long size; + struct messageq_transportshm_params params; + + size = copy_from_user(¶ms, cargs->args.shared_memreq.params, + sizeof(struct messageq_transportshm_params)); + if (size) { + retval = -EFAULT; + goto exit; + } + + cargs->args.shared_memreq.bytes = + messageq_transportshm_shared_mem_req(¶ms); + + cargs->api_status = 0; +exit: + return retval; +} + +/* + * ======== messageq_transportshm_ioctl ======== + * Purpose: + * ioctl interface function for messageq_transportshm + */ +int messageq_transportshm_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long args) +{ + int os_status = 0; + struct messageq_transportshm_cmd_args __user *uarg = + (struct messageq_transportshm_cmd_args __user *)args; + s32 retval = 0; + struct messageq_transportshm_cmd_args cargs; + unsigned long size; + + if (_IOC_DIR(cmd) & _IOC_READ) + os_status = !access_ok(VERIFY_WRITE, uarg, _IOC_SIZE(cmd)); + else if (_IOC_DIR(cmd) & _IOC_WRITE) + os_status = !access_ok(VERIFY_READ, uarg, _IOC_SIZE(cmd)); + if (os_status) { + os_status = -EFAULT; + goto exit; + } + + /* Copy the full args from user-side */ + size = copy_from_user(&cargs, uarg, + sizeof(struct messageq_transportshm_cmd_args)); + if (size) { + os_status = -EFAULT; + goto exit; + } + + switch (cmd) { + case CMD_MESSAGEQ_TRANSPORTSHM_GETCONFIG: + os_status = messageq_transportshm_ioctl_get_config(&cargs); + break; + + case CMD_MESSAGEQ_TRANSPORTSHM_SETUP: + os_status = messageq_transportshm_ioctl_setup(&cargs); + break; + + case CMD_MESSAGEQ_TRANSPORTSHM_DESTROY: + os_status = messageq_transportshm_ioctl_destroy(&cargs); + break; + + case CMD_MESSAGEQ_TRANSPORTSHM_PARAMS_INIT: + retval = messageq_transportshm_ioctl_params_init(&cargs); + break; + + case CMD_MESSAGEQ_TRANSPORTSHM_CREATE: + os_status = messageq_transportshm_ioctl_create(&cargs); + break; + + case CMD_MESSAGEQ_TRANSPORTSHM_DELETE: + os_status = messageq_transportshm_ioctl_delete(&cargs); + break; + + case CMD_MESSAGEQ_TRANSPORTSHM_PUT: + os_status = messageq_transportshm_ioctl_put(&cargs); + break; + + case CMD_MESSAGEQ_TRANSPORTSHM_GETSTATUS: + os_status = messageq_transportshm_ioctl_get_status(&cargs); + break; + + case CMD_MESSAGEQ_TRANSPORTSHM_SHAREDMEMREQ: + os_status = messageq_transportshm_ioctl_shared_memreq(&cargs); + break; + + default: + WARN_ON(cmd); + os_status = -ENOTTY; + break; + } + + if ((cargs.api_status == -ERESTARTSYS) || (cargs.api_status == -EINTR)) + os_status = -ERESTARTSYS; + + if (os_status < 0) + goto exit; + + /* Copy the full args to the user-side. */ + size = copy_to_user(uarg, &cargs, + sizeof(struct messageq_transportshm_cmd_args)); + if (size) { + os_status = -EFAULT; + goto exit; + } + return os_status; + +exit: + printk(KERN_ERR "messageq_transportshm_ioctl failed: status = 0x%x\n", + os_status); + return os_status; +} diff --git a/drivers/dsp/syslink/multicore_ipc/multiproc.c b/drivers/dsp/syslink/multicore_ipc/multiproc.c new file mode 100755 index 000000000000..17a3bce19113 --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/multiproc.c @@ -0,0 +1,242 @@ +/* +* multiproc.c +* +* Many multi-processor modules have the concept of processor id. MultiProc +* centeralizes the processor id management. +* +* Copyright (C) 2008-2009 Texas Instruments, Inc. +* +* This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR +* PURPOSE. +*/ + +/* + * ======== multiproc.c ======== + * Notes: + * The processor id start at 0 and ascend without skipping values till maximum_ + * no_of_processors - 1 + */ + +/* Standard headers */ +#include <linux/types.h> +#include <linux/module.h> +#include <syslink/atomic_linux.h> +/* Utilities headers */ +#include <linux/string.h> + +/* Module level headers */ +#include <multiproc.h> + +/* Macro to make a correct module magic number with ref_count */ +#define MULTIPROC_MAKE_MAGICSTAMP(x) ((MULTIPROC_MODULEID << 12u) | (x)) + +/* + * multiproc module state object + */ +struct multiproc_module_object { + struct multiproc_config cfg; /* Module configuration structure */ + struct multiproc_config def_cfg; /* Default module configuration */ + atomic_t ref_count; /* Reference count */ +}; + +static struct multiproc_module_object multiproc_state = { + .def_cfg.max_processors = 4, + .def_cfg.name_list[0][0] = "MPU", + .def_cfg.name_list[1][0] = "Tesla", + .def_cfg.name_list[2][0] = "SysM3", + .def_cfg.name_list[3][0] = "AppM3", + .def_cfg.id = 0 +}; + +/* + * ======== multiproc_get_config ======== + * Purpose: + * This will get the default configuration for the multiproc module + */ +void multiproc_get_config(struct multiproc_config *cfg) +{ + BUG_ON(cfg == NULL); + if (atomic_cmpmask_and_lt( + &(multiproc_state.ref_count), + MULTIPROC_MAKE_MAGICSTAMP(0), + MULTIPROC_MAKE_MAGICSTAMP(1)) == true) { + /* (If setup has not yet been called) */ + memcpy(cfg, &multiproc_state.def_cfg, + sizeof(struct multiproc_config)); + } else { + memcpy(cfg, &multiproc_state.cfg, + sizeof(struct multiproc_config)); + } +} +EXPORT_SYMBOL(multiproc_get_config); + +/* + * ======== multiproc_setup ======== + * Purpose: + * This function sets up the multiproc module. This function + * must be called before any other instance-level APIs can be + * invoked + */ +s32 multiproc_setup(struct multiproc_config *cfg) +{ + s32 status = 0; + struct multiproc_config tmp_cfg; + + /* This sets the ref_count variable is not initialized, upper 16 bits is + * written with module Id to ensure correctness of ref_count variable. + */ + atomic_cmpmask_and_set(&multiproc_state.ref_count, + MULTIPROC_MAKE_MAGICSTAMP(0), + MULTIPROC_MAKE_MAGICSTAMP(0)); + + if (atomic_inc_return(&multiproc_state.ref_count) + != MULTIPROC_MAKE_MAGICSTAMP(1u)) { + status = 1; + } else { + if (cfg == NULL) { + multiproc_get_config(&tmp_cfg); + cfg = &tmp_cfg; + } + + memcpy(&multiproc_state.cfg, cfg, + sizeof(struct multiproc_config)); + } + + return status; +} +EXPORT_SYMBOL(multiproc_setup); + +/* + * ======== multiproc_setup ======== + * Purpose: + * This function destroy the multiproc module. + * Once this function is called, other multiproc module APIs, + * except for the multiproc_get_config API cannot be called + * anymore. + */ +s32 multiproc_destroy(void) +{ + int status = 0; + + if (atomic_cmpmask_and_lt( + &(multiproc_state.ref_count), + MULTIPROC_MAKE_MAGICSTAMP(0), + MULTIPROC_MAKE_MAGICSTAMP(1)) == true) { + status = -ENODEV; + goto exit; + } + + atomic_dec_return(&multiproc_state.ref_count); + +exit: + return status; +} +EXPORT_SYMBOL(multiproc_destroy); + +/* + * ======== multiProc_set_local_id ======== + * Purpose: + * This will set the processor id of local processor on run time + */ +int multiproc_set_local_id(u16 proc_id) +{ + int status = 0; + + if (WARN_ON(atomic_cmpmask_and_lt( + &(multiproc_state.ref_count), + MULTIPROC_MAKE_MAGICSTAMP(0), + MULTIPROC_MAKE_MAGICSTAMP(1)) == true)) { + status = -ENODEV; + goto exit; + } + + if (WARN_ON(proc_id >= MULTIPROC_MAXPROCESSORS)) { + status = -EINVAL; + goto exit; + } + + multiproc_state.cfg.id = proc_id; + +exit: + return status; +} +EXPORT_SYMBOL(multiproc_set_local_id); + +/* + * ======== multiProc_get_local_id ======== + * Purpose: + * This will get the processor id from proccessor name + */ +u16 multiproc_get_id(const char *proc_name) +{ + s32 i; + u16 proc_id = MULTIPROC_INVALIDID; + + if (WARN_ON(atomic_cmpmask_and_lt( + &(multiproc_state.ref_count), + MULTIPROC_MAKE_MAGICSTAMP(0), + MULTIPROC_MAKE_MAGICSTAMP(1)) == true)) + goto exit; + + /* If the name is NULL, just return the local id */ + if (proc_name == NULL) + proc_id = multiproc_state.cfg.id; + else { + for (i = 0; i < multiproc_state.cfg.max_processors ; i++) { + if (strcmp(proc_name, + &multiproc_state.cfg.name_list[i][0]) == 0) { + proc_id = i; + break; + } + } + } + +exit: + return proc_id; +} +EXPORT_SYMBOL(multiproc_get_id); + +/* + * ======== multiProc_set_local_id ======== + * Purpose: + * This will get the processor name from proccessor id + */ +char *multiproc_get_name(u16 proc_id) +{ + char *proc_name = NULL; + + /* On error condition return NULL pointer, else entry from name list */ + if (WARN_ON(atomic_cmpmask_and_lt( + &(multiproc_state.ref_count), + MULTIPROC_MAKE_MAGICSTAMP(0), + MULTIPROC_MAKE_MAGICSTAMP(1)) == true)) + goto exit; + + if (WARN_ON(proc_id >= MULTIPROC_MAXPROCESSORS)) + goto exit; + + proc_name = multiproc_state.cfg.name_list[proc_id]; + +exit: + return proc_name; +} +EXPORT_SYMBOL(multiproc_get_name); + +/* + * ======== multiProc_set_local_id ======== + * Purpose: + * This will get the maximum proccessor id in the system + */ +u16 multiproc_get_max_processors(void) +{ + return multiproc_state.cfg.max_processors; + +} +EXPORT_SYMBOL(multiproc_get_max_processors); + diff --git a/drivers/dsp/syslink/multicore_ipc/multiproc_ioctl.c b/drivers/dsp/syslink/multicore_ipc/multiproc_ioctl.c new file mode 100755 index 000000000000..8f36304f3397 --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/multiproc_ioctl.c @@ -0,0 +1,171 @@ +/* +* multiproc_ioctl.c +* +* This provides the ioctl interface for multiproc module +* +* Copyright (C) 2008-2009 Texas Instruments, Inc. +* +* This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR +* PURPOSE. +*/ +#include <linux/uaccess.h> +#include <linux/slab.h> +#include <linux/types.h> +#include <linux/fs.h> +#include <linux/mm.h> +#include <multiproc.h> +#include <multiproc_ioctl.h> + +/* + * ======== mproc_ioctl_setup ======== + * Purpose: + * This wrapper function will call the multproc function + * to setup the module + */ +static int mproc_ioctl_setup(struct multiproc_cmd_args *cargs) +{ + struct multiproc_config config; + s32 status = 0; + ulong size; + + size = copy_from_user(&config, + cargs->args.setup.config, + sizeof(struct multiproc_config)); + if (size) { + status = -EFAULT; + goto exit; + } + + cargs->api_status = multiproc_setup(&config); + +exit: + return status; +} + +/* + * ======== mproc_ioctl_destroy ======== + * Purpose: + * This wrapper function will call the multproc function + * to destroy the module + */ +static int mproc_ioctl_destroy(struct multiproc_cmd_args *cargs) +{ + cargs->api_status = multiproc_destroy(); + return 0; +} + +/* + * ======== mproc_ioctl_get_config ======== + * Purpose: + * This wrapper function will call the multproc function + * to get the default configuration the module + */ +static int mproc_ioctl_get_config(struct multiproc_cmd_args *cargs) +{ + struct multiproc_config config; + u32 size; + + multiproc_get_config(&config); + size = copy_to_user(cargs->args.get_config.config, &config, + sizeof(struct multiproc_config)); + if (size) { + cargs->api_status = -EFAULT; + return 0; + } + cargs->api_status = 0; + return 0; +} + +/* + * ======== mproc_ioctl_setup ======== + * Purpose: + * This wrapper function will call the multproc function + * to setup the module + */ +static int multiproc_ioctl_set_local_id(struct multiproc_cmd_args *cargs) +{ + cargs->api_status = multiproc_set_local_id(cargs->args.set_local_id.id); + return 0; +} + +/* + * ======== multiproc_ioctl ======== + * Purpose: + * This ioctl interface for multiproc module + */ +int multiproc_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long args) +{ + s32 status = 0; + s32 size = 0; + struct multiproc_cmd_args __user *uarg = + (struct multiproc_cmd_args __user *)args; + struct multiproc_cmd_args cargs; + + + if (_IOC_DIR(cmd) & _IOC_READ) + status = !access_ok(VERIFY_WRITE, uarg, _IOC_SIZE(cmd)); + else if (_IOC_DIR(cmd) & _IOC_WRITE) + status = !access_ok(VERIFY_READ, uarg, _IOC_SIZE(cmd)); + + if (status) { + status = -EFAULT; + goto exit; + } + + /* Copy the full args from user-side */ + size = copy_from_user(&cargs, uarg, + sizeof(struct multiproc_cmd_args)); + if (size) { + status = -EFAULT; + goto exit; + } + + switch (cmd) { + case CMD_MULTIPROC_SETUP: + status = mproc_ioctl_setup(&cargs); + break; + + case CMD_MULTIPROC_DESTROY: + status = mproc_ioctl_destroy(&cargs); + break; + + case CMD_MULTIPROC_GETCONFIG: + status = mproc_ioctl_get_config(&cargs); + break; + + case CMD_MULTIPROC_SETLOCALID: + status = multiproc_ioctl_set_local_id(&cargs); + break; + + default: + WARN_ON(cmd); + status = -ENOTTY; + break; + } + + if ((cargs.api_status == -ERESTARTSYS) || (cargs.api_status == -EINTR)) + status = -ERESTARTSYS; + + if (status < 0) + goto exit; + + + /* Copy the full args to the user-side. */ + size = copy_to_user(uarg, &cargs, sizeof(struct multiproc_cmd_args)); + if (size) { + status = -EFAULT; + goto exit; + } + +exit: + return status; + +} + diff --git a/drivers/dsp/syslink/multicore_ipc/nameserver.c b/drivers/dsp/syslink/multicore_ipc/nameserver.c new file mode 100644 index 000000000000..12261f9b0506 --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/nameserver.c @@ -0,0 +1,1005 @@ +/* + * nameserver.c + * + * The nameserver module manages local name/value pairs that + * enables an application and other modules to store and retrieve + * values based on a name. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +#include <linux/module.h> +#include <linux/types.h> +#include <linux/string.h> +#include <linux/list.h> +#include <linux/mutex.h> +#include <linux/slab.h> +#include <syslink/atomic_linux.h> + +#include <nameserver.h> +#include <multiproc.h> +#include <nameserver_remote.h> + +#define NS_MAX_NAME_LEN 32 +#define NS_MAX_RUNTIME_ENTRY (~0) +#define NS_MAX_VALUE_LEN 4 + +/* + * The dynamic name/value table looks like the following. This approach allows + * each instance table to have different value and different name lengths. + * The names block is allocated on the create. The size of that block is + * (max_runtime_entries * max_name_en). That block is sliced and diced up and + * given to each table entry. + * The same thing is done for the values block. + * + * names table values + * ------------- ------------- ------------- + * | |<-\ | elem | /----->| | + * | | \-------| name | / | | + * | | | value |-/ | | + * | | | len | | | + * | |<-\ |-----------| | | + * | | \ | elem | | | + * | | \------| name | /------>| | + * | | | value |-/ | | + * ------------- | len | | | + * ------------- | | + * | | + * | | + * ------------- + * + * There is an optimization for small values (e.g. <= sizeof(UInt32). + * In this case, there is no values block allocated. Instead the value + * field is used directly. This optimization occurs and is managed when + * obj->max_value_len <= sizeof(Us3232). + * + * The static create is a little different. The static entries point directly + * to a name string (and value). Since it points directly to static items, + * this entries cannot be removed. + * If max_runtime_entries is non-zero, a names and values block is created. + * Here is an example of a table with 1 static entry and 2 dynamic entries + * + * ------------ + * this entries cannot be removed. + * If max_runtime_entries is non-zero, a names and values block is created. + * Here is an example of a table with 1 static entry and 2 dynamic entries + * + * ------------ + * | elem | + * "myName" <-----------| name |----------> someValue + * | value | + * names | len | values + * ------------- ------------- ------------- + * | |<-\ | elem | /----->| | + * | | \-------| name | / | | + * | | | value |-/ | | + * | | | len | | | + * | |<-\ |-----------| | | + * | | \ | elem | | | + * | | \------| name | /------>| | + * | | | value |-/ | | + * ------------- | len | | | + * ------------- | | + * | | + * | | + * ------------- + * + * NameServerD uses a freeList and namelist to maintain the empty + * and filled-in entries. So when a name/value pair is added, an entry + * is pulled off the freeList, filled-in and placed on the namelist. + * The reverse happens on a remove. + * + * For static adds, the entries are placed on the namelist statically. + * + * For dynamic creates, the freeList is populated in postInt and there are no + * entries placed on the namelist (this happens when the add is called). + * + */ + +/* Macro to make a correct module magic number with refCount */ +#define NAMESERVER_MAKE_MAGICSTAMP(x) ((NAMESERVER_MODULEID << 12u) | (x)) + +/* + * A name/value table entry + */ +struct nameserver_entry { + struct list_head elem; /* List element */ + u32 hash; /* Hash value */ + char *name; /* Name portion of name/value pair */ + u32 len; /* Length of the value field. */ + void *buf; /* Value portion of name/value entry */ + bool collide; /* Does the hash collides? */ + struct nameserver_entry *next; /* Pointer to the next entry, + used incase of collision only */ +}; + +/* + * A nameserver instance object + */ +struct nameserver_object { + struct list_head elem; + char *name; /* Name of the instance */ + u32 count; /* Counter for entries */ + struct mutex *gate_handle; /* Gate for critical regions */ + struct list_head name_list; /* Filled entries list */ + struct nameserver_params params; /* The parameter structure */ +}; + + +/* nameserver module state object */ +struct nameserver_module_object { + struct list_head obj_list; + struct mutex *list_lock; + struct nameserver_remote_object **remote_handle_list; + atomic_t ref_count; +}; + +/* + * Variable for holding state of the nameserver module. + */ +struct nameserver_module_object nameserver_state = { + .obj_list = LIST_HEAD_INIT(nameserver_state.obj_list), + .list_lock = NULL, + .remote_handle_list = NULL, +}; + +/* + * Lookup table for CRC calculation. + */ +static const u32 string_crc_table[256u] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, + 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, + 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, + 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, + 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, + 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, + 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, + 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, + 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, + 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, + 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, +}; + +/* + * ======== nameserver_setup ======== + * Purpose: + * This will calculate hash for a string + */ +static u32 nameserver_string_hash(const char *string) +{ + u32 i; + u32 hash ; + u32 len = strlen(string); + + for (i = 0, hash = len; i < len; i++) + hash = (hash >> 8) ^ + string_crc_table[(hash & 0xff)] ^ string[i]; + + return hash; +} + +/* + * ======== nameserver_setup ======== + * Purpose: + * This will setup the nameserver module + */ +int nameserver_setup(void) +{ + struct nameserver_remote_object **list = NULL; + s32 retval = 0; + u16 nr_procs = 0; + + /* This sets the ref_count variable if not initialized, upper 16 bits is + * written with module Id to ensure correctness of refCount variable + */ + atomic_cmpmask_and_set(&nameserver_state.ref_count, + NAMESERVER_MAKE_MAGICSTAMP(0), + NAMESERVER_MAKE_MAGICSTAMP(0)); + + if (atomic_inc_return(&nameserver_state.ref_count) + != NAMESERVER_MAKE_MAGICSTAMP(1)) { + return 1; + } + + nr_procs = multiproc_get_max_processors(); + list = kmalloc(nr_procs * sizeof(struct nameserver_remote_object *), + GFP_KERNEL); + if (list == NULL) { + retval = -ENOMEM; + goto error; + } + + memset(list , 0, nr_procs * sizeof(struct nameserver_remote_object *)); + nameserver_state.remote_handle_list = list; + nameserver_state.list_lock = kmalloc(sizeof(struct mutex), GFP_KERNEL); + if (nameserver_state.list_lock == NULL) { + retval = -ENOMEM; + goto error; + } + + /* mutex is initialized with state = UNLOCKED */ + mutex_init(nameserver_state.list_lock); + return 0; + +error: + kfree(list); + printk(KERN_ERR "nameserver_setup failed, retval: %x\n", retval); + return retval; +} +EXPORT_SYMBOL(nameserver_setup); + +/* + * ======== nameserver_destroy ======== + * Purpose: + * This will destroy the nameserver module + */ +int nameserver_destroy(void) +{ + s32 retval = 0; + struct mutex *lock = NULL; + + if (WARN_ON(atomic_cmpmask_and_lt(&(nameserver_state.ref_count), + NAMESERVER_MAKE_MAGICSTAMP(0), + NAMESERVER_MAKE_MAGICSTAMP(1)) == true)) { + retval = -ENODEV; + goto exit; + } + + if (!(atomic_dec_return(&nameserver_state.ref_count) + == NAMESERVER_MAKE_MAGICSTAMP(0))) { + retval = 1; + goto exit; + } + + if (WARN_ON(nameserver_state.list_lock == NULL)) { + retval = -ENODEV; + goto exit; + } + + /* If a nameserver instance exist, do not proceed */ + if (!list_empty(&nameserver_state.obj_list)) { + retval = -EBUSY; + goto exit; + } + + retval = mutex_lock_interruptible(nameserver_state.list_lock); + if (retval) + goto exit; + + lock = nameserver_state.list_lock; + nameserver_state.list_lock = NULL; + mutex_unlock(lock); + kfree(lock); + kfree(nameserver_state.remote_handle_list); + nameserver_state.remote_handle_list = NULL; + return 0; + +exit: + if (retval < 0) { + printk(KERN_ERR "nameserver_destroy failed, retval: %x\n", + retval); + } + return retval; +} +EXPORT_SYMBOL(nameserver_destroy); + +/*! + * Purpose: + * Initialize this config-params structure with supplier-specified + * defaults before instance creation. + */ +int nameserver_params_init(struct nameserver_params *params) +{ + BUG_ON(params == NULL); + params->check_existing = true; + params->gate_handle = NULL; + params->max_name_len = NS_MAX_NAME_LEN; + params->max_runtime_entries = NS_MAX_RUNTIME_ENTRY; + params->max_value_len = NS_MAX_VALUE_LEN; + params->table_heap = NULL; + return 0; +} +EXPORT_SYMBOL(nameserver_params_init); + +/* + * ======== nameserver_get_params ======== + * Purpose: + * This will initialize config-params structure with + * supplier-specified defaults before instance creation + */ +int nameserver_get_params(void *handle, + struct nameserver_params *params) +{ + struct nameserver_object *nshandle = NULL; + + BUG_ON(params == NULL); + if (handle == NULL) { + params->check_existing = true; + params->max_name_len = NS_MAX_NAME_LEN; + params->max_runtime_entries = NS_MAX_RUNTIME_ENTRY; + params->max_value_len = NS_MAX_VALUE_LEN; + params->gate_handle = NULL; + params->table_heap = NULL; + } else { + nshandle = (struct nameserver_object *)handle; + params->check_existing = nshandle->params.check_existing; + params->max_name_len = nshandle->params.max_name_len; + params->max_runtime_entries = + nshandle->params.max_runtime_entries; + params->max_value_len = nshandle->params.max_value_len; + params->gate_handle = nshandle->params.gate_handle; + params->table_heap = nshandle->params.table_heap; + } + return 0; +} +EXPORT_SYMBOL(nameserver_get_params); + +/* + * ======== nameserver_get_params ======== + * Purpose: + * This will get the handle of a nameserver instance + * from name + */ +void *nameserver_get_handle(const char *name) +{ + struct nameserver_object *obj = NULL; + + BUG_ON(name == NULL); + list_for_each_entry(obj, &nameserver_state.obj_list, elem) { + if (strcmp(obj->name, name) == 0) + goto succes; + } + return NULL; + +succes: + return (void *)obj; +} +EXPORT_SYMBOL(nameserver_get_handle); + +/* + * ======== nameserver_create ======== + * Purpose: + * This will create a name server instance + */ +void *nameserver_create(const char *name, + const struct nameserver_params *params) +{ + struct nameserver_object *new_obj = NULL; + u32 name_len; + s32 retval = 0; + + BUG_ON(name == NULL); + BUG_ON(params == NULL); + + name_len = strlen(name) + 1; + if (name_len > params->max_name_len) { + retval = -E2BIG; + goto exit; + } + + retval = mutex_lock_interruptible(nameserver_state.list_lock); + if (retval) + goto exit; + + /* check if the name is already registered or not */ + new_obj = nameserver_get_handle(name); + if (new_obj != NULL) { + retval = -EEXIST; + goto error_handle; + } + + new_obj = kmalloc(sizeof(struct nameserver_object), GFP_KERNEL); + if (new_obj == NULL) { + retval = -ENOMEM; + goto error; + } + + new_obj->name = kmalloc(name_len, GFP_ATOMIC); + if (new_obj->name == NULL) { + retval = -ENOMEM; + goto error; + } + + strncpy(new_obj->name, name, name_len); + memcpy(&new_obj->params, params, + sizeof(struct nameserver_params)); + if (params->max_value_len < sizeof(u32)) + new_obj->params.max_value_len = sizeof(u32); + else + new_obj->params.max_value_len = params->max_value_len; + + new_obj->gate_handle = + kmalloc(sizeof(struct mutex), GFP_KERNEL); + if (new_obj->gate_handle == NULL) { + retval = -ENOMEM; + goto error_mutex; + } + + mutex_init(new_obj->gate_handle); + new_obj->count = 0; + /* Put in the nameserver instance to local list */ + INIT_LIST_HEAD(&new_obj->name_list); + list_add_tail(&new_obj->elem, &nameserver_state.obj_list); + mutex_unlock(nameserver_state.list_lock); + return (void *)new_obj; + +error_mutex: + kfree(new_obj->name); +error: + kfree(new_obj); +error_handle: + mutex_unlock(nameserver_state.list_lock); +exit: + printk(KERN_ERR "nameserver_create failed retval:%x \n", retval); + return NULL; +} +EXPORT_SYMBOL(nameserver_create); + + +/* + * ======== nameserver_delete ======== + * Purpose: + * This will delete a name server instance + */ +int nameserver_delete(void **handle) +{ + struct nameserver_object *temp_obj = NULL; + struct mutex *gate_handle = NULL; + bool localgate = false; + s32 retval = 0; + + BUG_ON(handle == NULL); + temp_obj = (struct nameserver_object *) (*handle); + retval = mutex_lock_interruptible(temp_obj->gate_handle); + if (retval) + goto exit; + + /* Do not proceed if an entry in the in the table */ + if (temp_obj->count != 0) { + retval = -EBUSY; + goto error; + } + + retval = mutex_lock_interruptible(nameserver_state.list_lock); + if (retval) + goto error; + + list_del(&temp_obj->elem); + mutex_unlock(nameserver_state.list_lock); + gate_handle = temp_obj->gate_handle; + /* free the memory allocated for instance name */ + kfree(temp_obj->name); + /* Delete the lock handle if created internally */ + if (temp_obj->params.gate_handle == NULL) + localgate = true; + + /* Free the memory used for handle */ + kfree(temp_obj); + *handle = NULL; + mutex_unlock(gate_handle); + if (localgate == true) + kfree(gate_handle); + return 0; + +error: + mutex_unlock(temp_obj->gate_handle); +exit: + printk(KERN_ERR "nameserver_delete failed retval:%x \n", retval); + return retval; +} +EXPORT_SYMBOL(nameserver_delete); + +/* + * ======== nameserver_is_entry_found ======== + * Purpose: + * This will return true if the entry fond in the table + */ +static bool nameserver_is_entry_found(const char *name, u32 hash, + struct list_head *list, + struct nameserver_entry **entry) +{ + struct nameserver_entry *node = NULL; + bool hash_match = false; + bool name_match = false; + + + list_for_each_entry(node, list, elem) { + /* Hash not matchs, take next node */ + if (node->hash == hash) + hash_match = true; + else + continue; + /* If the name matchs, incase hash is duplicate */ + if (strcmp(node->name, name) == 0) + name_match = true; + + if (hash_match && name_match) { + if (entry != NULL) + *entry = node; + return true; + } + + hash_match = false; + name_match = false; + } + return false; +} + +/* + * ======== nameserver_add ======== + * Purpose: + * This will add an entry into a nameserver instance + */ +void *nameserver_add(void *handle, const char *name, + void *buffer, u32 length) +{ + struct nameserver_entry *new_node = NULL; + struct nameserver_object *temp_obj = NULL; + bool found = false; + u32 hash; + u32 name_len; + s32 retval = 0; + + BUG_ON(handle == NULL); + BUG_ON(name == NULL); + BUG_ON(buffer == NULL); + if (WARN_ON(length == 0)) { + retval = -EINVAL; + goto exit; + } + + temp_obj = (struct nameserver_object *)handle; + retval = mutex_lock_interruptible(temp_obj->gate_handle); + if (retval) + goto exit; + + if (temp_obj->count >= temp_obj->params.max_runtime_entries) { + retval = -ENOSPC; + goto error; + } + + /* make the null char in to account */ + name_len = strlen(name) + 1; + if (name_len > temp_obj->params.max_name_len) { + retval = -E2BIG; + goto error; + } + + /* TODO : hash and collide ?? */ + hash = nameserver_string_hash(name); + found = nameserver_is_entry_found(name, hash, + &temp_obj->name_list, &new_node); + if (found == true) { + retval = -EEXIST; + goto error_entry; + } + + new_node = kmalloc(sizeof(struct nameserver_entry), GFP_KERNEL); + if (new_node == NULL) { + retval = -ENOMEM; + goto error; + } + + new_node->hash = hash; + new_node->collide = true; + new_node->len = length; + new_node->next = NULL; + new_node->name = kmalloc(name_len, GFP_KERNEL); + if (new_node->name == NULL) { + retval = -ENOMEM; + goto error; + } + + new_node->buf = kmalloc(length, GFP_KERNEL); + if (new_node->buf == NULL) { + retval = -ENOMEM; + goto error1; + } + + strncpy(new_node->name, name, name_len); + memcpy(new_node->buf, buffer, length); + list_add_tail(&new_node->elem, &temp_obj->name_list); + temp_obj->count++; + mutex_unlock(temp_obj->gate_handle); + return new_node; + +error1: + kfree(new_node->name); +error: + kfree(new_node); +error_entry: + mutex_unlock(temp_obj->gate_handle); +exit: + printk(KERN_ERR "nameserver_add failed status: %x \n", retval); + return NULL; + +} +EXPORT_SYMBOL(nameserver_add); + +/* + * ======== nameserver_add_uint32 ======== + * Purpose: + * This will a Uint32 value into a nameserver instance + */ +void *nameserver_add_uint32(void *handle, const char *name, + u32 value) +{ + struct nameserver_entry *new_node = NULL; + BUG_ON(handle == NULL); + BUG_ON(name == NULL); + + new_node = nameserver_add(handle, name, &value, sizeof(u32)); + return new_node; +} +EXPORT_SYMBOL(nameserver_add_uint32); + +/* + * ======== nameserver_remove ======== + * Purpose: + * This will remove a name/value pair from a name server + */ +int nameserver_remove(void *handle, const char *name) +{ + struct nameserver_object *temp_obj = NULL; + struct nameserver_entry *entry = NULL; + bool found = false; + u32 hash; + u32 name_len; + s32 retval = 0; + + BUG_ON(handle == NULL); + BUG_ON(name == NULL); + + temp_obj = (struct nameserver_object *)handle; + name_len = strlen(name) + 1; + if (name_len > temp_obj->params.max_name_len) { + retval = -E2BIG; + goto exit; + } + + retval = mutex_lock_interruptible(temp_obj->gate_handle); + if (retval) + goto exit; + + /* TODO :check collide & hash usage */ + hash = nameserver_string_hash(name); + found = nameserver_is_entry_found(name, hash, + &temp_obj->name_list, &entry); + if (found == false) { + retval = -ENOENT; + goto error; + } + + kfree(entry->buf); + kfree(entry->name); + list_del(&entry->elem); + kfree(entry); + temp_obj->count--; + mutex_unlock(temp_obj->gate_handle); + return 0; + +error: + mutex_unlock(temp_obj->gate_handle); + +exit: + printk(KERN_ERR "nameserver_remove failed status:%x \n", retval); + return retval; +} +EXPORT_SYMBOL(nameserver_remove); + +/* + * ======== nameserver_remove_entry ======== + * Purpose: + * This will remove a name/value pair from a name server + */ +int nameserver_remove_entry(void *nshandle, void *nsentry) +{ + struct nameserver_entry *node = NULL; + struct nameserver_object *handle = NULL; + s32 retval = 0; + + BUG_ON(nshandle == NULL); + BUG_ON(nsentry == NULL); + + handle = (struct nameserver_object *)nshandle; + node = (struct nameserver_entry *)nsentry; + retval = mutex_lock_interruptible(handle->gate_handle); + if (retval) + goto exit; + + kfree(node->buf); + kfree(node->name); + list_del(&node->elem); + kfree(node); + handle->count--; + mutex_unlock(handle->gate_handle); + return 0; + +exit: + printk(KERN_ERR "nameserver_remove_entry failed status:%x \n", retval); + return retval; +} +EXPORT_SYMBOL(nameserver_remove_entry); + + +/* + * ======== nameserver_get_local ======== + * Purpose: + * This will retrieve the value portion of a name/value + * pair from local table + */ +int nameserver_get_local(void *handle, const char *name, + void *buffer, u32 length) +{ + struct nameserver_object *temp_obj = NULL; + struct nameserver_entry *entry = NULL; + bool found = false; + u32 hash; + s32 retval = 0; + + BUG_ON(handle == NULL); + BUG_ON(name == NULL); + BUG_ON(buffer == NULL); + if (WARN_ON(length == 0)) { + retval = -EINVAL; + goto exit; + } + + temp_obj = (struct nameserver_object *)handle; + retval = mutex_lock_interruptible(temp_obj->gate_handle); + if (retval) + goto exit; + + /* TODO :check collide & hash usage */ + hash = nameserver_string_hash(name); + found = nameserver_is_entry_found(name, hash, + &temp_obj->name_list, &entry); + if (found == false) { + retval = -ENOENT; + goto error; + } + + if (entry->len >= length) { + memcpy(buffer, entry->buf, length); + retval = length; + } else { + memcpy(buffer, entry->buf, entry->len); + retval = entry->len; + } + + mutex_unlock(temp_obj->gate_handle); + return retval; + +error: + mutex_unlock(temp_obj->gate_handle); + +exit: + printk(KERN_ERR "nameserver_get_local entry not found!\n"); + return retval; +} +EXPORT_SYMBOL(nameserver_get_local); + +/* + * ======== nameserver_get ======== + * Purpose: + * This will etrieve the value portion of a name/value + * pair from local table + */ +int nameserver_get(void *handle, const char *name, + void *buffer, u32 length, u16 proc_id[]) +{ + struct nameserver_object *temp_obj = NULL; + u16 max_proc_id; + u16 local_proc_id; + s32 retval = -ENOENT; + u32 i; + + BUG_ON(handle == NULL); + BUG_ON(name == NULL); + BUG_ON(buffer == NULL); + if (WARN_ON(length == 0)) { + retval = -EINVAL; + goto exit; + } + + temp_obj = (struct nameserver_object *)handle; + max_proc_id = multiproc_get_max_processors(); + local_proc_id = multiproc_get_id(NULL); + if (proc_id == NULL) { + retval = nameserver_get_local(temp_obj, name, + buffer, length); + if (retval > 0) /* Got the value */ + goto exit; + + for (i = 0; i < max_proc_id; i++) { + /* Skip current processor */ + if (i == local_proc_id) + continue; + + if (nameserver_state.remote_handle_list[i] == NULL) + continue; + + retval = nameserver_remote_get( + nameserver_state.remote_handle_list[i], + temp_obj->name, name, buffer, length); + if (retval > 0 || ((retval < 0) && + (retval != -ENOENT))) /* Got the value */ + break; + } + goto exit; + } + + for (i = 0; i < max_proc_id; i++) { + /* Skip processor with invalid id */ + if (proc_id[i] == MULTIPROC_INVALIDID) + continue; + + if (i == local_proc_id) { + retval = nameserver_get_local(temp_obj, + name, buffer, length); + if (retval > 0) + break; + + } else { + retval = nameserver_remote_get( + nameserver_state.remote_handle_list[proc_id[i]], + temp_obj->name, name, buffer, length); + if (retval > 0 || ((retval < 0) && + (retval != -ENOENT))) /* Got the value */ + break; + } + } + +exit: + if (retval < 0) + printk(KERN_ERR "nameserver_get failed: status=%x \n", retval); + return retval; +} +EXPORT_SYMBOL(nameserver_get); + +/* + * ======== nameserver_get ======== + * Purpose: + * This will etrieve the value portion of a name/value + * pair from local table + * + * Returns the number of characters that matched with an entry + * So if "abc" was an entry and you called match with "abcd", this + * function will have the "abc" entry. The return would be 3 since + * three characters matched + * + */ +int nameserver_match(void *handle, const char *name, u32 *value) +{ + struct nameserver_object *temp_obj = NULL; + struct nameserver_entry *node = NULL; + s32 retval = 0; + u32 hash; + bool found = false; + + BUG_ON(handle == NULL); + BUG_ON(name == NULL); + BUG_ON(value == NULL); + + temp_obj = (struct nameserver_object *)handle; + retval = mutex_lock_interruptible(temp_obj->gate_handle); + if (retval) + goto exit; + + hash = nameserver_string_hash(name); + list_for_each_entry(node, &temp_obj->name_list, elem) { + if (node->hash == hash) { + *value = *(u32 *)node->buf; + found = true; + } + } + + if (found == false) + retval = -ENOENT; + + mutex_unlock(temp_obj->gate_handle); + +exit: + if (retval < 0) + printk(KERN_ERR "nameserver_match failed status:%x \n", retval); + return retval; +} +EXPORT_SYMBOL(nameserver_match); + +/* + * ======== nameserver_register_remote_driver ======== + * Purpose: + * This will register a remote driver for a processor + */ +int nameserver_register_remote_driver(void *handle, u16 proc_id) +{ + struct nameserver_remote_object *temp = NULL; + s32 retval = 0; + u16 proc_count; + + BUG_ON(handle == NULL); + proc_count = multiproc_get_max_processors(); + if (WARN_ON(proc_id >= proc_count)) { + retval = -EINVAL; + goto exit; + } + + temp = (struct nameserver_remote_object *)handle; + nameserver_state.remote_handle_list[proc_id] = temp; + return 0; + +exit: + printk(KERN_ERR + "nameserver_register_remote_driver failed status:%x \n", + retval); + return retval; +} +EXPORT_SYMBOL(nameserver_register_remote_driver); + +/* + * ======== nameserver_unregister_remote_driver ======== + * Purpose: + * This will unregister a remote driver for a processor + */ +int nameserver_unregister_remote_driver(u16 proc_id) +{ + s32 retval = 0; + u16 proc_count; + + proc_count = multiproc_get_max_processors(); + if (WARN_ON(proc_id >= proc_count)) { + retval = -EINVAL; + goto exit; + } + + nameserver_state.remote_handle_list[proc_id] = NULL; + return 0; + +exit: + printk(KERN_ERR + "nameserver_unregister_remote_driver failed status:%x \n", + retval); + return retval; +} +EXPORT_SYMBOL(nameserver_unregister_remote_driver); + diff --git a/drivers/dsp/syslink/multicore_ipc/nameserver_ioctl.c b/drivers/dsp/syslink/multicore_ipc/nameserver_ioctl.c new file mode 100755 index 000000000000..1564fb61fd26 --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/nameserver_ioctl.c @@ -0,0 +1,597 @@ +/* +* nameserver_ioctl.c +* +* This provides the ioctl interface for nameserver module +* +* Copyright (C) 2008-2009 Texas Instruments, Inc. +* +* This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR +* PURPOSE. +*/ +#include <linux/uaccess.h> +#include <linux/types.h> +#include <linux/bug.h> +#include <linux/fs.h> +#include <linux/mm.h> +#include <nameserver.h> +#include <nameserver_ioctl.h> + +/* + * FUNCTIONS NEED TO BE REVIEWED OPTIMIZED! + */ + +/* + * ======== nameserver_ioctl_setup ======== + * Purpose: + * This wrapper function will call the nameserver function to + * setup nameserver module + */ +static int nameserver_ioctl_setup( + struct nameserver_cmd_args *cargs) +{ + cargs->api_status = nameserver_setup(); + return 0; +} + +/* + * ======== nameserver_ioctl_destroy ======== + * Purpose: + * This wrapper function will call the nameserver function to + * destroy nameserver module + */ +static int nameserver_ioctl_destroy( + struct nameserver_cmd_args *cargs) +{ + cargs->api_status = nameserver_destroy(); + return 0; +} + +/* + * ======== nameserver_ioctl_params_init ======== + * Purpose: + * This wrapper function will call the nameserver function to + * get the default configuration of a nameserver instance + */ +static int nameserver_ioctl_params_init(struct nameserver_cmd_args *cargs) +{ + struct nameserver_params params; + s32 status = 0; + ulong size; + + cargs->api_status = nameserver_params_init(¶ms); + size = copy_to_user(cargs->args.params_init.params, ¶ms, + sizeof(struct nameserver_params)); + if (size) + status = -EFAULT; + + return status; +} + +/* + * ======== nameserver_ioctl_get_handle ======== + * Purpose: + * This wrapper function will call the nameserver function to + * get the handle of a nameserver instance from name + */ +static int nameserver_ioctl_get_handle(struct nameserver_cmd_args *cargs) +{ + void *handle = NULL; + char *name = NULL; + s32 status = 0; + ulong size; + + name = kmalloc(cargs->args.get_handle.name_len + 1, GFP_KERNEL); + if (name == NULL) { + status = -ENOMEM; + goto exit; + } + + name[cargs->args.get_handle.name_len] = '\0'; + size = copy_from_user(name, cargs->args.get_handle.name, + cargs->args.get_handle.name_len); + if (size) { + status = -EFAULT; + goto name_from_usr_error; + } + + handle = nameserver_get_handle(name); + cargs->args.get_handle.handle = handle; + cargs->api_status = 0; + +name_from_usr_error: + kfree(name); + +exit: + return status; +} + +/* + * ======== nameserver_ioctl_create ======== + * Purpose: + * This wrapper function will call the nameserver function to + * create a name server instance + */ +static int nameserver_ioctl_create(struct nameserver_cmd_args *cargs) +{ + struct nameserver_params params; + void *handle = NULL; + char *name = NULL; + s32 status = 0; + ulong size; + + name = kmalloc(cargs->args.create.name_len + 1, GFP_KERNEL); + if (name == NULL) { + status = -ENOMEM; + goto exit; + } + + name[cargs->args.get_handle.name_len] = '\0'; + size = copy_from_user(name, cargs->args.create.name, + cargs->args.create.name_len); + if (size) { + status = -EFAULT; + goto copy_from_usr_error; + } + + size = copy_from_user(¶ms, cargs->args.create.params, + sizeof(struct nameserver_params)); + if (size) { + status = -EFAULT; + goto copy_from_usr_error; + } + + handle = nameserver_create(name, ¶ms); + cargs->args.create.handle = handle; + cargs->api_status = 0; + +copy_from_usr_error: + kfree(name); + +exit: + return status; +} + + +/* + * ======== nameserver_ioctl_delete ======== + * Purpose: + * This wrapper function will call the nameserver function to + * delete a name server instance + */ +static int nameserver_ioctl_delete(struct nameserver_cmd_args *cargs) +{ + cargs->api_status = + nameserver_delete(&cargs->args.delete_instance.handle); + return 0; +} + +/* + * ======== nameserver_ioctl_add ======== + * Purpose: + * This wrapper function will call the nameserver function to + * add an entry into a nameserver instance + */ +static int nameserver_ioctl_add(struct nameserver_cmd_args *cargs) +{ + char *name = NULL; + char *buf = NULL; + void *entry; + s32 status = 0; + ulong size; + + name = kmalloc(cargs->args.add.name_len + 1, GFP_KERNEL); + if (name == NULL) { + status = -ENOMEM; + goto exit; + } + + name[cargs->args.get_handle.name_len] = '\0'; + size = copy_from_user(name, cargs->args.add.name, + cargs->args.add.name_len); + if (size) { + status = -EFAULT; + goto name_from_usr_error; + } + + buf = kmalloc(cargs->args.add.len, GFP_KERNEL); + if (buf == NULL) { + status = -ENOMEM; + goto buf_alloc_error; + } + + size = copy_from_user(buf, cargs->args.add.buf, + cargs->args.add.len); + if (size) { + status = -EFAULT; + goto buf_from_usr_error; + } + + entry = nameserver_add(cargs->args.add.handle, name, buf, + cargs->args.add.len); + cargs->args.add.entry = entry; + cargs->args.add.node = entry; + cargs->api_status = 0; + +buf_from_usr_error: + kfree(buf); + +buf_alloc_error: /* Fall through */ +name_from_usr_error: + kfree(name); + +exit: + return status; +} + + +/* + * ======== nameserver_ioctl_add_uint32 ======== + * Purpose: + * This wrapper function will call the nameserver function to + * add a Uint32 entry into a nameserver instance + */ +static int nameserver_ioctl_add_uint32(struct nameserver_cmd_args *cargs) +{ + char *name = NULL; + void *entry; + s32 status = 0; + ulong size; + + name = kmalloc(cargs->args.addu32.name_len + 1, GFP_KERNEL); + if (name == NULL) { + status = -ENOMEM; + goto exit; + } + + name[cargs->args.get_handle.name_len] = '\0'; + size = copy_from_user(name, cargs->args.addu32.name, + cargs->args.addu32.name_len); + if (size) { + status = -EFAULT; + goto name_from_usr_error; + } + + entry = nameserver_add_uint32(cargs->args.addu32.handle, name, + cargs->args.addu32.value); + cargs->args.addu32.entry = entry; + cargs->api_status = 0; + +name_from_usr_error: + kfree(name); + +exit: + return status; +} + + +/* + * ======== nameserver_ioctl_match ======== + * Purpose: + * This wrapper function will call the nameserver function + * to retrieve the value portion of a name/value + * pair from local table + */ +static int nameserver_ioctl_match(struct nameserver_cmd_args *cargs) +{ + char *name = NULL; + u32 buf; + s32 status = 0; + ulong size; + + name = kmalloc(cargs->args.match.name_len + 1, GFP_KERNEL); + if (name == NULL) { + status = -ENOMEM; + goto exit; + } + + name[cargs->args.get_handle.name_len] = '\0'; + size = copy_from_user(name, cargs->args.match.name, + cargs->args.match.name_len); + if (size) { + status = -EFAULT; + goto name_from_usr_error; + } + + cargs->api_status = + nameserver_match(cargs->args.match.handle, name, &buf); + size = copy_to_user(cargs->args.match.value, &buf, sizeof(u32 *)); + if (size) { + status = -EFAULT; + goto buf_to_usr_error; + } + +buf_to_usr_error: /* Fall through */ +name_from_usr_error: + kfree(name); + +exit: + return status; +} + +/* + * ======== nameserver_ioctl_remove ======== + * Purpose: + * This wrapper function will call the nameserver function to + * remove a name/value pair from a name server + */ +static int nameserver_ioctl_remove(struct nameserver_cmd_args *cargs) +{ + char *name = NULL; + s32 status = 0; + ulong size; + + name = kmalloc(cargs->args.remove.name_len + 1, GFP_KERNEL); + if (name == NULL) { + status = -ENOMEM; + goto exit; + } + + name[cargs->args.get_handle.name_len] = '\0'; + size = copy_from_user(name, cargs->args.remove.name, + cargs->args.remove.name_len); + if (size) { + status = -EFAULT; + goto name_from_usr_error; + } + + cargs->api_status = + nameserver_remove(cargs->args.remove.handle, name); + +name_from_usr_error: + kfree(name); + +exit: + return status; +} + + +/* + * ======== nameserver_ioctl_remove_entry ======== + * Purpose: + * This wrapper function will call the nameserver function to + * remove an entry from a name server + */ +static int nameserver_ioctl_remove_entry(struct nameserver_cmd_args *cargs) +{ + cargs->api_status = nameserver_remove_entry( + cargs->args.remove_entry.handle, + cargs->args.remove_entry.entry); + return 0; +} + +/* + * ======== nameserver_ioctl_get_local ======== + * Purpose: + * This wrapper function will call the nameserver function to + * retrieve the value portion of a name/value pair from local table + */ +static int nameserver_ioctl_get_local(struct nameserver_cmd_args *cargs) +{ + char *name = NULL; + char *buf = NULL; + s32 status = 0; + ulong size; + + name = kmalloc(cargs->args.get_local.name_len + 1, GFP_KERNEL); + if (name == NULL) { + status = -ENOMEM; + goto exit; + } + + name[cargs->args.get_handle.name_len] = '\0'; + buf = kmalloc(cargs->args.get_local.len, GFP_KERNEL); + if (buf == NULL) { + status = -ENOMEM; + goto buf_alloc_error; + } + + size = copy_from_user(name, cargs->args.get_local.name, + cargs->args.get_local.name_len); + if (size) { + status = -EFAULT; + goto name_from_usr_error; + } + + cargs->api_status = nameserver_get_local( + cargs->args.get_local.handle, name, + buf, cargs->args.get_local.len); + size = copy_to_user(cargs->args.get_local.buf, buf, + cargs->args.get_local.len); + if (size) + status = -EFAULT; + +name_from_usr_error: + kfree(buf); + +buf_alloc_error: + kfree(name); + +exit: + return status; +} + + +/* + * ======== nameserver_ioctl_get ======== + * Purpose: + * This wrapper function will call the nameserver function to + * retrieve the value portion of a name/value pair from table + */ +static int nameserver_ioctl_get(struct nameserver_cmd_args *cargs) +{ + char *name = NULL; + char *buf = NULL; + u16 *proc_id = NULL; + s32 status = 0; + ulong size; + + name = kmalloc(cargs->args.get.name_len + 1, GFP_KERNEL); + if (name == NULL) { + status = -ENOMEM; + goto exit; + } + + name[cargs->args.get_handle.name_len] = '\0'; + buf = kmalloc(cargs->args.get.len, GFP_KERNEL); + if (buf == NULL) { + status = -ENOMEM; + goto buf_alloc_error; + } + + proc_id = kmalloc(cargs->args.get.proc_len, GFP_KERNEL); + if (proc_id == NULL) { + status = -ENOMEM; + goto proc_alloc_error; + } + + size = copy_from_user(name, cargs->args.get.name, + cargs->args.get.name_len); + if (size) { + status = -EFAULT; + goto name_from_usr_error; + } + + status = copy_from_user(proc_id, cargs->args.get.proc_id, + cargs->args.get.proc_len); + if (size) { + status = -EFAULT; + goto proc_from_usr_error; + } + + cargs->api_status = nameserver_get(cargs->args.get.handle, name, buf, + cargs->args.get.len, proc_id); + size = copy_to_user(cargs->args.get.buf, buf, + cargs->args.get.len); + if (size) + status = -EFAULT; + + +proc_from_usr_error: /* Fall through */ +name_from_usr_error: + kfree(proc_id); + +proc_alloc_error: + kfree(buf); + +buf_alloc_error: + kfree(name); + +exit: + return status; +} + +/* + * ======== nameserver_ioctl ======== + * Purpose: + * This ioctl interface for nameserver module + */ +int nameserver_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long args) +{ + s32 status = 0; + s32 size = 0; + struct nameserver_cmd_args __user *uarg = + (struct nameserver_cmd_args __user *)args; + struct nameserver_cmd_args cargs; + + + if (_IOC_DIR(cmd) & _IOC_READ) + status = !access_ok(VERIFY_WRITE, uarg, _IOC_SIZE(cmd)); + else if (_IOC_DIR(cmd) & _IOC_WRITE) + status = !access_ok(VERIFY_READ, uarg, _IOC_SIZE(cmd)); + + if (status) { + status = -EFAULT; + goto exit; + } + + /* Copy the full args from user-side */ + size = copy_from_user(&cargs, uarg, + sizeof(struct nameserver_cmd_args)); + if (size) { + status = -EFAULT; + goto exit; + } + + switch (cmd) { + case CMD_NAMESERVER_ADD: + status = nameserver_ioctl_add(&cargs); + break; + + case CMD_NAMESERVER_ADDUINT32: + status = nameserver_ioctl_add_uint32(&cargs); + break; + + case CMD_NAMESERVER_GET: + status = nameserver_ioctl_get(&cargs); + break; + + case CMD_NAMESERVER_GETLOCAL: + status = nameserver_ioctl_get_local(&cargs); + break; + + case CMD_NAMESERVER_MATCH: + status = nameserver_ioctl_match(&cargs); + break; + + case CMD_NAMESERVER_REMOVE: + status = nameserver_ioctl_remove(&cargs); + break; + + case CMD_NAMESERVER_REMOVEENTRY: + status = nameserver_ioctl_remove_entry(&cargs); + break; + + case CMD_NAMESERVER_PARAMS_INIT: + status = nameserver_ioctl_params_init(&cargs); + break; + + case CMD_NAMESERVER_CREATE: + status = nameserver_ioctl_create(&cargs); + break; + + case CMD_NAMESERVER_DELETE: + status = nameserver_ioctl_delete(&cargs); + break; + + case CMD_NAMESERVER_GETHANDLE: + status = nameserver_ioctl_get_handle(&cargs); + break; + + case CMD_NAMESERVER_SETUP: + status = nameserver_ioctl_setup(&cargs); + break; + + case CMD_NAMESERVER_DESTROY: + status = nameserver_ioctl_destroy(&cargs); + break; + + default: + WARN_ON(cmd); + status = -ENOTTY; + break; + } + + if ((cargs.api_status == -ERESTARTSYS) || (cargs.api_status == -EINTR)) + status = -ERESTARTSYS; + + if (status < 0) + goto exit; + + /* Copy the full args to the user-side. */ + size = copy_to_user(uarg, &cargs, sizeof(struct nameserver_cmd_args)); + if (size) { + status = -EFAULT; + goto exit; + } + +exit: + return status; +} + diff --git a/drivers/dsp/syslink/multicore_ipc/nameserver_remote.c b/drivers/dsp/syslink/multicore_ipc/nameserver_remote.c new file mode 100644 index 000000000000..43227996266a --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/nameserver_remote.c @@ -0,0 +1,49 @@ +/* + * nameserver_remote.c + * + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#include <linux/types.h> +#include <linux/slab.h> + +#include <nameserver_remote.h> + +/* + * ======== nameserver_remote_get ======== + * Purpose: + * This will get data from remote name server + */ +int nameserver_remote_get(const struct nameserver_remote_object *handle, + const char *instance_name, const char *name, + void *value, u32 value_len) +{ + s32 retval = 0; + + if (handle == NULL) { + retval = -EINVAL; + goto exit; + } + + if (WARN_ON((instance_name == NULL) || (name == NULL) + || (value == NULL))) { + retval = -EINVAL; + goto exit; + } + + retval = handle->get(handle, instance_name, + name, value, value_len, NULL); + +exit: + return retval; +} diff --git a/drivers/dsp/syslink/multicore_ipc/nameserver_remotenotify.c b/drivers/dsp/syslink/multicore_ipc/nameserver_remotenotify.c new file mode 100755 index 000000000000..68cdec953b5b --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/nameserver_remotenotify.c @@ -0,0 +1,721 @@ +/* + * nameserver_remotenotify.c + * + * The nameserver_remotenotify module provides functionality to get name + * value pair from a remote nameserver. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +/* Standard headers */ +#include <linux/types.h> + +/* Utilities headers */ +#include <linux/string.h> +#include <linux/mutex.h> +#include <linux/slab.h> +#include <linux/semaphore.h> + +/* Syslink headers */ +#include <syslink/atomic_linux.h> + +/* Module level headers */ +#include <gate_remote.h> +#include <gatepeterson.h> +#include <nameserver.h> +#include <multiproc.h> +#include <nameserver_remotenotify.h> +#include <notify.h> + + +/* + * Macro to make a correct module magic number with refCount + */ +#define NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(x) \ + ((NAMESERVERREMOTENOTIFY_MODULEID << 12u) | (x)) + +/* + * Cache line length + * TODO: Short-term hack. Make parameter or figure out some other way! + */ +#define NAMESERVERREMOTENOTIFY_CACHESIZE 128 + +/* + * Maximum length of value buffer that can be stored in the NameServer + * managed by this NameServerRemoteNotify instance. + */ +#define NAMESERVERREMOTENOTIFY_MAXVALUEBUFLEN 300 + +/* Defines the nameserver_remotenotify state object, which contains all the + * module specific information + */ +struct nameserver_remotenotify_module_object { + struct nameserver_remotenotify_config cfg; + struct nameserver_remotenotify_config def_cfg; + struct nameserver_remotenotify_params def_inst_params; + bool is_setup; + void *gate_handle; + atomic_t ref_count; +}; + +/* + * NameServer remote transport state attributes + */ +struct nameserver_remotenotify_attrs { + u32 version; + u32 status; + u32 shared_addr_size; +}; + +/* + * NameServer remote transport packet definition + */ +struct nameserver_remotenotify_message { + u32 request; + u32 response; + u32 request_status; + u32 value; + u32 value_len; + char instance_name[32]; + char name[32]; + char value_buf[NAMESERVERREMOTENOTIFY_MAXVALUEBUFLEN]; +}; + +/* + * NameServer remote transport state object definition + */ +struct nameserver_remotenotify_obj { + struct nameserver_remotenotify_attrs *attrs; + struct nameserver_remotenotify_message *msg[2]; + struct nameserver_remotenotify_params params; + u16 remote_proc_id; + struct mutex *local_gate; + struct semaphore *sem_handle; /* Binary semaphore */ +}; + +/* + * NameServer remote transport state object definition + */ +struct nameserver_remotenotify_object { + int (*get)(void *, + const char *instance_name, const char *name, + void *value, u32 value_len, void *reserved); + void *obj; /* Implementation specific object */ +}; + +/* + * nameserver_remotenotify state object variable + */ +static struct nameserver_remotenotify_module_object + nameserver_remotenotify_state = { + .is_setup = false, + .gate_handle = NULL, + .def_cfg.reserved = 0, + .def_inst_params.gate = NULL, + .def_inst_params.shared_addr = 0x0, + .def_inst_params.shared_addr_size = 0x0, + .def_inst_params.notify_event_no = (u32) -1, + .def_inst_params.notify_driver = NULL, +}; + +/* + * ======== nameserver_remotenotify_get_config ======== + * Purpose: + * This will get the default configuration for the nameserver remote + * module + * This function can be called by the application to get their + * configuration parameter to nameserver_remotenotify_setup filled + * in by the nameserver_remotenotify module with the default + * parameters. If the user does not wish to make any change in the + * default parameters, this API is not required to be called + */ +void nameserver_remotenotify_get_config( + struct nameserver_remotenotify_config *cfg) +{ + BUG_ON(cfg == NULL); + if (nameserver_remotenotify_state.is_setup == false) + memcpy(cfg, &(nameserver_remotenotify_state.def_cfg), + sizeof(struct nameserver_remotenotify_config)); + else + memcpy(cfg, &(nameserver_remotenotify_state.cfg), + sizeof(struct nameserver_remotenotify_config)); +} + + +/* + * ======== nameserver_remotenotify_setup ======== + * Purpose: + * This will setup the nameserver_remotenotify module + * This function sets up the nameserver_remotenotify module. This + * function must be called before any other instance-level APIs can + * be invoked + * Module-level configuration needs to be provided to this + * function. If the user wishes to change some specific config + * parameters, then nameserver_remotenotify_get_config can be called + * to get the configuration filled with the default values. After + * this, only the required configuration values can be changed. If + * the user does not wish to make any change in the default + * parameters, the application can simply call + * nameserver_remotenotify_setup with NULL parameters. The default + * parameters would get automatically used + */ +int nameserver_remotenotify_setup( + struct nameserver_remotenotify_config *cfg) +{ + struct nameserver_remotenotify_config tmp_cfg; + s32 retval = 0; + struct mutex *lock = NULL; + bool user_cfg = true; + + /* This sets the ref_count variable is not initialized, upper 16 bits is + * written with module Id to ensure correctness of refCount variable. + */ + atomic_cmpmask_and_set(&nameserver_remotenotify_state.ref_count, + NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(0), + NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(0)); + if (atomic_inc_return(&nameserver_remotenotify_state.ref_count) + != NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(1)) { + return 1; + } + + if (cfg == NULL) { + nameserver_remotenotify_get_config(&tmp_cfg); + cfg = &tmp_cfg; + user_cfg = false; + } + + /* Create a default gate handle for local module protection */ + lock = kmalloc(sizeof(struct mutex), GFP_KERNEL); + if (lock == NULL) { + retval = -ENOMEM; + goto exit; + } + + mutex_init(lock); + nameserver_remotenotify_state.gate_handle = lock; + if (user_cfg) + memcpy(&nameserver_remotenotify_state.cfg, cfg, + sizeof(struct nameserver_remotenotify_config)); + + nameserver_remotenotify_state.is_setup = true; + +exit: + return retval; +} + +/* + * ======== nameserver_remotenotify_destroy ======== + * Purpose: + * This will destroy the nameserver_remotenotify module. + * Once this function is called, other nameserver_remotenotify + * module APIs, except for the nameserver_remotenotify_get_config + * API cannot be called anymore. + */ +int nameserver_remotenotify_destroy(void) +{ + s32 retval = 0; + + if (WARN_ON(atomic_cmpmask_and_lt( + &(nameserver_remotenotify_state.ref_count), + NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(0), + NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(1)) == true)) { + retval = -ENODEV; + goto exit; + } + + if (!(atomic_dec_return(&nameserver_remotenotify_state.ref_count) + == NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(0))) { + retval = 1; + goto exit; + } + + if (nameserver_remotenotify_state.gate_handle != NULL) + kfree(nameserver_remotenotify_state.gate_handle); + + nameserver_remotenotify_state.is_setup = false; + return 0; + +exit: + return retval; +} + +/* + * ======== ameserver_remotenotify_params_init ======== + * Purpose: + * This will get the current configuration values + */ +void nameserver_remotenotify_params_init(void *handle, + struct nameserver_remotenotify_params *params) +{ + struct nameserver_remotenotify_object *object = NULL; + struct nameserver_remotenotify_obj *obj = NULL; + + if (atomic_cmpmask_and_lt(&(nameserver_remotenotify_state.ref_count), + NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(0), + NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(1)) == true) { + printk(KERN_ERR "nameserver_remotenotify_params_init failed: " + "Module is not initialized!\n"); + return; + } + + if (WARN_ON(params == NULL)) { + printk(KERN_ERR "nameserver_remotenotify_params_init failed: " + "Argument of type(nameserver_remotenotify_params *) " + "is NULL!\n"); + return; + } + + object = (struct nameserver_remotenotify_object *)handle; + if (handle == NULL) + memcpy(params, + &(nameserver_remotenotify_state.def_inst_params), + sizeof(struct nameserver_remotenotify_params)); + else { + obj = (struct nameserver_remotenotify_obj *)object->obj; + /* Return updated nameserver_remotenotify instance specific + * parameters. + */ + memcpy(params, &(obj->params), + sizeof(struct nameserver_remotenotify_params)); + } +} + + +/* + * ======== nameserver_remotenotify_callback ======== + * Purpose: + * This will be called when a notify event is received + */ +void nameserver_remotenotify_callback(u16 proc_id, u32 event_no, + void *arg, u32 payload) +{ + struct nameserver_remotenotify_obj *handle = NULL; + u32 proc_count; + u16 offset = 0; + void *nshandle = NULL; + u32 value_len; + u32 key; + s32 retval = 0; + s32 count = -ENOENT; + + if (atomic_cmpmask_and_lt(&(nameserver_remotenotify_state.ref_count), + NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(0), + NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto exit; + } + + if (WARN_ON(arg == NULL)) { + retval = -EINVAL; + goto exit; + } + + proc_count = multiproc_get_max_processors(); + if (WARN_ON(proc_id >= proc_count)) { + retval = -EINVAL; + goto exit; + } + + handle = (struct nameserver_remotenotify_obj *)arg; + if ((multiproc_get_id(NULL) > proc_id)) + offset = 1; + + if (handle->msg[1 - offset]->request != true) + goto signal_response; + + /* This is a request */ + value_len = handle->msg[1 - offset]->value_len; + nshandle = nameserver_get_handle( + handle->msg[1 - offset]->instance_name); + if (nshandle != NULL) { + /* Search for the NameServer entry */ + if (value_len == sizeof(u32)) { + count = nameserver_get_local(nshandle, + handle->msg[1 - offset]->name, + &handle->msg[1 - offset]->value, + value_len); + } else { + count = nameserver_get_local(nshandle, + handle->msg[1 - offset]->name, + &handle->msg[1 - offset]->value_buf, + value_len); + } + } + + key = gatepeterson_enter(handle->params.gate); + /* If retval > 0 then an entry found */ + if (count != -ENOENT) + handle->msg[1 - offset]->request_status = true; + + /* Send a response back */ + handle->msg[1 - offset]->response = true; + handle->msg[1 - offset]->request = false; + /* now we can leave the gate */ + gatepeterson_leave(handle->params.gate, key); + + /* + * The NotifyDriver handle must exists at this point, + * otherwise the notify_sendEvent should have failed + */ + retval = notify_sendevent(handle->params.notify_driver, + proc_id, event_no, 0, true); + +signal_response: + if (handle->msg[offset]->response == true) + up(handle->sem_handle); +exit: + if (retval < 0) { + printk(KERN_ERR "nameserver_remotenotify_callback failed! " + "status = 0x%x\n", retval); + } + return; +} + +/* + * ======== nameserver_remotenotify_get ======== + * Purpose: + * This will get a remote name value pair + */ +int nameserver_remotenotify_get(void *rhandle, + const char *instance_name, const char *name, + void *value, u32 value_len, void *reserved) +{ + struct nameserver_remotenotify_object *handle = NULL; + struct nameserver_remotenotify_obj *obj = NULL; + s32 offset = 0; + s32 len; + u32 key; + s32 retval = 0; + + BUG_ON(instance_name == NULL); + BUG_ON(name == NULL); + BUG_ON(value == NULL); + BUG_ON((value_len <= 0) || \ + (value_len > NAMESERVERREMOTENOTIFY_MAXVALUEBUFLEN)); + + if (atomic_cmpmask_and_lt(&(nameserver_remotenotify_state.ref_count), + NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(0), + NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto exit; + } + + if (WARN_ON(rhandle == NULL)) { + retval = -EINVAL; + goto exit; + } + + if ((value_len == 0) || \ + (value_len > NAMESERVERREMOTENOTIFY_MAXVALUEBUFLEN)) { + retval = -EINVAL; + goto exit; + } + + handle = (struct nameserver_remotenotify_object *)rhandle; + obj = (struct nameserver_remotenotify_obj *)handle->obj; + if (multiproc_get_id(NULL) > obj->remote_proc_id) + offset = 1; + + key = gatepeterson_enter(obj->params.gate); + /* This is a request message */ + obj->msg[offset]->request = 1; + obj->msg[offset]->response = 0; + obj->msg[offset]->request_status = 0; + obj->msg[offset]->value_len = value_len; + len = strlen(instance_name) + 1; /* Take termination null char */ + if (len >= 32) { + retval = -EINVAL; + goto inval_len_error; + } + strncpy(obj->msg[offset]->instance_name, instance_name, len); + len = strlen(name); + if (len >= 32) { + retval = -EINVAL; + goto inval_len_error; + } + strncpy(obj->msg[offset]->name, name, len); + + /* Send the notification to remote processor */ + retval = notify_sendevent(obj->params.notify_driver, + obj->remote_proc_id, + obj->params.notify_event_no, + 0, /* Payload */ + false); /* Not sending a payload */ + if (retval < 0) { + /* Undo previous operations */ + obj->msg[offset]->request = 0; + obj->msg[offset]->value_len = 0; + goto notify_error; + } + + gatepeterson_leave(obj->params.gate, key); + + /* Pend on the semaphore */ + retval = down_interruptible(obj->sem_handle); + if (retval) { + goto exit; + } + + key = gatepeterson_enter(obj->params.gate); + if (obj->msg[offset]->request_status != true) { + retval = -ENOENT; + goto request_error; + } + + if (!value_len) { + retval = -ENOENT; + goto request_error; + } + + if (value_len == sizeof(u32)) + memcpy((void *)value, (void *) &(obj->msg[offset]->value), + sizeof(u32)); + else + memcpy((void *)value, (void *)&(obj->msg[offset]->value_buf), + value_len); + + obj->msg[offset]->request_status = false; + obj->msg[offset]->request = 0; + obj->msg[offset]->response = 0; + retval = value_len; + +inval_len_error: +notify_error: +request_error: + gatepeterson_leave(obj->params.gate, key); +exit: + return retval; +} + +/* + * ======== nameServer_remote_notify_params_init ======== + * Purpose: + * This will get the current configuration values + */ +int nameServer_remote_notify_params_init( + struct nameserver_remotenotify_params *params) +{ + BUG_ON(params == NULL); + + params->notify_event_no = 0; + params->notify_driver = NULL; + params->shared_addr = NULL; + params->shared_addr_size = 0; + params->gate = NULL; + return 0; +} + +/* + * ======== nameserver_remotenotify_create ======== + * Purpose: + * This will setup the nameserver remote module + */ +void *nameserver_remotenotify_create(u16 proc_id, + const struct nameserver_remotenotify_params *params) +{ + struct nameserver_remotenotify_object *handle = NULL; + struct nameserver_remotenotify_obj *obj = NULL; + u16 proc_count; + s32 retval = 0; + s32 retval1 = 0; + u32 offset = 0; + + if (atomic_cmpmask_and_lt(&(nameserver_remotenotify_state.ref_count), + NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(0), + NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto exit; + } + + if (WARN_ON(params == NULL)) { + retval = -EINVAL; + goto exit; + } + + if (WARN_ON(params->notify_driver == NULL || + params->shared_addr == NULL || + params->shared_addr_size == 0)) { + retval = -EINVAL; + goto exit; + } + + proc_count = multiproc_get_max_processors(); + if (proc_id >= proc_count) { + retval = -EINVAL; + goto exit; + } + + obj = kmalloc(sizeof(struct nameserver_remotenotify_obj), GFP_KERNEL); + handle = kmalloc(sizeof(struct nameserver_remotenotify_object), + GFP_KERNEL); + if (obj == NULL || handle == NULL) { + retval = -ENOMEM; + goto mem_error; + } + + handle->get = nameserver_remotenotify_get; + handle->obj = (void *)obj; + obj->local_gate = kmalloc(sizeof(struct mutex), GFP_KERNEL); + if (obj->local_gate == NULL) { + retval = -ENOMEM; + goto mem_error; + } + + obj->remote_proc_id = proc_id; + if (multiproc_get_id(NULL) > proc_id) + offset = 1; + + obj->attrs = (struct nameserver_remotenotify_attrs *) + params->shared_addr; + obj->msg[0] = (struct nameserver_remotenotify_message *) + ((u32)obj->attrs + + NAMESERVERREMOTENOTIFY_CACHESIZE); + obj->msg[1] = (struct nameserver_remotenotify_message *) + ((u32)obj->msg[0] + + sizeof(struct + nameserver_remotenotify_message)); + /* Clear out self shared structures */ + memset(obj->msg[offset], 0, + sizeof(struct nameserver_remotenotify_message)); + memcpy(&obj->params, params, + sizeof(struct nameserver_remotenotify_params)); + retval = notify_register_event(params->notify_driver, proc_id, + params->notify_event_no, + nameserver_remotenotify_callback, + (void *)obj); + if (retval < 0) + goto notify_error; + + retval = nameserver_register_remote_driver((void *)handle, proc_id); + obj->sem_handle = kmalloc(sizeof(struct semaphore), GFP_KERNEL); + if (obj->sem_handle == NULL) { + retval = -ENOMEM; + goto sem_alloc_error; + } + + sema_init(obj->sem_handle, 0); + /* its is at the end since its init state = unlocked? */ + mutex_init(obj->local_gate); + return (void *)handle; + +sem_alloc_error: + nameserver_unregister_remote_driver(proc_id); + /* Do we want to check the staus ? */ + retval1 = notify_unregister_event(obj->params.notify_driver, + obj->remote_proc_id, + obj->params.notify_event_no, + nameserver_remotenotify_callback, + (void *)obj); + +notify_error: + kfree(obj->local_gate); + +mem_error: + kfree(obj); + kfree(handle); + +exit: + printk(KERN_ERR "nameserver_remotenotify_create failed! " + "status = 0x%x\n", retval); + return NULL; +} + + +/* + * ======== nameserver_remotenotify_create ======== + * Purpose: + * This will delete the nameserver remote transport instance + */ +int nameserver_remotenotify_delete(void **rhandle) +{ + struct nameserver_remotenotify_object *handle = NULL; + struct nameserver_remotenotify_obj *obj = NULL; + s32 retval = 0; + struct mutex *gate = NULL; + + if (atomic_cmpmask_and_lt(&(nameserver_remotenotify_state.ref_count), + NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(0), + NAMESERVERREMOTENOTIFY_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto exit; + } + + if (WARN_ON((rhandle == NULL) || (*rhandle == NULL))) { + retval = -EINVAL; + goto exit; + } + + handle = (struct nameserver_remotenotify_object *)(*rhandle); + obj = (struct nameserver_remotenotify_obj *)handle->obj; + if (obj == NULL) { + retval = -EINVAL; + goto exit; + } + + retval = mutex_lock_interruptible(obj->local_gate); + if (retval) + goto exit; + + retval = nameserver_unregister_remote_driver(obj->remote_proc_id); + /* Do we have to bug_on/warn_on oops here intead of exit ?*/ + if (retval < 0) + goto exit; + + kfree(obj->sem_handle); + obj->sem_handle = NULL; + /* Unregister the event from Notify */ + retval = notify_unregister_event(obj->params.notify_driver, + obj->remote_proc_id, + obj->params.notify_event_no, + nameserver_remotenotify_callback, + (void *)obj); + if (retval == NOTIFY_SUCCESS) + retval = 0; + gate = obj->local_gate; + kfree(obj); + kfree(handle); + *rhandle = NULL; + mutex_unlock(gate); + kfree(gate); + +exit: + if (retval < 0) { + printk(KERN_ERR "nameserver_remotenotify_delete failed! " + "status = 0x%x\n", retval); + } + return retval; +} + + +/* + * ======== nameserver_remotenotify_create ======== + * Purpose: + * This will give shared memory requirements for the + * nameserver remote transport instance + */ +u32 nameserver_remotenotify_shared_memreq(const + struct nameserver_remotenotify_params *params) +{ + u32 total_size; + /* params is not used- to remove warning. */ + (void)params; + + BUG_ON(params == NULL); + /* + * The attrs takes a Ipc_cacheSize plus 2 Message structs are required. + * One for sending request and one for sending response. + */ + total_size = NAMESERVERREMOTENOTIFY_CACHESIZE + + (2 * sizeof(struct nameserver_remotenotify_message)); + return total_size; +} + diff --git a/drivers/dsp/syslink/multicore_ipc/nameserver_remotenotify_ioctl.c b/drivers/dsp/syslink/multicore_ipc/nameserver_remotenotify_ioctl.c new file mode 100755 index 000000000000..934b47c068f9 --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/nameserver_remotenotify_ioctl.c @@ -0,0 +1,346 @@ +/* + * nameserver_remotenotify_ioctl.h + * + * The nameserver_remotenotify module provides functionality to get name + * value pair from a remote nameserver. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#include <linux/uaccess.h> +#include <linux/types.h> +#include <linux/bug.h> +#include <linux/fs.h> +#include <linux/mm.h> +#include <sharedregion.h> +#include <nameserver_remotenotify_ioctl.h> + +/* + * ======== nameserver_remotenotify_ioctl_get ====== + * Purpose: + * This ioctl interface to nameserver_remotenotify_get function + */ +static int nameserver_remotenotify_ioctl_get( + struct nameserver_remotenotify_cmd_args *cargs) +{ + s32 status = 0; + ulong size; + char *instance_name = NULL; + char *name = NULL; + u8 *value = NULL; + + BUG_ON(cargs->args.get.instance_name_len == 0); + if (cargs->args.get.instance_name_len) { + instance_name = kmalloc(cargs->args.get.instance_name_len + 1, + GFP_KERNEL); + if (instance_name == NULL) { + status = ENOMEM; + goto exit; + } + + instance_name[cargs->args.get.instance_name_len] = '\0'; + size = copy_from_user(instance_name, + cargs->args.get.instance_name, + cargs->args.get.instance_name_len); + if (size) { + status = -ENOMEM; + goto exit; + } + } + + if (cargs->args.get.name_len) { + name = kmalloc(cargs->args.get.name_len + 1, + GFP_KERNEL); + if (name == NULL) { + status = ENOMEM; + goto exit; + } + + instance_name[cargs->args.get.instance_name_len] = '\0'; + size = copy_from_user(name, cargs->args.get.name, + cargs->args.get.name_len); + if (size) { + status = -ENOMEM; + goto exit; + } + } + + /* Allocate memory for the value */ + if (cargs->args.get.value_len >= 0) { + value = kmalloc(cargs->args.get.value_len, GFP_KERNEL); + size = copy_from_user(value, cargs->args.get.value, + cargs->args.get.value_len); + if (size) { + status = -ENOMEM; + goto exit; + } + } + + cargs->args.get.len = nameserver_remotenotify_get( + cargs->args.get.handle, + instance_name, + name, + value, + cargs->args.get.value_len, + cargs->args.get.reserved); + cargs->api_status = 0; + +exit: + kfree(value); + kfree(name); + kfree(instance_name); + return status; +} + +/* + * ======== nameserver_remotenotify_ioctl_shared_memreq ====== + * Purpose: + * This ioctl interface to nameserver_remotenotify_shared_memreq function + */ +static int nameserver_remotenotify_ioctl_shared_memreq( + struct nameserver_remotenotify_cmd_args *cargs) +{ + struct nameserver_remotenotify_params params; + s32 status = 0; + ulong size; + + /* params may be NULL. */ + if (cargs->args.shared_memreq.params != NULL) { + size = copy_from_user(¶ms, + cargs->args.shared_memreq.params, + sizeof(struct nameserver_remotenotify_params)); + if (size) { + status = -EFAULT; + goto exit; + } + } + + cargs->args.shared_memreq.shared_mem_size = + nameserver_remotenotify_shared_memreq(¶ms); + cargs->api_status = 0; + +exit: + return status; +} + +/* + * ======== nameserver_remotenotify_ioctl_params_init ======== + * Purpose: + * This ioctl interface to nameserver_remotenotify_params_init function + */ +static int nameserver_remotenotify_ioctl_params_init( + struct nameserver_remotenotify_cmd_args *cargs) +{ + struct nameserver_remotenotify_params params; + s32 status = 0; + ulong size; + + nameserver_remotenotify_params_init(cargs->args.params_init.handle, + ¶ms); + size = copy_to_user(cargs->args.params_init.params, ¶ms, + sizeof(struct nameserver_remotenotify_params)); + if (size) + status = -EFAULT; + + cargs->api_status = 0; + return status; +} + +/* + * ======== nameserver_remotenotify_ioctl_create======== + * Purpose: + * This ioctl interface to nameserver_remotenotify_create function + */ +static int nameserver_remotenotify_ioctl_create( + struct nameserver_remotenotify_cmd_args *cargs) +{ + struct nameserver_remotenotify_params params; + s32 status = 0; + ulong size; + size = copy_from_user(¶ms, cargs->args.create.params, + sizeof(struct nameserver_remotenotify_params)); + if (size) { + status = -EFAULT; + goto exit; + } + + params.shared_addr = sharedregion_get_ptr((u32 *) + cargs->args.create.params->shared_addr); + cargs->args.create.handle = nameserver_remotenotify_create( + cargs->args.create.proc_id, + ¶ms); + cargs->api_status = 0; +exit: + return status; +} + +/* + * ======== nameserver_remotenotify_ioctl_delete ======== + * Purpose: + * This ioctl interface to nameserver_remotenotify_delete function + */ +static int nameserver_remotenotify_ioctl_delete( + struct nameserver_remotenotify_cmd_args *cargs) +{ + cargs->api_status = nameserver_remotenotify_delete( + &cargs->args.delete_instance.handle); + return 0; +} + +/* + * ======== nameserver_remotenotify_ioctl_get_config ======== + * Purpose: + * This ioctl interface to nameserver_remotenotify_get_config function + */ +static int nameserver_remotenotify_ioctl_get_config( + struct nameserver_remotenotify_cmd_args *cargs) +{ + s32 status = 0; + ulong size; + struct nameserver_remotenotify_config config; + + nameserver_remotenotify_get_config(&config); + size = copy_to_user(cargs->args.get_config.config, &config, + sizeof(struct nameserver_remotenotify_config)); + if (size) + status = -EFAULT; + + cargs->api_status = 0; + return status; +} + +/* + * ======== nameserver_remotenotify_ioctl_setup ======== + * Purpose: + * This ioctl interface to nameserver_remotenotify_setup function + */ +static int nameserver_remotenotify_ioctl_setup( + struct nameserver_remotenotify_cmd_args *cargs) +{ + struct nameserver_remotenotify_config config; + s32 status = 0; + ulong size; + + size = copy_from_user(&config, cargs->args.setup.config, + sizeof(struct nameserver_remotenotify_config)); + if (size) { + status = -EFAULT; + goto exit; + } + + cargs->api_status = nameserver_remotenotify_setup(&config); +exit: + return status; +} + + +/* + * ======== nameserver_remotenotify_ioctl_destroy ======== + * Purpose: + * This ioctl interface to nameserver_remotenotify_destroy function + */ +static int nameserver_remotenotify_ioctl_destroy( + struct nameserver_remotenotify_cmd_args *cargs) +{ + cargs->api_status = nameserver_remotenotify_destroy(); + return 0; +} + +/* + * ======== nameserver_remotenotify_ioctl ======== + * Purpose: + * This ioctl interface for nameserver_remotenotify module + */ +int nameserver_remotenotify_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long args) +{ + s32 status = 0; + s32 size = 0; + struct nameserver_remotenotify_cmd_args __user *uarg = + (struct nameserver_remotenotify_cmd_args __user *)args; + struct nameserver_remotenotify_cmd_args cargs; + + if (_IOC_DIR(cmd) & _IOC_READ) + status = !access_ok(VERIFY_WRITE, uarg, _IOC_SIZE(cmd)); + else if (_IOC_DIR(cmd) & _IOC_WRITE) + status = !access_ok(VERIFY_READ, uarg, _IOC_SIZE(cmd)); + + if (status) { + status = -EFAULT; + goto exit; + } + + /* Copy the full args from user-side */ + size = copy_from_user(&cargs, uarg, + sizeof(struct nameserver_remotenotify_cmd_args)); + if (size) { + status = -EFAULT; + goto exit; + } + + switch (cmd) { + case CMD_NAMESERVERREMOTENOTIFY_GET: + status = nameserver_remotenotify_ioctl_get(&cargs); + break; + + case CMD_NAMESERVERREMOTENOTIFY_SHAREDMEMREQ: + status = nameserver_remotenotify_ioctl_shared_memreq(&cargs); + break; + + case CMD_NAMESERVERREMOTENOTIFY_PARAMS_INIT: + status = nameserver_remotenotify_ioctl_params_init(&cargs); + break; + + case CMD_NAMESERVERREMOTENOTIFY_CREATE: + status = nameserver_remotenotify_ioctl_create(&cargs); + break; + + case CMD_NAMESERVERREMOTENOTIFY_DELETE: + status = nameserver_remotenotify_ioctl_delete(&cargs); + break; + + case CMD_NAMESERVERREMOTENOTIFY_GETCONFIG: + status = nameserver_remotenotify_ioctl_get_config(&cargs); + break; + + case CMD_NAMESERVERREMOTENOTIFY_SETUP: + status = nameserver_remotenotify_ioctl_setup(&cargs); + break; + + case CMD_NAMESERVERREMOTENOTIFY_DESTROY: + status = nameserver_remotenotify_ioctl_destroy(&cargs); + break; + + default: + WARN_ON(cmd); + status = -ENOTTY; + break; + } + + if ((cargs.api_status == -ERESTARTSYS) || (cargs.api_status == -EINTR)) + status = -ERESTARTSYS; + + if (status < 0) + goto exit; + + /* Copy the full args to the user-side. */ + size = copy_to_user(uarg, &cargs, + sizeof(struct nameserver_remotenotify_cmd_args)); + if (size) { + status = -EFAULT; + goto exit; + } + +exit: + return status; +} + diff --git a/drivers/dsp/syslink/multicore_ipc/platform.c b/drivers/dsp/syslink/multicore_ipc/platform.c new file mode 100644 index 000000000000..5a08400b0743 --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/platform.c @@ -0,0 +1,1420 @@ +/* + * platform.c + * + * Implementation of platform initialization logic for Syslink IPC. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + + +/* Standard header files */ +#include <linux/types.h> +#include <linux/module.h> + + +/* Utilities & Osal headers */ +/*#include <Gate.h> +#include <GateMutex.h> +#include <Memory.h>*/ + +/* SysLink device specific headers */ +#include "../procmgr/proc4430/proc4430.h" + +/* Module level headers */ +#include <multiproc.h> +#include <sysmgr.h> +#include <_sysmgr.h> +#include <sysmemmgr.h> +#include <platform.h> +#include <gatepeterson.h> +#include <sharedregion.h> +#include <listmp.h> +#include <messageq.h> +#include <messageq_transportshm.h> +#include <notify.h> +/*#include <NotifyDriver.h>*/ +#include <notify_ducatidriver.h> +#include <nameserver.h> +#include <nameserver_remote.h> +#include <nameserver_remotenotify.h> +#include <procmgr.h> +#include <heap.h> +#include <heapbuf.h> + +#include <platform_mem.h> + + +/** ============================================================================ + * Application specific configuration, please change these value according to + * your application's need. + * ============================================================================ + */ +/* App defines */ + +/* SYSM3 Heap */ +#define SYSM3HEAPID 0 +#define SYSM3HEAPNAME "SysMgrHeap0" + +/* APPM3 Heap */ +#define APPM3HEAPID 1 +#define APPM3HEAPNAME "SysMgrHeap1" + + +/*! + * @brief Interrupt ID of physical interrupt handled by the Notify driver to + * receive events. + */ +#define BASE_DUCATI2ARM_INTID 26 + +/*! + * @brief Interrupt ID of physical interrupt handled by the Notify driver to + * send events. + */ +#define BASE_ARM2DUCATI_INTID 50 + +/*! + * @brief Maximum events supported by Notify component + */ +#define NOTIFY_MAX_EVENTS 32 + +/*! + * @brief Number of event reserved i.e. can not be used by application + */ +#define NOTIFY_NUMRESERVEDEVENTS 0 + +/*! + * @brief Wait for this much poll count when sending event + */ +#define NOTIFY_SENDEVENTPOLLCOUNT 0xfffff + +/*! + * @brief Align buffer in Heap + */ +#define HEAPBUF_ALIGN 128 + +/*! + * @brief Number of blocks in the heap + */ +#define HEAPBUF_NUMBLOCKS 16 + +/*! + * @brief Size of each blocks in heap + */ +#define HEAPBUF_BLOCKSIZE 256 + + +/*! @brief Start of IPC shared memory */ +#define SHAREDMEMORY_PHY_BASEADDR 0x9CF00000 +#define SHAREDMEMORY_PHY_BASESIZE 0x00100000 + +/*! @brief Start of IPC shared memory for SysM3 */ +#define SHAREDMEMORY_PHY_BASEADDR_SYSM3 0x9CF00000 +#define SHAREDMEMORY_PHY_BASESIZE_SYSM3 0x00054000 + +/*! @brief Start of IPC shared memory AppM3 */ +#define SHAREDMEMORY_PHY_BASEADDR_APPM3 0x9CF55000 +#define SHAREDMEMORY_PHY_BASESIZE_APPM3 0x00054000 + +/*! @brief Start of IPC SHM for SysM3 */ +#define SHAREDMEMORY_SLV_VRT_BASEADDR_SYSM3 0xA0000000 +#define SHAREDMEMORY_SLV_VRT_BASESIZE_SYSM3 0x00055000 + +/*! @brief Start of IPC SHM for AppM3 */ +#define SHAREDMEMORY_SLV_VRT_BASEADDR_APPM3 0xA0055000 +#define SHAREDMEMORY_SLV_VRT_BASESIZE_APPM3 0x00055000 + +/*! @brief Start of Boot load page for SysM3 */ +#define BOOTLOADPAGE_SLV_VRT_BASEADDR_SYSM3 0xA0054000 +#define BOOTLOADPAGE_SLV_VRT_BASESIZE_SYSM3 0x00001000 + +/*! @brief Start of Boot load page for AppM3 */ +#define BOOTLOADPAGE_SLV_VRT_BASEADDR_APPM3 0xA00A9000 +#define BOOTLOADPAGE_SLV_VRT_BASESIZE_APPM3 0x00001000 + +/*! @brief Start of SW DMM shared memory */ +#define SHAREDMEMORY_SWDMM_PHY_BASEADDR 0x9F300000 +#define SHAREDMEMORY_SWDMM_PHY_BASESIZE 0x00C00000 + +/*! @brief Start of SW DMM SHM for Ducati */ +#define SHAREDMEMORY_SWDMM_SLV_VRT_BASEADDR 0x81300000 +#define SHAREDMEMORY_SWDMM_SLV_VRT_BASESIZE 0x00C00000 + +/*! + * @brief Size of the shared memory heap, this heap is used for providing + * shared memory to drivers/instances. Should not be used for any other purpose. + */ +#define SMHEAP_SIZE SHAREDMEMORY_PHY_BASESIZE + +/*! + * @brief Shared region index for Shared memory heap. + */ +#define SMHEAP_SRINDEX 0 + +/*! + * @brief Shared region index for Shared memory heap for SysM3. + */ +#define SMHEAP_SRINDEX_SYSM3 0 + +/*! + * @brief Shared region index for Shared memory heap for AppM3. + */ +#define SMHEAP_SRINDEX_APPM3 1 + +/*! + * @brief Shared region index for Shared memory SW DMM section. + */ +#define SMHEAP_SRINDEX_SWDMM 2 + +/*! + * @brief Shared region index for SysM3 boot load page + */ +#define BOOTLOADPAGE_SRINDEX 1 + + +/*! + * @brief Event no used by sysmemmgr + */ +#define PLATFORM_SYSMEMMGR_EVENTNO 31 + + +/** ============================================================================ + * Command Id used by bootloadpage logic to transfer info + * ============================================================================ + */ +/*! + * @brief Command ID for notify driver. + */ +#define PLATFORM_CMD_NOTIFYDRIVER SYSMGR_CMD_SHAREDREGION_ENTRY_END + +/*! + * @brief Command ID for GatePeterson used by nameserverremotenotify. + */ +#define PLATFORM_CMD_GPNSRN (PLATFORM_CMD_NOTIFYDRIVER + 1) + +/*! + * @brief Command ID for nameserverremotenotify. + */ +#define PLATFORM_CMD_NSRN (PLATFORM_CMD_NOTIFYDRIVER + 2) + +/*! + * @brief Command ID for GatePeterson used by HeapBuf. + */ +#define PLATFORM_CMD_GPHEAPBUF (PLATFORM_CMD_NOTIFYDRIVER + 3) + +/*! + * @brief Command ID for HeapBuf. + */ +#define PLATFORM_CMD_HEAPBUF (PLATFORM_CMD_NOTIFYDRIVER + 4) + +/*! + * @brief Command ID for GatePeterson used by MessageQTransportShm. + */ +#define PLATFORM_CMD_GPMQT (PLATFORM_CMD_NOTIFYDRIVER + 5) + +/*! + * @brief Command ID for MessageQTransportShm. + */ +#define PLATFORM_CMD_MQT (PLATFORM_CMD_NOTIFYDRIVER + 6) + + +/** ============================================================================ + * Handles used by platform logic + * ============================================================================ + */ +void *platform_notifydrv_handle; + +/* Handles for SysM3 */ +void *platform_nsrn_gate_handle_sysm3; +void *platform_nsrn_handle_sysm3; +void *platform_notifydrv_handle_sysm3; +void *platform_heap_gate_handle_sysm3; +void *platform_heap_handle_sysm3; +void *platform_mqt_gate_handle_sysm3; +void *platform_transport_shm_handle_sysm3; +void *platform_messageq_sysm3; + +/* Handles for AppM3 */ +void *platform_nsrn_gate_handle_appm3; +void *platform_nsrn_handle_appm3; +void *platform_notifydrv_handle_appm3; +void *platform_heap_gate_handle_appm3; +void *platform_heap_handle_appm3; +void *platform_mqt_gate_handle_appm3; +void *platform_transport_shm_handle_appm3; +void *platform_messageq_appm3; + + +/** ============================================================================ + * Struct & Enums. + * ============================================================================ + */ +/* Struct for reading platform specific gate peterson configuration values */ +struct platform_gaterpeterson_params { + u32 shared_mem_addr; /* Shared memory address */ + u32 shared_mem_size; /* Shared memory size */ + u32 remote_proc_id; /* Remote processor identifier */ +}; + +struct platform_notify_ducatidrv_params { + u32 shared_mem_addr; /* Shared memory address */ + u32 shared_mem_size; /* Shared memory size */ + u16 remote_proc_id; /* Remote processor identifier */ +}; + +struct platform_nameserver_remotenotify_params { + u32 shared_mem_addr; /* Shared memory address */ + u32 shared_mem_size; /* Shared memory size */ + u32 notify_event_no; /* Notify Event number to used */ +}; + +struct platform_heapbuf_params { + u32 shared_mem_addr; /* Shared memory address */ + u32 shared_mem_size; /* Shared memory size */ + u32 shared_buf_addr; /* Shared memory address */ + u32 shared_buf_size; /* Shared memory size */ + u32 num_blocks; + u32 block_size; +}; + +struct platform_messageq_transportshm_params { + u32 shared_mem_addr; /* Shared memory address */ + u32 shared_mem_size; /* Shared memory size */ + u32 notify_event_no; /* Notify Event number */ +}; + +struct platform_proc_config_params { + u32 use_notify; + u32 use_messageq; + u32 use_heapbuf; + u32 use_frameq; + u32 use_ring_io; + u32 use_listmp; + u32 use_nameserver; +}; + +/** ============================================================================ + * Macros and types + * ============================================================================ + */ +/*! + * @brief Number of slave memory entries for OMAP4430. + */ +#define NUM_MEM_ENTRIES 3 + +/*! + * @brief Number of slave memory entries for OMAP4430 SYSM3. + */ +#define NUM_MEM_ENTRIES_SYSM3 1 + +/*! + * @brief Number of slave memory entries for OMAP4430 APPM3. + */ +#define NUM_MEM_ENTRIES_APPM3 1 + +/*! + * @brief Position of reset vector memory region in the memEntries array. + */ +#define RESET_VECTOR_ENTRY_ID 0 + + +/** ============================================================================ + * Globals + * ============================================================================ + */ +/*! + * @brief Array of memory entries for OMAP4430 + */ +static struct proc4430_mem_entry mem_entries[NUM_MEM_ENTRIES] = { + { + "DUCATI_SHM_SYSM3", /* NAME : Name of the memory region */ + SHAREDMEMORY_PHY_BASEADDR_SYSM3, + /* PHYSADDR : Physical address */ + SHAREDMEMORY_SLV_VRT_BASEADDR_SYSM3, + /* SLAVEVIRTADDR : Slave virtual address */ + (u32) -1u, + /* MASTERVIRTADDR : Master virtual address (if known) */ + SHAREDMEMORY_SLV_VRT_BASESIZE_SYSM3, + /* SIZE : Size of the memory region */ + true, /* SHARE : Shared access memory? */ + }, + { + "DUCATI_SHM_APPM3", /* NAME : Name of the memory region */ + SHAREDMEMORY_PHY_BASEADDR_APPM3, + /* PHYSADDR : Physical address */ + SHAREDMEMORY_SLV_VRT_BASEADDR_APPM3, + /* SLAVEVIRTADDR : Slave virtual address */ + (u32) -1u, + /* MASTERVIRTADDR : Master virtual address (if known) */ + SHAREDMEMORY_SLV_VRT_BASESIZE_APPM3, + /* SIZE : Size of the memory region */ + true, /* SHARE : Shared access memory? */ + }, + { + "DUCATI_SHM_SWDMM", /* NAME : Name of the memory region */ + SHAREDMEMORY_SWDMM_PHY_BASEADDR, + /* PHYSADDR : Physical address */ + SHAREDMEMORY_SWDMM_SLV_VRT_BASEADDR, + /* SLAVEVIRTADDR : Slave virtual address */ + (u32) -1u, + /* MASTERVIRTADDR : Master virtual address (if known) */ + SHAREDMEMORY_SWDMM_SLV_VRT_BASESIZE, + /* SIZE : Size of the memory region */ + true, /* SHARE : Shared access memory? */ + } +}; + +void *procmgr_handle; +void *procmgr_proc_handle; +void *platform_sm_heap_virt_addr_sysm3; +void *platform_sm_heap_virt_addr_appm3; + +/*! + * @brief Handle to the ProcMgr instance used. + */ +void *procmgr_handle; + +/*! + * @brief Handle to the Processor instance used. + */ +void *procmgr_proc_handle; + +/*! + * @brief Handle to the SysM3 ProcMgr instance used. + */ +void *procmgr_handle_sysm3; + +/*! + * @brief Handle to the AppM3 ProcMgr instance used. + */ +void *procmgr_handle_appm3; + + +/*! + * @brief Handle to the SysM3 Processor instance used. + */ +void *procmgr_proc_handle_sysm3; + +/*! + * @brief Handle to the AppM3 Processor instance used. + */ +void *procmgr_proc_handle_appm3; + +/*! + * @brief File ID of the file loaded. + */ +u32 procmgr_file_id; + +/*! + * @brief Shared memory heap virtual address. + */ +void *platform_sm_heap_virt_addr; + +/*! + * @brief Shared memory heap physical address. + */ +void *platform_sm_heap_phys_addr; + +/*! + * @brief Scalability info + */ +struct sysmgr_proc_config pc_params; + +/*! + * @brief SW DMM virtual address. + */ +void *platform_sw_dmm_virt_addr; + +/* ============================================================================= + * APIS + * ============================================================================= + */ + +/* + * ======== platform_setup ======== + * Purpose: + * TBD: logic would change completely in the final system. + */ +s32 platform_setup(struct sysmgr_config *config) +{ + + s32 status = 0; + struct proc4430_config proc_config; + struct proc_mgr_params params; + struct proc4430_params proc_params; + struct proc_mgr_attach_params attach_params; + u16 proc_id; + struct sysmemmgr_config sysmemmgr_cfg; + struct platform_mem_map_info info; + + if (WARN_ON(config == NULL)) { + /*! @retval SYSMGR_E_INVALIDARG Argument of type + * (GatePeterson_Config *) passed is null*/ + status = -EINVAL; + goto invalid_config_fail; + } + + /* Map the static region */ + info.src = SHAREDMEMORY_PHY_BASEADDR; + info.size = SHAREDMEMORY_PHY_BASESIZE; + info.is_cached = false; + status = platform_mem_map(&info); + if (status < 0) + goto mem_map_fail; + + /* Get default config for System memory manager */ + sysmemmgr_get_config(&sysmemmgr_cfg); + /* Initialize the System memory manager */ + sysmemmgr_cfg.static_mem_size = SHAREDMEMORY_PHY_BASESIZE; + sysmemmgr_cfg.static_phys_base_addr = SHAREDMEMORY_PHY_BASEADDR; + sysmemmgr_cfg.static_virt_base_addr = info.dst; + sysmemmgr_cfg.event_no = PLATFORM_SYSMEMMGR_EVENTNO; + status = sysmemmgr_setup(&sysmemmgr_cfg); + if (status < 0) + goto sysmemmgr_setup_fail; + + /* The heap for SysM3 and AppM3 are allocated at once */ + platform_sm_heap_virt_addr = sysmemmgr_alloc(SMHEAP_SIZE, + sysmemmgr_allocflag_physical); + if (platform_sm_heap_virt_addr == NULL) + goto sysmemmgr_alloc_fail; + + platform_sm_heap_virt_addr_sysm3 = platform_sm_heap_virt_addr; + /* The AppM3 shared area is after SysM3 heap + boot load page */ + platform_sm_heap_virt_addr_appm3 = (platform_sm_heap_virt_addr_sysm3 + + SHAREDMEMORY_PHY_BASESIZE_SYSM3 + + BOOTLOADPAGE_SLV_VRT_BASESIZE_SYSM3); + + + /* Create the shared region entry for the SysM3 heap */ + sharedregion_add(SMHEAP_SRINDEX_SYSM3, + platform_sm_heap_virt_addr_sysm3, + SHAREDMEMORY_PHY_BASESIZE_SYSM3); + /* Zero out the shared memory for SysM3 */ + memset((void *) platform_sm_heap_virt_addr_sysm3, + 0, + SHAREDMEMORY_PHY_BASESIZE_SYSM3); + + /* Create the shared region entry for the AppM3 heap */ + sharedregion_add(SMHEAP_SRINDEX_APPM3, + platform_sm_heap_virt_addr_appm3, + SHAREDMEMORY_PHY_BASESIZE_APPM3); + /* Zero out the shared memory for AppM3 */ + memset((void *) platform_sm_heap_virt_addr_appm3, + 0, + SHAREDMEMORY_PHY_BASESIZE_APPM3); + + /* Map the static region */ + info.src = SHAREDMEMORY_SWDMM_PHY_BASEADDR; + info.size = SHAREDMEMORY_SWDMM_PHY_BASESIZE; + info.is_cached = false; + status = platform_mem_map(&info); + if (status < 0) + goto mem_map_fail; + platform_sw_dmm_virt_addr = (void *) info.dst; + /* Create the shared region entry for the SW DMM heap */ + sharedregion_add(SMHEAP_SRINDEX_SWDMM, + platform_sw_dmm_virt_addr, + info.size); + + proc4430_get_config(&proc_config); + status = proc4430_setup(&proc_config); + if (status < 0) + goto proc_setup_fail; + + + /* Get MultiProc ID by name. */ + proc_id = multiproc_get_id("SysM3"); + + /* Create an instance of the Processor object for OMAP4430 */ + proc4430_params_init(NULL, &proc_params); + proc_params.num_mem_entries = NUM_MEM_ENTRIES; + proc_params.mem_entries = mem_entries; + proc_params.reset_vector_mem_entry = RESET_VECTOR_ENTRY_ID; + procmgr_proc_handle = proc4430_create(proc_id, &proc_params); + if (procmgr_proc_handle == NULL) { + status = SYSMGR_E_FAIL; + goto proc_create_fail; + } + + /* Initialize parameters */ + proc_mgr_params_init(NULL, ¶ms); + params.proc_handle = procmgr_proc_handle; + procmgr_handle = proc_mgr_create(proc_id, ¶ms); + if (procmgr_handle == NULL) { + status = SYSMGR_E_FAIL; + goto proc_mgr_create_fail; + } + + proc_mgr_get_attach_params(NULL, &attach_params); + /* Default params will be used if NULL is passed. */ + status = proc_mgr_attach(procmgr_handle, &attach_params); + if (status < 0) { + status = SYSMGR_E_FAIL; + goto proc_mgr_attach_fail; + } + + + /* SysM3 and AppM3 use the same handle */ + procmgr_handle_sysm3 = procmgr_handle; + procmgr_proc_handle_sysm3 = procmgr_proc_handle; + + procmgr_handle = NULL; + procmgr_proc_handle = NULL; + + + + /* Get MultiProc ID by name. */ + proc_id = multiproc_get_id("AppM3"); + + /* Create an instance of the Processor object for OMAP4430 */ + proc4430_params_init(NULL, &proc_params); + proc_params.num_mem_entries = NUM_MEM_ENTRIES; + proc_params.mem_entries = mem_entries; + proc_params.reset_vector_mem_entry = RESET_VECTOR_ENTRY_ID; + procmgr_proc_handle = proc4430_create(proc_id, &proc_params); + if (procmgr_proc_handle == NULL) { + status = SYSMGR_E_FAIL; + goto proc_create_fail; + } + + /* Initialize parameters */ + proc_mgr_params_init(NULL, ¶ms); + params.proc_handle = procmgr_proc_handle; + procmgr_handle = proc_mgr_create(proc_id, ¶ms); + if (procmgr_handle == NULL) { + status = SYSMGR_E_FAIL; + goto proc_mgr_create_fail; + } + + proc_mgr_get_attach_params(NULL, &attach_params); + /* Default params will be used if NULL is passed. */ + status = proc_mgr_attach(procmgr_handle, &attach_params); + if (status < 0) { + status = SYSMGR_E_FAIL; + goto proc_mgr_attach_fail; + } + + procmgr_handle_appm3 = procmgr_handle; + procmgr_proc_handle_appm3 = procmgr_proc_handle; + goto exit; + +proc_mgr_attach_fail: + printk(KERN_ERR "platform_setup: proc_mgr_attach failed [0x%x]" + " for processor [0x%x]\n", status, proc_id); + goto exit; + +proc_mgr_create_fail: + printk(KERN_ERR "platform_setup: proc_mgr_create failed [0x%x]", + status); + goto exit; +proc_create_fail: + printk(KERN_ERR "platform_setup: proc4430_create failed [0x%x]", + status); + goto exit; +proc_setup_fail: + printk(KERN_ERR "platform_setup: proc4430_setup failed [0x%x]", + status); + goto exit; +sysmemmgr_alloc_fail: + printk(KERN_ERR "platform_setup: sysmemmgr_alloc failed [0x%x]", + status); + goto exit; +sysmemmgr_setup_fail: + printk(KERN_ERR "platform_setup: sysmemmgr_setup failed [0x%x]", + status); + goto exit; +mem_map_fail: + printk(KERN_ERR "platform_setup: platform_mem_map failed [0x%x]", + status); + goto exit; +invalid_config_fail: + printk(KERN_ERR "platform_setup: Argument of type (sysmgr_get_config *)" + " passed is null [0x%x]", status); +exit: + return status; +} + + +/* + * ======== platform_destroy ======== + * Purpose: + * Function to finalize the platform. + */ +s32 platform_destroy(void) +{ + s32 status = 0; + struct platform_mem_unmap_info u_info; + /* Delete the Processor instances */ + + if (procmgr_handle_appm3 != NULL) { + status = proc_mgr_detach(procmgr_handle_appm3); + WARN_ON(status < 0); + } + + if (procmgr_proc_handle_appm3 != NULL) { + status = proc4430_delete(&procmgr_proc_handle_appm3); + WARN_ON(status < 0); + } + + if (procmgr_handle_appm3 != NULL) { + status = proc_mgr_delete(&procmgr_handle_appm3); + WARN_ON(status < 0); + } + + if (procmgr_handle_sysm3 != NULL) { + status = proc_mgr_detach(procmgr_handle_sysm3); + WARN_ON(status < 0); + } + + if (procmgr_proc_handle_sysm3 != NULL) { + status = proc4430_delete(&procmgr_proc_handle_sysm3); + WARN_ON(status < 0); + } + + if (procmgr_handle_sysm3 != NULL) { + status = proc_mgr_delete(&procmgr_handle_sysm3); + WARN_ON(status < 0); + } + + status = proc4430_destroy(); + WARN_ON(status < 0); + + + sharedregion_remove(SMHEAP_SRINDEX_APPM3); + sharedregion_remove(SMHEAP_SRINDEX_SYSM3); + + sysmemmgr_free(platform_sm_heap_virt_addr, SMHEAP_SIZE, + sysmemmgr_allocflag_physical); + + status = sysmemmgr_destroy(); + WARN_ON(status < 0); + + if (platform_sm_heap_virt_addr != NULL) { + u_info.addr = (u32) platform_sm_heap_virt_addr; + platform_mem_unmap(&u_info); + } + + if (platform_sw_dmm_virt_addr != NULL) { + u_info.addr = (u32) platform_sw_dmm_virt_addr; + platform_mem_unmap(&u_info); + } + + return status; +} + + +/* + * ======== platform_load_callback ======== + * Purpose: + * Function called by proc_mgr when slave is in loaded state. + */ +void platform_load_callback(void *arg) +{ + s32 status = 0; + u16 proc_id = (u32) arg; + u16 local_id = MULTIPROC_INVALIDID; + struct sharedregion_info info; + u32 boot_load_page; + u32 sh_addr_base; + u32 nwrite; + int index; + + printk(KERN_ERR "platform_load_callback\n"); + + /* Get the written entry */ + local_id = multiproc_get_id(NULL); + + if (proc_id == multiproc_get_id("SysM3")) + index = SMHEAP_SRINDEX_SYSM3; + else if (proc_id == multiproc_get_id("AppM3")) + index = SMHEAP_SRINDEX_APPM3; + else { + status = SYSMGR_E_FAIL; + goto proc_invalid_id; + } + /* Add the to sharedregion */ + switch (index) { + case SMHEAP_SRINDEX_SYSM3: /* For SysM3 */ + /* Get the boot load page address */ + boot_load_page = BOOTLOADPAGE_SLV_VRT_BASEADDR_SYSM3; + status = proc_mgr_translate_addr(procmgr_handle_sysm3, + (void *) &sh_addr_base, + PROC_MGR_ADDRTYPE_MASTERKNLVIRT, + (void *) boot_load_page, + PROC_MGR_ADDRTYPE_SLAVEVIRT); + if (status < 0) + break; + /* Zero out the boot load page */ + memset((void *) sh_addr_base, + 0, + BOOTLOADPAGE_SLV_VRT_BASESIZE_SYSM3); + break; + + case SMHEAP_SRINDEX_APPM3: /* For AppM3 */ + /* Get the boot load page address */ + boot_load_page = BOOTLOADPAGE_SLV_VRT_BASEADDR_APPM3; + status = proc_mgr_translate_addr(procmgr_handle_appm3, + (void *) &sh_addr_base, + PROC_MGR_ADDRTYPE_MASTERKNLVIRT, + (void *) boot_load_page, + PROC_MGR_ADDRTYPE_SLAVEVIRT); + if (status < 0) + break; + + /* Zero out the boot load page */ + memset((void *) sh_addr_base, + 0, + BOOTLOADPAGE_SLV_VRT_BASESIZE_APPM3); + break; + } + + if (status < 0) + goto proc_mgr_translate_addr_fail; + + /* Set the boot load page address */ + sysmgr_set_boot_load_page(proc_id, sh_addr_base); + + /* Write the boot table (containing both regions) to */ + /* the current processor */ + + /* For SysM3 */ + sharedregion_get_table_info(SMHEAP_SRINDEX_SYSM3, + local_id, + &info); + platform_sm_heap_virt_addr_sysm3 = sysmemmgr_translate( + platform_sm_heap_virt_addr_sysm3, + sysmemmgr_xltflag_kvirt2phys); + info.base = (void *) SHAREDMEMORY_SLV_VRT_BASEADDR_SYSM3; + nwrite = sysmgr_put_object_config(proc_id, + (void *) &info, + SYSMGR_CMD_SHAREDREGION_ENTRY_START + + SMHEAP_SRINDEX_SYSM3, + sizeof(struct sharedregion_info)); + WARN_ON(nwrite != sizeof(struct sharedregion_info)); + + /* For AppM3 */ + sharedregion_get_table_info(SMHEAP_SRINDEX_APPM3, + local_id, + &info); + platform_sm_heap_virt_addr_appm3 = sysmemmgr_translate( + platform_sm_heap_virt_addr_appm3, + sysmemmgr_xltflag_kvirt2phys); + info.base = (void *) SHAREDMEMORY_SLV_VRT_BASEADDR_APPM3; + + /* Write info into the boot load page */ + nwrite = sysmgr_put_object_config(proc_id, + (void *) &info, + SYSMGR_CMD_SHAREDREGION_ENTRY_START + + SMHEAP_SRINDEX_APPM3, + sizeof(struct sharedregion_info)); + WARN_ON(nwrite != sizeof(struct sharedregion_info)); + + /* For SW DMM region */ + sharedregion_get_table_info(SMHEAP_SRINDEX_SWDMM, + local_id, + &info); + info.base = (void *) SHAREDMEMORY_SWDMM_SLV_VRT_BASEADDR; + + /* Write info into the boot load page */ + nwrite = sysmgr_put_object_config(proc_id, + (void *) &info, + SYSMGR_CMD_SHAREDREGION_ENTRY_START + + SMHEAP_SRINDEX_SWDMM, + sizeof(struct sharedregion_info)); + WARN_ON(nwrite != sizeof(struct sharedregion_info)); + goto exit; + +proc_mgr_translate_addr_fail: + printk(KERN_ERR "platform_load_callback: proc_mgr_translate_addr failed" + " [0x%x] for proc_id [0x%x]\n", + status, proc_id); + goto exit; +proc_invalid_id: + printk(KERN_ERR "platform_load_callback failed invalid proc_id [0x%x]\n", + proc_id); +exit: + return; +} +EXPORT_SYMBOL(platform_load_callback); + + +/* + * ======== platform_start_callback ======== + * Purpose: + * Function called by proc_mgr when slave is in started state. + * FIXME: logic would change completely in the final system. + */ +void platform_start_callback(void *arg) +{ + s32 status = 0; + u16 local_id = MULTIPROC_INVALIDID; + u16 proc_id = (u32) arg; + u32 nread = 0; + u32 i = 0; + u32 cmd_id; + u32 sh_addr; + int index; + + struct notify_ducatidrv_params notify_shm_params; + struct gatepeterson_params gate_params; + struct nameserver_remotenotify_params nsr_params; + struct heapbuf_params heap_params; + struct messageq_transportshm_params msgqt_params; + struct sharedregion_config sr_config; + struct sharedregion_info info; + + struct platform_notify_ducatidrv_params pnds_params; + struct platform_heapbuf_params phb_params; + struct platform_gaterpeterson_params pgp_params; + struct platform_nameserver_remotenotify_params pnsrn_params; + struct platform_messageq_transportshm_params pmqt_params; + /*u32 proc_ids[2];*/ + + printk(KERN_ERR "platform_start_callback\n"); + if (proc_id == multiproc_get_id("SysM3")) + index = SMHEAP_SRINDEX_SYSM3; + else if (proc_id == multiproc_get_id("AppM3")) + index = SMHEAP_SRINDEX_APPM3; + else { + status = SYSMGR_E_FAIL; + goto proc_invalid_id; + } + /* Wait for slave to write the scalability info */ + sysmgr_wait_for_scalability_info(proc_id); + /* Read the scalability info */ + do { + nread = sysmgr_get_object_config(proc_id, (void *) &pc_params, + SYSMGR_CMD_SCALABILITY, + sizeof(struct sysmgr_proc_config)); + } while (nread != sizeof(struct sysmgr_proc_config)); + + if (status >= 0) { + local_id = multiproc_get_id(NULL); + status = multiproc_set_local_id(local_id); + if (status < 0) { + status = SYSMGR_E_FAIL; + goto multiproc_fail; + } + } + + /* TODO: add condition: proc_id == multiproc_get_id("SysM3") */ + if (pc_params.use_notify) { + do { + nread = sysmgr_get_object_config(proc_id, + (void *) &pnds_params, + PLATFORM_CMD_NOTIFYDRIVER, + sizeof(struct \ + platform_notify_ducatidrv_params)); + } while (nread != \ + sizeof(struct platform_notify_ducatidrv_params)); + + sh_addr = (u32)sharedregion_get_ptr((u32 *) + pnds_params.shared_mem_addr); + if (sh_addr == (u32)NULL) { + status = SYSMGR_E_FAIL; + goto sharedregion_getptr_fail; + } + notify_ducatidrv_params_init(NULL, ¬ify_shm_params); + notify_shm_params.shared_addr = sh_addr; + notify_shm_params.shared_addr_size = \ + pnds_params.shared_mem_size; + notify_shm_params.num_events = NOTIFY_MAX_EVENTS; + notify_shm_params.num_reserved_events = \ + NOTIFY_NUMRESERVEDEVENTS; + notify_shm_params.send_event_poll_count = \ + NOTIFY_SENDEVENTPOLLCOUNT; + notify_shm_params.recv_int_id = BASE_DUCATI2ARM_INTID; + notify_shm_params.send_int_id = BASE_ARM2DUCATI_INTID; + notify_shm_params.remote_proc_id = proc_id; + if (platform_notifydrv_handle == NULL) { + /* Create instance of Notify Ducati Driver */ + platform_notifydrv_handle = notify_ducatidrv_create( + "NOTIFYDRIVER_DUCATI", + ¬ify_shm_params); + if (platform_notifydrv_handle == NULL) { + status = SYSMGR_E_FAIL; + goto notify_ducatidrv_create_fail; + } + } + + /* The notify is created only once and used for Sys and App */ + if (index == SMHEAP_SRINDEX_APPM3) + platform_notifydrv_handle_appm3 = + platform_notifydrv_handle; + else + platform_notifydrv_handle_sysm3 = + platform_notifydrv_handle; + } + if (pc_params.use_nameserver) { + do { + nread = sysmgr_get_object_config(proc_id, + (void *) &pgp_params, + PLATFORM_CMD_GPNSRN, + sizeof(struct \ + platform_gaterpeterson_params)); + } while (nread != sizeof(struct platform_gaterpeterson_params)); + sh_addr = (u32)sharedregion_get_ptr((u32 *) + pgp_params.shared_mem_addr); + if (sh_addr == (u32)NULL) { + status = SYSMGR_E_FAIL; + goto sharedregion_getptr_fail; + } + gatepeterson_params_init(NULL, &gate_params); + gate_params.shared_addr = (void *) sh_addr; + gate_params.shared_addr_size = pgp_params.shared_mem_size; + do { + if (index == SMHEAP_SRINDEX_APPM3) + status = gatepeterson_open( + &platform_nsrn_gate_handle_appm3, + &gate_params); + else + status = gatepeterson_open( + &platform_nsrn_gate_handle_sysm3, + &gate_params); + } while (status == -ENXIO); + + if (status < 0) { + status = SYSMGR_E_FAIL; + goto gatepeterson_open_fail; + } + + do { + nread = sysmgr_get_object_config(proc_id, + (void *) &pnsrn_params, + PLATFORM_CMD_NSRN, + sizeof(struct \ + platform_nameserver_remotenotify_params)); + } while (nread != \ + sizeof(struct + platform_nameserver_remotenotify_params)); + sh_addr = (u32) sharedregion_get_ptr((u32 *) + pnsrn_params.shared_mem_addr); + if (sh_addr == (u32)NULL) { + status = SYSMGR_E_FAIL; + goto sharedregion_getptr_fail; + } + /* + * Create the NameServerRemote implementation that is used to + * communicate with the remote processor. It uses some shared + * memory and the Notify module. + * + * Note that this implementation uses Notify to communicate, so + * interrupts need to be enabled. + */ + nameserver_remotenotify_params_init(NULL, &nsr_params); + nsr_params.notify_driver = platform_notifydrv_handle; + /* Both are using same notify */ + nsr_params.notify_event_no = pnsrn_params.notify_event_no; + nsr_params.shared_addr = (void *) sh_addr; + nsr_params.shared_addr_size = pnsrn_params.shared_mem_size; + if (index == SMHEAP_SRINDEX_APPM3) { + nsr_params.gate = + (void *) platform_nsrn_gate_handle_appm3; + platform_nsrn_handle_appm3 = + nameserver_remotenotify_create( + proc_id, + &nsr_params); + if (platform_nsrn_handle_appm3 == NULL) { + status = SYSMGR_E_FAIL; + goto nameserver_remotenotify_create_fail; + } + } else { + nsr_params.gate = + (void *) platform_nsrn_gate_handle_sysm3; + platform_nsrn_handle_sysm3 = + nameserver_remotenotify_create( + proc_id, + &nsr_params); + if (platform_nsrn_handle_sysm3 == NULL) { + status = SYSMGR_E_FAIL; + goto nameserver_remotenotify_create_fail; + } + } + } + if (pc_params.use_heapbuf) { + do { + nread = sysmgr_get_object_config(proc_id, + (void *) &pgp_params, + PLATFORM_CMD_GPHEAPBUF, + sizeof(struct \ + platform_gaterpeterson_params)); + } while (nread != sizeof(struct + platform_gaterpeterson_params)); + sh_addr = (u32) sharedregion_get_ptr((u32 *) + pgp_params.shared_mem_addr); + if (sh_addr == (u32)NULL) { + status = SYSMGR_E_FAIL; + goto sharedregion_getptr_fail; + } + gatepeterson_params_init(NULL, &gate_params); + gate_params.shared_addr = (void *) sh_addr; + gate_params.shared_addr_size = pgp_params.shared_mem_size; + do { + if (index == SMHEAP_SRINDEX_APPM3) + status = gatepeterson_open( + &platform_heap_gate_handle_appm3, + &gate_params); + else + status = gatepeterson_open( + &platform_heap_gate_handle_sysm3, + &gate_params); + } while (status == -ENXIO); + if (status < 0) { + status = SYSMGR_E_FAIL; + goto gatepeterson_open_fail; + } + + do { + nread = sysmgr_get_object_config(proc_id, + (void *) &phb_params, + PLATFORM_CMD_HEAPBUF, + sizeof(struct platform_heapbuf_params)); + } while (nread != sizeof(struct platform_heapbuf_params)); + /* Create the heap. */ + sh_addr = (u32) sharedregion_get_ptr((u32 *) + phb_params.shared_mem_addr); + if (sh_addr == (u32)NULL) { + status = SYSMGR_E_FAIL; + goto sharedregion_getptr_fail; + } + heapbuf_params_init(NULL, &heap_params); + heap_params.shared_addr = (void *) sh_addr; + heap_params.align = HEAPBUF_ALIGN; + heap_params.num_blocks = phb_params.num_blocks; + heap_params.block_size = phb_params.block_size; + sh_addr = (u32) sharedregion_get_ptr((u32 *) + phb_params.shared_buf_size); + if (sh_addr == (u32)NULL) { + status = SYSMGR_E_FAIL; + goto sharedregion_getptr_fail; + } + heap_params.shared_buf_size = phb_params.shared_buf_size; + heap_params.shared_buf = (void *) sh_addr; + if (index == SMHEAP_SRINDEX_APPM3) { + heap_params.name = APPM3HEAPNAME; + heap_params.gate = platform_heap_gate_handle_appm3; + } else { + heap_params.name = SYSM3HEAPNAME; + heap_params.gate = platform_heap_gate_handle_sysm3; + } + heap_params.shared_addr_size = phb_params.shared_mem_size; + do { + if (index == SMHEAP_SRINDEX_APPM3) + status = heapbuf_open( + &platform_heap_handle_appm3, + &heap_params); + else + status = heapbuf_open( + &platform_heap_handle_sysm3, + &heap_params); + } while (status == -ENXIO); + if (status < 0) { + status = SYSMGR_E_FAIL; + goto heapbuf_open_fail; + } + } + if (pc_params.use_messageq) { + do { + nread = sysmgr_get_object_config(proc_id, &pgp_params, + PLATFORM_CMD_GPMQT, + sizeof(struct \ + platform_gaterpeterson_params)); + } while (nread != sizeof(struct platform_gaterpeterson_params)); + sh_addr = (u32) sharedregion_get_ptr((u32 *) + pgp_params.shared_mem_addr); + if (sh_addr == (u32)NULL) { + status = SYSMGR_E_FAIL; + goto sharedregion_getptr_fail; + } + gatepeterson_params_init(NULL, &gate_params); + gate_params.shared_addr = (void *) sh_addr; + gate_params.shared_addr_size = pgp_params.shared_mem_size; + do { + if (index == SMHEAP_SRINDEX_APPM3) + status = gatepeterson_open( + &platform_mqt_gate_handle_appm3, + &gate_params); + else + status = gatepeterson_open( + &platform_mqt_gate_handle_sysm3, + &gate_params); + } while (status == -ENXIO); + + if (status < 0) { + status = SYSMGR_E_FAIL; + goto gatepeterson_open_fail; + } + + do { + nread = sysmgr_get_object_config(proc_id, + (void *) &pmqt_params, + PLATFORM_CMD_MQT, + sizeof(struct \ + platform_messageq_transportshm_params)); + } while (nread != sizeof( + struct platform_messageq_transportshm_params)); + /* Register this heap with platform_messageq */ + if (index == SMHEAP_SRINDEX_APPM3) + messageq_register_heap(platform_heap_handle_appm3, + APPM3HEAPID); + else + messageq_register_heap(platform_heap_handle_sysm3, + SYSM3HEAPID); + sh_addr = (u32) sharedregion_get_ptr((u32 *) + pmqt_params.shared_mem_addr); + if (sh_addr == (u32)NULL) { + status = SYSMGR_E_FAIL; + goto sharedregion_getptr_fail; + } + messageq_transportshm_params_init(NULL, &msgqt_params); + msgqt_params.shared_addr = (void *) sh_addr; + msgqt_params.notify_event_no = pmqt_params.notify_event_no; + msgqt_params.notify_driver = platform_notifydrv_handle; + msgqt_params.shared_addr_size = pmqt_params.shared_mem_size; + if (index == SMHEAP_SRINDEX_APPM3) { + msgqt_params.gate = platform_mqt_gate_handle_appm3; + platform_transport_shm_handle_appm3 = + messageq_transportshm_create( + proc_id, + &msgqt_params); + if (platform_transport_shm_handle_appm3 == NULL) { + status = SYSMGR_E_FAIL; + goto messageq_transportshm_create_fail; + } + } else { + msgqt_params.gate = platform_mqt_gate_handle_sysm3; + platform_transport_shm_handle_sysm3 = + messageq_transportshm_create( + proc_id, + &msgqt_params); + if (platform_transport_shm_handle_sysm3 == NULL) { + status = SYSMGR_E_FAIL; + goto messageq_transportshm_create_fail; + } + + } + } + + if (status >= 0) { + /* Wait for slave to complete the setup */ + sysmgr_wait_for_slave_setup(proc_id); + + /* Now get the Shared region entries that may have been created + * by Slave, but actual physical memory is not assigned to + * those entries, only virtual DSP memory exists. + */ + sharedregion_get_config(&sr_config); + for (i = 0; i < sr_config.max_regions; i++) { + cmd_id = SYSMGR_CMD_SHAREDREGION_ENTRY_START + i; + nread = sysmgr_get_object_config(proc_id, + (void *) &info, cmd_id, + sizeof(struct sharedregion_info)); + if (nread == sizeof(struct sharedregion_info)) { + /* FIXME: Do the DMM and convert the entry into + * kernel virtual address and put it in the + * shared region for host */ + } + } + } + goto exit; + +messageq_transportshm_create_fail: + printk(KERN_ERR "platform_start_callback: " + "messageq_transportshm_create failed status[0x%x]", status); + goto exit; +heapbuf_open_fail: + printk(KERN_ERR "platform_start_callback: gatepeterson_open " + "failed status[0x%x]", status); + goto exit; +nameserver_remotenotify_create_fail: + printk(KERN_ERR "platform_start_callback: " + "nameserver_remotenotify_create failed status[0x%x]", status); + goto exit; +gatepeterson_open_fail: + printk(KERN_ERR "platform_start_callback: gatepeterson_open " + "failed status[0x%x]", status); + goto exit; +notify_ducatidrv_create_fail: + printk(KERN_ERR "platform_start_callback: notify_ducatidrv_create " + "failed status[0x%x]", status); + goto exit; +sharedregion_getptr_fail: + printk(KERN_ERR "platform_start_callback: sharedregion_get_ptr failed" + " status[0x%x]", status); + goto exit; +multiproc_fail: + printk(KERN_ERR "platform_start_callback: multiproc_set_local_id failed" + " status[0x%x]", status); +proc_invalid_id: + printk(KERN_ERR "platform_load_callback failed invalid" + " proc_id [0x%x]\n", proc_id); +exit: + return; +} +EXPORT_SYMBOL(platform_start_callback); +/* FIXME: since application has to call this API for now */ + + +/* + * ======== platform_stop_callback ======== + * Purpose: + * Function called by proc_mgr when slave is in stopped state. + * FIXME: logic would change completely in the final system. + */ +void platform_stop_callback(void *arg) +{ + s32 status = 0; + u16 proc_id = (u32) arg; + int index = 0; + u32 nread = 0; + + if (proc_id == multiproc_get_id("SysM3")) + index = SMHEAP_SRINDEX_SYSM3; + else if (proc_id == multiproc_get_id("AppM3")) + index = SMHEAP_SRINDEX_APPM3; + else { + status = SYSMGR_E_FAIL; + goto proc_invalid_id; + } + + /* Read the scalability info */ + do { + nread = sysmgr_get_object_config(proc_id, (void *) &pc_params, + SYSMGR_CMD_SCALABILITY, + sizeof(struct sysmgr_proc_config)); + } while (nread != sizeof(struct sysmgr_proc_config)); + + if (pc_params.use_messageq) { + /* Finalize drivers */ + if (index == SMHEAP_SRINDEX_APPM3) + status = gatepeterson_close( + &platform_mqt_gate_handle_appm3); + else + status = gatepeterson_close( + &platform_mqt_gate_handle_sysm3); + if (status < 0) { + printk(KERN_ERR "platform_stop_callback : mqt " + "gatepeterson_close failed [0x%x]", status); + } + + if (index == SMHEAP_SRINDEX_APPM3) + status = messageq_transportshm_delete( + &platform_transport_shm_handle_appm3); + else + status = messageq_transportshm_delete( + &platform_transport_shm_handle_sysm3); + if (status < 0) { + printk(KERN_ERR "platform_stop_callback : " + "messageq_transportshm_delete failed [0x%x]", + status); + } + } + + if (pc_params.use_nameserver) { + if (index == SMHEAP_SRINDEX_APPM3) + status = gatepeterson_close( + &platform_nsrn_gate_handle_appm3); + else + status = gatepeterson_close( + &platform_nsrn_gate_handle_sysm3); + if (status < 0) { + printk(KERN_ERR "platform_stop_callback : nsrn" + "gatepeterson_close failed [0x%x]", status); + } + + if (index == SMHEAP_SRINDEX_APPM3) + status = nameserver_remotenotify_delete( + &platform_nsrn_handle_appm3); + else + status = nameserver_remotenotify_delete( + &platform_nsrn_handle_sysm3); + if (status < 0) { + printk(KERN_ERR "platform_stop_callback : " + "nameserver_remotenotify_delete failed [0x%x]", + status); + } + } + + if (pc_params.use_heapbuf) { + if (index == SMHEAP_SRINDEX_APPM3) + status = messageq_unregister_heap(APPM3HEAPID); + else + status = messageq_unregister_heap(SYSM3HEAPID); + if (status < 0) { + printk(KERN_ERR "platform_stop_callback : " + "messageq_unregister_heap failed [0x%x]", + status); + } + + if (index == SMHEAP_SRINDEX_APPM3) + status = heapbuf_close(platform_heap_handle_appm3); + else + status = heapbuf_close(platform_heap_handle_sysm3); + if (status < 0) { + printk(KERN_ERR "platform_stop_callback : " + "heapbuf_close failed [0x%x]", status); + } + if (index == SMHEAP_SRINDEX_APPM3) + status = gatepeterson_close( + &platform_heap_gate_handle_appm3); + else + status = gatepeterson_close( + &platform_heap_gate_handle_sysm3); + if (status < 0) { + printk(KERN_ERR "platform_stop_callback : heap" + "gatepeterson_close failed [0x%x]", status); + } + + } + + if (pc_params.use_notify) { + if (index == SMHEAP_SRINDEX_APPM3) + platform_notifydrv_handle_appm3 = NULL; + else + platform_notifydrv_handle_sysm3 = NULL; + + if (platform_notifydrv_handle_sysm3 == NULL && + platform_notifydrv_handle_appm3 == NULL) { + status = notify_ducatidrv_delete( + (struct notify_driver_object **) + &platform_notifydrv_handle); + platform_notifydrv_handle = NULL; + } + if (status < 0) { + printk(KERN_ERR "platform_stop_callback : " + "notify_ducatidrv_delete failed [0x%x]", + status); + } + } + + status = sharedregion_remove(SMHEAP_SRINDEX_APPM3); + if (status < 0) { + printk(KERN_ERR "platform_stop_callback : " + "sharedregion_remove failed [0x%x]", status); + } + + status = sharedregion_remove(SMHEAP_SRINDEX_SYSM3); + if (status < 0) { + printk(KERN_ERR "platform_stop_callback : " + "sharedregion_remove failed [0x%x]", status); + } + + goto exit; + +proc_invalid_id: + printk(KERN_ERR "platform_load_callback failed invalid" + " proc_id [0x%x]\n", proc_id); +exit: + return; +} +EXPORT_SYMBOL(platform_stop_callback); +/* FIXME: since application has to call this API for now */ diff --git a/drivers/dsp/syslink/multicore_ipc/platform_mem.c b/drivers/dsp/syslink/multicore_ipc/platform_mem.c new file mode 100644 index 000000000000..025605b8295c --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/platform_mem.c @@ -0,0 +1,288 @@ +/* + * platform_mem.c + * + * Target memory management interface implementation. + * + * This abstracts the Memory management interface in the kernel + * code. Allocation, Freeing-up, copy and address translate are + * supported for the kernel memory management. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +/* Linux specific header files */ +#include <linux/types.h> +#include <linux/vmalloc.h> +#include <linux/string.h> +#include <linux/io.h> +#include <linux/list.h> +#include <linux/mutex.h> +#include <linux/slab.h> + +#include <platform_mem.h> +#include <atomic_linux.h> + +/* Macro to make a correct module magic number with ref_count */ +#define PLATFORM_MEM_MAKE_MAGICSTAMP(x) ((PLATFORM_MEM_MODULEID << 12u) | (x)) + +/* + * Structure for containing + */ +struct platform_mem_map_table_info { + struct list_head mem_entry; /* Pointer to mem_entry entry */ + u32 physical_address; /* Actual address */ + u32 knl_virtual_address; /* Mapped address */ + u32 size; /* Size of the region mapped */ +}; + +/* + * Structure defining state object of system memory manager + */ +struct platform_mem_module_object { + atomic_t ref_count; /* Reference count */ + struct list_head map_table; /* Head of map table */ + struct mutex *gate; /* Pointer to lock */ +}; + + +/* + * Object containing state of the platform mem module + */ +static struct platform_mem_module_object platform_mem_state; + +/* + * ======== platform_mem_setup ======== + * Purpose: + * This will initialize the platform mem module. + */ +int platform_mem_setup(void) +{ + s32 retval = 0; + + atomic_cmpmask_and_set(&platform_mem_state.ref_count, + PLATFORM_MEM_MAKE_MAGICSTAMP(0), + PLATFORM_MEM_MAKE_MAGICSTAMP(0)); + if (atomic_inc_return(&platform_mem_state.ref_count) + != PLATFORM_MEM_MAKE_MAGICSTAMP(1)) { + return 1; + } + + /* Create the Gate handle */ + platform_mem_state.gate = + kmalloc(sizeof(struct mutex), GFP_KERNEL); + if (platform_mem_state.gate == NULL) { + retval = -ENOMEM; + goto gate_create_fail; + } + + /* Construct the map table */ + INIT_LIST_HEAD(&platform_mem_state.map_table); + mutex_init(platform_mem_state.gate); + goto exit; + +gate_create_fail: + atomic_set(&platform_mem_state.ref_count, + PLATFORM_MEM_MAKE_MAGICSTAMP(0)); +exit: + return retval; +} +EXPORT_SYMBOL(platform_mem_setup); + +/* + * ======== platform_mem_destroy ======== + * Purpose: + * This will finalize the platform mem module. + */ +int platform_mem_destroy(void) +{ + s32 retval = 0; + + if (atomic_cmpmask_and_lt(&(platform_mem_state.ref_count), + PLATFORM_MEM_MAKE_MAGICSTAMP(0), + PLATFORM_MEM_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto exit; + } + + if (atomic_dec_return(&platform_mem_state.ref_count) + == PLATFORM_MEM_MAKE_MAGICSTAMP(0)) { + list_del(&platform_mem_state.map_table); + /* Delete the gate handle */ + kfree(platform_mem_state.gate); + } + +exit: + return retval; +} +EXPORT_SYMBOL(platform_mem_destroy); + +/* + * ======== platform_mem_map ======== + * Purpose: + * This will maps a memory area into virtual space. + */ +int platform_mem_map(memory_map_info *map_info) +{ + int retval = 0; + struct platform_mem_map_table_info *info = NULL; + + if (atomic_cmpmask_and_lt(&(platform_mem_state.ref_count), + PLATFORM_MEM_MAKE_MAGICSTAMP(0), + PLATFORM_MEM_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto exit; + } + + if (WARN_ON(map_info == NULL)) { + retval = -EINVAL; + goto exit; + + } + + if (map_info->src == (u32) NULL) { + retval = -EINVAL; + goto exit; + } + + info = kmalloc(sizeof(struct platform_mem_map_table_info), + GFP_KERNEL); + if (info == NULL) { + retval = -ENOMEM; + goto exit; + } + + retval = mutex_lock_interruptible(platform_mem_state.gate); + if (retval) + goto lock_fail; + + map_info->dst = 0; + if (map_info->is_cached == true) + map_info->dst = (u32) ioremap((dma_addr_t) + (map_info->src), map_info->size); + else + map_info->dst = (u32) ioremap_nocache((dma_addr_t) + (map_info->src), map_info->size); + + if (map_info->dst == 0) { + retval = -EFAULT; + goto ioremap_fail; + } + + /* Populate the info */ + info->physical_address = map_info->src; + info->knl_virtual_address = map_info->dst; + info->size = map_info->size; + /* Put the info into the list */ + list_add(&info->mem_entry, &platform_mem_state.map_table); + mutex_unlock(platform_mem_state.gate); + goto exit; + +ioremap_fail: + mutex_unlock(platform_mem_state.gate); +lock_fail: + kfree(info); +exit: + return retval; +} +EXPORT_SYMBOL(platform_mem_map); + +/* + * ======== platform_mem_unmap ======== + * Purpose: + * This will unmaps a memory area into virtual space. + */ +int platform_mem_unmap(memory_unmap_info *unmap_info) +{ + s32 retval = 0; + struct platform_mem_map_table_info *info = NULL; + + + if (atomic_cmpmask_and_lt(&(platform_mem_state.ref_count), + PLATFORM_MEM_MAKE_MAGICSTAMP(0), + PLATFORM_MEM_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto exit; + } + + if (unmap_info == NULL) { + retval = -EINVAL; + goto exit; + } + + if (unmap_info->addr == (u32) NULL) { + retval = -EINVAL; + goto exit; + } + + retval = mutex_lock_interruptible(platform_mem_state.gate); + if (retval) + goto exit; + + iounmap((unsigned int *) unmap_info->addr); + /* Delete the node in the map table */ + list_for_each_entry(info, &platform_mem_state.map_table, mem_entry) { + if (info->knl_virtual_address == unmap_info->addr) { + list_del(&info->mem_entry); + kfree(info); + break; + } + } + mutex_unlock(platform_mem_state.gate); + +exit: + return retval; +} +EXPORT_SYMBOL(platform_mem_unmap); + +/* + * ======== platform_mem_map ======== + * Purpose: + * This will translate an address. + */ +void *platform_mem_translate(void *src_addr, enum memory_xlt_flags flags) +{ + void *buf = NULL; + struct platform_mem_map_table_info *tinfo = NULL; + u32 frm_addr; + u32 to_addr; + s32 retval = 0; + + if (atomic_cmpmask_and_lt(&(platform_mem_state.ref_count), + PLATFORM_MEM_MAKE_MAGICSTAMP(0), + PLATFORM_MEM_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto exit; + } + + retval = mutex_lock_interruptible(platform_mem_state.gate); + if (retval) + goto exit; + + /* Traverse to the node in the map table */ + list_for_each_entry(tinfo, &platform_mem_state.map_table, mem_entry) { + frm_addr = (flags == PLATFORM_MEM_XLT_FLAGS_VIRT2PHYS) ? + tinfo->knl_virtual_address : tinfo->physical_address; + to_addr = (flags == PLATFORM_MEM_XLT_FLAGS_VIRT2PHYS) ? + tinfo->physical_address : tinfo->knl_virtual_address; + if ((((u32) src_addr) >= frm_addr) + && (((u32) src_addr) < (frm_addr + tinfo->size))) { + buf = (void *) (to_addr + ((u32)src_addr - frm_addr)); + break; + } + } + mutex_unlock(platform_mem_state.gate); + +exit: + return buf; +} +EXPORT_SYMBOL(platform_mem_translate); + diff --git a/drivers/dsp/syslink/multicore_ipc/platformcfg.c b/drivers/dsp/syslink/multicore_ipc/platformcfg.c new file mode 100755 index 000000000000..360b275f0f43 --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/platformcfg.c @@ -0,0 +1,91 @@ +/* + * platformcfg.c + * + * Implementation of platform specific configuration for Syslink. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + + +/* Standard headers */ +#include <linux/types.h> +#include <linux/module.h> + +/* Utilities headers */ +#include <linux/string.h> + + +/* Module headers */ +#include <sysmgr.h> + +/* ============================================================================= + * APIS + * ============================================================================= + */ +/* + * ======== platform_override_config ======== + * Purpose: + * Function to override the default confiuration values. + */ +int platform_override_config(struct sysmgr_config *config) +{ + int status = 0; + + if (WARN_ON(config == NULL)) { + status = -EINVAL; + goto failure; + } + + /* Override the multiproc default config */ + config->multiproc_cfg.max_processors = 4; + config->multiproc_cfg.id = 0; + strcpy(config->multiproc_cfg.name_list[0], "MPU"); + strcpy(config->multiproc_cfg.name_list[1], "Tesla"); + strcpy(config->multiproc_cfg.name_list[2], "SysM3"); + strcpy(config->multiproc_cfg.name_list[3], "AppM3"); + + /* Override the gatepeterson default config */ + + /* Override the sharedregion default config */ + config->sharedregion_cfg.gate_handle = NULL; + config->sharedregion_cfg.heap_handle = NULL; + config->sharedregion_cfg.max_regions = 4; + + /* Override the listmp default config */ + + /* Override the messageq default config */ + /* We use 2 heaps, 1 for APPM3 and 1 for SYSM3 */ + /* FIXME: Temporary Fix - Add one more for the SW DMM heap */ + if (config->messageq_cfg.num_heaps < 3) + config->messageq_cfg.num_heaps = 3; + + /* Override the notify default config */ + config->notify_cfg.maxDrivers = 2; + + /* Override the procmgr default config */ + + /* Override the heapbuf default config */ + + /* Override the listmp_sharedmemory default config */ + + /* Override the messageq_transportshm default config */ + + /* Override the notify ducati driver default config */ + + /* Override the nameserver remotenotify default config */ + goto success; + +failure: + printk(KERN_ERR "platform_override_config failed [0x%x]", status); +success: + return status; +} diff --git a/drivers/dsp/syslink/multicore_ipc/sharedregion.c b/drivers/dsp/syslink/multicore_ipc/sharedregion.c new file mode 100755 index 000000000000..cfcd1aa1ee53 --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/sharedregion.c @@ -0,0 +1,800 @@ +/* + * sharedregion.c + * + * The SharedRegion module is designed to be used in a + * multi-processor environment where there are memory regions + * that are shared and accessed across different processors + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ +#include <linux/module.h> +#include <linux/types.h> +#include <linux/string.h> +#include <linux/slab.h> +#include <syslink/atomic_linux.h> + +#include <multiproc.h> +#include <nameserver.h> +#include <sharedregion.h> + +/* Macro to make a correct module magic number with refCount */ +#define SHAREDREGION_MAKE_MAGICSTAMP(x) ((SHAREDREGION_MODULEID << 16u) | (x)) + +#define SHAREDREGION_MAX_REGIONS_DEFAULT 4 + +/* + * Module state object + */ +struct sharedregion_module_object { + atomic_t ref_count; /* Reference count */ + struct mutex *gate_handle; + struct sharedregion_info *table; /* Ptr to the table */ + u32 bitOffset; /* Index bit offset */ + u32 region_size; /* Max size of each region */ + struct sharedregion_config cfg; /* Current config values */ + u32 *ref_count_table; /* The number of times each + entry has been added */ +}; + +/* + * Shared region state object variable with default settings + */ +static struct sharedregion_module_object sharedregion_state = { + .cfg.heap_handle = NULL, + .cfg.gate_handle = NULL, + .cfg.max_regions = SHAREDREGION_MAX_REGIONS_DEFAULT +}; + +/* + * ======== sharedregion_get_config ======== + * Purpose: + * This will get sharedregion module configiguration + */ +int sharedregion_get_config(struct sharedregion_config *config) +{ + BUG_ON((config == NULL)); + memcpy(config, &sharedregion_state.cfg, + sizeof(struct sharedregion_config)); + return 0; +} +EXPORT_SYMBOL(sharedregion_get_config); + + +/* + * ======== sharedregion_get_bitoffset ======== + * Purpose: + * This will get get the bit offset + */ +static u32 sharedregion_get_bitoffset(u32 max_regions) +{ + u32 i; + u32 bitoffset = 0; + for (i = ((sizeof(void *) * 8) - 1); i >= 0; i--) { + if (max_regions > (1 << i)) + break; + } + + bitoffset = (((sizeof(void *) * 8) - 1) - i); + return bitoffset; +} + +/* + * ======== sharedregion_setup ======== + * Purpose: + * This will get setup the sharedregion module + */ +int sharedregion_setup(const struct sharedregion_config *config) +{ + struct sharedregion_config *tmpcfg = &sharedregion_state.cfg; + struct sharedregion_info *table = NULL; + u32 i; + u32 j; + s32 retval = 0; + u16 proc_count; + + /* This sets the refCount variable is not initialized, upper 16 bits is + * written with module Id to ensure correctness of refCount variable + */ + atomic_cmpmask_and_set(&sharedregion_state.ref_count, + SHAREDREGION_MAKE_MAGICSTAMP(0), + SHAREDREGION_MAKE_MAGICSTAMP(0)); + + if (atomic_inc_return(&sharedregion_state.ref_count) + != SHAREDREGION_MAKE_MAGICSTAMP(1)) { + return 1; + } + + if (config != NULL) { + if (WARN_ON(config->max_regions == 0)) { + retval = -EINVAL; + goto error; + } + memcpy(&sharedregion_state.cfg, config, + sizeof(struct sharedregion_config)); + } + + sharedregion_state.gate_handle = kmalloc(sizeof(struct mutex), + GFP_KERNEL); + if (sharedregion_state.gate_handle == NULL) + goto gate_create_fail; + + sharedregion_state.bitOffset = + sharedregion_get_bitoffset(tmpcfg->max_regions); + sharedregion_state.region_size = (1 << sharedregion_state.bitOffset); + proc_count = multiproc_get_max_processors(); + /* TODO check heap usage & + 1 ? */ + sharedregion_state.table = kmalloc(sizeof(struct sharedregion_info) * + tmpcfg->max_regions * (proc_count + 1), + GFP_KERNEL); + if (sharedregion_state.table == NULL) { + retval = -ENOMEM; + goto table_alloc_fail; + } + + sharedregion_state.ref_count_table = kmalloc(sizeof(u32) * + tmpcfg->max_regions * (proc_count + 1), + GFP_KERNEL); + if (sharedregion_state.ref_count_table == NULL) { + retval = -ENOMEM; + goto table_alloc_fail; + } + + table = sharedregion_state.table; + for (i = 0; i < tmpcfg->max_regions; i++) { + for (j = 0; j < (proc_count + 1); j++) { + (table + (j * tmpcfg->max_regions) + i)->is_valid = + false; + (table + (j * tmpcfg->max_regions) + i)->base = 0; + (table + (j * tmpcfg->max_regions) + i)->len = 0; + sharedregion_state.ref_count_table[(j * + tmpcfg->max_regions) + i] = 0; + } + } + + mutex_init(sharedregion_state.gate_handle); + return 0; + +table_alloc_fail: + kfree(sharedregion_state.gate_handle); + +gate_create_fail: + memset(&sharedregion_state, 0, + sizeof(struct sharedregion_module_object)); + sharedregion_state.cfg.max_regions = SHAREDREGION_MAX_REGIONS_DEFAULT; + +error: + printk(KERN_ERR "sharedregion_setup failed status:%x\n", retval); + return retval; +} +EXPORT_SYMBOL(sharedregion_setup); + +/* + * ======== sharedregion_destroy ======== + * Purpose: + * This will get destroy the sharedregion module + */ +int sharedregion_destroy(void) +{ + s32 retval = 0; + void *gate_handle = NULL; + + if (atomic_cmpmask_and_lt(&(sharedregion_state.ref_count), + SHAREDREGION_MAKE_MAGICSTAMP(0), + SHAREDREGION_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto error; + } + + if (!(atomic_dec_return(&sharedregion_state.ref_count) + == SHAREDREGION_MAKE_MAGICSTAMP(0))) { + retval = 1; /* Syslink is not handling this on 2.0.0.06 */ + goto error; + } + + retval = mutex_lock_interruptible(sharedregion_state.gate_handle); + if (retval) + goto error; + + kfree(sharedregion_state.ref_count_table); + kfree(sharedregion_state.table); + gate_handle = sharedregion_state.gate_handle; /* backup gate handle */ + memset(&sharedregion_state, 0, + sizeof(struct sharedregion_module_object)); + sharedregion_state.cfg.max_regions = SHAREDREGION_MAX_REGIONS_DEFAULT; + mutex_unlock(gate_handle); + kfree(gate_handle); + return 0; + +error: + if (retval < 0) { + printk(KERN_ERR "sharedregion_destroy failed status:%x\n", + retval); + } + return retval; +} +EXPORT_SYMBOL(sharedregion_destroy); + +/* + * ======== sharedregion_add ======== + * Purpose: + * This will add a memory segment to the lookup table + * during runtime by base and length + */ +int sharedregion_add(u32 index, void *base, u32 len) +{ + struct sharedregion_info *entry = NULL; + struct sharedregion_info *table = NULL; + s32 retval = 0; + u32 i; + u16 myproc_id; + bool overlap = false; + bool same = false; + + if (atomic_cmpmask_and_lt(&(sharedregion_state.ref_count), + SHAREDREGION_MAKE_MAGICSTAMP(0), + SHAREDREGION_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto error; + } + + if (index >= sharedregion_state.cfg.max_regions || + sharedregion_state.region_size < len) { + retval = -EINVAL; + goto error; + } + + myproc_id = multiproc_get_id(NULL); + retval = mutex_lock_interruptible(sharedregion_state.gate_handle); + if (retval) + goto error; + + + table = sharedregion_state.table; + /* Check for overlap */ + for (i = 0; i < sharedregion_state.cfg.max_regions; i++) { + entry = (table + + (myproc_id * sharedregion_state.cfg.max_regions) + + i); + if (entry->is_valid) { + /* Handle duplicate entry */ + if ((base == entry->base) && (len == entry->len)) { + same = true; + break; + } + + if ((base >= entry->base) && + (base < (void *)((u32)entry->base + entry->len))) { + overlap = true; + break; + } + + if ((base < entry->base) && + (void *)((u32)base + len) >= entry->base) { + overlap = true; + break; + } + } + } + + if (same) { + retval = 1; + goto success; + } + + if (overlap) { + /* FHACK: FIX ME */ + retval = 1; + goto mem_overlap_error; + } + + entry = (table + + (myproc_id * sharedregion_state.cfg.max_regions) + + index); + if (entry->is_valid == false) { + entry->base = base; + entry->len = len; + entry->is_valid = true; + + } else { + /* FHACK: FIX ME */ + sharedregion_state.ref_count_table[(myproc_id * + sharedregion_state.cfg.max_regions) + + index] += 1; + retval = 1; + goto dup_entry_error; + } + +success: + mutex_unlock(sharedregion_state.gate_handle); + return 0; + +dup_entry_error: /* Fall through */ +mem_overlap_error: + printk(KERN_WARNING "sharedregion_add entry exists status: %x\n", + retval); + mutex_unlock(sharedregion_state.gate_handle); + +error: + if (retval < 0) + printk(KERN_ERR "sharedregion_add failed status:%x\n", retval); + return retval; +} +EXPORT_SYMBOL(sharedregion_add); + +/* + * ======== sharedregion_remove ======== + * Purpose: + * This will removes a memory segment to the lookup table + * during runtime by base and length + */ +int sharedregion_remove(u32 index) +{ + struct sharedregion_info *entry = NULL; + struct sharedregion_info *table = NULL; + u16 myproc_id; + s32 retval = 0; + + if (atomic_cmpmask_and_lt(&(sharedregion_state.ref_count), + SHAREDREGION_MAKE_MAGICSTAMP(0), + SHAREDREGION_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto error; + } + + if (index >= sharedregion_state.cfg.max_regions) { + retval = -EINVAL; + goto error; + } + + retval = mutex_lock_interruptible(sharedregion_state.gate_handle); + if (retval) + goto error; + + myproc_id = multiproc_get_id(NULL); + table = sharedregion_state.table; + entry = (table + + (myproc_id * sharedregion_state.cfg.max_regions) + + index); + + if (sharedregion_state.ref_count_table[(myproc_id * + sharedregion_state.cfg.max_regions) + + index] > 0) + sharedregion_state.ref_count_table[(myproc_id * + sharedregion_state.cfg.max_regions) + + index] -= 1; + else { + entry->is_valid = false; + entry->base = NULL; + entry->len = 0; + } + mutex_unlock(sharedregion_state.gate_handle); + return 0; + +error: + printk(KERN_ERR "sharedregion_remove failed status:%x\n", retval); + return retval; +} +EXPORT_SYMBOL(sharedregion_remove); + +/* + * ======== sharedregion_get_index ======== + * Purpose: + * This will return the index for the specified address pointer. + */ +int sharedregion_get_index(void *addr) +{ + struct sharedregion_info *entry = NULL; + struct sharedregion_info *table = NULL; + bool found = false; + u32 i; + u16 myproc_id; + s32 retval = 0; + + if (WARN_ON(atomic_cmpmask_and_lt(&(sharedregion_state.ref_count), + SHAREDREGION_MAKE_MAGICSTAMP(0), + SHAREDREGION_MAKE_MAGICSTAMP(1)) == true)) { + retval = -ENODEV; + goto exit; + } + + myproc_id = multiproc_get_id(NULL); + retval = mutex_lock_interruptible(sharedregion_state.gate_handle); + if (retval) { + retval = -ENODEV; + goto exit; + } + + table = sharedregion_state.table; + for (i = 0; i < sharedregion_state.cfg.max_regions; i++) { + entry = (table + + (myproc_id * sharedregion_state.cfg.max_regions) + + i); + if ((addr >= entry->base) && + (addr < (void *)((u32)entry->base + (entry->len)))) { + found = true; + break; + } + } + + if (found) + retval = i; + else + retval = -ENOENT; /* No entry found in the table */ + + mutex_unlock(sharedregion_state.gate_handle); + return retval; + +exit: + printk(KERN_ERR "sharedregion_get_index failed index:%x\n", retval); + return retval; +} +EXPORT_SYMBOL(sharedregion_get_index); + +/* + * ======== sharedregion_get_ptr ======== + * Purpose: + * This will return the address pointer associated with the + * shared region pointer + */ +void *sharedregion_get_ptr(u32 *srptr) +{ + struct sharedregion_info *entry = NULL; + void *ptr = NULL; + u16 myproc_id; + s32 retval = 0; + + if (atomic_cmpmask_and_lt(&(sharedregion_state.ref_count), + SHAREDREGION_MAKE_MAGICSTAMP(0), + SHAREDREGION_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto error; + } + + if (srptr == SHAREDREGION_INVALIDSRPTR) + goto error; + + myproc_id = multiproc_get_id(NULL); + retval = mutex_lock_interruptible(sharedregion_state.gate_handle); + if (WARN_ON(retval != 0)) + goto error; + + entry = (sharedregion_state.table + + (myproc_id * sharedregion_state.cfg.max_regions) + + ((u32)srptr >> sharedregion_state.bitOffset)); + /* TO DO check:: is this correct ? */ + ptr = ((void *)(((u32)srptr & + ((1 << sharedregion_state.bitOffset) - 1)) + (u32)entry->base)); + mutex_unlock(sharedregion_state.gate_handle); + return ptr; + +error: + printk(KERN_ERR "sharedregion_get_ptr failed \n"); + return (void *)NULL; + +} +EXPORT_SYMBOL(sharedregion_get_ptr); + +/* + * ======== sharedregion_get_srptr ======== + * Purpose: + * This will return sharedregion pointer associated with the + * an address in a shared region area registered with the + * sharedregion module + */ +u32 *sharedregion_get_srptr(void *addr, s32 index) +{ + struct sharedregion_info *entry = NULL; + u32 *ptr = SHAREDREGION_INVALIDSRPTR ; + u32 myproc_id; + s32 retval = 0; + + if (atomic_cmpmask_and_lt(&(sharedregion_state.ref_count), + SHAREDREGION_MAKE_MAGICSTAMP(0), + SHAREDREGION_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto error; + } + + if (WARN_ON(addr == NULL)) + goto error; + + if (WARN_ON(index >= sharedregion_state.cfg.max_regions)) + goto error; + + retval = mutex_lock_interruptible(sharedregion_state.gate_handle); + if (WARN_ON(retval != 0)) + goto error; + + myproc_id = multiproc_get_id(NULL); + entry = (sharedregion_state.table + + (myproc_id * sharedregion_state.cfg.max_regions) + + index); + ptr = (u32 *) ((index << sharedregion_state.bitOffset) + | ((u32)addr - (u32)entry->base)); + mutex_unlock(sharedregion_state.gate_handle); + return ptr; + +error: + printk(KERN_ERR "sharedregion_get_srptr failed\n"); + return (u32 *)NULL; +} +EXPORT_SYMBOL(sharedregion_get_srptr); + +/* + * ======== sharedregion_get_table_info ======== + * Purpose: + * This will get the table entry information for the + * specified index and id + */ +int sharedregion_get_table_info(u32 index, u16 proc_id, + struct sharedregion_info *info) +{ + struct sharedregion_info *entry = NULL; + struct sharedregion_info *table = NULL; + u16 proc_count; + s32 retval = 0; + + BUG_ON(info == NULL); + if (atomic_cmpmask_and_lt(&(sharedregion_state.ref_count), + SHAREDREGION_MAKE_MAGICSTAMP(0), + SHAREDREGION_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto error; + } + + proc_count = multiproc_get_max_processors(); + if (index >= sharedregion_state.cfg.max_regions || + proc_id >= proc_count) { + retval = -EINVAL; + goto error; + } + + retval = mutex_lock_interruptible(sharedregion_state.gate_handle); + if (retval) + goto error; + + table = sharedregion_state.table; + entry = (table + + (proc_id * sharedregion_state.cfg.max_regions) + + index); + memcpy((void *) info, (void *) entry, sizeof(struct sharedregion_info)); + mutex_unlock(sharedregion_state.gate_handle); + return 0; + +error: + printk(KERN_ERR "sharedregion_get_table_info failed status:%x\n", + retval); + return retval; +} +EXPORT_SYMBOL(sharedregion_get_table_info); + +/* + * ======== sharedregion_set_table_info ======== + * Purpose: + * This will set the table entry information for the + * specified index and id + */ +int sharedregion_set_table_info(u32 index, u16 proc_id, + struct sharedregion_info *info) +{ + struct sharedregion_info *entry = NULL; + struct sharedregion_info *table = NULL; + u16 proc_count; + s32 retval = 0; + + BUG_ON(info != NULL); + if (atomic_cmpmask_and_lt(&(sharedregion_state.ref_count), + SHAREDREGION_MAKE_MAGICSTAMP(0), + SHAREDREGION_MAKE_MAGICSTAMP(1)) == true) { + retval = -ENODEV; + goto error; + } + + proc_count = multiproc_get_max_processors(); + if (index >= sharedregion_state.cfg.max_regions || + proc_id >= proc_count) { + retval = -EINVAL; + goto error; + } + + retval = mutex_lock_interruptible(sharedregion_state.gate_handle); + if (retval) + goto error; + + table = sharedregion_state.table; + entry = (table + + (proc_id * sharedregion_state.cfg.max_regions) + + index); + memcpy((void *) entry, (void *) info, sizeof(struct sharedregion_info)); + mutex_unlock(sharedregion_state.gate_handle); + return 0; + +error: + printk(KERN_ERR "sharedregion_set_table_info failed status:%x\n", + retval); + return retval; +} +EXPORT_SYMBOL(sharedregion_set_table_info); + +/* + * ======== Sharedregion_attach ======== + * Purpose: + * This will attachs the shared region with an proc_id + * + * Application should call this function from the callback + * function registered for device attach to the processor + * manager. All modules which requires some logic setup + * to be done when a device gets attach to the system, + * should export API like this. Please see the below psuedo + * code for example: + * Example + * code + * void function (proc_id, config) { + * NotifyDriver_attach (proc_id, config->ndParams); + * SysMemMgr_attach (proc_id); + * SMM_attach (proc_id); + * NameServerRemoteTransport_attach(proc_id, config->nsrtParams); + * SharedRegion_attach (proc_id); + * SharedMemory_getConfig (&cfg); + * for (i = 0u; i < cfg->maxRegions; i++) { + * SharedRegion_getTableInfo(i, &myinfo, myProcId); + * SharedRegion_getTableInfo(i, &peerinfo, proc_id); + * DMM_map (proc_id, + * PA(myinfo->vaddr), + * peerinfo->vaddr, + * myinfo->len); + * } + * ... + * } + * + * main () { + * # attach callback for device attach only + * ProcMgr_register (function, proc_id, DEV_ATTACH); + * } + * + */ +void sharedregion_attach(u16 proc_id) +{ + struct sharedregion_info *entry = NULL; + struct sharedregion_info *table = NULL; + char *hexstr = "0123456789ABCDEF"; + char tname[80]; + u16 proc_id_list[2]; + u32 addr = 0; + u32 len; + u16 proc_count; + void *nshandle; + s32 retval = 0; + s32 i; + + if (WARN_ON(sharedregion_state.table == NULL)) + goto error; + + proc_count = multiproc_get_max_processors(); + if (WARN_ON(proc_id >= proc_count)) + goto error; + + proc_id_list[0] = proc_id; + proc_id_list[1] = MULTIPROC_INVALIDID; + nshandle = nameserver_get_handle(SHAREDREGION_NAMESERVER); + if (nshandle == NULL) + goto error; + + /* Get Shared region entries from the remote shared region nameserver */ + for (i = 0u; i < sharedregion_state.cfg.max_regions; i++) { + memset(tname, 0, 80); + strcpy(tname, "SHAREDREGION:SRENTRY_ADDR_"); + tname[strlen(tname)] = hexstr[(proc_id >> 4u) & 0xF]; + tname[strlen(tname)] = hexstr[proc_id & 0xF]; + tname[strlen(tname)] = '_'; + tname[strlen(tname)] = hexstr[(i >> 28u) & 0xF]; + tname[strlen(tname)] = hexstr[(i >> 24u) & 0xF]; + tname[strlen(tname)] = hexstr[(i >> 20u) & 0xF]; + tname[strlen(tname)] = hexstr[(i >> 16u) & 0xF]; + tname[strlen(tname)] = hexstr[(i >> 12u) & 0xF]; + tname[strlen(tname)] = hexstr[(i >> 8u) & 0xF]; + tname[strlen(tname)] = hexstr[(i >> 4u) & 0xF]; + tname[strlen(tname)] = hexstr[i & 0xF]; + retval = nameserver_get(nshandle, tname, + &len, sizeof(u32), &proc_id_list[0]); + if (WARN_ON(retval)) + ; + + memset(tname, 0, 80u); + strcpy(tname, "SHAREDREGION:SRENTRY_LEN_"); + tname[strlen(tname)] = hexstr[(proc_id >> 4u) & 0xF]; + tname[strlen(tname)] = hexstr[proc_id & 0xF]; + tname[strlen(tname)] = '_'; + tname[strlen(tname)] = hexstr[(i >> 28u) & 0xF]; + tname[strlen(tname)] = hexstr[(i >> 24u) & 0xF]; + tname[strlen(tname)] = hexstr[(i >> 20u) & 0xF]; + tname[strlen(tname)] = hexstr[(i >> 16u) & 0xF]; + tname[strlen(tname)] = hexstr[(i >> 12u) & 0xF]; + tname[strlen(tname)] = hexstr[(i >> 8u) & 0xF]; + tname[strlen(tname)] = hexstr[(i >> 4u) & 0xF]; + tname[strlen(tname)] = hexstr[i & 0xF]; + + /* TO DO : check this */ + retval = nameserver_get(nshandle, tname, + &len, sizeof(u32), &proc_id_list[0]); + if (WARN_ON(retval)) + ; + + /* Found an entry in the remote nameserver */ + /* Add it into the shared region table */ + if (retval == 0) { + retval = mutex_lock_interruptible( + sharedregion_state.gate_handle); + if (WARN_ON(retval)) + break; + + table = sharedregion_state.table; + /* mark entry invalid */ + entry = (table + + (proc_id * sharedregion_state.cfg.max_regions) + + i); + entry->base = (void *)addr; + entry->len = len; + entry->is_valid = false; + mutex_unlock(sharedregion_state.gate_handle); + } + + } + +error: + return; +} +EXPORT_SYMBOL(sharedregion_attach); + +/* + * ======== Sharedregion_detach ======== + * Purpose: + * This will detachs the shared region for an proc_id + * + * Application should call this function from the callback + * function registered for device detach to the processorl + * manager. All modules which requires some logic setup + * to be done when a device gets detach from the system, + * should export API like this. + * Please see the below psuedo code for example: + * @Example + * @code + * void function (proc_id) { + * SharedRegion_detach (proc_id); + * SysMemMgr_detach (proc_id); + * ... + * # Name server must be detached last + * nameserver_detach (proc_id); + * } + * + * main () { + * # attach callback for device detach only + * Processor_register (function, proc_id, DEV_DETACH); + * } + * + */ +void sharedregion_detach(u16 proc_id) +{ + u16 proc_count; + + if (WARN_ON(sharedregion_state.table == NULL)) + goto error; + + proc_count = multiproc_get_max_processors(); + if (WARN_ON(proc_id >= proc_count)) + goto error; + +error: + return; +} +EXPORT_SYMBOL(sharedregion_detach); + diff --git a/drivers/dsp/syslink/multicore_ipc/sharedregion_ioctl.c b/drivers/dsp/syslink/multicore_ipc/sharedregion_ioctl.c new file mode 100755 index 000000000000..863bb1d4a033 --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/sharedregion_ioctl.c @@ -0,0 +1,354 @@ +/* + * sharedregion_ioctl.c + * + * The sharedregion module is designed to be used in a + * multi-processor environment where there are memory regions + * that are shared and accessed across different processors + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#include <linux/uaccess.h> +#include <linux/types.h> +#include <linux/bug.h> +#include <linux/fs.h> + +#include <multiproc.h> +#include <sharedregion.h> +#include <sharedregion_ioctl.h> +#include <platform_mem.h> + +/* + * ======== sharedregion_ioctl_get_config ======== + * Purpose: + * This ioctl interface to sharedregion_get_config function + */ +static int sharedregion_ioctl_get_config(struct sharedregion_cmd_args *cargs) +{ + + struct sharedregion_config config; + s32 status = 0; + s32 size; + + cargs->api_status = sharedregion_get_config(&config); + size = copy_to_user(cargs->args.get_config.config, &config, + sizeof(struct sharedregion_config)); + if (size) + status = -EFAULT; + + return status; +} + + +/* + * ======== sharedregion_ioctl_setup ======== + * Purpose: + * This ioctl interface to sharedregion_setup function + */ +static int sharedregion_ioctl_setup(struct sharedregion_cmd_args *cargs) +{ + struct sharedregion_config config; + struct sharedregion_config defaultcfg; + struct sharedregion_info info; + struct sharedregion_info *table; + u32 proc_count = 0; + u32 i; + u32 j; + s32 status = 0; + s32 size; + + size = copy_from_user(&config, cargs->args.setup.config, + sizeof(struct sharedregion_config)); + if (size) { + status = -EFAULT; + goto exit; + } + + cargs->api_status = sharedregion_setup(&config); + if (cargs->api_status != 0) + goto exit; + + cargs->api_status = sharedregion_get_config(&defaultcfg); + size = copy_to_user(cargs->args.setup.default_cfg, + &defaultcfg, + sizeof(struct sharedregion_config)); + if (size) { + status = -EFAULT; + goto exit; + } + + proc_count = multiproc_get_max_processors(); + table = cargs->args.setup.table; + for (i = 0; i < config.max_regions; i++) { + for (j = 0; j < (proc_count); j++) { + sharedregion_get_table_info(i, j, &info); + if (info.is_valid == true) { + /* Convert kernel virtual address to physical + * addresses */ + info.base = platform_mem_translate(info.base, + PLATFORM_MEM_XLT_FLAGS_VIRT2PHYS); + size = copy_to_user((void *) (table + + (j * config.max_regions) + + i), + (void *) &info, + sizeof( + struct sharedregion_info)); + if (size) { + status = -EFAULT; + goto exit; + } /* End of inner if */ + } /* End of outer if */ + } /* End of inner for loop */ + } + +exit: + return status; +} + +/* + * ======== sharedregion_ioctl_destroy======== + * Purpose: + * This ioctl interface to sharedregion_destroy function + */ +static int sharedregion_ioctl_destroy( + struct sharedregion_cmd_args *cargs) +{ + cargs->api_status = sharedregion_destroy(); + return 0; +} + +/* + * ======== sharedregion_ioctl_add ======== + * Purpose: + * This ioctl interface to sharedregion_add function + */ +static int sharedregion_ioctl_add(struct sharedregion_cmd_args *cargs) +{ + u32 base = (u32)platform_mem_translate(cargs->args.add.base, + PLATFORM_MEM_XLT_FLAGS_PHYS2VIRT); + cargs->api_status = sharedregion_add(cargs->args.add.index, + (void *)base, cargs->args.add.len); + return 0; +} + + + +/* + * ======== sharedregion_ioctl_get_index ======== + * Purpose: + * This ioctl interface to sharedregion_get_index function + */ +static int sharedregion_ioctl_get_index(struct sharedregion_cmd_args *cargs) +{ + s32 index = 0; + + index = sharedregion_get_index(cargs->args.get_index.addr); + cargs->args.get_index.index = index; + cargs->api_status = 0; + return 0; +} + +/* + * ======== sharedregion_ioctl_get_ptr ======== + * Purpose: + * This ioctl interface to sharedregion_get_ptr function + */ +static int sharedregion_ioctl_get_ptr(struct sharedregion_cmd_args *cargs) +{ + void *addr = NULL; + + addr = sharedregion_get_ptr(cargs->args.get_ptr.srptr); + /* We are not checking the return from the module, its user + responsibilty to pass proper value to application + */ + cargs->args.get_ptr.addr = addr; + cargs->api_status = 0; + return 0; +} + +/* + * ======== sharedregion_ioctl_get_srptr ======== + * Purpose: + * This ioctl interface to sharedregion_get_srptr function + */ +static int sharedregion_ioctl_get_srptr(struct sharedregion_cmd_args *cargs) +{ + u32 *srptr = NULL; + + srptr = sharedregion_get_srptr(cargs->args.get_srptr.addr, + cargs->args.get_srptr.index); + /* We are not checking the return from the module, its user + responsibilty to pass proper value to application + */ + cargs->args.get_srptr.srptr = srptr; + cargs->api_status = 0; + return 0; +} + +/* + * ======== sharedregion_ioctl_get_table_info ======== + * Purpose: + * This ioctl interface to sharedregion_get_table_info function + */ +static int sharedregion_ioctl_get_table_info( + struct sharedregion_cmd_args *cargs) +{ + struct sharedregion_info info; + s32 status = 0; + s32 size; + + cargs->api_status = sharedregion_get_table_info( + cargs->args.get_table_info.index, + cargs->args.get_table_info.proc_id, &info); + size = copy_to_user(cargs->args.get_table_info.info, &info, + sizeof(struct sharedregion_info)); + if (size) + status = -EFAULT; + + return status; +} + + +/* + * ======== sharedregion_ioctl_remove ======== + * Purpose: + * This ioctl interface to sharedregion_remove function + */ +static int sharedregion_ioctl_remove(struct sharedregion_cmd_args *cargs) +{ + cargs->api_status = sharedregion_remove(cargs->args.remove.index); + return 0; +} + +/* + * ======== sharedregion_ioctl_set_table_info ======== + * Purpose: + * This ioctl interface to sharedregion_set_table_info function + */ +static int sharedregion_ioctl_set_table_info( + struct sharedregion_cmd_args *cargs) +{ + struct sharedregion_info info; + s32 status = 0; + s32 size; + + size = copy_from_user(&info, cargs->args.set_table_info.info, + sizeof(struct sharedregion_info)); + if (size) { + status = -EFAULT; + goto exit; + } + + cargs->api_status = sharedregion_set_table_info( + cargs->args.set_table_info.index, + cargs->args.set_table_info.proc_id, &info); + +exit: + return status; +} + +/* + * ======== sharedregion_ioctl ======== + * Purpose: + * This ioctl interface for sharedregion module + */ +int sharedregion_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long args) +{ + s32 status = 0; + s32 size = 0; + struct sharedregion_cmd_args __user *uarg = + (struct sharedregion_cmd_args __user *)args; + struct sharedregion_cmd_args cargs; + + if (_IOC_DIR(cmd) & _IOC_READ) + status = !access_ok(VERIFY_WRITE, uarg, _IOC_SIZE(cmd)); + else if (_IOC_DIR(cmd) & _IOC_WRITE) + status = !access_ok(VERIFY_READ, uarg, _IOC_SIZE(cmd)); + + if (status) { + status = -EFAULT; + goto exit; + } + + /* Copy the full args from user-side */ + size = copy_from_user(&cargs, uarg, + sizeof(struct sharedregion_cmd_args)); + if (size) { + status = -EFAULT; + goto exit; + } + + switch (cmd) { + case CMD_SHAREDREGION_GETCONFIG: + status = sharedregion_ioctl_get_config(&cargs); + break; + + case CMD_SHAREDREGION_SETUP: + status = sharedregion_ioctl_setup(&cargs); + break; + + case CMD_SHAREDREGION_DESTROY: + status = sharedregion_ioctl_destroy(&cargs); + break; + + case CMD_SHAREDREGION_ADD: + status = sharedregion_ioctl_add(&cargs); + break; + + case CMD_SHAREDREGION_GETINDEX: + status = sharedregion_ioctl_get_index(&cargs); + break; + + case CMD_SHAREDREGION_GETPTR: + status = sharedregion_ioctl_get_ptr(&cargs); + break; + + case CMD_SHAREDREGION_GETSRPTR: + status = sharedregion_ioctl_get_srptr(&cargs); + break; + + case CMD_SHAREDREGION_GETTABLEINFO: + status = sharedregion_ioctl_get_table_info(&cargs); + break; + + case CMD_SHAREDREGION_REMOVE: + status = sharedregion_ioctl_remove(&cargs); + break; + + case CMD_SHAREDREGION_SETTABLEINFO: + status = sharedregion_ioctl_set_table_info(&cargs); + break; + + default: + WARN_ON(cmd); + status = -ENOTTY; + break; + } + + if ((cargs.api_status == -ERESTARTSYS) || (cargs.api_status == -EINTR)) + status = -ERESTARTSYS; + + if (status < 0) + goto exit; + + /* Copy the full args to the user-side. */ + size = copy_to_user(uarg, &cargs, sizeof(struct sharedregion_cmd_args)); + if (size) { + status = -EFAULT; + goto exit; + } + +exit: + return status; +} + diff --git a/drivers/dsp/syslink/multicore_ipc/sysmemmgr.c b/drivers/dsp/syslink/multicore_ipc/sysmemmgr.c new file mode 100644 index 000000000000..60bdad0c188f --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/sysmemmgr.c @@ -0,0 +1,459 @@ +/* + * sysmemmgr.c + * + * Manager for the Slave system memory. Slave system level memory is allocated + * through this modules. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + + +/* Standard headers */ +#include <linux/types.h> +#include <linux/module.h> + +/* Utils headers */ +#include <linux/vmalloc.h> +#include <syslink/atomic_linux.h> +#include <syslink/platform_mem.h> +/*#include <GateMutex.h> +#include <Memory.h> +#include <Trace.h>*/ + + +/* Module level headers */ +#include <sysmemmgr.h> +/*#include <BuddyPageAllocator.h>*/ + + +/* ============================================================================= + * Macros + * ============================================================================= + */ +/*! @brief Event reserved for System memory manager */ +#define SYSMEMMGR_EVENTNO 12 + +/* Macro to make a correct module magic number with ref_count */ +#define SYSMEMMGR_MAKE_MAGICSTAMP(x) ((SYSMEMMGR_MODULEID << 12) | (x)) + +/* ============================================================================= + * Structs & Enums + * ============================================================================= + */ +/*! @brief Structure containing list of buffers. The list is kept sorted by + * address. */ +struct sysmemmgr_static_mem_struct { + struct sysmemmgr_static_mem_struct *next; + /*!< Pointer to next entry */ + u32 address; + /*!< Address of this entry */ + u32 size; + /*!< Size of this entry */ +}; + + +/*! @brief Static memory manager object. */ +struct sysmemmgr_static_mem_mgr_obj { + struct sysmemmgr_static_mem_struct head; + /*!< Pointer to head entry */ + struct sysmemmgr_static_mem_struct tail; + /*!< Pointer to tail entry */ +}; + +/*! + * @brief Structure defining state object of system memory manager. + */ +struct sysmemmgr_module_object { + atomic_t ref_count; + /*!< Reference count */ + struct sysmemmgr_static_mem_mgr_obj static_mem_obj; + /*!< Static memory manager object */ + struct mutex *gate_handle; + /*!< Pointer to lock */ + struct sysmemmgr_config cfg; + /*!< Current configuration values */ + struct sysmemmgr_config default_cfg; + /*!< Default configuration values */ +}; + + +/*! + * @brief Object containing state of the system memory manager. + */ +static struct sysmemmgr_module_object sysmemmgr_state = { + .default_cfg.sizeof_valloc = 0x100000, + .default_cfg.sizeof_palloc = 0x100000, + .default_cfg.page_size = 0x1000, + .default_cfg.event_no = SYSMEMMGR_EVENTNO, +}; + + +/* ============================================================================= + * APIS + * ============================================================================= + */ +/* + * ======== sysmemmgr_get_config ======== + * Purpose: + * Function to get the default values for configuration. + */ +void sysmemmgr_get_config(struct sysmemmgr_config *config) +{ + if (WARN_ON(config == NULL)) + goto err_exit; + + if (atomic_cmpmask_and_lt(&(sysmemmgr_state.ref_count), + SYSMEMMGR_MAKE_MAGICSTAMP(0), + SYSMEMMGR_MAKE_MAGICSTAMP(1)) == true) + memcpy((void *) config, (void *)(&sysmemmgr_state.default_cfg), + sizeof(struct sysmemmgr_config)); + else + memcpy((void *) config, (void *)(&sysmemmgr_state.cfg), + sizeof(struct sysmemmgr_config)); + + return; + +err_exit: + printk(KERN_ERR "sysmemmgr_get_config: Argument of type " + "(struct sysmemmgr_config *) passed is NULL\n"); + return; +} + + +/* + * ======== sysmemmgr_setup ======== + * Purpose: + * Function to get the default values for configuration. + */ +int sysmemmgr_setup(struct sysmemmgr_config *config) +{ + int status = 0; + struct sysmemmgr_static_mem_mgr_obj *smmObj = NULL; + + /* This sets the ref_count variable is not initialized, upper 16 bits is + * written with module Id to ensure correctness of ref_count variable. + */ + atomic_cmpmask_and_set(&sysmemmgr_state.ref_count, + SYSMEMMGR_MAKE_MAGICSTAMP(0), SYSMEMMGR_MAKE_MAGICSTAMP(0)); + + if (atomic_inc_return(&sysmemmgr_state.ref_count) != \ + SYSMEMMGR_MAKE_MAGICSTAMP(1)) { + status = SYSMEMMGR_S_ALREADYSETUP; + goto exit; + } + + if (WARN_ON(config == NULL)) { + /* Config parameters are not provided */ + status = -EINVAL; + goto err_config; + } + if (WARN_ON((config->static_virt_base_addr == (u32) NULL) + && (config->static_mem_size != 0))) { + /* Virtual Base address of static memory region is NULL */ + status = -EINVAL; + goto err_virt_addr; + } + if (WARN_ON((config->static_phys_base_addr == (u32) NULL) + && (config->static_mem_size != 0))) { + /*Physical Base address of static memory region is NULL */ + status = -EINVAL; + goto err_phys_addr; + } + + /* Copy the config parameters to the module state */ + memcpy((void *)(&sysmemmgr_state.cfg), (void *) config, + sizeof(struct sysmemmgr_config)); + + /* Create the static memory allocator */ + if (config->static_mem_size != 0) { + smmObj = &sysmemmgr_state.static_mem_obj; + smmObj->head.address = config->static_virt_base_addr; + smmObj->head.size = 0; + smmObj->tail.address = (config->static_virt_base_addr + \ + config->static_mem_size); + smmObj->tail.size = 0; + smmObj->head.next = &smmObj->tail; + smmObj->tail.next = NULL; + } + + /* Create the lock */ + sysmemmgr_state.gate_handle = kzalloc(sizeof(struct mutex), GFP_KERNEL); + if (sysmemmgr_state.gate_handle == NULL) { + /* Failed to create gate handle */ + status = -ENOMEM; + goto err_mem_gate; + } + return 0; + +err_mem_gate: + printk(KERN_ERR "sysmemmgr_setup: Failed to create gate handle\n"); + goto exit; + +err_phys_addr: + printk(KERN_ERR "sysmemmgr_setup: Physical Base address of static " + "memory region is NULL\n"); + goto exit; + +err_virt_addr: + printk(KERN_ERR "sysmemmgr_setup: Virtual Base address of static " + "memory region is NULL\n"); + goto exit; + +err_config: + printk(KERN_ERR "sysmemmgr_setup: Argument of type " + "(struct sysmemmgr_config *) passed is NULL\n"); + goto exit; + +exit: + if (status < 0) { + atomic_set(&sysmemmgr_state.ref_count, + SYSMEMMGR_MAKE_MAGICSTAMP(0)); + } + return status; +} + + +/* + * ======== sysmemmgr_destroy ======== + * Purpose: + * Function to finalize the system memory manager module. + */ +int sysmemmgr_destroy(void) +{ + int status = 0; + + if (atomic_cmpmask_and_lt(&(sysmemmgr_state.ref_count), + SYSMEMMGR_MAKE_MAGICSTAMP(0), SYSMEMMGR_MAKE_MAGICSTAMP(1)) == \ + true) { + /*! @retval SYSMEMMGR_E_INVALIDSTATE Module was not + * initialized */ + status = SYSMEMMGR_E_INVALIDSTATE; + goto err_exit; + } + + if (atomic_dec_return(&sysmemmgr_state.ref_count) == \ + SYSMEMMGR_MAKE_MAGICSTAMP(0)) { + /* Delete the lock */ + kfree(sysmemmgr_state.gate_handle); + } + return 0; + +err_exit: + printk(KERN_ERR "sysmemgr_destroy: Module was not initialized\n"); + return status; +} + + +/* + * ======== sysmemmgr_alloc ======== + * Purpose: + * Function to allocate a memory block. + */ +void *sysmemmgr_alloc(u32 size, enum sysmemmgr_allocflag flag) +{ + int status = 0; + struct sysmemmgr_static_mem_mgr_obj *smObj = NULL; + struct sysmemmgr_static_mem_struct *ptr = NULL; + struct sysmemmgr_static_mem_struct *newptr = NULL; + void *ret_ptr = NULL; + + if (atomic_cmpmask_and_lt(&(sysmemmgr_state.ref_count), + SYSMEMMGR_MAKE_MAGICSTAMP(0), SYSMEMMGR_MAKE_MAGICSTAMP(1)) == \ + true) { + /*! @retval SYSMEMMGR_E_INVALIDSTATE Module was not + * initialized */ + status = SYSMEMMGR_E_INVALIDSTATE; + goto err_exit; + } + + if ((flag & sysmemmgr_allocflag_physical) && \ + !(flag & sysmemmgr_allocflag_dma)) { + /* TBD: works with DMM + ret_ptr = platform_mem_alloc (size, 0, + MemoryOS_MemTypeFlags_Physical); */ + if (ret_ptr == NULL) { + if (sysmemmgr_state.cfg.static_mem_size == 0) { + /* Memory pool is not configured. */ + status = -ENOMEM; + goto exit; + } + + smObj = &sysmemmgr_state.static_mem_obj; + ptr = &smObj->head; + while (ptr && ptr->next) { + if (((ptr->next->address - \ + (ptr->address + ptr->size)) >= size)) + break; + ptr = ptr->next; + } + + if (ptr->next == NULL) { + status = -ENOMEM; + goto exit; + } + + newptr = vmalloc( + sizeof(struct sysmemmgr_static_mem_struct)); + if (newptr != NULL) { + newptr->address = ptr->address + ptr->size; + newptr->size = size; + newptr->next = ptr->next; + ptr->next = newptr; + ret_ptr = (void *) newptr->address; + } else { + status = -ENOMEM; + } + } + goto exit; + } + + if (flag & sysmemmgr_allocflag_physical) { + ret_ptr = kmalloc(size, GFP_KERNEL); + if (ret_ptr == NULL) + status = -ENOMEM; + goto exit; + } + + if (flag & sysmemmgr_allocflag_dma) { + ret_ptr = kmalloc(size, GFP_KERNEL | GFP_DMA); + if (ret_ptr == NULL) + status = -ENOMEM; + goto exit; + } + + ret_ptr = vmalloc(size); + if (ret_ptr == NULL) { + status = -ENOMEM; + goto exit; + } + +err_exit: + printk(KERN_ERR "sysmemgr_alloc: Module was not initialized\n"); +exit: + if (WARN_ON(ret_ptr == NULL)) + printk(KERN_ERR "sysmemmgr_alloc: Allocation failed\n"); + return ret_ptr; +} + + +/* + * ======== sysmemmgr_free ======== + * Purpose: + * Function to de-allocate a previous allocated memory block. + */ +int sysmemmgr_free(void *blk, u32 size, enum sysmemmgr_allocflag flag) +{ + int status = 0; + struct sysmemmgr_static_mem_mgr_obj *smObj = NULL; + struct sysmemmgr_static_mem_struct *ptr = NULL; + struct sysmemmgr_static_mem_struct *prev = NULL; + + if (atomic_cmpmask_and_lt(&(sysmemmgr_state.ref_count), + SYSMEMMGR_MAKE_MAGICSTAMP(0), SYSMEMMGR_MAKE_MAGICSTAMP(1)) == \ + true) { + /*! @retval SYSMEMMGR_E_INVALIDSTATE Module was not + * initialized */ + status = SYSMEMMGR_E_INVALIDSTATE; + goto err_exit; + } + + if ((flag & sysmemmgr_allocflag_physical) && \ + !(flag & sysmemmgr_allocflag_dma)) { + if (((u32) blk >= sysmemmgr_state.cfg.static_virt_base_addr) + && ((u32) blk < \ + (sysmemmgr_state.cfg.static_virt_base_addr + \ + sysmemmgr_state.cfg.static_mem_size))) { + smObj = &sysmemmgr_state.static_mem_obj; + ptr = &smObj->head; + while (ptr && ptr->next) { + if (ptr->next->address == (u32) blk) + break; + ptr = ptr->next; + } + prev = ptr; + ptr = ptr->next; + prev->next = ptr->next; + + /* Free the node */ + vfree(ptr); + } else { + kfree(blk); + } + } else if (flag & sysmemmgr_allocflag_physical) { + kfree(blk); + } else if (flag & sysmemmgr_allocflag_dma) { + kfree(blk); + } else { + vfree(blk); + } + return 0; + +err_exit: + printk(KERN_ERR "sysmemgr_free: Module was not initialized\n"); + return status; +} + + +/* + * ======== sysmemmgr_setup ======== + * Purpose: + * Function to translate an address among different address spaces. + */ +void *sysmemmgr_translate(void *src_addr, enum sysmemmgr_xltflag flags) +{ + void *ret_ptr = NULL; + + switch (flags) { + case sysmemmgr_xltflag_kvirt2phys: + { + if (((u32) src_addr >= \ + sysmemmgr_state.cfg.static_virt_base_addr) && \ + ((u32) src_addr < \ + (sysmemmgr_state.cfg.static_virt_base_addr + \ + sysmemmgr_state.cfg.static_mem_size))) { + ret_ptr = (void *)(((u32) src_addr - \ + sysmemmgr_state.cfg.static_virt_base_addr) + \ + (sysmemmgr_state.cfg.static_phys_base_addr)); + } else { + ret_ptr = platform_mem_translate(src_addr, + PLATFORM_MEM_XLT_FLAGS_VIRT2PHYS); + } + } + break; + + case sysmemmgr_xltflag_phys2kvirt: + { + if (((u32) src_addr >= \ + sysmemmgr_state.cfg.static_phys_base_addr) && \ + ((u32) src_addr < \ + (sysmemmgr_state.cfg.static_phys_base_addr + \ + sysmemmgr_state.cfg.static_mem_size))) { + ret_ptr = (void *)(((u32) src_addr - \ + sysmemmgr_state.cfg.static_phys_base_addr) + \ + (sysmemmgr_state.cfg.static_virt_base_addr)); + } else { + ret_ptr = platform_mem_translate(src_addr, + PLATFORM_MEM_XLT_FLAGS_PHYS2VIRT); + } + } + break; + + default: + { + printk(KERN_ALERT "sysmemmgr_translate: Unhandled translation " + "flag\n"); + } + break; + } + + return ret_ptr; +} diff --git a/drivers/dsp/syslink/multicore_ipc/sysmemmgr_ioctl.c b/drivers/dsp/syslink/multicore_ipc/sysmemmgr_ioctl.c new file mode 100644 index 000000000000..591e04849873 --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/sysmemmgr_ioctl.c @@ -0,0 +1,227 @@ +/* + * sysmemmgr_ioctl.c + * + * This file implements all the ioctl operations required on the sysmemmgr + * module. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +/* Standard headers */ +#include <linux/types.h> + +/* Linux headers */ +#include <linux/uaccess.h> +#include <linux/bug.h> +#include <linux/fs.h> +#include <linux/mm.h> + +/* Module Headers */ +#include <sysmemmgr.h> +#include <sysmemmgr_ioctl.h> + + +/* + * ======== sysmemmgr_ioctl_get_config ======== + * Purpose: + * This ioctl interface to sysmemmgr_get_config function + */ +static inline int sysmemmgr_ioctl_get_config(struct sysmemmgr_cmd_args *cargs) +{ + s32 retval = 0; + unsigned long size; + struct sysmemmgr_config config; + + sysmemmgr_get_config(&config); + size = copy_to_user(cargs->args.get_config.config, &config, + sizeof(struct sysmemmgr_config)); + if (size) { + retval = -EFAULT; + goto exit; + } + + cargs->api_status = 0; +exit: + return retval; +} + +/* + * ======== sysmemmgr_ioctl_setup ======== + * Purpose: + * This ioctl interface to sysmemmgr_setup function + */ +static inline int sysmemmgr_ioctl_setup(struct sysmemmgr_cmd_args *cargs) +{ + s32 retval = 0; + unsigned long size; + struct sysmemmgr_config config; + + if (cargs->args.setup.config == NULL) { + cargs->api_status = sysmemmgr_setup(NULL); + goto exit; + } + + size = copy_from_user(&config, cargs->args.setup.config, + sizeof(struct sysmemmgr_config)); + if (size) { + retval = -EFAULT; + goto exit; + } + + cargs->api_status = sysmemmgr_setup(&config); + +exit: + return retval; +} + +/* + * ======== sysmemmgr_ioctl_destroy ======== + * Purpose: + * This ioctl interface to sysmemmgr_destroy function + */ +static inline int sysmemmgr_ioctl_destroy(struct sysmemmgr_cmd_args *cargs) +{ + cargs->api_status = sysmemmgr_destroy(); + return 0; +} + +/* + * ======== sysmemmgr_ioctl_alloc ======== + * Purpose: + * This ioctl interface to sysmemmgr_alloc function + */ +static inline int sysmemmgr_ioctl_alloc(struct sysmemmgr_cmd_args *cargs) +{ + void *kbuf = NULL; + void *phys = NULL; + + kbuf = sysmemmgr_alloc(cargs->args.alloc.size, + cargs->args.alloc.flags); + if (unlikely(kbuf == NULL)) + goto exit; + + /* If the flag is not virtually contiguous */ + if (cargs->args.alloc.flags != sysmemmgr_allocflag_virtual) + phys = sysmemmgr_translate(kbuf, sysmemmgr_xltflag_kvirt2phys); + cargs->api_status = 0; + +exit: + cargs->args.alloc.kbuf = kbuf; + cargs->args.alloc.kbuf = phys; + return 0; +} + +/* + * ======== sysmemmgr_ioctl_free ======== + * Purpose: + * This ioctl interface to sysmemmgr_free function + */ +static inline int sysmemmgr_ioctl_free(struct sysmemmgr_cmd_args *cargs) +{ + cargs->api_status = sysmemmgr_free(cargs->args.free.kbuf, + cargs->args.free.size, + cargs->args.alloc.flags); + return 0; +} + +/* + * ======== sysmemmgr_ioctl_translate ======== + * Purpose: + * This ioctl interface to sysmemmgr_translate function + */ +static inline int sysmemmgr_ioctl_translate(struct sysmemmgr_cmd_args *cargs) +{ + cargs->args.translate.ret_ptr = sysmemmgr_translate( + cargs->args.translate.buf, + cargs->args.translate.flags); + WARN_ON(cargs->args.translate.ret_ptr == NULL); + cargs->api_status = 0; + return 0; +} + +/* + * ======== sysmemmgr_ioctl ======== + * Purpose: + * ioctl interface function for sysmemmgr module + */ +int sysmemmgr_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long args) +{ + int os_status = 0; + struct sysmemmgr_cmd_args __user *uarg = + (struct sysmemmgr_cmd_args __user *)args; + struct sysmemmgr_cmd_args cargs; + unsigned long size; + + if (_IOC_DIR(cmd) & _IOC_READ) + os_status = !access_ok(VERIFY_WRITE, uarg, _IOC_SIZE(cmd)); + else if (_IOC_DIR(cmd) & _IOC_WRITE) + os_status = !access_ok(VERIFY_READ, uarg, _IOC_SIZE(cmd)); + if (os_status) { + os_status = -EFAULT; + goto exit; + } + + /* Copy the full args from user-side */ + size = copy_from_user(&cargs, uarg, sizeof(struct sysmemmgr_cmd_args)); + if (size) { + os_status = -EFAULT; + goto exit; + } + + switch (cmd) { + case CMD_SYSMEMMGR_GETCONFIG: + os_status = sysmemmgr_ioctl_get_config(&cargs); + break; + + case CMD_SYSMEMMGR_SETUP: + os_status = sysmemmgr_ioctl_setup(&cargs); + break; + + case CMD_SYSMEMMGR_DESTROY: + os_status = sysmemmgr_ioctl_destroy(&cargs); + break; + + case CMD_SYSMEMMGR_ALLOC: + os_status = sysmemmgr_ioctl_alloc(&cargs); + break; + + case CMD_SYSMEMMGR_FREE: + os_status = sysmemmgr_ioctl_free(&cargs); + break; + + case CMD_SYSMEMMGR_TRANSLATE: + os_status = sysmemmgr_ioctl_translate(&cargs); + break; + + default: + WARN_ON(cmd); + os_status = -ENOTTY; + break; + } + + if ((cargs.api_status == -ERESTARTSYS) || (cargs.api_status == -EINTR)) + os_status = -ERESTARTSYS; + + if (os_status < 0) + goto exit; + + /* Copy the full args to the user-side. */ + size = copy_to_user(uarg, &cargs, sizeof(struct sysmemmgr_cmd_args)); + if (size) { + os_status = -EFAULT; + goto exit; + } + +exit: + return os_status; +} diff --git a/drivers/dsp/syslink/multicore_ipc/sysmgr.c b/drivers/dsp/syslink/multicore_ipc/sysmgr.c new file mode 100644 index 000000000000..bbf9b4be4b27 --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/sysmgr.c @@ -0,0 +1,846 @@ +/* + * sysmgr.c + * + * Implementation of System manager. + * + * Copyright (C) 2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + + +/* Standard headers */ +#include <linux/types.h> +#include <linux/module.h> + +#include <syslink/atomic_linux.h> + +/* Module headers */ +#include <multiproc.h> +#include <sysmemmgr.h> +#include <sysmgr.h> +#include <_sysmgr.h> +#include <platform.h> +#include <platform_mem.h> + +#include <gatepeterson.h> +#include <sharedregion.h> +#include <listmp.h> +#include <messageq.h> +#include <messageq_transportshm.h> +#include <notify.h> +/*#include <notify_driver.h>*/ +#include <notify_ducatidriver.h> + +#include <nameserver.h> +#include <nameserver_remote.h> +#include <nameserver_remotenotify.h> +#include <procmgr.h> +#include <heap.h> +#include <heapbuf.h> + +/* ============================================================================= + * Macros + * ============================================================================= + */ +/*! + * @def BOOTLOADPAGESIZE + * @brief Error code base for System manager. + */ +#define BOOTLOADPAGESIZE (0x1000) /* 4K page size */ + +/*! + * @def SYSMGR_ENTRYVALIDITYSTAMP + * @brief Validity stamp for boot load page entries. + */ +#define SYSMGR_ENTRYVALIDITYSTAMP (0xBABAC0C0) + +/*! + * @def SYSMGR_ENTRYVALIDSTAMP + * @brief Validity stamp for boot load page entries. + */ +#define SYSMGR_ENTRYVALIDSTAMP (0xBABAC0C0) + +/*! + * @def SYSMGR_SCALABILITYHANDSHAKESTAMP + * @brief scalability configuration handshake value. + */ +#define SYSMGR_SCALABILITYHANDSHAKESTAMP (0xBEEF0000) + +/*! + * @def SYSMGR_SETUPHANDSHAKESTAMP + * @brief Platform configured handshake value. + */ +#define SYSMGR_SETUPHANDSHAKESTAMP (0xBEEF0001) + +/*! + * @def SYSMGR_DESTROYHANDSHAKESTAMP + * @brief Destroy handshake value. + */ +#define SYSMGR_DESTROYHANDSHAKESTAMP (0xBEEF0002) + +/*! + * @def SYSMGR_BOOTLOADPAGESIZE + * @brief Boot load page size. + */ +#define SYSMGR_BOOTLOADPAGESIZE (0x00001000) + +/* Macro to make a correct module magic number with ref_count */ +#define SYSMGR_MAKE_MAGICSTAMP(x) ((SYSMGR_MODULEID << 12) | (x)) + + +/* ============================================================================= + * Structures & Enums + * ============================================================================= + */ +/*! @brief structure for System manager boot load page entry */ +struct sysmgr_bootload_page_entry { + VOLATILE u32 offset; + /* Offset of next entry (-1 if not present) */ + VOLATILE u32 valid; + /* Validity of the entry */ + VOLATILE u32 size; + /* Size of the entry data */ + VOLATILE u32 cmd_id; + /* Command ID */ +}; + +/*! @brief structure containg system manager state object */ +struct sysmgr_boot_load_page { + VOLATILE struct sysmgr_bootload_page_entry host_config; + /* First entry, host specific configuration in the boot load page */ + u8 padding1[(BOOTLOADPAGESIZE/2) - \ + sizeof(struct sysmgr_bootload_page_entry)]; + /* Padding1 */ + VOLATILE u32 handshake; + /* Handshake variable, wrote by slave to indicate configuration done. */ + VOLATILE struct sysmgr_bootload_page_entry slave_config; + /* First entry, slave specific configuration in the boot load page */ + u8 padding2[(BOOTLOADPAGESIZE/2) - \ + sizeof(struct sysmgr_bootload_page_entry) - \ + sizeof(u32)]; + /* Padding2 */ +}; + +/*! @brief structure for System manager module state */ +struct sysmgr_module_object { + atomic_t ref_count; + /* Reference count */ + struct sysmgr_config config; + /* Overall system configuration */ + struct sysmgr_boot_load_page *boot_load_page[MULTIPROC_MAXPROCESSORS]; + /* Boot load page of the slaves */ + bool platform_mem_init_flag; + /* Platform memory manager initialize flag */ + bool multiproc_init_flag; + /* Multiproc Initialize flag */ + bool gatepeterson_init_flag; + /* Gatepeterson Initialize flag */ + bool sharedregion_init_flag; + /* Sharedregion Initialize flag */ + bool listmp_init_flag; + /* Listmp Initialize flag */ + bool messageq_init_flag; + /* Messageq Initialize flag */ + bool notify_init_flag; + /* Notify Initialize flag */ + bool proc_mgr_init_flag; + /* Processor manager Initialize flag */ + bool heapbuf_init_flag; + /* Heapbuf Initialize flag */ + bool nameserver_init_flag; + /* Nameserver_remotenotify Initialize flag */ + bool listmp_sharedmemory_init_flag; + /* Listmp_sharedmemory Initialize flag */ + bool messageq_transportshm_init_flag; + /* Messageq_transportshm Initialize flag */ + bool notify_ducatidrv_init_flag; + /* notify_ducatidrv Initialize flag */ + bool nameserver_remotenotify_init_flag; + /* nameserver_remotenotify Initialize flag */ + bool platform_init_flag; + /* Flag to indicate platform initialization status */ +}; + + +/* ============================================================================= + * Globals + * ============================================================================= + */ +/*! + * @var sysmgr_state + * + * @brief Variable holding state of system manager. + */ +static struct sysmgr_module_object sysmgr_state; + + +/* ============================================================================= + * APIS + * ============================================================================= + */ +/* + * ======== sysmgr_get_config ======== + * Purpose: + * Function to get the default values for configuration. + */ +void sysmgr_get_config(struct sysmgr_config *config) +{ + s32 status = 0; + + if (WARN_ON(config == NULL)) { + status = -EINVAL; + printk(KERN_ALERT "sysmgr_get_config [0x%x] : Argument of type" + " (sysmgr_get_config *) passed is null!", + status); + return; + } + + /* Get the gatepeterson default config */ + multiproc_get_config(&config->multiproc_cfg); + + /* Get the gatepeterson default config */ + gatepeterson_get_config(&config->gatepeterson_cfg); + + /* Get the sharedregion default config */ + sharedregion_get_config(&config->sharedregion_cfg); + + /* Get the messageq default config */ + messageq_get_config(&config->messageq_cfg); + + /* Get the notify default config */ + notify_get_config(&config->notify_cfg); + + /* Get the proc_mgr default config */ + proc_mgr_get_config(&config->proc_mgr_cfg); + + /* Get the heapbuf default config */ + heapbuf_get_config(&config->heapbuf_cfg); + + /* Get the listmp_sharedmemory default config */ + listmp_sharedmemory_get_config(&config->listmp_sharedmemory_cfg); + + /* Get the messageq_transportshm default config */ + messageq_transportshm_get_config(&config->messageq_transportshm_cfg); + + /* Get the notify_ducati driver default config */ + notify_ducatidrv_getconfig(&config->notify_ducatidrv_cfg); + + /* Get the nameserver_remotenotify default config */ + nameserver_remotenotify_get_config( + &config->nameserver_remotenotify_cfg); +} +EXPORT_SYMBOL(sysmgr_get_config); + +/* + * ======== sysmgr_get_object_config ======== + * Purpose: + * Function to get the SysMgr Object configuration from Slave. + */ +u32 sysmgr_get_object_config(u16 proc_id, void *config, u32 cmd_id, u32 size) +{ + struct sysmgr_bootload_page_entry *entry = NULL; + u32 offset = 0; + u32 ret = 0; + struct sysmgr_boot_load_page *blp = NULL; + + if ((proc_id < 0) || (proc_id >= MULTIPROC_MAXPROCESSORS)) { + ret = 0; + goto exit; + } + + blp = (struct sysmgr_boot_load_page *) + sysmgr_state.boot_load_page[proc_id]; + + entry = (struct sysmgr_bootload_page_entry *) &blp->slave_config; + while (entry->valid == SYSMGR_ENTRYVALIDSTAMP) { + if (entry->cmd_id == cmd_id) { + if (size == entry->size) { + memcpy(config, (void *)((u32)entry + \ + sizeof(struct sysmgr_bootload_page_entry)), + size); + ret = size; + break; + } + } + if (entry->offset != -1) { + offset += entry->offset; + entry = (struct sysmgr_bootload_page_entry *) + ((u32) &blp->slave_config + entry->offset); + } else { + break; + } + } + +exit: + /* return number of bytes wrote to the boot load page */ + return ret; +} + + +/* + * ======== sysmgr_put_object_config ======== + * Purpose: + * Function to put the SysMgr Object configuration to Slave. + */ +u32 sysmgr_put_object_config(u16 proc_id, void *config, u32 cmd_id, u32 size) +{ + struct sysmgr_bootload_page_entry *entry = NULL; + struct sysmgr_bootload_page_entry *prev = NULL; + u32 offset = 0; + struct sysmgr_boot_load_page *blp = NULL; + + if ((proc_id < 0) || (proc_id >= MULTIPROC_MAXPROCESSORS)) { + size = 0; + goto exit; + } + + /* Get the boot load page pointer */ + blp = sysmgr_state.boot_load_page[proc_id]; + + /* Put the entry at the end of list */ + entry = (struct sysmgr_bootload_page_entry *) &blp->host_config; + while (entry->valid == SYSMGR_ENTRYVALIDSTAMP) { + prev = entry; + if (entry->offset != -1) { + offset += entry->offset; + entry = (struct sysmgr_bootload_page_entry *) + ((u32) &blp->host_config + entry->offset); + } else { + break; + } + } + + /* First entry has prev set to NULL */ + if (prev == NULL) { + entry->offset = -1; + entry->cmd_id = cmd_id; + entry->size = size; + memcpy((void *)((u32)entry + \ + sizeof(struct sysmgr_bootload_page_entry)), + config, size); + entry->valid = SYSMGR_ENTRYVALIDSTAMP; + } else { + entry = (struct sysmgr_bootload_page_entry *)((u32)entry + \ + sizeof(struct sysmgr_bootload_page_entry) + \ + entry->size); + entry->offset = -1; + entry->cmd_id = cmd_id; + entry->size = size; + memcpy((void *)((u32)entry + \ + sizeof(struct sysmgr_bootload_page_entry)), + config, size); + entry->valid = SYSMGR_ENTRYVALIDSTAMP; + + /* Attach the new created entry */ + prev->offset = ((u32) entry - (u32) &blp->host_config); + } + +exit: + /* return number of bytes wrote to the boot load page */ + return size; +} + + +/* + * ======== sysmgr_setup ======== + * Purpose: + * Function to setup the System. + */ +s32 sysmgr_setup(const struct sysmgr_config *cfg) +{ + s32 status = 0; + struct sysmgr_config *config = NULL; + + /* This sets the ref_count variable is not initialized, upper 16 bits is + * written with module Id to ensure correctness of ref_count variable. + */ + atomic_cmpmask_and_set(&sysmgr_state.ref_count, + SYSMGR_MAKE_MAGICSTAMP(0), + SYSMGR_MAKE_MAGICSTAMP(0)); + + if (atomic_inc_return(&sysmgr_state.ref_count) + != SYSMGR_MAKE_MAGICSTAMP(1)) { + status = 1; + goto exit; + } + + if (cfg == NULL) { + sysmgr_get_config(&sysmgr_state.config); + config = &sysmgr_state.config; + } else { + memcpy((void *) (&sysmgr_state.config), (void *) cfg, + sizeof(struct sysmgr_config)); + config = (struct sysmgr_config *) cfg; + } + + /* Initialize PlatformMem */ + status = platform_mem_setup(); + if (status < 0) { + printk(KERN_ERR "sysmgr_setup : platform_mem_setup " + "failed [0x%x]\n", status); + } else { + printk(KERN_ERR "platform_mem_setup : status [0x%x]\n" , + status); + sysmgr_state.platform_mem_init_flag = true; + } + + /* Override the platform specific configuration */ + platform_override_config(config); + + status = multiproc_setup(&(config->multiproc_cfg)); + if (status < 0) { + printk(KERN_ERR "sysmgr_setup : multiproc_setup " + "failed [0x%x]\n", status); + } else { + printk(KERN_ERR "sysmgr_setup : status [0x%x]\n" , status); + sysmgr_state.multiproc_init_flag = true; + } + + /* Initialize ProcMgr */ + if (status >= 0) { + status = proc_mgr_setup(&(config->proc_mgr_cfg)); + if (status < 0) { + printk(KERN_ERR "sysmgr_setup : proc_mgr_setup " + "failed [0x%x]\n", status); + } else { + printk(KERN_ERR "proc_mgr_setup : status [0x%x]\n" , + status); + sysmgr_state.proc_mgr_init_flag = true; + } + } + + /* Initialize SharedRegion */ + if (status >= 0) { + status = sharedregion_setup(&config->sharedregion_cfg); + if (status < 0) { + printk(KERN_ERR "sysmgr_setup : sharedregion_setup " + "failed [0x%x]\n", status); + } else { + printk(KERN_ERR "sharedregion_setup : status [0x%x]\n" , + status); + sysmgr_state.sharedregion_init_flag = true; + } + } + + /* Initialize Notify */ + if (status >= 0) { + status = notify_setup(&config->notify_cfg); + if (status < 0) { + printk(KERN_ERR "sysmgr_setup : notify_setup " + "failed [0x%x]\n", status); + } else { + printk(KERN_ERR "notify_setup : status [0x%x]\n" , + status); + sysmgr_state.notify_init_flag = true; + } + } + + /* Initialize NameServer */ + if (status >= 0) { + status = nameserver_setup(); + if (status < 0) { + printk(KERN_ERR "sysmgr_setup : nameserver_setup " + "failed [0x%x]\n", status); + } else { + printk(KERN_ERR "nameserver_setup : status [0x%x]\n" , + status); + sysmgr_state.nameserver_init_flag = true; + } + } + + /* Initialize GatePeterson */ + if (status >= 0) { + status = gatepeterson_setup(&config->gatepeterson_cfg); + if (status < 0) { + printk(KERN_ERR "sysmgr_setup : gatepeterson_setup " + "failed [0x%x]\n", status); + } else { + printk(KERN_ERR "gatepeterson_setup : status [0x%x]\n" , + status); + sysmgr_state.gatepeterson_init_flag = true; + } + } + + /* Intialize MessageQ */ + if (status >= 0) { + status = messageq_setup(&config->messageq_cfg); + if (status < 0) { + printk(KERN_ERR "sysmgr_setup : messageq_setup " + "failed [0x%x]\n", status); + } else { + printk(KERN_ERR "messageq_setup : status [0x%x]\n" , + status); + sysmgr_state.messageq_init_flag = true; + } + } + + /* Intialize HeapBuf */ + if (status >= 0) { + status = heapbuf_setup(&config->heapbuf_cfg); + if (status < 0) { + printk(KERN_ERR "sysmgr_setup : heapbuf_setup " + "failed [0x%x]\n", status); + } else { + printk(KERN_ERR "heapbuf_setup : status [0x%x]\n" , + status); + sysmgr_state.heapbuf_init_flag = true; + } + } + + /* Initialize ListMPSharedMemory */ + if (status >= 0) { + status = listmp_sharedmemory_setup( + &config->listmp_sharedmemory_cfg); + if (status < 0) { + printk(KERN_ERR "sysmgr_setup : " + "listmp_sharedmemory_setup failed [0x%x]\n", + status); + } else { + printk(KERN_ERR "listmp_sharedmemory_setup : " + "status [0x%x]\n" , status); + sysmgr_state.listmp_sharedmemory_init_flag = true; + } + } + + /* Initialize MessageQTransportShm */ + if (status >= 0) { + status = messageq_transportshm_setup( + &config->messageq_transportshm_cfg); + if (status < 0) { + printk(KERN_ERR "sysmgr_setup : " + "messageq_transportshm_setup failed [0x%x]\n", + status); + } else { + printk(KERN_ERR "messageq_transportshm_setup : " + "status [0x%x]\n", status); + sysmgr_state.messageq_transportshm_init_flag = true; + } + } + + /* Initialize Notify DucatiDriver */ + if (status >= 0) { + status = notify_ducatidrv_setup(&config->notify_ducatidrv_cfg); + if (status < 0) { + printk(KERN_ERR "sysmgr_setup : " + "notify_ducatidrv_setup failed [0x%x]\n", + status); + } else { + printk(KERN_ERR "notify_ducatidrv_setup : " + "status [0x%x]\n" , status); + sysmgr_state.notify_ducatidrv_init_flag = true; + } + } + + /* Initialize NameServerRemoteNotify */ + if (status >= 0) { + status = nameserver_remotenotify_setup( + &config->nameserver_remotenotify_cfg); + if (status < 0) { + printk(KERN_ERR "sysmgr_setup : " + "nameserver_remotenotify_setup failed [0x%x]\n", + status); + } else { + printk(KERN_ERR "nameserver_remotenotify_setup : " + "status [0x%x]\n" , status); + sysmgr_state.nameserver_remotenotify_init_flag = true; + } + } + + if (status >= 0) { + /* Call platform setup function */ + status = platform_setup(config); + if (status < 0) { + printk(KERN_ERR "sysmgr_setup : platform_setup " + "failed [0x%x]\n", status); + } else { + printk(KERN_ERR "platform_setup : status [0x%x]\n" , + status); + sysmgr_state.platform_init_flag = true; + } + } + +exit: + if (status < 0) + atomic_set(&sysmgr_state.ref_count, SYSMGR_MAKE_MAGICSTAMP(0)); + + return status; +} +EXPORT_SYMBOL(sysmgr_setup); + +/* + * ======== sysmgr_setup ======== + * Purpose: + * Function to finalize the System. + */ +s32 sysmgr_destroy(void) +{ + s32 status = 0; + + if (atomic_cmpmask_and_lt(&(sysmgr_state.ref_count), + SYSMGR_MAKE_MAGICSTAMP(0), + SYSMGR_MAKE_MAGICSTAMP(1)) != false) { + /*! @retval SYSMGR_E_INVALIDSTATE Module was not initialized */ + status = SYSMGR_E_INVALIDSTATE; + goto exit; + } + + if (atomic_dec_return(&sysmgr_state.ref_count) + != SYSMGR_MAKE_MAGICSTAMP(0)) { + status = 1; + goto exit; + } + + /* Finalize Platform module*/ + if (sysmgr_state.platform_init_flag == true) { + status = platform_destroy(); + if (status < 0) { + printk(KERN_ERR "sysmgr_destroy : platform_destroy " + "failed [0x%x]\n", status); + } else { + sysmgr_state.platform_init_flag = false; + } + } + + /* Finalize NameServerRemoteNotify module */ + if (sysmgr_state.nameserver_remotenotify_init_flag == true) { + status = nameserver_remotenotify_destroy(); + if (status < 0) { + printk(KERN_ERR "sysmgr_destroy : " + "nameserver_remotenotify_destroy " + "failed [0x%x]\n", status); + } else { + sysmgr_state.nameserver_remotenotify_init_flag \ + = false; + } + } + + /* Finalize Notify Ducati Driver module */ + if (sysmgr_state.notify_ducatidrv_init_flag == true) { + status = notify_ducatidrv_destroy(); + if (status < 0) { + printk(KERN_ERR "sysmgr_destroy : " + "notify_ducatidrv_destroy failed [0x%x]\n", + status); + } else { + sysmgr_state.notify_ducatidrv_init_flag = false; + } + } + + /* Finalize MessageQTransportShm module */ + if (sysmgr_state.messageq_transportshm_init_flag == true) { + status = messageq_transportshm_destroy(); + if (status < 0) { + printk(KERN_ERR "sysmgr_destroy : " + "messageq_transportshm_destroy failed [0x%x]\n", + status); + } else { + sysmgr_state.messageq_transportshm_init_flag = \ + false; + } + } + + /* Finalize ListMPSharedMemory module */ + if (sysmgr_state.listmp_sharedmemory_init_flag == true) { + status = listmp_sharedmemory_destroy(); + if (status < 0) { + printk(KERN_ERR "sysmgr_destroy : " + "listmp_sharedmemory_destroy failed [0x%x]\n", + status); + } else { + sysmgr_state.listmp_sharedmemory_init_flag = \ + false; + } + } + + /* Finalize HeapBuf module */ + if (sysmgr_state.heapbuf_init_flag == true) { + status = heapbuf_destroy(); + if (status < 0) { + printk(KERN_ERR "sysmgr_destroy : heapbuf_destroy " + "failed [0x%x]\n", status); + } else { + sysmgr_state.heapbuf_init_flag = false; + } + } + + /* Finalize MessageQ module */ + if (sysmgr_state.messageq_init_flag == true) { + status = messageq_destroy(); + if (status < 0) { + printk(KERN_ERR "sysmgr_destroy : messageq_destroy " + "failed [0x%x]\n", status); + } else { + sysmgr_state.messageq_init_flag = false; + } + } + + /* Finalize GatePeterson module */ + if (sysmgr_state.gatepeterson_init_flag == true) { + status = gatepeterson_destroy(); + if (status < 0) { + printk(KERN_ERR "sysmgr_destroy : " + "gatepeterson_destroy failed [0x%x]\n", status); + } else { + sysmgr_state.gatepeterson_init_flag = false; + } + } + + /* Finalize NameServer module */ + if (sysmgr_state.nameserver_init_flag == true) { + status = nameserver_destroy(); + if (status < 0) { + printk(KERN_ERR "sysmgr_destroy : nameserver_destroy " + "failed [0x%x]\n", status); + } else { + sysmgr_state.nameserver_init_flag = false; + } + } + + /* Finalize Notify module */ + if (sysmgr_state.notify_init_flag == true) { + status = notify_destroy(); + if (status < 0) { + printk(KERN_ERR "sysmgr_destroy : sysmgr_destroy " + "failed [0x%x]\n", status); + } else { + sysmgr_state.notify_init_flag = false; + } + } + + /* Finalize SharedRegion module */ + if (sysmgr_state.sharedregion_init_flag == true) { + status = sharedregion_destroy(); + if (status < 0) { + printk(KERN_ERR "sysmgr_destroy : " + "sharedregion_destroy failed [0x%x]\n", status); + } else { + sysmgr_state.sharedregion_init_flag = false; + } + } + + /* Finalize ProcMgr module */ + if (sysmgr_state.proc_mgr_init_flag == true) { + status = proc_mgr_destroy(); + if (status < 0) { + printk(KERN_ERR "sysmgr_destroy : proc_mgr_destroy " + "failed [0x%x]\n", status); + } else { + sysmgr_state.proc_mgr_init_flag = false; + } + } + + /* Finalize MultiProc module */ + if (sysmgr_state.multiproc_init_flag == true) { + status = multiproc_destroy(); + if (status < 0) { + printk(KERN_ERR "sysmgr_destroy : multiproc_destroy " + "failed [0x%x]\n", status); + } else { + sysmgr_state.proc_mgr_init_flag = false; + } + } + + /* Finalize PlatformMem module */ + if (sysmgr_state.platform_mem_init_flag == true) { + status = platform_mem_destroy(); + if (status < 0) { + printk(KERN_ERR "sysmgr_destroy : platform_mem_destroy " + "failed [0x%x]\n", status); + } else { + sysmgr_state.platform_mem_init_flag = false; + } + } + + atomic_set(&sysmgr_state.ref_count, SYSMGR_MAKE_MAGICSTAMP(0)); + +exit: + if (status < 0) { + printk(KERN_ERR "sysmgr_destroy : failed with " + "status = [0x%x]\n", status); + } + return status; +} +EXPORT_SYMBOL(sysmgr_destroy); + +/* + * ======== sysmgr_set_boot_load_page ======== + * Purpose: + * Function to set the boot load page address for a slave. + */ +void sysmgr_set_boot_load_page(u16 proc_id, u32 boot_load_page) +{ + struct sysmgr_boot_load_page *temp = \ + (struct sysmgr_boot_load_page *) boot_load_page; + + if ((proc_id < 0) || (proc_id >= MULTIPROC_MAXPROCESSORS)) { + printk(KERN_ERR + "sysmgr_set_boot_load_page failed: Invalid proc_id passed\n"); + return; + } + + /* Initialize the host config area */ + sysmgr_state.boot_load_page[proc_id] = temp; + temp->host_config.offset = -1; + temp->host_config.valid = 0; + temp->handshake = 0; +} + + +/* + * ======== sysmgr_wait_for_scalability_info ======== + * Purpose: + * Function to wait for scalability handshake value. + */ +void sysmgr_wait_for_scalability_info(u16 proc_id) +{ + VOLATILE struct sysmgr_boot_load_page *temp = NULL; + + if ((proc_id < 0) || (proc_id >= MULTIPROC_MAXPROCESSORS)) { + printk(KERN_ERR "sysmgr_wait_for_scalability_info failed: " + "Invalid proc_id passed\n"); + return; + } + temp = sysmgr_state.boot_load_page[proc_id]; + + printk(KERN_ERR "sysmgr_wait_for_scalability_info: BF while temp->handshake:%x\n", + temp->handshake); + while (temp->handshake != SYSMGR_SCALABILITYHANDSHAKESTAMP) + ; + printk(KERN_ERR "sysmgr_wait_for_scalability_info:AF while temp->handshake:%x\n", + temp->handshake); + + /* Reset the handshake value for reverse synchronization */ + temp->handshake = 0; +} + + +/* + * ======== sysmgr_wait_for_slave_setup ======== + * Purpose: + * Function to wait for slave to complete setup. + */ +void sysmgr_wait_for_slave_setup(u16 proc_id) +{ + VOLATILE struct sysmgr_boot_load_page *temp = NULL; + + if ((proc_id < 0) || (proc_id >= MULTIPROC_MAXPROCESSORS)) { + printk(KERN_ERR "sysmgr_wait_for_slave_setup failed: " + "Invalid proc_id passed\n"); + return; + } + temp = sysmgr_state.boot_load_page[proc_id]; + + while (temp->handshake != SYSMGR_SETUPHANDSHAKESTAMP) + ; + + /* Reset the handshake value for reverse synchronization */ + temp->handshake = 0; +} diff --git a/drivers/dsp/syslink/multicore_ipc/sysmgr_ioctl.c b/drivers/dsp/syslink/multicore_ipc/sysmgr_ioctl.c new file mode 100644 index 000000000000..1f7d01803967 --- /dev/null +++ b/drivers/dsp/syslink/multicore_ipc/sysmgr_ioctl.c @@ -0,0 +1,147 @@ +/* + * sysmgr_ioctl.c + * + * This file implements all the ioctl operations required on the sysmgr + * module. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +/* Standard headers */ +#include <linux/types.h> + +/* Linux headers */ +#include <linux/uaccess.h> +#include <linux/bug.h> +#include <linux/fs.h> +#include <linux/mm.h> + +/* Module Headers */ +#include <sysmgr.h> +#include <sysmgr_ioctl.h> +#include <platform.h> +/* + * ======== sysmgr_ioctl_setup ======== + * Purpose: + * This ioctl interface to sysmgr_setup function + */ +static inline int sysmgr_ioctl_setup(struct sysmgr_cmd_args *cargs) +{ + s32 retval = 0; + unsigned long size; + struct sysmgr_config config; + + size = copy_from_user(&config, cargs->args.setup.config, + sizeof(struct sysmgr_config)); + if (size) { + retval = -EFAULT; + goto exit; + } + + cargs->api_status = sysmgr_setup(&config); + +exit: + return retval; +} + +/* + * ======== sysmgr_ioctl_destroy ======== + * Purpose: + * This ioctl interface to sysmgr_destroy function + */ +static inline int sysmgr_ioctl_destroy(struct sysmgr_cmd_args *cargs) +{ + cargs->api_status = sysmgr_destroy(); + return 0; +} + +/* + * ======== sysmgr_ioctl ======== + * Purpose: + * ioctl interface function for sysmgr module + */ +int sysmgr_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long args) +{ + int os_status = 0; + struct sysmgr_cmd_args __user *uarg = + (struct sysmgr_cmd_args __user *)args; + struct sysmgr_cmd_args cargs; + unsigned long size; + + if (_IOC_DIR(cmd) & _IOC_READ) + os_status = !access_ok(VERIFY_WRITE, uarg, _IOC_SIZE(cmd)); + else if (_IOC_DIR(cmd) & _IOC_WRITE) + os_status = !access_ok(VERIFY_READ, uarg, _IOC_SIZE(cmd)); + if (os_status) { + os_status = -EFAULT; + goto exit; + } + + /* Copy the full args from user-side */ + size = copy_from_user(&cargs, uarg, sizeof(struct sysmgr_cmd_args)); + if (size) { + os_status = -EFAULT; + goto exit; + } + + switch (cmd) { + case CMD_SYSMGR_SETUP: + os_status = sysmgr_ioctl_setup(&cargs); + break; + + case CMD_SYSMGR_DESTROY: + os_status = sysmgr_ioctl_destroy(&cargs); + break; + + case CMD_SYSMGR_LOADCALLBACK: +#if defined CONFIG_SYSLINK_USE_SYSMGR + platform_load_callback((void *)(cargs.args.proc_id)); + cargs.api_status = 0; +#endif + break; + + case CMD_SYSMGR_STARTCALLBACK: +#if defined CONFIG_SYSLINK_USE_SYSMGR + platform_start_callback((void *)(cargs.args.proc_id)); + cargs.api_status = 0; +#endif + break; + + case CMD_SYSMGR_STOPCALLBACK: +#if defined CONFIG_SYSLINK_USE_SYSMGR + platform_stop_callback((void *)(cargs.args.proc_id)); + cargs.api_status = 0; +#endif + break; + default: + WARN_ON(cmd); + os_status = -ENOTTY; + break; + } + + if ((cargs.api_status == -ERESTARTSYS) || (cargs.api_status == -EINTR)) + os_status = -ERESTARTSYS; + + if (os_status < 0) + goto exit; + + /* Copy the full args to the user-side. */ + size = copy_to_user(uarg, &cargs, sizeof(struct sysmgr_cmd_args)); + if (size) { + os_status = -EFAULT; + goto exit; + } + +exit: + return os_status; +} diff --git a/drivers/dsp/syslink/notify_ducatidriver/Kbuild b/drivers/dsp/syslink/notify_ducatidriver/Kbuild new file mode 100644 index 000000000000..fd82baca9f04 --- /dev/null +++ b/drivers/dsp/syslink/notify_ducatidriver/Kbuild @@ -0,0 +1,19 @@ + + +omap_ducatidriver = notify_ducati.o drv_ducati.o + + +obj-$(CONFIG_NOTIFY_DUCATI) += notify_ducatidriver.o +notify_ducatidriver-objs = $(omap_ducatidriver) + + +ccflags-y += -Wno-strict-prototypes + +#Machine dependent +ccflags-y += -DCONFIG_DISABLE_BRIDGE_PM -DDSP_TRACEBUF_DISABLED \ + -DVPOM4430_1_06 + +#Header files +ccflags-y += -Idrivers/dsp/syslink/inc +ccflags-y += -Iarch/arm/plat-omap/include/ + diff --git a/drivers/dsp/syslink/notify_ducatidriver/drv_ducati.c b/drivers/dsp/syslink/notify_ducatidriver/drv_ducati.c new file mode 100644 index 000000000000..eaf53f4b5a24 --- /dev/null +++ b/drivers/dsp/syslink/notify_ducatidriver/drv_ducati.c @@ -0,0 +1,348 @@ +/* + * drv_ducatidrv.c + * + * Syslink driver support functions for TI OMAP processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + + +/* ----------------------------------- OS Specific Headers */ +#include <generated/autoconf.h> +#include <linux/spinlock.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/fs.h> +#include <linux/mm.h> +#include <linux/uaccess.h> +#include <linux/io.h> +#include <linux/cdev.h> + +#include <linux/io.h> +#include <asm/pgtable.h> +#include <syslink/notifydefs.h> +#include <syslink/notify_ducatidriver.h> +#include <syslink/notify_ducatidriver_defs.h> +#include <syslink/GlobalTypes.h> + + +/** ============================================================================ + * Macros and types + * ============================================================================ + */ +#define NOTIFYDUCATI_NAME "notifyducatidrv" + +static char *driver_name = NOTIFYDUCATI_NAME; + +static s32 driver_major; + +static s32 driver_minor; + +struct notifyducati_dev { + struct cdev cdev; +}; + +static struct notifyducati_dev *notifyducati_device; + +static struct class *notifyducati_class; + + + + + +/* driver function to open the notify mailbox driver object. */ +static int drvducati_open(struct inode *inode, struct file *filp); +static int drvducati_release(struct inode *inode, struct file *filp); +static int drvducati_ioctl(struct inode *inode, + struct file *filp, + unsigned int cmd, + unsigned long args); + + +/* notify mailbox driver initialization function. */ +static int __init drvducati_initialize_module(void) ; + +/* notify mailbox driver cleanup function. */ +static void __exit drvducati_finalize_module(void) ; + + +/* Function to invoke the APIs through ioctl. */ +static const struct file_operations driver_ops = { + .open = drvducati_open, + .release = drvducati_release, + .ioctl = drvducati_ioctl, + +}; + +/* Initialization function */ +static int __init drvducati_initialize_module(void) +{ + int result = 0 ; + dev_t dev; + + if (driver_major) { + dev = MKDEV(driver_major, driver_minor); + result = register_chrdev_region(dev, 1, driver_name); + } else { + result = alloc_chrdev_region(&dev, driver_minor, 1, + driver_name); + driver_major = MAJOR(dev); + } + + notifyducati_device = kmalloc(sizeof(struct notifyducati_dev), + GFP_KERNEL); + if (!notifyducati_device) { + result = -ENOMEM; + unregister_chrdev_region(dev, 1); + goto func_end; + } + memset(notifyducati_device, 0, sizeof(struct notifyducati_dev)); + cdev_init(¬ifyducati_device->cdev, &driver_ops); + notifyducati_device->cdev.owner = THIS_MODULE; + notifyducati_device->cdev.ops = &driver_ops; + + result = cdev_add(¬ifyducati_device->cdev, dev, 1); + + if (result) { + printk(KERN_ERR "Failed to add the syslink notify ducati device \n"); + goto func_end; + } + + /* udev support */ + notifyducati_class = class_create(THIS_MODULE, "syslink-notifyducati"); + + if (IS_ERR(notifyducati_class)) { + printk(KERN_ERR "Error creating notifyducati class \n"); + goto func_end; + } + device_create(notifyducati_class, NULL, + MKDEV(driver_major, driver_minor), NULL, + NOTIFYDUCATI_NAME); + +func_end: + return result ; +} + +/* Finalization function */ +static void __exit drvducati_finalize_module(void) +{ + dev_t dev_no; + + dev_no = MKDEV(driver_major, driver_minor); + if (notifyducati_device) { + cdev_del(¬ifyducati_device->cdev); + kfree(notifyducati_device); + } + unregister_chrdev_region(dev_no, 1); + if (notifyducati_class) { + /* remove the device from sysfs */ + device_destroy(notifyducati_class, MKDEV(driver_major, + driver_minor)); + class_destroy(notifyducati_class); + } + +} +/* driver open*/ +static int drvducati_open(struct inode *inode, struct file *filp) +{ + return 0 ; +} + +/*drivr close*/ +static int drvducati_release(struct inode *inode, struct file *filp) +{ + return 0; +} + + + +/* + * brief linux driver function to invoke the APIs through ioctl. + * + */ +static int drvducati_ioctl(struct inode *inode, + struct file *filp, + unsigned int cmd, + unsigned long args) +{ + int status = 0; + int retval = 0; + struct notify_ducatidrv_cmdargs *cmd_args = + (struct notify_ducatidrv_cmdargs *) args; + struct notify_ducatidrv_cmdargs common_args; + + switch (cmd) { + case CMD_NOTIFYDRIVERSHM_GETCONFIG: { + struct notify_ducatidrv_cmdargs_getconfig *src_args = + (struct notify_ducatidrv_cmdargs_getconfig *) args; + struct notify_ducatidrv_config cfg; + notify_ducatidrv_getconfig(&cfg); + + retval = copy_to_user((void *)(src_args->cfg), + (const void *) &cfg, + sizeof(struct notify_ducatidrv_config)); + + if (WARN_ON(retval != 0)) + goto func_end; + + } + break; + + case CMD_NOTIFYDRIVERSHM_SETUP: { + struct notify_ducatidrv_cmdargs_setup *src_args = + (struct notify_ducatidrv_cmdargs_setup *) args; + struct notify_ducatidrv_config cfg; + retval = copy_from_user((void *) &cfg, + (const void *)(src_args->cfg), + sizeof(struct notify_ducatidrv_config)); + if (WARN_ON(retval != 0)) + goto func_end; + + status = notify_ducatidrv_setup(&cfg); + if (status < 0) + printk(KERN_ERR "FAIL: notify_ducatidrv_setup\n"); + } + break; + + case CMD_NOTIFYDRIVERSHM_DESTROY: { + status = notify_ducatidrv_destroy(); + + if (status < 0) + printk(KERN_ERR "FAIL: notify_ducatidrv_destroy\n"); + } + break; + + case CMD_NOTIFYDRIVERSHM_PARAMS_INIT: { + struct notify_ducatidrv_cmdargs_paramsinit src_args; + struct notify_ducatidrv_params params; + retval = copy_from_user((void *) &src_args, + (const void *)(args), + sizeof( + struct notify_ducatidrv_cmdargs_paramsinit)); + if (WARN_ON(retval != 0)) + goto func_end; + notify_ducatidrv_params_init(src_args.handle, ¶ms); + + retval = copy_to_user((void *)(src_args.params), + (const void *) ¶ms, + sizeof(struct notify_ducatidrv_params)); + if (WARN_ON(retval != 0)) + goto func_end; + } + break; + + case CMD_NOTIFYDRIVERSHM_CREATE: { + struct notify_ducatidrv_cmdargs_create src_args; + retval = copy_from_user((void *) &src_args, + (const void *)(args), + sizeof(struct notify_ducatidrv_cmdargs_create)); + if (WARN_ON(retval != 0)) + goto func_end; + src_args.handle = notify_ducatidrv_create( + src_args.driverName, + &(src_args.params)); + if (src_args.handle == NULL) { + status = -EFAULT; + printk(KERN_ERR "drvducati_ioctl:status 0x%x," + "NotifyDriverShm_create failed", + status); + } + retval = copy_to_user((void *)(args), + (const void *) &src_args, + sizeof(struct notify_ducatidrv_cmdargs_create)); + if (WARN_ON(retval != 0)) + goto func_end; + } + break; + + case CMD_NOTIFYDRIVERSHM_DELETE: { + struct notify_ducatidrv_cmdargs_delete src_args; + retval = copy_from_user((void *) &src_args, + (const void *)(args), + sizeof(struct notify_ducatidrv_cmdargs_delete)); + if (WARN_ON(retval != 0)) + goto func_end; + + status = notify_ducatidrv_delete(&(src_args.handle)); + if (status < 0) + printk(KERN_ERR "drvducati_ioctl:" + " notify_ducatidrv_delete failed" + " status = %d\n", status); + } + break; + + case CMD_NOTIFYDRIVERSHM_OPEN: { + struct notify_ducatidrv_cmdargs_open src_args; + + retval = copy_from_user((void *) &src_args, + (const void *)(args), + sizeof(struct notify_ducatidrv_cmdargs_open)); + if (WARN_ON(retval != 0)) + goto func_end; + + status = notify_ducatidrv_open(src_args.driverName, + &(src_args.handle)); + if (status < 0) + printk(KERN_ERR "drvducati_ioctl:" + " notify_ducatidrv_open failed" + " status = %d\n", status); + retval = copy_to_user((void *)(args), + (const void *) &src_args, + sizeof(struct notify_ducatidrv_cmdargs_open)); + if (WARN_ON(retval != 0)) + goto func_end; + } + break; + + case CMD_NOTIFYDRIVERSHM_CLOSE: { + struct notify_ducatidrv_cmdargs_close src_args; + + retval = copy_from_user((void *) &src_args, + (const void *)(args), + sizeof(struct notify_ducatidrv_cmdargs_close)); + if (WARN_ON(retval != 0)) + goto func_end; + + status = notify_ducatidrv_close(&(src_args.handle)); + if (status < 0) + printk(KERN_ERR "drvducati_ioctl:" + " notify_ducatidrv_close" + " failed status = %d\n", status); + } + break; + + default: { + status = -EINVAL; + printk(KERN_ERR "drivducati_ioctl:Unsupported" + " ioctl command specified"); + } + break; + } + +func_end: + /* Set the status and copy the common args to user-side. */ + common_args.api_status = status; + status = copy_to_user((void *) cmd_args, + (const void *) &common_args, + sizeof(struct notify_ducatidrv_cmdargs)); + + if (status < 0) + retval = -EFAULT; + + return retval; +} + + + + +MODULE_LICENSE("GPL"); +module_init(drvducati_initialize_module); +module_exit(drvducati_finalize_module); diff --git a/drivers/dsp/syslink/notify_ducatidriver/notify_ducati.c b/drivers/dsp/syslink/notify_ducatidriver/notify_ducati.c new file mode 100755 index 000000000000..f18f30694f15 --- /dev/null +++ b/drivers/dsp/syslink/notify_ducatidriver/notify_ducati.c @@ -0,0 +1,1262 @@ +/* + * notify_ducati.c + * + * Syslink driver support functions for TI OMAP processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + + +#include <linux/spinlock.h> +#include <linux/semaphore.h> +#include <linux/timer.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/io.h> +#include <linux/module.h> +#include <plat/mailbox.h> + +#include <syslink/notify_driver.h> +#include <syslink/notifydefs.h> +#include <syslink/notify_driverdefs.h> +#include <syslink/notify_ducatidriver.h> +#include <syslink/multiproc.h> +#include <syslink/atomic_linux.h> + + + +#define NOTIFYSHMDRV_MEM_ALIGN 0 + +#define NOTIFYSHMDRV_MAX_EVENTS 32 + +#define NOTIFYSHMDRV_INIT_STAMP 0xA9C8B7D6 + +#define NOTIFYNONSHMDRV_MAX_EVENTS 1 + +#define NOTIFYNONSHMDRV_RESERVED_EVENTS 1 + +#define NOTIFYDRV_DUCATI_RECV_MBX 2 + +#define NOTIFYDRV_DUCATI_SEND_MBX 3 + +/*FIX ME: Make use of Multi Proc module */ +#define SELF_ID 0 + +#define OTHER_ID 1 + +#define UP 1 + +#define DOWN 0 + +#define PROC_TESLA 0 +#define PROC_DUCATI 1 +#define PROC_GPP 2 +#define PROCSYSM3 2 +#define PROCAPPM3 3 +#define MAX_SUBPROC_EVENTS 15 + +/*FIXME MOVE THIS TO A SUITABLE HEADER */ +#define NOTIFYDRIVERSHM_MODULEID (u32) 0xb9d4 + +/* Macro to make a correct module magic number with refCount */ +#define NOTIFYDRIVERSHM_MAKE_MAGICSTAMP(x) \ + ((NOTIFYDRIVERSHM_MODULEID << 12u) | (x)) + +static struct omap_mbox *ducati_mbox; +static void notify_ducatidrv_isr(void *ntfy_msg); +static void notify_ducatidrv_isr_callback(void *ref_data, void* ntfy_msg); + +struct notify_driver_object_list { + struct list_head elem; + struct notify_driver_object *drv_handle; +}; + + +/* + * brief Notify ducati driver instance object. + */ +struct notify_ducatidrv_object { + struct notify_ducatidrv_params params; + short int proc_id; + struct notify_drv_eventlist *event_list; + VOLATILE struct notify_shmdrv_ctrl *ctrl_ptr; + struct notify_shmdrv_eventreg *reg_chart; + struct notify_driver_object *drv_handle; + short int self_id; + short int other_id; +}; + + +/* + * brief Defines the notify_ducatidrv state object, which contains all + * the module specific information. + */ +struct notify_ducatidrv_module { + atomic_t ref_count; + struct notify_ducatidrv_config cfg; + struct notify_ducatidrv_config def_cfg; + struct notify_ducatidrv_params def_inst_params; + struct mutex *gate_handle; + struct list_head drv_handle_list; +} ; + + +static struct notify_ducatidrv_module notify_ducatidriver_state = { + .gate_handle = NULL, + .def_inst_params.shared_addr = 0x0, + .def_inst_params.shared_addr_size = 0x0, + .def_inst_params.num_events = NOTIFYSHMDRV_MAX_EVENTS, + .def_inst_params.num_reserved_events = 3, + .def_inst_params.send_event_poll_count = (int) -1, + .def_inst_params.remote_proc_id = -1, + .def_inst_params.recv_int_id = (int) -1, + .def_inst_params.send_int_id = (int) -1 +}; + +/* + * This function searchs for a element the List. + */ +static void notify_ducatidrv_qsearch_elem(struct list_head *list, + struct notify_drv_eventlistner *check_obj, + struct notify_drv_eventlistner **listener); + + +/* + * brief Get the default configuration for the notify_ducatidrv module. + * + * This function can be called by the application to get their + * configuration parameter to notify_ducatidrv_setup filled in by + * the notify_ducatidrv module with the default parameters. If the + * user does not wish to make any change in the default parameters, + * this API is not required to be called. + * + */ +void notify_ducatidrv_getconfig(struct notify_ducatidrv_config *cfg) +{ + BUG_ON(cfg == NULL); + + if (atomic_cmpmask_and_lt(&(notify_ducatidriver_state.ref_count), + NOTIFYDRIVERSHM_MAKE_MAGICSTAMP(0), + NOTIFYDRIVERSHM_MAKE_MAGICSTAMP(1)) + == true) + memcpy(cfg, + &(notify_ducatidriver_state.def_cfg), + sizeof(struct notify_ducatidrv_config)); + else + memcpy(cfg, + &(notify_ducatidriver_state.cfg), + sizeof(struct notify_ducatidrv_config)); +} +EXPORT_SYMBOL(notify_ducatidrv_getconfig); + +/* + * brief Function to open a handle to an existing notify_ducatidrv_object + * handling the procId. + * + * This function returns a handle to an existing notify_ducatidrv + * instance created for this procId. It enables other entities to + * access and use this notify_ducatidrv instance. + */ +int notify_ducatidrv_open(char *driver_name, + struct notify_driver_object **handle_ptr) +{ + int status = 0; + BUG_ON(driver_name == NULL); + BUG_ON(handle_ptr == NULL); + /* Enter critical section protection. */ + WARN_ON(mutex_lock_interruptible(notify_ducatidriver_state. + gate_handle) != 0); + /* Get the handle from Notify module. */ + status = notify_get_driver_handle(driver_name, handle_ptr); + WARN_ON(status < 0); + mutex_unlock(notify_ducatidriver_state.gate_handle); + return status; +} + + + + +/* + * brief Function to close this handle to the notify_ducatidrv instance. + * + * This function closes the handle to the notify_ducatidrv instance + * obtained through notify_ducatidrv_open call made earlier. + */ +int notify_ducatidrv_close(struct notify_driver_object **handle_ptr) +{ + int status = 0; + BUG_ON(handle_ptr == NULL); + BUG_ON(*handle_ptr == NULL); + *handle_ptr = NULL; + return status; +} + + + + +/* + * brief Function to initialize the parameters for this notify_ducatidrv + * instance. + */ +void notify_ducatidrv_params_init(struct notify_driver_object *handle, + struct notify_ducatidrv_params *params) +{ + struct notify_ducatidrv_object *driver_obj; + BUG_ON(params == NULL); + + if (atomic_cmpmask_and_lt(&(notify_ducatidriver_state.ref_count), + NOTIFYDRIVERSHM_MAKE_MAGICSTAMP(0), + NOTIFYDRIVERSHM_MAKE_MAGICSTAMP(1)) + == true) { + /*FIXME not intialized to be returned */ + BUG_ON(1); + } + + if (handle == NULL) { + memcpy(params, + &(notify_ducatidriver_state.def_inst_params), + sizeof(struct notify_ducatidrv_params)); + } else { + /*Return updated notify_ducatidrv instance specific parameters*/ + driver_obj = (struct notify_ducatidrv_object *) + handle->driver_object; + memcpy(params, &(driver_obj->params), + sizeof(struct notify_ducatidrv_params)); + } +} +EXPORT_SYMBOL(notify_ducatidrv_params_init); + + + +/* + * brief Function to create an instance of this Notify ducati driver. + * + */ +struct notify_driver_object *notify_ducatidrv_create(char *driver_name, + const struct notify_ducatidrv_params *params) +{ + + int status = 0; + struct notify_ducatidrv_object *driver_obj = NULL; + struct notify_driver_object *drv_handle = NULL; + struct notify_drv_eventlist *event_list = NULL; + VOLATILE struct notify_shmdrv_proc_ctrl *ctrl_ptr = NULL; + struct notify_driver_attrs drv_attrs; + struct notify_interface fxn_table; + struct notify_driver_object_list *drv_handle_inst = NULL; + int proc_id; + int i; + u32 shm_va; + int tmp_status = NOTIFY_SUCCESS; + + BUG_ON(driver_name == NULL); + BUG_ON(params == NULL); + + if (atomic_cmpmask_and_lt(&(notify_ducatidriver_state.ref_count), + NOTIFYDRIVERSHM_MAKE_MAGICSTAMP(0), + NOTIFYDRIVERSHM_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "Module not initialized\n"); + goto func_end; + } + + if (params->num_events > NOTIFYSHMDRV_MAX_EVENTS) { + printk(KERN_ERR "More than max number of events passed\n"); + goto func_end; + } + WARN_ON(mutex_lock_interruptible(notify_ducatidriver_state. + gate_handle) != 0); + proc_id = PROC_DUCATI; + + tmp_status = notify_get_driver_handle(driver_name, &drv_handle); + + if (tmp_status != NOTIFY_E_NOTFOUND) { + printk(KERN_ERR "Driver handle not found\n"); + goto error_unlock_and_return; + } + + /* Fill in information about driver attributes. */ + /* This driver supports interaction with one other remote + * processor.*/ + + for (i = 0 ; i < MULTIPROC_MAXPROCESSORS; i++) { + /* Initialize all to invalid. */ + drv_attrs.proc_info[i].proc_id = (u16)0xFFFF; + } + + /*FIXME: Hack to allow SYSM3 and APPM3 events. Re-visit later */ + if (params->remote_proc_id >= PROCSYSM3) { + for (i = PROCSYSM3; i <= PROCAPPM3; i++) { + drv_attrs.numProc = 1; + drv_attrs.proc_info[i].max_events = params->num_events; + drv_attrs.proc_info[i].reserved_events = + params->num_reserved_events; + /* Events are prioritized. */ + drv_attrs.proc_info[i].event_priority = true; + /* 32-bit payload supported. */ + drv_attrs.proc_info[i].payload_size = sizeof(int); + drv_attrs.proc_info[i].proc_id = i; + } + } + + /* Function table information */ + fxn_table.register_event = (void *)¬ify_ducatidrv_register_event; + fxn_table.unregister_event = (void *)¬ify_ducatidrv_unregister_event; + fxn_table.send_event = (void *)¬ify_ducatidrv_sendevent; + fxn_table.disable = (void *)¬ify_ducatidrv_disable; + fxn_table.restore = (void *)¬ify_ducatidrv_restore; + fxn_table.disable_event = (void *)¬ify_ducatidrv_disable_event; + fxn_table.enable_event = (void *)¬ify_ducatidrv_enable_event; + + /* Register driver with the Notify module. */ + status = notify_register_driver(driver_name, + &fxn_table, + &drv_attrs, + &drv_handle); + /*FIXME: To take care of already exists case */ + if ((status != NOTIFY_SUCCESS) && (status != NOTIFY_E_ALREADYEXISTS)) { + printk(KERN_ERR "Notify register failed\n"); + goto error_clean_and_exit; + } + /* Allocate memory for the notify_ducatidrv_object object. */ + drv_handle->driver_object = driver_obj = + kmalloc(sizeof(struct notify_ducatidrv_object), + GFP_ATOMIC); + + if (driver_obj == NULL) { + status = -ENOMEM; + goto error_clean_and_exit; + } else { + memcpy(&(driver_obj->params), (void *) params, + sizeof(struct notify_ducatidrv_params)); + } + + if (params->remote_proc_id > multiproc_get_id(NULL)) { + driver_obj->self_id = SELF_ID; + driver_obj->other_id = OTHER_ID; + } else { + driver_obj->self_id = OTHER_ID; + driver_obj->other_id = SELF_ID; + } + + shm_va = get_ducati_virt_mem(); + driver_obj->ctrl_ptr = (struct notify_shmdrv_ctrl *) shm_va; + ctrl_ptr = &(driver_obj->ctrl_ptr-> + proc_ctrl[driver_obj->self_id]); + ctrl_ptr->self_event_chart = + (struct notify_shmdrv_event_entry *) + ((int)(driver_obj->ctrl_ptr) + + sizeof(struct notify_shmdrv_ctrl)+ + (sizeof(struct + notify_shmdrv_event_entry) + * params->num_events + * driver_obj->other_id)); + + ctrl_ptr->other_event_chart = + (struct notify_shmdrv_event_entry *) + ((int)(driver_obj->ctrl_ptr) + + sizeof(struct notify_shmdrv_ctrl) + + (sizeof(struct + notify_shmdrv_event_entry) + * params->num_events + * driver_obj->self_id)); + driver_obj->proc_id = params->remote_proc_id; + driver_obj->event_list = kmalloc( + (sizeof(struct notify_drv_eventlist) + * params->num_events), GFP_ATOMIC); + if (driver_obj->event_list == NULL) { + status = -ENOMEM; + goto error_clean_and_exit; + } else { + memset(driver_obj->event_list, 0, + sizeof(struct notify_drv_eventlist)*params-> + num_events); + } + + driver_obj->reg_chart = kmalloc(sizeof( + struct notify_shmdrv_eventreg) + *params->num_events, + GFP_ATOMIC); + if (driver_obj->reg_chart == NULL) { + status = -ENOMEM; + goto error_clean_and_exit; + } else { + memset(driver_obj->reg_chart, 0, + sizeof(struct notify_shmdrv_eventreg) + *params->num_events); + } + + event_list = driver_obj->event_list; + + for (i = 0 ; (i < params->num_events) ; i++) { + ctrl_ptr->self_event_chart[i].flag = 0; + driver_obj->reg_chart[i].reg_event_no = (int) -1; + event_list[i].event_handler_count = 0; + INIT_LIST_HEAD(&event_list[i].listeners); + } + + /*Set up the ISR on the Modena-ducati FIFO */ + /* Add the driver handle to list */ + drv_handle_inst = kmalloc(sizeof + (struct notify_driver_object_list), GFP_ATOMIC); + if (drv_handle_inst == NULL) { + status = -ENOMEM; + goto error_clean_and_exit; + } + + drv_handle_inst->drv_handle = drv_handle; + list_add_tail(&(drv_handle_inst->elem), + &(notify_ducatidriver_state.drv_handle_list)); + + driver_obj = drv_handle->driver_object; + ctrl_ptr->reg_mask.mask = 0x0; + ctrl_ptr->reg_mask.enable_mask = 0xFFFFFFFF; + ctrl_ptr->recv_init_status = NOTIFYSHMDRV_INIT_STAMP; + ctrl_ptr->send_init_status = NOTIFYSHMDRV_INIT_STAMP; + drv_handle->is_init = NOTIFY_DRIVERINITSTATUS_DONE; + mutex_unlock(notify_ducatidriver_state.gate_handle); + omap_mbox_enable_irq(ducati_mbox, IRQ_RX); + + /* Done with initialization. goto function end */ + goto func_end; + +error_clean_and_exit: + if (drv_handle != NULL) { + /* Unregister driver from the Notify module*/ + notify_unregister_driver(drv_handle); + if (ctrl_ptr != NULL) { + /* Clear initialization status in + shared memory. */ + ctrl_ptr->recv_init_status = 0x0; + ctrl_ptr->send_init_status = 0x0; + ctrl_ptr = NULL; + } + /* Check if driverObj was allocated. */ + if (driver_obj != NULL) { + /* Check if event List was allocated. */ + if (driver_obj->event_list != NULL) { + /* Check if lists were + created. */ + for (i = 0 ; + i < params->num_events ; i++) { + list_del( + (struct list_head *) + &driver_obj-> + event_list[i]. + listeners); + } + kfree(driver_obj->event_list); + driver_obj->event_list = NULL; + } + /* Check if regChart was allocated. */ + if (driver_obj->reg_chart != NULL) { + kfree(driver_obj->reg_chart); + driver_obj->reg_chart + = NULL; + } + kfree(driver_obj); + } + drv_handle->is_init = + NOTIFY_DRIVERINITSTATUS_NOTDONE; + drv_handle = NULL; + } + +error_unlock_and_return: + /* Leave critical section protection. */ + mutex_unlock(notify_ducatidriver_state.gate_handle); +func_end: + return drv_handle; +} +EXPORT_SYMBOL(notify_ducatidrv_create); + +/* + * brief Function to delete the instance of shared memory driver + * + */ +int notify_ducatidrv_delete(struct notify_driver_object **handle_ptr) +{ + int status = 0; + struct notify_driver_object *drv_handle = NULL; + struct notify_ducatidrv_object *driver_obj = NULL; + struct notify_drv_eventlist *event_list; + short int i = 0; + struct list_head *elem = NULL; + struct notify_driver_object_list *drv_list_entry = NULL; + int proc_id; + + if (atomic_cmpmask_and_lt(&(notify_ducatidriver_state.ref_count), + NOTIFYDRIVERSHM_MAKE_MAGICSTAMP(0), + NOTIFYDRIVERSHM_MAKE_MAGICSTAMP(1)) + == true) { + /*FIXME not intialized to be returned */ + return -1; + } + + WARN_ON(handle_ptr == NULL); + if (handle_ptr == NULL) + return -1; + + drv_handle = (*handle_ptr); + WARN_ON(drv_handle == NULL); + if (drv_handle == NULL) + return -1; + + driver_obj = (struct notify_ducatidrv_object *) + (*handle_ptr)->driver_object; + WARN_ON((*handle_ptr)->driver_object == NULL); + + /*Uninstall the ISRs & Disable the Mailbox interrupt.*/ + + if (drv_handle != NULL) { + list_for_each(elem, + ¬ify_ducatidriver_state.drv_handle_list) { + drv_list_entry = container_of(elem, + struct notify_driver_object_list, elem); + if (drv_list_entry->drv_handle == drv_handle) { + list_del(elem); + kfree(drv_list_entry); + status = notify_unregister_driver(drv_handle); + drv_handle = NULL; + break; + } + } + } + + if (status != NOTIFY_SUCCESS) + printk(KERN_WARNING "driver is not registerd\n"); + + if (driver_obj != NULL) { + if (driver_obj->ctrl_ptr != NULL) { + /* Clear initialization status in shared memory. */ + driver_obj->ctrl_ptr->proc_ctrl[driver_obj->self_id]. + recv_init_status = 0x0; + driver_obj->ctrl_ptr->proc_ctrl[driver_obj->self_id]. + send_init_status = 0x0; + unmap_ducati_virt_mem((u32)(driver_obj->ctrl_ptr)); + driver_obj->ctrl_ptr = NULL; + } + + event_list = driver_obj->event_list; + if (event_list != NULL) { + /* Check if lists were created. */ + for (i = 0 ; i < driver_obj->params.num_events ; i++) { + WARN_ON(event_list[i].event_handler_count != 0); + event_list[i].event_handler_count = 0; + list_del((struct list_head *) + &event_list[i].listeners); + } + + kfree(event_list); + driver_obj->event_list = NULL; + } + + /* Check if regChart was allocated. */ + if (driver_obj->reg_chart != NULL) { + kfree(driver_obj->reg_chart); + driver_obj->reg_chart = NULL; + } + + /* Disable the interrupt, Uninstall the ISR and delete it. */ + /* Check if ISR was created. */ + /*Remove the ISR on the Modena-ducati FIFO */ + proc_id = PROC_DUCATI; + + omap_mbox_disable_irq(ducati_mbox, IRQ_RX); + + kfree(driver_obj); + driver_obj = NULL; + } + return status; +} +EXPORT_SYMBOL(notify_ducatidrv_delete); + + +/* + * brief Destroy the notify_ducatidrv module. + * + */ +int notify_ducatidrv_destroy(void) +{ + int status = 0; + struct list_head *handle_list = NULL; + struct notify_driver_object_list *entry_list = NULL; + struct notify_driver_object *drv_handle = NULL; + struct list_head *entry; + + if (atomic_cmpmask_and_lt(&(notify_ducatidriver_state.ref_count), + NOTIFYDRIVERSHM_MAKE_MAGICSTAMP(0), + NOTIFYDRIVERSHM_MAKE_MAGICSTAMP(1)) + == true) + /* FIXME Invalid state to be reuurned. */ + return -1; + + if (atomic_dec_return(&(notify_ducatidriver_state.ref_count)) == + NOTIFYDRIVERSHM_MAKE_MAGICSTAMP(0)) { + + /* Temprarily increment the refcount */ + atomic_set(&(notify_ducatidriver_state.ref_count), + NOTIFYDRIVERSHM_MAKE_MAGICSTAMP(1)); + handle_list = &(notify_ducatidriver_state.drv_handle_list); + + list_for_each(entry, handle_list) { + entry_list = (struct notify_driver_object_list *) + container_of(entry, + struct notify_driver_object_list, elem); + drv_handle = entry_list->drv_handle; + notify_ducatidrv_delete(&drv_handle); + } + + /* Check if the gate_handle was created internally. */ + + if (notify_ducatidriver_state.gate_handle != NULL) + kfree(notify_ducatidriver_state.gate_handle); + + atomic_set(&(notify_ducatidriver_state.ref_count), + NOTIFYDRIVERSHM_MAKE_MAGICSTAMP(0)); + + omap_mbox_put(ducati_mbox); + ducati_mbox = NULL; + } + + + return status; +} +EXPORT_SYMBOL(notify_ducatidrv_destroy); + + + +/* + * brief Setup the notify_ducatidrv module. + * + * This function sets up the notify_ducatidrv module. This function + * must be called before any other instance-level APIs can be + * invoked. + * Module-level configuration needs to be provided to this + * function. If the user wishes to change some specific config + * parameters, then notify_ducatidrv_getconfig can be called to get + * the configuration filled with the default values. After this, + * only the required configuration values can be changed. If the + * user does not wish to make any change in the default parameters, + * the application can simply call notify_ducatidrv_setup with NULL + * parameters. The default parameters would get automatically used. + */ +int notify_ducatidrv_setup(struct notify_ducatidrv_config *cfg) +{ + int status = 0; + struct notify_ducatidrv_config tmp_cfg; + + if (cfg == NULL) { + notify_ducatidrv_getconfig(&tmp_cfg); + cfg = &tmp_cfg; + } + + /* Init the ref_count to 0 */ + atomic_cmpmask_and_set(&(notify_ducatidriver_state.ref_count), + NOTIFYDRIVERSHM_MAKE_MAGICSTAMP(0), + NOTIFYDRIVERSHM_MAKE_MAGICSTAMP(0)); + if (atomic_inc_return(&(notify_ducatidriver_state.ref_count)) != + NOTIFYDRIVERSHM_MAKE_MAGICSTAMP(1u)) { + return 1; + } + + + /* Create a default gate handle here */ + notify_ducatidriver_state.gate_handle = + kmalloc(sizeof(struct mutex), GFP_KERNEL); + mutex_init(notify_ducatidriver_state.gate_handle); + + if (notify_ducatidriver_state.gate_handle == NULL) { + atomic_set(&(notify_ducatidriver_state.ref_count), + NOTIFYDRIVERSHM_MAKE_MAGICSTAMP(0)); + status = -ENOMEM; + goto error_exit; + } else { + memcpy(¬ify_ducatidriver_state.cfg, + cfg, sizeof(struct notify_ducatidrv_config)); + } + + INIT_LIST_HEAD(&(notify_ducatidriver_state. + drv_handle_list)); + /* Initialize the maibox modulde for ducati */ + if (ducati_mbox == NULL) { + ducati_mbox = omap_mbox_get("mailbox-2"); + if (ducati_mbox == NULL) { + printk(KERN_ERR "Failed in omap_mbox_get()\n"); + status = -ENODEV; + goto error_mailbox_get_failed; + } + ducati_mbox->rxq->callback = + (int (*)(void *))notify_ducatidrv_isr; + } + + return 0; + +error_mailbox_get_failed: + kfree(notify_ducatidriver_state.gate_handle); +error_exit: + return status; +} +EXPORT_SYMBOL(notify_ducatidrv_setup); + + +/* +* brief register a callback for an event with the Notify driver. +* +*/ +int notify_ducatidrv_register_event( + struct notify_driver_object *handle, + short int proc_id, + int event_no, + fn_notify_cbck fn_notify_cbck, + void *cbck_arg) +{ + int status = 0; + int first_reg = false; + bool done = true; + struct notify_drv_eventlistner *event_listener; + struct notify_drv_eventlist *event_list; + struct notify_ducatidrv_object *driver_object; + struct notify_shmdrv_eventreg *reg_chart; + VOLATILE struct notify_shmdrv_ctrl *ctrl_ptr; + VOLATILE struct notify_shmdrv_event_entry *self_event_chart; + int i; + int j; + BUG_ON(handle == NULL); + BUG_ON(handle->is_init != NOTIFY_DRIVERINITSTATUS_DONE); + BUG_ON(handle->driver_object == NULL); + BUG_ON(fn_notify_cbck == NULL); + + + driver_object = (struct notify_ducatidrv_object *) + handle->driver_object; + + ctrl_ptr = driver_object->ctrl_ptr; + /* Allocate memory for event listener. */ + event_listener = kmalloc(sizeof(struct notify_drv_eventlistner), + GFP_ATOMIC); + + if (event_listener == NULL) { + status = -ENOMEM; + goto func_end; + } else { + memset(event_listener, 0, + sizeof(struct notify_drv_eventlistner)); + } + + if (mutex_lock_interruptible(notify_ducatidriver_state.gate_handle) + != 0) + WARN_ON(1); + + event_list = driver_object->event_list; + WARN_ON(event_list == NULL); + event_listener->fn_notify_cbck = fn_notify_cbck; + event_listener->cbck_arg = cbck_arg; + /* Check if this is the first registration for this event. */ + + if (list_empty((struct list_head *) + &event_list[event_no].listeners)) { + first_reg = true; + self_event_chart = ctrl_ptr->proc_ctrl[driver_object->self_id]. + self_event_chart; + /* Clear any pending unserviced event as there are no listeners + * for the pending event + */ + self_event_chart[event_no].flag = DOWN; + } + + list_add_tail((struct list_head *) + &(event_listener->element), + (struct list_head *) + &event_list[event_no].listeners); + event_list[event_no].event_handler_count++; + + + if (first_reg == true) { + reg_chart = driver_object->reg_chart; + for (i = 0 ; i < driver_object->params.num_events ; i++) { + /* Find the correct slot in the registration array. */ + if (reg_chart[i].reg_event_no == (int) -1) { + for (j = (i - 1); j >= 0; j--) { + if (event_no < reg_chart[j]. + reg_event_no) { + reg_chart[j + 1].reg_event_no = + reg_chart[j]. + reg_event_no; + reg_chart[j + 1].reserved = + reg_chart[j].reserved; + i = j; + } else { + /* End the loop, slot found. */ + j = -1; + } + } + reg_chart[i].reg_event_no = event_no; + done = true; + break; + } + } + + if (done) { + set_bit(event_no, (unsigned long *) + &ctrl_ptr->proc_ctrl[driver_object->self_id]. + reg_mask.mask); + } else { + /*retval NOTIFY_E_MAXEVENTS Maximum number of + supported events have already been registered. */ + status = -EINVAL; + kfree(event_listener); + + } + } +func_end: + mutex_unlock(notify_ducatidriver_state.gate_handle); + return status; +} + + +/* +* +* brief Unregister a callback for an event with the Notify driver. +* +*/ + +int notify_ducatidrv_unregister_event( + struct notify_driver_object *handle, + short int proc_id, + int event_no, + fn_notify_cbck fn_notify_cbck, + void *cbck_arg) +{ + int status = 0; + struct notify_drv_eventlistner *listener = NULL; + int num_events; + struct notify_ducatidrv_object *driver_object; + struct notify_drv_eventlist *event_list; + struct notify_shmdrv_eventreg *reg_chart; + VOLATILE struct notify_shmdrv_ctrl *ctrl_ptr = NULL; + struct notify_drv_eventlistner unreg_info; + VOLATILE struct notify_shmdrv_event_entry *self_event_chart; + int i; + int j; + + BUG_ON(fn_notify_cbck == NULL); + BUG_ON(handle == NULL); + BUG_ON(handle->driver_object == NULL); + + driver_object = (struct notify_ducatidrv_object *) + handle->driver_object; + num_events = driver_object->params.num_events; + + ctrl_ptr = driver_object->ctrl_ptr; + + /* Enter critical section protection. */ + if (mutex_lock_interruptible(notify_ducatidriver_state.gate_handle) + != 0) + WARN_ON(1); + + event_list = driver_object->event_list; + + + unreg_info.fn_notify_cbck = fn_notify_cbck; + unreg_info.cbck_arg = cbck_arg; + notify_ducatidrv_qsearch_elem(&event_list[event_no].listeners, + &unreg_info, + &listener); + if (listener == NULL) { + status = -EFAULT; + goto func_end; + } + list_del((struct list_head *)&(listener->element)); + kfree(listener); + event_list[event_no].event_handler_count--; + + + if (list_empty((struct list_head *) + &event_list[event_no].listeners) == true) { + clear_bit(event_no, (unsigned long *) + &ctrl_ptr->proc_ctrl[driver_object->self_id].reg_mask. + mask); + self_event_chart = ctrl_ptr->proc_ctrl[driver_object->self_id]. + self_event_chart; + /* Clear any pending unserviced event as there are no + * listeners for the pending event + */ + self_event_chart[event_no].flag = DOWN; + reg_chart = driver_object->reg_chart; + for (i = 0; i < num_events; i++) { + /* Find the correct slot in the registration array. */ + if (event_no == reg_chart[i].reg_event_no) { + reg_chart[i].reg_event_no = (int) -1; + for (j = (i + 1); + (reg_chart[j].reg_event_no != (int) -1) + && (j != num_events); j++) { + reg_chart[j - 1].reg_event_no = + reg_chart[j].reg_event_no; + reg_chart[j - 1].reserved = + reg_chart[j].reserved; + } + + if (j == num_events) { + reg_chart[j - 1].reg_event_no = + (int) -1; + } + break; + } + } + } + + + +func_end: + mutex_unlock(notify_ducatidriver_state.gate_handle); + return status; +} + +/* +* brief Send a notification event to the registered users for this +* notification on the specified processor. +* +*/ +int notify_ducatidrv_sendevent(struct notify_driver_object *handle, + short int proc_id, int event_no, + int payload, short int wait_clear) +{ + int status = 0; + struct notify_ducatidrv_object *driver_object; + VOLATILE struct notify_shmdrv_ctrl *ctrl_ptr; + int max_poll_count; + VOLATILE struct notify_shmdrv_event_entry *other_event_chart; + + int i = 0; + + BUG_ON(handle == NULL); + BUG_ON(handle->driver_object == NULL); + + dsb(); + driver_object = (struct notify_ducatidrv_object *) + handle->driver_object; + + BUG_ON(event_no > driver_object->params.num_events); + + ctrl_ptr = driver_object->ctrl_ptr; + other_event_chart = ctrl_ptr->proc_ctrl[driver_object->self_id]. + other_event_chart; + max_poll_count = driver_object->params.send_event_poll_count; + + /* Check whether driver supports interrupts from this processor to the + other processor, and if it is initialized + */ + if (ctrl_ptr->proc_ctrl[driver_object->other_id].recv_init_status + != NOTIFYSHMDRV_INIT_STAMP) { + status = -ENODEV; + /* This may be used for polling till other-side + driver is ready, sodo not set failure reason. + */ + } else { + /* Check if other side is ready to receive this event. */ + if ((test_bit(event_no, (unsigned long *) + &ctrl_ptr->proc_ctrl[driver_object->other_id]. + reg_mask.mask) != 1) + || (test_bit(event_no, &ctrl_ptr-> + proc_ctrl[driver_object->other_id].reg_mask. + enable_mask) != 1)) { + status = -ENODEV; + printk(KERN_ERR "NOTIFY DRV: OTHER SIDE NOT READY TO" + "RECEIVE. %d\n", event_no); + /* This may be used for polling till other-side + is ready, so do not set failure reason.*/ + } else { + dsb(); + /* Enter critical section protection. */ + if (mutex_lock_interruptible(notify_ducatidriver_state. + gate_handle) != 0) + WARN_ON(1); + if (wait_clear == true) { + /*Wait for completion of prev + event from other side*/ + while ((other_event_chart[event_no].flag + != DOWN) + && status == 0) { + /* Leave critical section protection + Create a window of opportunity + for other interrupts to be handled. + */ + mutex_unlock(notify_ducatidriver_state. + gate_handle); + i++; + if ((max_poll_count != (int) -1) + && (i == max_poll_count)) { + status = -EBUSY; + } + /* Enter critical section protection. */ + if (mutex_lock_interruptible( + notify_ducatidriver_state. + gate_handle) != 0) + WARN_ON(1); + } + } + if (status >= 0) { + /* Set the event bit field and payload. */ + other_event_chart[event_no].payload = payload; + other_event_chart[event_no].flag = UP; + /* Send an interrupt with the event + information to theremote processor */ + status = omap_mbox_msg_send(ducati_mbox, + payload); + } + /* Leave critical section protection. */ + mutex_unlock(notify_ducatidriver_state.gate_handle); + } + } + + return status; +} + +/* +* brief Disable all events for this Notify driver. +* +*/ +void *notify_ducatidrv_disable(struct notify_driver_object *handle) +{ + + omap_mbox_disable_irq(ducati_mbox, IRQ_RX); + + return NULL; /*No flags to be returned. */ +} + +/* +* brief Restore the notify_ducatidrv to the state before the +* last disable was called. +* +*/ +int notify_ducatidrv_restore(struct notify_driver_object *handle, + void *flags) +{ + (void) handle; + (void) flags; + /*Enable the receive interrupt for ducati */ + omap_mbox_enable_irq(ducati_mbox, IRQ_RX); + return 0; +} + +/* +* brief Disable a specific event for this Notify ducati driver +* +*/ +int notify_ducatidrv_disable_event( + struct notify_driver_object *handle, + short int proc_id, int event_no) +{ + static int access_count ; + signed long int status = 0; + struct notify_ducatidrv_object *driver_object; + BUG_ON(handle == NULL); + BUG_ON(handle->driver_object == NULL); + access_count++; + driver_object = (struct notify_ducatidrv_object *) + handle->driver_object; + /* Enter critical section protection. */ + + if (mutex_lock_interruptible(notify_ducatidriver_state. + gate_handle) != 0) + WARN_ON(1); + + clear_bit(event_no, (unsigned long *) + &driver_object->ctrl_ptr->proc_ctrl[driver_object->self_id]. + reg_mask.enable_mask); + /* Leave critical section protection. */ + mutex_unlock(notify_ducatidriver_state.gate_handle); + return status; +} + +/* +* brief Enable a specific event for this Notify ducati driver +* +*/ +int notify_ducatidrv_enable_event(struct notify_driver_object *handle, + short int proc_id, int event_no) +{ + int status = 0; + struct notify_ducatidrv_object *driver_object; + BUG_ON(handle == NULL); + BUG_ON(handle->driver_object == NULL); + + driver_object = (struct notify_ducatidrv_object *) + handle->driver_object; + /* Enter critical section protection. */ + + if (mutex_lock_interruptible(notify_ducatidriver_state. + gate_handle) != 0) + WARN_ON(1); + + set_bit(event_no, (unsigned long *) + &driver_object->ctrl_ptr->proc_ctrl[driver_object->self_id]. + reg_mask.enable_mask); + + mutex_unlock(notify_ducatidriver_state.gate_handle); + return status; +} + +/* +* brief Print debug information for the Notify ducati driver +* +*/ +int notify_ducatidrv_debug(struct notify_driver_object *handle) +{ + int status = 0; + printk(KERN_WARNING "ducati Debug: Nothing being printed currently\n"); + return status; +} + + +/* + * + * brief This function implements the interrupt service routine for the + * interrupt received from the Ducati processor. + * + */ +static void notify_ducatidrv_isr(void *ntfy_msg) +{ + struct notify_driver_object_list *obj_list; + struct list_head *entry = NULL; + list_for_each(entry, &(notify_ducatidriver_state.drv_handle_list)) { + obj_list = (struct notify_driver_object_list *) + container_of(entry, + struct notify_driver_object_list, elem); + notify_ducatidrv_isr_callback( + obj_list->drv_handle->driver_object, ntfy_msg); + } +} +EXPORT_SYMBOL(notify_ducatidrv_isr); + + +static void notify_ducatidrv_isr_callback(void *ref_data, void* ntfy_msg) +{ + int payload = 0; + int i = 0; + struct list_head *temp; + int j = 0; + VOLATILE struct notify_shmdrv_event_entry *self_event_chart; + struct notify_ducatidrv_object *driver_obj; + struct notify_shmdrv_eventreg *reg_chart; + VOLATILE struct notify_shmdrv_proc_ctrl *proc_ctrl_ptr; + int event_no; + dsb(); + /* Enter critical section protection. */ + + driver_obj = (struct notify_ducatidrv_object *) ref_data; + proc_ctrl_ptr = &(driver_obj->ctrl_ptr->proc_ctrl[driver_obj->self_id]); + reg_chart = driver_obj->reg_chart; + self_event_chart = proc_ctrl_ptr->self_event_chart; + dsb(); + /* Execute the loop till no asserted event + is found for one complete loop + through all registered events + */ + do { + /* Check if the entry is a valid registered event.*/ + event_no = reg_chart[i].reg_event_no; + /* Determine the current high priority event.*/ + /* Check if the event is set and enabled.*/ + if (self_event_chart[event_no].flag == UP && + test_bit(event_no, + (unsigned long *) &proc_ctrl_ptr->reg_mask.enable_mask) + && (event_no != (int) -1)) { + + payload = self_event_chart[event_no]. + payload; + dsb(); + /* Acknowledge the event. */ + payload = (int)ntfy_msg; + self_event_chart[event_no].flag = DOWN; + dsb(); + /*Call the callbacks associated with the event*/ + temp = driver_obj-> + event_list[event_no]. + listeners.next; + if (temp != NULL) { + for (j = 0; j < driver_obj-> + event_list[event_no]. + event_handler_count; + j++) { + /* Check for empty list. */ + if (temp == NULL) + continue; + /*FIXME: Hack to support SYSM3 and + APPM3 */ + if ((driver_obj->proc_id == PROCAPPM3) + && (event_no <= MAX_SUBPROC_EVENTS)) { + driver_obj->proc_id = PROCSYSM3; + } + if ((driver_obj->proc_id == PROCSYSM3) + && (event_no > MAX_SUBPROC_EVENTS)) { + driver_obj->proc_id = PROCAPPM3; + } + ((struct notify_drv_eventlistner *) + temp)->fn_notify_cbck( + driver_obj->proc_id, + event_no, + ((struct notify_drv_eventlistner *) + temp)->cbck_arg, + payload); + temp = temp->next; + } + /* reinitialize the event check counter. */ + i = 0; + } + } else { + /* check for next event. */ + i++; + } + } while ((event_no != (int) -1) + && (i < driver_obj->params.num_events)); + +} + +/* +* brief This function searchs for a element the List. +* +*/ +static void notify_ducatidrv_qsearch_elem(struct list_head *list, + struct notify_drv_eventlistner *check_obj, + struct notify_drv_eventlistner **listener) +{ + struct list_head *temp = NULL ; + struct notify_drv_eventlistner *l_temp = NULL ; + short int found = false; + + BUG_ON(list == NULL); + BUG_ON(check_obj == NULL); + BUG_ON(listener == NULL); + + *listener = NULL; + if ((list != NULL) && (check_obj != NULL)) { + if (list_empty((struct list_head *)list) == false) { + temp = list->next; + while ((found == false) && (temp != NULL)) { + l_temp = + (struct notify_drv_eventlistner *) + (temp); + if ((l_temp->fn_notify_cbck == + check_obj->fn_notify_cbck) && + (l_temp->cbck_arg == + check_obj->cbck_arg)) { + found = true; + } else + temp = temp->next; + } + if (found == true) + *listener = l_temp; + } + } + return; +} diff --git a/drivers/dsp/syslink/omap_notify/Kbuild b/drivers/dsp/syslink/omap_notify/Kbuild new file mode 100755 index 000000000000..c1fed9e32f51 --- /dev/null +++ b/drivers/dsp/syslink/omap_notify/Kbuild @@ -0,0 +1,19 @@ +libomap_notify = notify_driver.o notify.o drv_notify.o + + + +obj-$(CONFIG_MPU_BRIDGE_NOTIFY) += omap_notify.o +omap_notify-objs = $(libomap_notify) + + +ccflags-y += -Wno-strict-prototypes + +#Machine dependent +ccflags-y += -D_TI_ -D_DB_TIOMAP -DTMS32060 \ + -DTICFG_PROC_VER -DTICFG_EVM_TYPE -DCHNL_SMCLASS \ + -DCHNL_MESSAGES -DUSE_LEVEL_1_MACROS \ + -DCONFIG_DISABLE_BRIDGE_PM -DDSP_TRACEBUF_DISABLED + +#Header files +ccflags-y += -Iarch/arm/plat-omap/include + diff --git a/drivers/dsp/syslink/omap_notify/drv_notify.c b/drivers/dsp/syslink/omap_notify/drv_notify.c new file mode 100755 index 000000000000..d6695df040b8 --- /dev/null +++ b/drivers/dsp/syslink/omap_notify/drv_notify.c @@ -0,0 +1,918 @@ +/* + * drv_notify.c + * + * Syslink support functions for TI OMAP processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include <generated/autoconf.h> +#include <linux/spinlock.h> +#include <linux/semaphore.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/fs.h> +#include <linux/mm.h> +#include <linux/list.h> +#include <linux/uaccess.h> +#include <linux/io.h> +#include <asm/pgtable.h> +#include <linux/types.h> +#include <linux/cdev.h> + +#include <syslink/gt.h> +#include <syslink/notify_driver.h> +#include <syslink/notify.h> +#include <syslink/GlobalTypes.h> + + +/** ============================================================================ + * Macros and types + * ============================================================================ + */ +#define IPCNOTIFY_NAME "ipcnotify" + +static char *driver_name = IPCNOTIFY_NAME; + +static s32 driver_major; + +static s32 driver_minor; + +struct ipcnotify_dev { + struct cdev cdev; +}; + +static struct ipcnotify_dev *ipcnotify_device; + +static struct class *ipcnotify_class; + + +/* + * Maximum number of user supported. + */ + +#define MAX_PROCESSES 32 + +/*Structure of Event Packet read from notify kernel-side..*/ +struct notify_drv_event_packet { + struct list_head element; + u32 pid; + u32 proc_id; + u32 event_no; + u32 data; + notify_callback_fxn func; + void *param; + bool is_exit; +}; + +/*Structure of Event callback argument passed to register fucntion*/ +struct notify_drv_event_cbck { + struct list_head element; + u32 proc_id; + notify_callback_fxn func; + void *param; + u32 pid; +}; + +/*Keeps the information related to Event.*/ +struct notifydrv_event_state { + struct list_head buf_list; + u32 pid; + u32 ref_count; + /*Reference count, used when multiple Notify_registerEvent are called + from same process space(multi threads/processes). */ + struct semaphore *semhandle; + /* Semphore for waiting on event. */ + struct semaphore *tersemhandle; + /* Termination synchronization semaphore. */ +}; + +struct notifydrv_moduleobject{ + bool is_setup; + /*Indicates whether the module has been already setup */ + int open_refcount; + /* Open reference count. */ + struct mutex *gatehandle; + /*Handle of gate to be used for local thread safety */ + struct list_head evt_cbck_list; + /*List containg callback arguments for all registered handlers from + user mode. */ + struct notifydrv_event_state event_state[MAX_PROCESSES]; + /* List for all user processes registered. */ +}; + +struct notifydrv_moduleobject notifydrv_state = { + .is_setup = false, + .open_refcount = 0, + .gatehandle = NULL, +}; + +/*Major number of driver.*/ +int major = 232; + +static void notify_drv_setup(void); + +static int notify_drv_add_buf_by_pid(u16 procId, u32 pid, + u32 eventNo, u32 data, notify_callback_fxn cbFxn, void *param); + +/* open the Notify driver object..*/ +static int notify_drv_open(struct inode *inode, struct file *filp) ; + +/* close the Notify driver object..*/ +static int notify_drv_close(struct inode *inode, struct file *filp); + +/* Linux driver function to map memory regions to user space. */ +static int notify_drv_mmap(struct file *filp, struct vm_area_struct *vma); + +/* read function for of Notify driver.*/ +static int notify_drv_read(struct file *filp, char *dst, + size_t size, loff_t *offset); + +/* ioctl function for of Linux Notify driver.*/ +static int notify_drv_ioctl(struct inode *inode, struct file *filp, u32 cmd, + unsigned long args); + +/* Module initialization function for Linux driver.*/ +static int __init notify_drv_init_module(void); + +/* Module finalization function for Linux driver.*/ +static void __exit notify_drv_finalize_module(void) ; + +static void notify_drv_destroy(void); + +static int notify_drv_register_driver(void); + +static int notify_drv_unregister_driver(void); + +/* Attach a process to notify user support framework. */ +static int notify_drv_attach(u32 pid); + +/* Detach a process from notify user support framework. */ +static int notify_drv_detach(u32 pid); + + +/* Function to invoke the APIs through ioctl.*/ +static const struct file_operations driver_ops = { + .open = notify_drv_open, + .ioctl = notify_drv_ioctl, + .release = notify_drv_close, + .read = notify_drv_read, + .mmap = notify_drv_mmap, +}; + +static int notify_drv_register_driver(void) +{ + notify_drv_setup(); + return 0; +} + +static int notify_drv_unregister_driver(void) +{ + notify_drv_destroy(); + return 0; +} + + +/* +* This function implements the callback registered with IPS. Here +* to pass event no. back to user function(so that it can do another +* level of demultiplexing of callbacks) +*/ +static void notify_drv_cbck(u16 proc_id, u32 event_no, + void *arg, u32 payload) +{ + struct notify_drv_event_cbck *cbck; + + if (WARN_ON(notifydrv_state.is_setup == false)) + goto func_end; + BUG_ON(arg == NULL); + cbck = (struct notify_drv_event_cbck *)arg; + notify_drv_add_buf_by_pid(proc_id, cbck->pid, event_no, payload, + cbck->func, cbck->param); +func_end: + return; +} + +/* + * Linux specific function to open the driver. + */ +static int notify_drv_open(struct inode *inode, struct file *filp) +{ + return 0; +} + +/* + * close the driver + */ +static int notify_drv_close(struct inode *inode, struct file *filp) +{ + return 0 ; +} + +/* + * read data from the driver + */ +static int notify_drv_read(struct file *filp, char *dst, size_t size, + loff_t *offset) +{ + + bool flag = false; + struct notify_drv_event_packet *u_buf = NULL; + int ret_val = 0; + u32 i; + struct list_head *elem; + struct notify_drv_event_packet t_buf; + if (WARN_ON(notifydrv_state.is_setup == false)) { + ret_val = -EFAULT; + goto func_end; + } + + ret_val = copy_from_user((void *)&t_buf, + (void *)dst, + sizeof(struct notify_drv_event_packet)); + WARN_ON(ret_val != 0); + + + for (i = 0 ; i < MAX_PROCESSES ; i++) { + if (notifydrv_state.event_state[i].pid == t_buf.pid) { + flag = true; + break; + } + } + if (flag == false) { + ret_val = -EFAULT; + goto func_end; + } + /* Wait for the event */ + ret_val = down_interruptible( + notifydrv_state.event_state[i].semhandle); + if (ret_val < 0) { + ret_val = -ERESTARTSYS; + goto func_end; + } + WARN_ON(mutex_lock_interruptible(notifydrv_state.gatehandle)); + elem = ((struct list_head *)&(notifydrv_state.event_state[i]. \ + buf_list))->next; + u_buf = container_of(elem, struct notify_drv_event_packet, + element); + list_del(elem); + mutex_unlock(notifydrv_state.gatehandle); + if (u_buf == NULL) { + ret_val = -EFAULT; + goto func_end; + } + ret_val = copy_to_user((void *)dst, u_buf, + sizeof(struct notify_drv_event_packet)); + + if (WARN_ON(ret_val != 0)) + ret_val = -EFAULT; + if (u_buf->is_exit == true) + up(notifydrv_state.event_state[i].tersemhandle); + + kfree(u_buf); + u_buf = NULL; + + +func_end: + return ret_val ; +} + +static int notify_drv_mmap(struct file *filp, struct vm_area_struct *vma) +{ + vma->vm_page_prot = pgprot_dmacoherent(vma->vm_page_prot); + + if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, + vma->vm_end - vma->vm_start, vma->vm_page_prot)) { + return -EAGAIN; + } + return 0; +} + +/* + * name notify_drv_ioctl + * + * ioctl function for of Linux Notify driver. + * +*/ +static int notify_drv_ioctl(struct inode *inode, struct file *filp, u32 cmd, + unsigned long args) +{ + int retval = 0; + int status = NOTIFY_SUCCESS; + struct notify_cmd_args *cmdArgs = (struct notify_cmd_args *)args; + struct notify_cmd_args commonArgs; + + switch (cmd) { + case CMD_NOTIFY_GETCONFIG: + { + struct notify_cmd_args_get_config *src_args = + (struct notify_cmd_args_get_config *)args; + struct notify_config cfg; + notify_get_config(&cfg); + retval = copy_to_user((void *) (src_args->cfg), + (const void *) &cfg, sizeof(struct notify_config)); + } + break; + + case CMD_NOTIFY_SETUP: + { + struct notify_cmd_args_setup *src_args = + (struct notify_cmd_args_setup *) args; + struct notify_config cfg; + + retval = copy_from_user((void *) &cfg, + (const void *) (src_args->cfg), + sizeof(struct notify_config)); + if (WARN_ON(retval != 0)) + goto func_end; + notify_setup(&cfg); + } + break; + + case CMD_NOTIFY_DESTROY: + { + /* copy_from_user is not needed for Notify_getConfig, since the + * user's config is not used. + */ + status = notify_destroy(); + } + break; + + case CMD_NOTIFY_REGISTEREVENT: + { + struct notify_cmd_args_register_event src_args; + struct notify_drv_event_cbck *cbck = NULL; + + /* Copy the full args from user-side. */ + retval = copy_from_user((void *) &src_args, + (const void *) (args), + sizeof(struct notify_cmd_args_register_event)); + + if (WARN_ON(retval != 0)) + goto func_end; + cbck = kmalloc(sizeof(struct notify_drv_event_cbck), + GFP_ATOMIC); + WARN_ON(cbck == NULL); + cbck->proc_id = src_args.procId; + cbck->func = src_args.fnNotifyCbck; + cbck->param = src_args.cbckArg; + cbck->pid = src_args.pid; + status = notify_register_event(src_args.handle, src_args.procId, + src_args.eventNo, notify_drv_cbck, (void *)cbck); + if (status < 0) { + /* This does not impact return status of this function, + * so retval comment is not used. + */ + kfree(cbck); + } else { + WARN_ON(mutex_lock_interruptible + (notifydrv_state.gatehandle)); + INIT_LIST_HEAD((struct list_head *)&(cbck->element)); + list_add_tail(&(cbck->element), + &(notifydrv_state.evt_cbck_list)); + mutex_unlock(notifydrv_state.gatehandle); + } + } + break; + + case CMD_NOTIFY_UNREGISTEREVENT: + { + bool found = false; + u32 pid; + struct notify_drv_event_cbck *cbck = NULL; + struct list_head *entry = NULL; + struct notify_cmd_args_unregister_event src_args; + + /* Copy the full args from user-side. */ + retval = copy_from_user((void *)&src_args, (const void *)(args), + sizeof(struct notify_cmd_args_unregister_event)); + + if (WARN_ON(retval != 0)) + goto func_end; + + pid = src_args.pid; + WARN_ON(mutex_lock_interruptible(notifydrv_state.gatehandle)); + list_for_each(entry, + (struct list_head *)&(notifydrv_state.evt_cbck_list)) { + cbck = (struct notify_drv_event_cbck *)(entry); + if ((cbck->func == src_args.fnNotifyCbck) && + (cbck->param == src_args.cbckArg) && + (cbck->pid == pid) && + (cbck->proc_id == src_args.procId)) { + found = true; + break; + } + } + mutex_unlock(notifydrv_state.gatehandle); + if (found == false) { + status = NOTIFY_E_NOTFOUND; + goto func_end; + } + status = notify_unregister_event(src_args.handle, + src_args.procId, + src_args.eventNo, + notify_drv_cbck, (void *) cbck); + /* This check is needed at run-time also to propagate the + * status to user-side. This must not be optimized out. + */ + if (status < 0) + printk(KERN_ERR " notify_unregister_event failed \n"); + else { + WARN_ON(mutex_lock_interruptible + (notifydrv_state.gatehandle)); + list_del((struct list_head *)cbck); + mutex_unlock(notifydrv_state.gatehandle); + kfree(cbck); + } + } + break; + + case CMD_NOTIFY_SENDEVENT: + { + struct notify_cmd_args_send_event src_args; + + /* Copy the full args from user-side. */ + retval = copy_from_user((void *) &src_args, + (const void *) (args), + sizeof(struct notify_cmd_args_send_event)); + if (WARN_ON(retval != 0)) { + retval = -EFAULT; + goto func_end; + } + status = notify_sendevent(src_args.handle, src_args.procId, + src_args.eventNo, src_args.payload, + src_args.waitClear); + } + break; + + case CMD_NOTIFY_DISABLE: + { + struct notify_cmd_args_disable src_args; + + /* Copy the full args from user-side. */ + retval = copy_from_user((void *) &src_args, + (const void *) (args), + sizeof(struct notify_cmd_args_disable)); + + /* This check is needed at run-time also since it depends on + * run environment. It must not be optimized out. + */ + if (WARN_ON(retval != 0)) { + retval = -EFAULT; + goto func_end; + } + src_args.flags = notify_disable(src_args.procId); + + /* Copy the full args to user-side */ + retval = copy_to_user((void *) (args), + (const void *) &src_args, + sizeof(struct notify_cmd_args_disable)); + /* This check is needed at run-time also since it depends on + * run environment. It must not be optimized out. + */ + if (WARN_ON(retval != 0)) + retval = -EFAULT; + } + break; + + case CMD_NOTIFY_RESTORE: + { + struct notify_cmd_args_restore src_args; + + /* Copy the full args from user-side. */ + retval = copy_from_user((void *) &src_args, + (const void *)(args), + sizeof(struct notify_cmd_args_restore)); + if (WARN_ON(retval != 0)) { + retval = -EFAULT; + goto func_end; + } + notify_restore(src_args.key, src_args.procId); + } + break; + + case CMD_NOTIFY_DISABLEEVENT: + { + struct notify_cmd_args_disable_event src_args; + + /* Copy the full args from user-side. */ + retval = copy_from_user((void *) &src_args, + (const void *)(args), + sizeof(struct notify_cmd_args_disable_event)); + + /* This check is needed at run-time also since it depends on + * run environment. It must not be optimized out. + */ + if (WARN_ON(retval != 0)) { + retval = -EFAULT; + goto func_end; + } + notify_disable_event(src_args.handle, src_args.procId, + src_args.eventNo); + } + break; + + case CMD_NOTIFY_ENABLEEVENT: + { + struct notify_cmd_args_enable_event src_args; + + /* Copy the full args from user-side. */ + retval = copy_from_user((void *)&src_args, + (const void *)(args), + sizeof(struct notify_cmd_args_enable_event)); + if (WARN_ON(retval != 0)) { + retval = -EFAULT; + goto func_end; + } + notify_enable_event(src_args.notify_driver_handle, + src_args.procId, src_args.eventNo); + } + break; + + case CMD_NOTIFY_ATTACH: + { + /* FIXME: User copy_from_user */ + u32 pid = *((u32 *)args); + status = notify_drv_attach(pid); + + if (status < 0) + printk(KERN_ERR "NOTIFY_ATTACH FAILED\n"); + } + break; + + case CMD_NOTIFY_DETACH: + { + /* FIXME: User copy_from_user */ + u32 pid = *((u32 *)args); + status = notify_drv_detach(pid); + + if (status < 0) + printk(KERN_ERR "NOTIFY_DETACH FAILED\n"); + } + break; + + default: + { + /* This does not impact return status of this function,so retval + * comment is not used. + */ + status = NOTIFY_E_INVALIDARG; + printk(KERN_ERR "not valid command\n"); + } + break; + } +func_end: + /* Set the status and copy the common args to user-side. */ + commonArgs.apiStatus = status; + status = copy_to_user((void *) cmdArgs, + (const void *) &commonArgs, + sizeof(struct notify_cmd_args)); + if (status < 0) + retval = -EFAULT; + return retval; +} + +/*==================== + * notify_drv_add_buf_by_pid + * + */ +static int notify_drv_add_buf_by_pid(u16 proc_id, u32 pid, + u32 event_no, u32 data, notify_callback_fxn cbFxn, void *param) +{ + s32 status = 0; + bool flag = false; + bool is_exit = false; + struct notify_drv_event_packet *u_buf = NULL; + u32 i; + + for (i = 0 ; (i < MAX_PROCESSES) && (flag != true) ; i++) { + if (notifydrv_state.event_state[i].pid == pid) { + flag = true ; + break ; + } + } + if (WARN_ON(flag == false)) { + status = -EFAULT; + goto func_end; + } + u_buf = kzalloc(sizeof(struct notify_drv_event_packet), GFP_ATOMIC); + + if (u_buf != NULL) { + INIT_LIST_HEAD((struct list_head *)&u_buf->element); + u_buf->proc_id = proc_id; + u_buf->data = data ; + u_buf->event_no = event_no ; + u_buf->func = cbFxn; + u_buf->param = param; + if (u_buf->event_no == (u32) -1) { + u_buf->is_exit = true; + is_exit = true; + } + if (mutex_lock_interruptible(notifydrv_state.gatehandle)) + return NOTIFY_E_OSFAILURE; + list_add_tail((struct list_head *)&(u_buf->element), + (struct list_head *) + &(notifydrv_state.event_state[i].buf_list)); + mutex_unlock(notifydrv_state.gatehandle); + up(notifydrv_state.event_state[i].semhandle); + /* Termination packet */ + if (is_exit == true) { + if (down_interruptible(notifydrv_state. + event_state[i].tersemhandle)) + status = NOTIFY_E_OSFAILURE; + } + } +func_end: + return status; +} + +/* + * Module setup function. + * + */ +static void notify_drv_setup(void) +{ + int i; + + INIT_LIST_HEAD((struct list_head *)&(notifydrv_state.evt_cbck_list)); + notifydrv_state.gatehandle = kmalloc(sizeof(struct mutex), + GFP_KERNEL); + mutex_init(notifydrv_state.gatehandle); + for (i = 0; i < MAX_PROCESSES ; i++) { + notifydrv_state.event_state[i].pid = -1; + notifydrv_state.event_state[i].ref_count = 0; + INIT_LIST_HEAD((struct list_head *) + &(notifydrv_state.event_state[i].buf_list)); + } + notifydrv_state.is_setup = true; +} + + +/* +* brief Module destroy function. +*/ +static void notify_drv_destroy(void) +{ + int i; + struct notify_drv_event_packet *packet; + struct list_head *entry; + struct notify_drv_event_cbck *cbck; + + for (i = 0; i < MAX_PROCESSES ; i++) { + list_for_each(entry, (struct list_head *) + &(notifydrv_state.event_state[i].buf_list)) { + packet = (struct notify_drv_event_packet *)entry; + if (packet != NULL) + kfree(packet); + } + INIT_LIST_HEAD(¬ifydrv_state.event_state[i].buf_list); + } + list_for_each(entry, + (struct list_head *)&(notifydrv_state.evt_cbck_list)) { + cbck = (struct notify_drv_event_cbck *)(entry); + if (cbck != NULL) + kfree(cbck) ; + } + INIT_LIST_HEAD(¬ifydrv_state.evt_cbck_list); + mutex_destroy(notifydrv_state.gatehandle); + kfree(notifydrv_state.gatehandle); + notifydrv_state.is_setup = false; + return; +} + + + + +/* + * brief Attach a process to notify user support framework. + */ +static int notify_drv_attach(u32 pid) +{ + s32 status = NOTIFY_SUCCESS; + bool flag = false; + bool is_init = false; + u32 i; + struct semaphore *sem_handle; + struct semaphore *ter_sem_handle; + int ret_val = 0; + + if (notifydrv_state.is_setup == false) { + status = NOTIFY_E_FAIL; + } else { + WARN_ON(mutex_lock_interruptible(notifydrv_state.gatehandle)); + + for (i = 0 ; (i < MAX_PROCESSES) ; i++) { + if (notifydrv_state.event_state[i].pid == pid) { + notifydrv_state.event_state[i].ref_count++; + is_init = true; + break; + } + } + mutex_unlock(notifydrv_state.gatehandle); + + if (is_init == true) + goto func_end; + + sem_handle = kmalloc(sizeof(struct semaphore), GFP_ATOMIC); + ter_sem_handle = kmalloc(sizeof(struct semaphore), GFP_ATOMIC); + + sema_init(sem_handle, 0); + /* Create the termination semaphore */ + sema_init(ter_sem_handle, 0); + + WARN_ON(mutex_lock_interruptible(notifydrv_state.gatehandle)); + /* Search for an available slot for user process. */ + for (i = 0 ; i < MAX_PROCESSES ; i++) { + if (notifydrv_state.event_state[i].pid == -1) { + notifydrv_state.event_state[i].semhandle = + sem_handle; + notifydrv_state.event_state[i].tersemhandle = + ter_sem_handle; + notifydrv_state.event_state[i].pid = pid; + notifydrv_state.event_state[i].ref_count + = 1; + INIT_LIST_HEAD(&(notifydrv_state.event_state[i]. + buf_list)); + flag = true; + break; + } + } + mutex_unlock(notifydrv_state.gatehandle); + + if (WARN_ON(flag != true)) { + /* Max users have registered. No more clients + * can be supported */ + status = NOTIFY_E_MAXCLIENTS; + } + + if (status == NOTIFY_SUCCESS) + ret_val = 0; + else { + kfree(ter_sem_handle); + kfree(sem_handle); + ret_val = -EINVAL; + } + + } +func_end: + return ret_val; +} + + +/* + * brief Detach a process from notify user support framework. + */ +static int notify_drv_detach(u32 pid) +{ + s32 status = NOTIFY_SUCCESS; + bool flag = false; + u32 i; + struct semaphore *sem_handle; + struct semaphore *ter_sem_handle; + + if (notifydrv_state.is_setup == false) { + status = NOTIFY_E_FAIL; + goto func_end; + } + + /* Send the termination packet to notify thread */ + status = notify_drv_add_buf_by_pid(0, pid, (u32)-1, (u32)0, + NULL, NULL); + + if (status < 0) + goto func_end; + + if (mutex_lock_interruptible(notifydrv_state.gatehandle)) { + status = NOTIFY_E_OSFAILURE; + goto func_end; + } + for (i = 0; i < MAX_PROCESSES; i++) { + if (notifydrv_state.event_state[i].pid == pid) { + if (notifydrv_state.event_state[i].ref_count == 1) { + /* Last client being unregistered for this + * process*/ + notifydrv_state.event_state[i].pid = -1; + notifydrv_state.event_state[i].ref_count = 0; + sem_handle = + notifydrv_state.event_state[i].semhandle; + ter_sem_handle = + notifydrv_state.event_state[i].tersemhandle; + INIT_LIST_HEAD((struct list_head *) + &(notifydrv_state.event_state[i].buf_list)); + notifydrv_state.event_state[i].semhandle = + NULL; + notifydrv_state.event_state[i].tersemhandle = + NULL; + flag = true; + break; + } else + notifydrv_state.event_state[i].ref_count--; + } + } + mutex_unlock(notifydrv_state.gatehandle); + + if ((flag == false) && (i == MAX_PROCESSES)) { + /*retval NOTIFY_E_NOTFOUND The specified user process was + * not found registered with Notify Driver module. */ + status = NOTIFY_E_NOTFOUND; + } else { + kfree(sem_handle); + kfree(ter_sem_handle); + } +func_end: + return status; + + /*! @retval NOTIFY_SUCCESS Operation successfully completed */ + return status; +} + + +/* Module initialization function for Notify driver.*/ +static int __init notify_drv_init_module(void) +{ + int result = 0 ; + dev_t dev; + + if (driver_major) { + dev = MKDEV(driver_major, driver_minor); + result = register_chrdev_region(dev, 1, driver_name); + } else { + result = alloc_chrdev_region(&dev, driver_minor, 1, + driver_name); + driver_major = MAJOR(dev); + } + + ipcnotify_device = kmalloc(sizeof(struct ipcnotify_dev), GFP_KERNEL); + if (!ipcnotify_device) { + result = -ENOMEM; + unregister_chrdev_region(dev, 1); + goto func_end; + } + memset(ipcnotify_device, 0, sizeof(struct ipcnotify_dev)); + cdev_init(&ipcnotify_device->cdev, &driver_ops); + ipcnotify_device->cdev.owner = THIS_MODULE; + ipcnotify_device->cdev.ops = &driver_ops; + + result = cdev_add(&ipcnotify_device->cdev, dev, 1); + + if (result) { + printk(KERN_ERR "Failed to add the syslink ipcnotify device \n"); + goto func_end; + } + + /* udev support */ + ipcnotify_class = class_create(THIS_MODULE, "syslink-ipcnotify"); + + if (IS_ERR(ipcnotify_class)) { + printk(KERN_ERR "Error creating ipcnotify class \n"); + goto func_end; + } + device_create(ipcnotify_class, NULL, MKDEV(driver_major, driver_minor), + NULL, IPCNOTIFY_NAME); + result = notify_drv_register_driver(); +func_end: + return result ; +} + +/* Module finalization function for Notify driver.*/ +static void __exit notify_drv_finalize_module(void) +{ + dev_t dev_no; + + notify_drv_unregister_driver(); + + dev_no = MKDEV(driver_major, driver_minor); + if (ipcnotify_device) { + cdev_del(&ipcnotify_device->cdev); + kfree(ipcnotify_device); + } + unregister_chrdev_region(dev_no, 1); + if (ipcnotify_class) { + /* remove the device from sysfs */ + device_destroy(ipcnotify_class, MKDEV(driver_major, + driver_minor)); + class_destroy(ipcnotify_class); + } + return; +} + + +/* + *name module_init/module_exit + * + *desc Macro calls that indicate initialization and finalization functions + *to the kernel. + * + */ +module_init(notify_drv_init_module) ; +module_exit(notify_drv_finalize_module) ; +MODULE_LICENSE("GPL"); + diff --git a/drivers/dsp/syslink/omap_notify/notify.c b/drivers/dsp/syslink/omap_notify/notify.c new file mode 100755 index 000000000000..389ee72d997b --- /dev/null +++ b/drivers/dsp/syslink/omap_notify/notify.c @@ -0,0 +1,548 @@ +/* + * notify.c + * + * Syslink driver support for OMAP Processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ +#include <linux/spinlock.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/fs.h> +#include <linux/mm.h> +#include <linux/uaccess.h> +#include <linux/io.h> +#include <asm/pgtable.h> + +#include <syslink/notify.h> +#include <syslink/notify_driver.h> +#include <syslink/GlobalTypes.h> +#include <syslink/gt.h> +#include <syslink/multiproc.h> +#include <syslink/atomic_linux.h> + +/* + * func _notify_is_support_proc + * + *desc Check if specified processor ID is supported by the Notify driver. + * + */ +static bool _notify_is_support_proc(struct notify_driver_object *drv_handle, + int proc_id); + +struct notify_module_object notify_state = { + .def_cfg.maxDrivers = 2, +}; +EXPORT_SYMBOL(notify_state); + + +/* + * Get the default configuration for the Notify module. + * + * This function can be called by the application to get their + * configuration parameter to Notify_setup filled in by the + * Notify module with the default parameters. If the user + * does not wish to make any change in the default parameters, this + * API is not required to be called. + * + * param-cfg :Pointer to the Notify module configuration + * structure in which the default config is to be returned. + */ +void notify_get_config(struct notify_config *cfg) +{ + BUG_ON(cfg == NULL); + + if (atomic_cmpmask_and_lt(&(notify_state.ref_count), + NOTIFY_MAKE_MAGICSTAMP(0), + NOTIFY_MAKE_MAGICSTAMP(1)) == true) + memcpy(cfg, ¬ify_state.def_cfg, + sizeof(struct notify_config)); + else + memcpy(cfg, ¬ify_state.cfg, sizeof(struct notify_config)); +} +EXPORT_SYMBOL(notify_get_config); + +/* + * Setup the Notify module. + * + * This function sets up the Notify module. This function + * must be called before any other instance-level APIs can be + * invoked. + * Module-level configuration needs to be provided to this + * function. If the user wishes to change some specific config + * parameters, then Notify_getConfig can be called to get the + * configuration filled with the default values. After this, only + * the required configuration values can be changed. If the user + * does not wish to make any change in the default parameters, the + * application can simply call Notify_setup with NULL + * parameters. The default parameters would get automatically used. + * + * param -cfg Optional Notify module configuration. If provided as + * NULL, default configuration is used. + */ +int notify_setup(struct notify_config *cfg) +{ + int status = NOTIFY_SUCCESS; + struct notify_config tmpCfg; + + atomic_cmpmask_and_set(¬ify_state.ref_count, + NOTIFY_MAKE_MAGICSTAMP(0), + NOTIFY_MAKE_MAGICSTAMP(0)); + + if (atomic_inc_return(¬ify_state.ref_count) + != NOTIFY_MAKE_MAGICSTAMP(1u)) { + status = NOTIFY_S_ALREADYSETUP; + } else { + if (cfg == NULL) { + notify_get_config(&tmpCfg); + cfg = &tmpCfg; + } + + notify_state.gate_handle = kmalloc(sizeof(struct mutex), + GFP_ATOMIC); + /*User has not provided any gate handle, + so create a default handle.*/ + mutex_init(notify_state.gate_handle); + + if (WARN_ON(cfg->maxDrivers > NOTIFY_MAX_DRIVERS)) { + status = NOTIFY_E_CONFIG; + kfree(notify_state.gate_handle); + atomic_set(¬ify_state.ref_count, + NOTIFY_MAKE_MAGICSTAMP(0)); + goto func_end; + } + memcpy(¬ify_state.cfg, cfg, sizeof(struct notify_config)); + memset(¬ify_state.drivers, 0, + (sizeof(struct notify_driver_object) * + NOTIFY_MAX_DRIVERS)); + + notify_state.disable_depth = 0; + + } +func_end: + return status; +} +EXPORT_SYMBOL(notify_setup); + +/* + * Destroy the Notify module. + * + * Once this function is called, other Notify module APIs, + * except for the Notify_getConfig API cannot be called + * anymore. + */ +int notify_destroy(void) +{ + int i; + int status = NOTIFY_SUCCESS; + + if (atomic_cmpmask_and_lt(&(notify_state.ref_count), + NOTIFY_MAKE_MAGICSTAMP(0), + NOTIFY_MAKE_MAGICSTAMP(1)) == true) { + status = NOTIFY_E_INVALIDSTATE; + } else { + if (atomic_dec_return(&(notify_state.ref_count)) == + NOTIFY_MAKE_MAGICSTAMP(0)) { + + /* Check if any Notify driver instances have + * not been deleted so far. If not, assert. + */ + for (i = 0; i < NOTIFY_MAX_DRIVERS; i++) + WARN_ON(notify_state.drivers[i].is_init + != false); + + if (notify_state.gate_handle != NULL) + kfree(notify_state.gate_handle); + + atomic_set(¬ify_state.ref_count, + NOTIFY_MAKE_MAGICSTAMP(0)); + } + } + return status; +} +EXPORT_SYMBOL(notify_destroy); + +/* + * func notify_register_event + * + * desc This function registers a callback for a specific event with the + * Notify module. + */ +int notify_register_event(void *notify_driver_handle, u16 proc_id, + u32 event_no, notify_callback_fxn notify_callback_fxn, void *cbck_arg) +{ + int status = NOTIFY_SUCCESS; + + struct notify_driver_object *drv_handle = + (struct notify_driver_object *)notify_driver_handle; + + BUG_ON(drv_handle == NULL); + + if (atomic_cmpmask_and_lt(&(notify_state.ref_count), + NOTIFY_MAKE_MAGICSTAMP(0), + NOTIFY_MAKE_MAGICSTAMP(1)) == true) { + status = NOTIFY_E_INVALIDSTATE; + goto func_end; + } + if (WARN_ON(drv_handle->is_init == false)) { + status = NOTIFY_E_INVALIDSTATE; + goto func_end; + } + if (WARN_ON(_notify_is_support_proc(drv_handle, proc_id) != true)) { + status = NOTIFY_E_INVALIDARG; + goto func_end; + } + if (WARN_ON(((event_no & NOTIFY_EVENT_MASK) + >= drv_handle->attrs.proc_info[proc_id].max_events))) { + status = NOTIFY_E_INVALIDEVENT; + goto func_end; + } + if (WARN_ON(((event_no & NOTIFY_EVENT_MASK) < + drv_handle->attrs.proc_info[proc_id].reserved_events) && + ((event_no & NOTIFY_SYSTEM_KEY_MASK) >> sizeof(u16)) != + NOTIFY_SYSTEM_KEY)) { + status = NOTIFY_E_RESERVEDEVENT; + goto func_end; + } + if (mutex_lock_interruptible(notify_state.gate_handle) != 0) + WARN_ON(1); + + status = drv_handle->fn_table.register_event(drv_handle, proc_id, + (event_no & NOTIFY_EVENT_MASK), notify_callback_fxn, + cbck_arg); + mutex_unlock(notify_state.gate_handle); + if (WARN_ON(status < 0)) + status = NOTIFY_E_FAIL; + else + status = NOTIFY_SUCCESS; +func_end: + return status; +} +EXPORT_SYMBOL(notify_register_event); + +/* + * func notify_unregister_event + * + * desc This function un-registers the callback for the specific event with + * the Notify module. + */ + +int notify_unregister_event(void *notify_driver_handle, u16 proc_id, + u32 event_no, notify_callback_fxn notify_callback_fxn, void *cbck_arg) +{ + int status = NOTIFY_SUCCESS; + struct notify_driver_object *drv_handle = + (struct notify_driver_object *)notify_driver_handle; + BUG_ON(drv_handle == NULL); + + if (atomic_cmpmask_and_lt(&(notify_state.ref_count), + NOTIFY_MAKE_MAGICSTAMP(0), + NOTIFY_MAKE_MAGICSTAMP(1)) == true) { + status = NOTIFY_E_INVALIDSTATE; + goto func_end; + } + if (WARN_ON(drv_handle->is_init == false)) { + status = NOTIFY_E_INVALIDSTATE; + goto func_end; + } + if (WARN_ON(_notify_is_support_proc(drv_handle, proc_id) != true)) { + status = NOTIFY_E_INVALIDARG; + goto func_end; + } + if (WARN_ON(((event_no & NOTIFY_EVENT_MASK) + >= drv_handle->attrs.proc_info[proc_id].max_events))) { + status = NOTIFY_E_INVALIDEVENT; + goto func_end; + } + if (WARN_ON(((event_no & NOTIFY_EVENT_MASK) < + drv_handle->attrs.proc_info[proc_id].reserved_events) && + ((event_no & NOTIFY_SYSTEM_KEY_MASK) >> sizeof(u16)) != + NOTIFY_SYSTEM_KEY)) { + status = NOTIFY_E_RESERVEDEVENT; + goto func_end; + } + if (mutex_lock_interruptible(notify_state.gate_handle) != 0) + WARN_ON(1); + status = drv_handle->fn_table.unregister_event(drv_handle, + proc_id, (event_no & NOTIFY_EVENT_MASK), + notify_callback_fxn, cbck_arg); + mutex_unlock(notify_state.gate_handle); + if (WARN_ON(status < 0)) + status = NOTIFY_E_FAIL; + else + status = NOTIFY_SUCCESS; + +func_end: + return status; +} +EXPORT_SYMBOL(notify_unregister_event); + +/* + * func notify_sendevent + * + * desc This function sends a notification to the specified event. + * + * + */ +int notify_sendevent(void *notify_driver_handle, u16 proc_id, + u32 event_no, u32 payload, bool wait_clear) +{ + int status = NOTIFY_SUCCESS; + struct notify_driver_object *drv_handle = + (struct notify_driver_object *)notify_driver_handle; + BUG_ON(drv_handle == NULL); + + if (atomic_cmpmask_and_lt(&(notify_state.ref_count), + NOTIFY_MAKE_MAGICSTAMP(0), + NOTIFY_MAKE_MAGICSTAMP(1)) == true) { + status = NOTIFY_E_INVALIDSTATE; + goto func_end; + } + if (WARN_ON(drv_handle->is_init == false)) { + status = NOTIFY_E_INVALIDSTATE; + goto func_end; + } + if (WARN_ON(_notify_is_support_proc(drv_handle, proc_id) != true)) { + status = NOTIFY_E_INVALIDARG; + goto func_end; + } + if (WARN_ON(((event_no & NOTIFY_EVENT_MASK) + >= drv_handle->attrs.proc_info[proc_id].max_events))) { + status = NOTIFY_E_INVALIDEVENT; + goto func_end; + } + if (WARN_ON(((event_no & NOTIFY_EVENT_MASK) < + drv_handle->attrs.proc_info[proc_id].reserved_events) && + ((event_no & NOTIFY_SYSTEM_KEY_MASK) >> sizeof(u16)) != + NOTIFY_SYSTEM_KEY)) { + status = NOTIFY_E_RESERVEDEVENT; + goto func_end; + } + if (mutex_lock_interruptible(notify_state.gate_handle) != 0) + WARN_ON(1); + status = drv_handle->fn_table.send_event + (drv_handle, proc_id, (event_no & NOTIFY_EVENT_MASK), + payload, wait_clear); + mutex_unlock(notify_state.gate_handle); + if (status < 0) + status = NOTIFY_E_FAIL; + else + status = NOTIFY_SUCCESS; +func_end: + return status; +} +EXPORT_SYMBOL(notify_sendevent); + +/* + * func notify_disable + * + * desc This function disables all events. This is equivalent to global + * interrupt disable, however restricted within interrupts handled by + * the Notify module. All callbacks registered for all events are + * disabled with this API. It is not possible to disable a specific + * callback. + * + */ +u32 notify_disable(u16 proc_id) +{ + struct notify_driver_object *drv_handle; + int i; + + if (atomic_cmpmask_and_lt(&(notify_state.ref_count), + NOTIFY_MAKE_MAGICSTAMP(0), + NOTIFY_MAKE_MAGICSTAMP(1)) == true) + WARN_ON(1); + + + if (mutex_lock_interruptible(notify_state.gate_handle) != 0) + WARN_ON(1); + + for (i = 0; i < notify_state.cfg.maxDrivers; i++) { + drv_handle = &(notify_state.drivers[i]); + WARN_ON(_notify_is_support_proc(drv_handle, proc_id) + == false); + if (drv_handle->is_init == + NOTIFY_DRIVERINITSTATUS_NOTDONE) { + if (drv_handle->fn_table.disable) { + drv_handle->disable_flag[notify_state. + disable_depth] = + (u32 *)drv_handle->fn_table. + disable(drv_handle, + proc_id); + } + } + } + notify_state.disable_depth++; + mutex_unlock(notify_state.gate_handle); + + return notify_state.disable_depth; +} +EXPORT_SYMBOL(notify_disable); + +/* + * notify_restore + * + * desc This function restores the Notify module to the state before the + * last notify_disable() was called. This is equivalent to global + * interrupt restore, however restricted within interrupts handled by + * the Notify module. All callbacks registered for all events as + * specified in the flags are enabled with this API. It is not possible + * to enable a specific callback. + * + * + */ +void notify_restore(u32 key, u16 proc_id) +{ + struct notify_driver_object *drv_handle; + int i; + + if (atomic_cmpmask_and_lt(&(notify_state.ref_count), + NOTIFY_MAKE_MAGICSTAMP(0), + NOTIFY_MAKE_MAGICSTAMP(1)) == true) + WARN_ON(1); + + if (mutex_lock_interruptible(notify_state.gate_handle) != 0) + WARN_ON(1); + notify_state.disable_depth--; + for (i = 0; i < notify_state.cfg.maxDrivers; i++) { + drv_handle = &(notify_state.drivers[i]); + if (drv_handle->fn_table.restore) + drv_handle->fn_table.restore(drv_handle, + key, proc_id); + } + mutex_unlock(notify_state.gate_handle); + return; +} +EXPORT_SYMBOL(notify_restore); + +/* + *func notify_disable_event + * + * desc This function disables a specific event. All callbacks registered + * for the specific event are disabled with this API. It is not + * possible to disable a specific callback. + * + */ + +void notify_disable_event(void *notify_driver_handle, u16 proc_id, u32 event_no) +{ + int status = 0; + struct notify_driver_object *drv_handle = + (struct notify_driver_object *)notify_driver_handle; + BUG_ON(drv_handle == NULL); + + if (atomic_cmpmask_and_lt(&(notify_state.ref_count), + NOTIFY_MAKE_MAGICSTAMP(0), + NOTIFY_MAKE_MAGICSTAMP(1)) == true) { + status = NOTIFY_E_INVALIDSTATE; + goto func_end; + } + + if (WARN_ON(drv_handle->is_init == false)) { + status = NOTIFY_E_INVALIDSTATE; + goto func_end; + } + if (WARN_ON(_notify_is_support_proc(drv_handle, proc_id) != true)) { + status = NOTIFY_E_INVALIDARG; + goto func_end; + } + if (WARN_ON(((event_no & NOTIFY_EVENT_MASK) + >= drv_handle->attrs.proc_info[proc_id].max_events))) { + status = NOTIFY_E_INVALIDEVENT; + goto func_end; + } + if (WARN_ON(((event_no & NOTIFY_EVENT_MASK) < + drv_handle->attrs.proc_info[proc_id].reserved_events) && + ((event_no & NOTIFY_SYSTEM_KEY_MASK) >> sizeof(u16)) != + NOTIFY_SYSTEM_KEY)) { + status = NOTIFY_E_RESERVEDEVENT; + goto func_end; + } + if (mutex_lock_interruptible(notify_state.gate_handle) != 0) + WARN_ON(1); + drv_handle->fn_table.disable_event(drv_handle, + proc_id, (event_no & NOTIFY_EVENT_MASK)); + mutex_unlock(notify_state.gate_handle); +func_end: + return; +} +EXPORT_SYMBOL(notify_disable_event); + +/* + * notify_enable_event + * + * This function enables a specific event. All callbacks registered for + * this specific event are enabled with this API. It is not possible to + * enable a specific callback. + * + */ +void notify_enable_event(void *notify_driver_handle, u16 proc_id, u32 event_no) +{ + + struct notify_driver_object *drv_handle = + (struct notify_driver_object *) notify_driver_handle; + + BUG_ON(drv_handle == NULL); + + if (atomic_cmpmask_and_lt(&(notify_state.ref_count), + NOTIFY_MAKE_MAGICSTAMP(0), + NOTIFY_MAKE_MAGICSTAMP(1)) == true) { + goto func_end; + } + + if (WARN_ON(drv_handle->is_init == false)) + goto func_end; + if (WARN_ON(_notify_is_support_proc(drv_handle, proc_id) != true)) + goto func_end; + if (WARN_ON(((event_no & NOTIFY_EVENT_MASK) + >= drv_handle->attrs.proc_info[proc_id].max_events))) + goto func_end; + if (WARN_ON(((event_no & NOTIFY_EVENT_MASK) < + drv_handle->attrs.proc_info[proc_id].reserved_events) && + ((event_no & NOTIFY_SYSTEM_KEY_MASK) >> sizeof(u16)) != + NOTIFY_SYSTEM_KEY)) + goto func_end; + + if (mutex_lock_interruptible(notify_state.gate_handle) != 0) + WARN_ON(1); + if (drv_handle->fn_table.enable_event) { + drv_handle->fn_table.enable_event(drv_handle, + proc_id, (event_no & NOTIFY_EVENT_MASK)); + } + mutex_unlock(notify_state.gate_handle); +func_end: + return; +} +EXPORT_SYMBOL(notify_enable_event); + +/* + *_notify_is_support_proc + * + * Check if specified processor ID is supported by the Notify driver. + * + */ +static bool _notify_is_support_proc(struct notify_driver_object *drv_handle, + int proc_id) +{ + bool found = false; + struct notify_driver_attrs *attrs; + int i; + + BUG_ON(drv_handle == NULL); + attrs = &(drv_handle->attrs); + for (i = 0; i < MULTIPROC_MAXPROCESSORS; i++) { + if (attrs->proc_info[i].proc_id == proc_id) { + found = true; + break; + } + } + return found; +} diff --git a/drivers/dsp/syslink/omap_notify/notify_driver.c b/drivers/dsp/syslink/omap_notify/notify_driver.c new file mode 100755 index 000000000000..c90c57335918 --- /dev/null +++ b/drivers/dsp/syslink/omap_notify/notify_driver.c @@ -0,0 +1,172 @@ +/* + * notify_driver.c + * + * Syslink driver support for OMAP Processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include <linux/spinlock.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/fs.h> +#include <linux/mm.h> +#include <linux/uaccess.h> + +#include <linux/io.h> +#include <asm/pgtable.h> +#include <syslink/gt.h> + +#include <syslink/notify.h> +#include <syslink/notify_driver.h> +#include <syslink/atomic_linux.h> + +/* + *func notify_register_driver + * + *desc This function registers a Notify driver with the Notify module. + */ + +int notify_register_driver(char *driver_name, + struct notify_interface *fn_table, + struct notify_driver_attrs *drv_attrs, + struct notify_driver_object **driver_handle) +{ + int status = NOTIFY_SUCCESS; + struct notify_driver_object *drv_handle = NULL; + int i; + + BUG_ON(driver_name == NULL); + BUG_ON(fn_table == NULL); + BUG_ON(drv_attrs == NULL); + BUG_ON(driver_handle == NULL); + + if (atomic_cmpmask_and_lt(&(notify_state.ref_count), + NOTIFY_MAKE_MAGICSTAMP(0), + NOTIFY_MAKE_MAGICSTAMP(1)) == true) { + status = NOTIFY_E_INVALIDSTATE; + goto func_end; + } + + /*Initialize to status that indicates that an empty slot was not + *found for the driver. + */ + if (mutex_lock_interruptible(notify_state.gate_handle) != 0) + WARN_ON(1); + status = NOTIFY_E_MAXDRIVERS; + for (i = 0; i < notify_state.cfg.maxDrivers; i++) { + drv_handle = &(notify_state.drivers[i]); + + if (drv_handle->is_init == NOTIFY_DRIVERINITSTATUS_DONE) { + if (strncmp(driver_name, drv_handle->name, + NOTIFY_MAX_NAMELEN) == 0) { + status = NOTIFY_E_ALREADYEXISTS; + goto return_existing_handle; + } + } + if (drv_handle->is_init == NOTIFY_DRIVERINITSTATUS_NOTDONE) { + /* Found an empty slot, so block it. */ + drv_handle->is_init = + NOTIFY_DRIVERINITSTATUS_INPROGRESS; + status = NOTIFY_SUCCESS; + break; + } + } + mutex_unlock(notify_state.gate_handle); + WARN_ON(status < 0); + /*Complete registration of the driver. */ + strncpy(drv_handle->name, + driver_name, NOTIFY_MAX_NAMELEN); + memcpy(&(drv_handle->attrs), drv_attrs, + sizeof(struct notify_driver_attrs)); + memcpy(&(drv_handle->fn_table), fn_table, + sizeof(struct notify_interface)); + drv_handle->driver_object = NULL; + +return_existing_handle: + /*is_setup is set when driverInit is called. */ + *driver_handle = drv_handle; + +func_end: + return status; +} +EXPORT_SYMBOL(notify_register_driver); + +/*======================================== + *func notify_unregister_driver + * + *desc This function un-registers a Notify driver with the Notify module. + */ +int notify_unregister_driver(struct notify_driver_object *drv_handle) +{ + int status = NOTIFY_SUCCESS; + + BUG_ON(drv_handle == NULL); + + + if (atomic_cmpmask_and_lt(&(notify_state.ref_count), + NOTIFY_MAKE_MAGICSTAMP(0), + NOTIFY_MAKE_MAGICSTAMP(1)) == true) { + status = NOTIFY_E_INVALIDSTATE; + } else { + /* Unregister the driver. */ + drv_handle->is_init = NOTIFY_DRIVERINITSTATUS_NOTDONE; + + } + return status; +} +EXPORT_SYMBOL(notify_unregister_driver); + + +/*================================== + * Function to find and return the driver handle maintained within + * the Notify module. + * + * driver_name Name of the driver to be searched. + * handle Return parameter: Handle to the driver. + * + */ +int notify_get_driver_handle(char *driver_name, + struct notify_driver_object **handle) +{ + int status = NOTIFY_E_NOTFOUND; + struct notify_driver_object *drv_handle; + int i; + + BUG_ON(handle == NULL); + + if (atomic_cmpmask_and_lt(&(notify_state.ref_count), + NOTIFY_MAKE_MAGICSTAMP(0), + NOTIFY_MAKE_MAGICSTAMP(1)) == true) { + status = NOTIFY_E_INVALIDSTATE; + } else if (WARN_ON(driver_name == NULL)) + status = NOTIFY_E_INVALIDARG; + else { + if (mutex_lock_interruptible(notify_state.gate_handle) != 0) + WARN_ON(1); + + for (i = 0; i < notify_state.cfg.maxDrivers; i++) { + drv_handle = &(notify_state.drivers[i]); + /* Check whether the driver handle slot is occupied. */ + if (drv_handle->is_init == true) { + if (strncmp(driver_name, drv_handle->name, + NOTIFY_MAX_NAMELEN) == 0) { + status = NOTIFY_SUCCESS; + *handle = drv_handle; + break; + } + } + } + mutex_unlock(notify_state.gate_handle); + } + return status; +} +EXPORT_SYMBOL(notify_get_driver_handle); diff --git a/drivers/dsp/syslink/procmgr/Kbuild b/drivers/dsp/syslink/procmgr/Kbuild new file mode 100755 index 000000000000..58f6d3155250 --- /dev/null +++ b/drivers/dsp/syslink/procmgr/Kbuild @@ -0,0 +1,10 @@ +libomap_syslink_proc = processor.o procmgr.o procmgr_drv.o + +obj-$(CONFIG_SYSLINK_PROC) += syslink_proc.o +syslink_proc-objs = $(libomap_syslink_proc) + +ccflags-y += -Wno-strict-prototypes + +#Header files +ccflags-y += -Iarch/arm/plat-omap/include/syslink + diff --git a/drivers/dsp/syslink/procmgr/proc4430/Kbuild b/drivers/dsp/syslink/procmgr/proc4430/Kbuild new file mode 100755 index 000000000000..f82f2e23f79a --- /dev/null +++ b/drivers/dsp/syslink/procmgr/proc4430/Kbuild @@ -0,0 +1,10 @@ +libomap_proc4430 = proc4430.o proc4430_drv.o dmm4430.o \ + ducatienabler.o hw_mmu.o + +obj-$(CONFIG_SYSLINK_PROC) += syslink_proc4430.o +syslink_proc4430-objs = $(libomap_proc4430) + +ccflags-y += -Wno-strict-prototypes -DUSE_LEVEL_1_MACROS + +#Header files +ccflags-y += -Iarch/arm/plat-omap/include/syslink diff --git a/drivers/dsp/syslink/procmgr/proc4430/dmm4430.c b/drivers/dsp/syslink/procmgr/proc4430/dmm4430.c new file mode 100755 index 000000000000..d2ed9ece2245 --- /dev/null +++ b/drivers/dsp/syslink/procmgr/proc4430/dmm4430.c @@ -0,0 +1,355 @@ +/* + * dmm4430.c + * + * Syslink support functions for TI OMAP processors. + * + * Copyright (C) 2009-2010 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* + * ======== dmm.c ======== + * Purpose: + *The Dynamic Memory Manager (DMM) module manages the DSP Virtual address + *space that can be directly mapped to any MPU buffer or memory region + * + * Public Functions: + *dmm_create_tables + *dmm_create + *dmm_destroy + *dmm_exit + *dmm_init + *dmm_map_memory + *DMM_Reset + *dmm_reserve_memory + *dmm_unmap_memory + *dmm_unreserve_memory + * + * Private Functions: + *add_region + *create_region + *get_region + * get_free_region + * get_mapped_region + * + * Notes: + *Region: Generic memory entitiy having a start address and a size + *Chunk: Reserved region + * + *! + */ + +#include <linux/types.h> +#include <linux/mm.h> +#include <linux/mutex.h> +#include <linux/vmalloc.h> +#include <asm/page.h> +#include "dmm4430.h" + + +#define DMM_ADDR_VIRTUAL(x, a) \ + do { \ + x = (((struct map_page *)(a) - p_virt_mapping_tbl) * PAGE_SIZE \ + + dyn_mem_map_begin);\ + } while (0) + +#define DMM_ADDR_TO_INDEX(i, a) \ + do { \ + i = (((a) - dyn_mem_map_begin) / PAGE_SIZE); \ + } while (0) + +struct map_page { + u32 region_size:31; + u32 b_reserved:1; +}; + +/* Create the free list */ +static struct map_page *p_virt_mapping_tbl; +static u32 i_freeregion; /* The index of free region */ +static u32 i_freesize; +static u32 table_size;/* The size of virtual and physical pages tables */ +static u32 dyn_mem_map_begin; +struct mutex *dmm_lock; + +static struct map_page *get_free_region(u32 size); +static struct map_page *get_mapped_region(u32 addr); + +/* ======== dmm_create_tables ======== + * Purpose: + *Create table to hold information of the virtual memory that is reserved + *for DSP. + */ +int dmm_create_tables(u32 addr, u32 size) +{ + int status = 0; + + dmm_delete_tables(); + if (WARN_ON(mutex_lock_interruptible(dmm_lock)) < 0) { + status = -EFAULT; + goto func_exit; + } + dyn_mem_map_begin = addr; + table_size = (size/PAGE_SIZE) + 1; + /* Create the free list */ + p_virt_mapping_tbl = (struct map_page *)vmalloc( + table_size*sizeof(struct map_page)); + if (WARN_ON(p_virt_mapping_tbl == NULL)) + status = -ENOMEM; + /* On successful allocation, + * all entries are zero ('free') */ + i_freeregion = 0; + i_freesize = table_size*PAGE_SIZE; + p_virt_mapping_tbl[0].region_size = table_size; + mutex_unlock(dmm_lock); + +func_exit: + return status; +} + +/* + * ======== dmm_create ======== + * Purpose: + *Create a dynamic memory manager object. + */ +int dmm_create(void) +{ + int status = 0; + dmm_lock = kmalloc(sizeof(struct mutex), GFP_KERNEL); + if (WARN_ON(dmm_lock == NULL)) { + status = -EFAULT; + goto func_exit; + } + mutex_init(dmm_lock); +func_exit: + return status; +} + +/* + * ======== dmm_destroy ======== + * Purpose: + *Release the communication memory manager resources. + */ +void dmm_destroy(void) +{ + dmm_delete_tables(); + kfree(dmm_lock); +} + + +/* + * ======== dmm_delete_tables ======== + * Purpose: + *Delete DMM Tables. + */ +void dmm_delete_tables(void) +{ + /* Delete all DMM tables */ + WARN_ON(mutex_lock_interruptible(dmm_lock)); + if (p_virt_mapping_tbl != NULL) { + vfree(p_virt_mapping_tbl); + p_virt_mapping_tbl = NULL; + } + mutex_unlock(dmm_lock); +} + +/* + * ======== dmm_init ======== + * Purpose: + *Initializes private state of DMM module. + */ +void dmm_init(void) +{ + p_virt_mapping_tbl = NULL ; + table_size = 0; + return; +} + +/* + * ======== dmm_reserve_memory ======== + * Purpose: + *Reserve a chunk of virtually contiguous DSP/IVA address space. + */ +int dmm_reserve_memory(u32 size, u32 *p_rsv_addr) +{ + int status = 0; + struct map_page *node; + u32 rsv_addr = 0; + u32 rsv_size = 0; + + if (WARN_ON(mutex_lock_interruptible(dmm_lock)) < 0) { + status = -EFAULT; + goto func_exit; + } + + /* Try to get a DSP chunk from the free list */ + node = get_free_region(size); + if (node != NULL) { + /* DSP chunk of given size is available. */ + DMM_ADDR_VIRTUAL(rsv_addr, node); + /* Calculate the number entries to use */ + rsv_size = size/PAGE_SIZE; + if (rsv_size < node->region_size) { + /* Mark remainder of free region */ + node[rsv_size].b_reserved = false; + node[rsv_size].region_size = + node->region_size - rsv_size; + } + /* get_region will return first fit chunk. But we only use what + is requested. */ + node->b_reserved = true; + node->region_size = rsv_size; + /* Return the chunk's starting address */ + *p_rsv_addr = rsv_addr; + } else + /*dSP chunk of given size is not available */ + status = -ENOMEM; + + mutex_unlock(dmm_lock); +func_exit: + return status; +} + + +/* + * ======== dmm_unreserve_memory ======== + * Purpose: + *Free a chunk of reserved DSP/IVA address space. + */ +int dmm_unreserve_memory(u32 rsv_addr, u32 *psize) +{ + struct map_page *chunk; + int status = 0; + + WARN_ON(mutex_lock_interruptible(dmm_lock)); + + /* Find the chunk containing the reserved address */ + chunk = get_mapped_region(rsv_addr); + if (chunk == NULL) + status = -ENXIO; + WARN_ON(status < 0); + if (status == 0) { + chunk->b_reserved = false; + *psize = chunk->region_size * PAGE_SIZE; + /* NOTE: We do NOT coalesce free regions here. + * Free regions are coalesced in get_region(), as it traverses + *the whole mapping table + */ + } + mutex_unlock(dmm_lock); + return status; +} + +/* + * ======== get_free_region ======== + * Purpose: + * Returns the requested free region + */ +static struct map_page *get_free_region(u32 size) +{ + struct map_page *curr_region = NULL; + u32 i = 0; + u32 region_size = 0; + u32 next_i = 0; + + if (p_virt_mapping_tbl == NULL) + return curr_region; + if (size > i_freesize) { + /* Find the largest free region + * (coalesce during the traversal) */ + while (i < table_size) { + region_size = p_virt_mapping_tbl[i].region_size; + next_i = i+region_size; + if (p_virt_mapping_tbl[i].b_reserved == false) { + /* Coalesce, if possible */ + if (next_i < table_size && + p_virt_mapping_tbl[next_i].b_reserved + == false) { + p_virt_mapping_tbl[i].region_size += + p_virt_mapping_tbl[next_i].region_size; + continue; + } + region_size *= PAGE_SIZE; + if (region_size > i_freesize) { + i_freeregion = i; + i_freesize = region_size; + } + } + i = next_i; + } + } + if (size <= i_freesize) { + curr_region = p_virt_mapping_tbl + i_freeregion; + i_freeregion += (size / PAGE_SIZE); + i_freesize -= size; + } + return curr_region; +} + +/* + * ======== get_mapped_region ======== + * Purpose: + * Returns the requestedmapped region + */ +static struct map_page *get_mapped_region(u32 addr) +{ + u32 i = 0; + struct map_page *curr_region = NULL; + + if (p_virt_mapping_tbl == NULL) + return curr_region; + + DMM_ADDR_TO_INDEX(i, addr); + if (i < table_size && (p_virt_mapping_tbl[i].b_reserved)) + curr_region = p_virt_mapping_tbl + i; + return curr_region; +} + +#ifdef DSP_DMM_DEBUG +int dmm_mem_map_dump(void) +{ + struct map_page *curNode = NULL; + u32 i; + u32 freemem = 0; + u32 bigsize = 0; + + WARN_ON(mutex_lock_interruptible(dmm_lock)); + + if (p_virt_mapping_tbl != NULL) { + for (i = 0; i < table_size; i += + p_virt_mapping_tbl[i].region_size) { + curNode = p_virt_mapping_tbl + i; + if (curNode->b_reserved == true) { + /*printk("RESERVED size = 0x%x, " + "Map size = 0x%x\n", + (curNode->region_size * PAGE_SIZE), + (curNode->b_mapped == false) ? 0 : + (curNode->mapped_size * PAGE_SIZE)); +*/ + } else { +/* printk("UNRESERVED size = 0x%x\n", + (curNode->region_size * PAGE_SIZE)); +*/ + freemem += (curNode->region_size * PAGE_SIZE); + if (curNode->region_size > bigsize) + bigsize = curNode->region_size; + } + } + } + printk(KERN_INFO "Total DSP VA FREE memory = %d Mbytes\n", + freemem/(1024*1024)); + printk(KERN_INFO "Total DSP VA USED memory= %d Mbytes \n", + (((table_size * PAGE_SIZE)-freemem))/(1024*1024)); + printk(KERN_INFO "DSP VA - Biggest FREE block = %d Mbytes \n\n", + (bigsize*PAGE_SIZE/(1024*1024))); + mutex_unlock(dmm_lock); + + return 0; +} +#endif diff --git a/drivers/dsp/syslink/procmgr/proc4430/dmm4430.h b/drivers/dsp/syslink/procmgr/proc4430/dmm4430.h new file mode 100755 index 000000000000..7d879f4fe123 --- /dev/null +++ b/drivers/dsp/syslink/procmgr/proc4430/dmm4430.h @@ -0,0 +1,50 @@ +/* + * dmm.h + * + * DSP-BIOS Bridge driver support functions for TI OMAP processors. + * + * Copyright (C) 2005-2006 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + + +/* + * ======== dmm.h ======== + * Purpose: + *The Dynamic Memory Mapping(DMM) module manages the DSP Virtual address + *space that can be directly mapped to any MPU buffer or memory region + * + * Public Functions: + * + */ + +#ifndef DMM_4430_ +#define DMM_4430_ + +#include <linux/types.h> + +int dmm_reserve_memory(u32 size, u32 *p_rsv_addr); + +int dmm_unreserve_memory(u32 rsv_addr, u32 *psize); + +void dmm_destroy(void); + +void dmm_delete_tables(void); + +int dmm_create(void); + +void dmm_init(void); + +int dmm_create_tables(u32 addr, u32 size); + +#ifdef DSP_DMM_DEBUG +int dmm_mem_map_dump(void); +#endif +#endif/* DMM_4430_ */ diff --git a/drivers/dsp/syslink/procmgr/proc4430/ducatienabler.c b/drivers/dsp/syslink/procmgr/proc4430/ducatienabler.c new file mode 100644 index 000000000000..581888639cdf --- /dev/null +++ b/drivers/dsp/syslink/procmgr/proc4430/ducatienabler.c @@ -0,0 +1,869 @@ +/* + * ducatienabler.c + * + * Syslink driver support for TI OMAP processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + + + +#include <linux/types.h> +#include <linux/mm.h> +#include <linux/gfp.h> +#include <linux/io.h> +#include <linux/module.h> +#include <asm/page.h> +#include <linux/kernel.h> +#include <linux/pagemap.h> + + +#include <generated/autoconf.h> +#include <asm/system.h> +#include <asm/atomic.h> +#include <linux/semaphore.h> +#include <linux/uaccess.h> +#include <asm/irq.h> +#include <linux/io.h> +#include <linux/syscalls.h> +#include <linux/version.h> +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/stddef.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/spinlock.h> +#include <linux/sched.h> +#include <linux/fs.h> +#include <linux/file.h> +#include <linux/slab.h> +#include <linux/delay.h> +#include <linux/ctype.h> +#include <linux/mm.h> +#include <linux/device.h> +#include <linux/vmalloc.h> +#include <linux/ioport.h> +#include <linux/platform_device.h> +#include <linux/clk.h> +#include <linux/pagemap.h> +#include <asm/cacheflush.h> +#include <linux/dma-mapping.h> + +#include <linux/interrupt.h> +#include <plat/irqs.h> + +#include <syslink/ducatienabler.h> +#include <syslink/MMUAccInt.h> + +#include <plat/iommu.h> +#include "../../../arch/arm/plat-omap/iopgtable.h" + + +#ifdef DEBUG_DUCATI_IPC +#define DPRINTK(fmt, args...) printk(KERN_INFO "%s: " fmt, __func__, ## args) +#else +#define DPRINTK(fmt, args...) +#endif + + +#define base_ducati_l2_mmuPhys 0x55082000 + +/* + * Macro to define the physical memory address for the + * Ducati Base image. The 74Mb memory is preallocated + * during the make menuconfig. + * + */ +/* #define DUCATI_BASEIMAGE_PHYSICAL_ADDRESS 0x87200000 */ +#define DUCATI_BASEIMAGE_PHYSICAL_ADDRESS 0x9CF00000 + + +/* Attributes of L2 page tables for DSP MMU.*/ +struct page_info { + /* Number of valid PTEs in the L2 PT*/ + u32 num_entries; +}; + +enum pagetype { + SECTION = 0, + LARGE_PAGE = 1, + SMALL_PAGE = 2, + SUPER_SECTION = 3 +}; + + +static u32 shm_phys_addr; +static u32 shm_virt_addr; + +struct iommu *ducati_iommu_ptr; + +static void bad_page_dump(u32 pa, struct page *pg) +{ + pr_emerg("DSPBRIDGE: MAP function: COUNT 0 FOR PA 0x%x\n", pa); + pr_emerg("Bad page state in process '%s'\n", current->comm); + BUG(); +} + +/*============================================ + * This function calculates PTE address (MPU virtual) to be updated + * It also manages the L2 page tables + */ +static int pte_set(u32 pa, u32 va, u32 size, struct hw_mmu_map_attrs_t *attrs) +{ + struct iotlb_entry tlb_entry; + switch (size) { + case HW_PAGE_SIZE_16MB: + tlb_entry.pgsz = MMU_CAM_PGSZ_16M; + break; + case HW_PAGE_SIZE_1MB: + tlb_entry.pgsz = MMU_CAM_PGSZ_1M; + break; + case HW_PAGE_SIZE_64KB: + tlb_entry.pgsz = MMU_CAM_PGSZ_64K; + break; + case HW_PAGE_SIZE_4KB: + tlb_entry.pgsz = MMU_CAM_PGSZ_4K; + break; + } + tlb_entry.prsvd = MMU_CAM_P; + tlb_entry.valid = MMU_CAM_V; + switch (attrs->element_size) { + case HW_ELEM_SIZE_8BIT: + tlb_entry.elsz = MMU_RAM_ELSZ_8; + break; + case HW_ELEM_SIZE_16BIT: + tlb_entry.elsz = MMU_RAM_ELSZ_16; + break; + case HW_ELEM_SIZE_32BIT: + tlb_entry.elsz = MMU_RAM_ELSZ_32; + break; + case HW_ELEM_SIZE_64BIT: + tlb_entry.elsz = 0x3; /* No translation */ + break; + } + switch (attrs->endianism) { + case HW_LITTLE_ENDIAN: + tlb_entry.endian = MMU_RAM_ENDIAN_LITTLE; + break; + case HW_BIG_ENDIAN: + tlb_entry.endian = MMU_RAM_ENDIAN_BIG; + break; + } + switch (attrs->mixedSize) { + case HW_MMU_TLBES: + tlb_entry.mixed = 0; + break; + case HW_MMU_CPUES: + tlb_entry.mixed = MMU_RAM_MIXED; + break; + } + tlb_entry.da = va; + tlb_entry.pa = pa; + DPRINTK("pte set ducati_iommu_ptr = 0x%x, tlb_entry = 0x%x \n", + ducati_iommu_ptr, tlb_entry); + if (iopgtable_store_entry(ducati_iommu_ptr, &tlb_entry)) + goto error_exit; + return 0; +error_exit: + printk(KERN_ERR "pte set failure \n"); + return -EFAULT; +} + + +/*============================================= + * This function calculates the optimum page-aligned addresses and sizes + * Caller must pass page-aligned values + */ +static int pte_update(u32 pa, u32 va, u32 size, + struct hw_mmu_map_attrs_t *map_attrs) +{ + u32 i; + u32 all_bits; + u32 pa_curr = pa; + u32 va_curr = va; + u32 num_bytes = size; + int status = 0; + u32 pg_size[] = {HW_PAGE_SIZE_16MB, HW_PAGE_SIZE_1MB, + HW_PAGE_SIZE_64KB, HW_PAGE_SIZE_4KB}; + DPRINTK("> pte_update pa %x, va %x, " + "size %x, map_attrs %x\n", pa, va, size, (u32)map_attrs); + while (num_bytes && (status == 0)) { + /* To find the max. page size with which both PA & VA are + * aligned */ + all_bits = pa_curr | va_curr; + DPRINTK("all_bits %x, pa_curr %x, va_curr %x, " + "num_bytes %x\n ", + all_bits, pa_curr, va_curr, num_bytes); + + for (i = 0; i < 4; i++) { + if ((num_bytes >= pg_size[i]) && ((all_bits & + (pg_size[i] - 1)) == 0)) { + DPRINTK("pg_size %x\n", pg_size[i]); + status = pte_set(pa_curr, + va_curr, pg_size[i], map_attrs); + pa_curr += pg_size[i]; + va_curr += pg_size[i]; + num_bytes -= pg_size[i]; + /* Don't try smaller sizes. Hopefully we have + * reached an address aligned to a bigger page + * size */ + break; + } + } + } + DPRINTK("< pte_update status %x num_bytes %x\n", status, num_bytes); + return status; +} + +/* + * ======== ducati_mem_unmap ======== + * Invalidate the PTEs for the DSP VA block to be unmapped. + * + * PTEs of a mapped memory block are contiguous in any page table + * So, instead of looking up the PTE address for every 4K block, + * we clear consecutive PTEs until we unmap all the bytes + */ +int ducati_mem_unmap(u32 da, u32 num_bytes) +{ + u32 bytes; + struct page *pg = NULL; + int temp = 0; + u32 nent; + u32 phyaddress; + s32 numofBytes = num_bytes; + + while (num_bytes > 0) { + u32 *iopgd = iopgd_offset(ducati_iommu_ptr, da); + if (*iopgd & IOPGD_TABLE) { + u32 *iopte = iopte_offset(iopgd, da); + if (*iopte & IOPTE_LARGE) { + nent = 16; + /* rewind to the 1st entry */ + iopte = (u32 *)((u32)iopte & IOLARGE_MASK); + } else + nent = 1; + phyaddress = (*iopte) & IOPAGE_MASK; + } else { + if ((*iopgd & IOPGD_SUPER) == IOPGD_SUPER) { + nent = 4096; + /* rewind to the 1st entry */ + iopgd = (u32 *)((u32)iopgd & IOSUPER_MASK); + } else + nent = 256; + phyaddress = (*iopgd) & IOPGD_MASK; + } + for (temp = 0; temp < nent; temp++) { + if (pfn_valid(__phys_to_pfn(phyaddress))) { + pg = phys_to_page(phyaddress); + if (page_count(pg) < 1) { + pr_info("DSPBRIDGE:UNMAP function: " + "COUNT 0 FOR PA 0x%x," + " size = 0x%x\n", + phyaddress, numofBytes); + bad_page_dump(phyaddress, pg); + } + SetPageDirty(pg); + page_cache_release(pg); + } + phyaddress += HW_PAGE_SIZE_4KB; + } + bytes = iopgtable_clear_entry(ducati_iommu_ptr, da); + num_bytes -= bytes; + da += bytes; + } + return 0; +} + + +/* + * ======== ducati_mem_virtToPhys ======== + * This funciton provides the translation from + * Remote virtual address to Physical address + */ + +inline u32 ducati_mem_virtToPhys(u32 da) +{ +#if 0 + /* FIXME: temp work around till L2MMU issue + * is resolved + */ + u32 *iopgd = iopgd_offset(ducati_iommu_ptr, da); + u32 phyaddress; + + if (*iopgd & IOPGD_TABLE) { + u32 *iopte = iopte_offset(iopgd, da); + if (*iopte & IOPTE_LARGE) { + phyaddress = *iopte & IOLARGE_MASK; + phyaddress |= (da & (IOLARGE_SIZE - 1)); + } else + phyaddress = (*iopte) & IOPAGE_MASK; + } else { + if ((*iopgd & IOPGD_SUPER) == IOPGD_SUPER) { + phyaddress = *iopgd & IOSUPER_MASK; + phyaddress |= (da & (IOSUPER_SIZE - 1)); + } else { + phyaddress = (*iopgd) & IOPGD_MASK; + phyaddress |= (da & (IOPGD_SIZE - 1)); + } + } +#endif + return da; +} + + +/* + * ======== user_va2pa ======== + * Purpose: + * This function walks through the Linux page tables to convert a userland + * virtual address to physical address + */ +u32 user_va2pa(struct mm_struct *mm, u32 address) +{ + pgd_t *pgd; + pmd_t *pmd; + pte_t *ptep, pte; + + pgd = pgd_offset(mm, address); + if (!(pgd_none(*pgd) || pgd_bad(*pgd))) { + pmd = pmd_offset(pgd, address); + if (!(pmd_none(*pmd) || pmd_bad(*pmd))) { + ptep = pte_offset_map(pmd, address); + if (ptep) { + pte = *ptep; + if (pte_present(pte)) + return pte & PAGE_MASK; + } + } + } + + return 0; +} + +/*============================================ + * This function maps MPU buffer to the DSP address space. It performs +* linear to physical address translation if required. It translates each +* page since linear addresses can be physically non-contiguous +* All address & size arguments are assumed to be page aligned (in proc.c) + * + */ +int ducati_mem_map(u32 mpu_addr, u32 ul_virt_addr, + u32 num_bytes, u32 map_attr) +{ + u32 attrs; + int status = 0; + struct hw_mmu_map_attrs_t hw_attrs; + struct vm_area_struct *vma; + struct mm_struct *mm = current->mm; + struct task_struct *curr_task = current; + u32 write = 0; + u32 da = ul_virt_addr; + u32 pa = 0; + int pg_i = 0; + int pg_num = 0; + struct page *mappedPage, *pg; + int num_usr_pages = 0; + + DPRINTK("> WMD_BRD_MemMap pa %x, va %x, " + "size %x, map_attr %x\n", mpu_addr, ul_virt_addr, + num_bytes, map_attr); + if (num_bytes == 0) + return -EINVAL; + if (map_attr != 0) { + attrs = map_attr; + } else { + /* Assign default attributes */ + attrs = DSP_MAPVIRTUALADDR | DSP_MAPELEMSIZE32; + } + /* Take mapping properties */ + if (attrs & DSP_MAPBIGENDIAN) + hw_attrs.endianism = HW_BIG_ENDIAN; + else + hw_attrs.endianism = HW_LITTLE_ENDIAN; + + hw_attrs.mixedSize = (enum hw_mmu_mixed_size_t) + ((attrs & DSP_MAPMIXEDELEMSIZE) >> 2); + /* Ignore element_size if mixedSize is enabled */ + if (hw_attrs.mixedSize == 0) { + if (attrs & DSP_MAPELEMSIZE8) { + /* Size is 8 bit */ + hw_attrs.element_size = HW_ELEM_SIZE_8BIT; + } else if (attrs & DSP_MAPELEMSIZE16) { + /* Size is 16 bit */ + hw_attrs.element_size = HW_ELEM_SIZE_16BIT; + } else if (attrs & DSP_MAPELEMSIZE32) { + /* Size is 32 bit */ + hw_attrs.element_size = HW_ELEM_SIZE_32BIT; + } else if (attrs & DSP_MAPELEMSIZE64) { + /* Size is 64 bit */ + hw_attrs.element_size = HW_ELEM_SIZE_64BIT; + } else { + /* Mixedsize isn't enabled, so size can't be + * zero here */ + DPRINTK("WMD_BRD_MemMap: MMU element size is zero\n"); + return -EINVAL; + } + } + /* + * Do OS-specific user-va to pa translation. + * Combine physically contiguous regions to reduce TLBs. + * Pass the translated pa to PteUpdate. + */ + if ((attrs & DSP_MAPPHYSICALADDR)) { + status = pte_update(mpu_addr, ul_virt_addr, num_bytes, + &hw_attrs); + goto func_cont; + } + /* + * Important Note: mpu_addr is mapped from user application process + * to current process - it must lie completely within the current + * virtual memory address space in order to be of use to us here! + */ + down_read(&mm->mmap_sem); + vma = find_vma(mm, mpu_addr); + /* + * It is observed that under some circumstances, the user buffer is + * spread across several VMAs. So loop through and check if the entire + * user buffer is covered + */ + while ((vma) && (mpu_addr + num_bytes > vma->vm_end)) { + /* jump to the next VMA region */ + vma = find_vma(mm, vma->vm_end + 1); + } + if (!vma) { + status = -EINVAL; + up_read(&mm->mmap_sem); + goto func_cont; + } + if (vma->vm_flags & VM_IO) { + num_usr_pages = num_bytes / PAGE_SIZE; + /* Get the physical addresses for user buffer */ + for (pg_i = 0; pg_i < num_usr_pages; pg_i++) { + pa = user_va2pa(mm, mpu_addr); + if (!pa) { + status = -EFAULT; + pr_err("DSPBRIDGE: VM_IO mapping physical" + "address is invalid\n"); + break; + } + if (pfn_valid(__phys_to_pfn(pa))) { + pg = phys_to_page(pa); + get_page(pg); + if (page_count(pg) < 1) { + pr_err("Bad page in VM_IO buffer\n"); + bad_page_dump(pa, pg); + } + } + status = pte_set(pa, da, HW_PAGE_SIZE_4KB, &hw_attrs); + if (WARN_ON(status < 0)) + break; + mpu_addr += HW_PAGE_SIZE_4KB; + da += HW_PAGE_SIZE_4KB; + } + } else { + num_usr_pages = num_bytes / PAGE_SIZE; + if (vma->vm_flags & (VM_WRITE | VM_MAYWRITE)) + write = 1; + + for (pg_i = 0; pg_i < num_usr_pages; pg_i++) { + pg_num = get_user_pages(curr_task, mm, mpu_addr, 1, + write, 1, &mappedPage, NULL); + if (pg_num > 0) { + if (page_count(mappedPage) < 1) { + pr_err("Bad page count after doing" + "get_user_pages on" + "user buffer\n"); + bad_page_dump(page_to_phys(mappedPage), + mappedPage); + } + status = pte_set(page_to_phys(mappedPage), da, + HW_PAGE_SIZE_4KB, &hw_attrs); + if (WARN_ON(status < 0)) + break; + da += HW_PAGE_SIZE_4KB; + mpu_addr += HW_PAGE_SIZE_4KB; + } else { + pr_err("DSPBRIDGE: get_user_pages FAILED," + "MPU addr = 0x%x," + "vma->vm_flags = 0x%lx," + "get_user_pages Err" + "Value = %d, Buffer" + "size=0x%x\n", mpu_addr, + vma->vm_flags, pg_num, + num_bytes); + status = -EFAULT; + break; + } + } + } + up_read(&mm->mmap_sem); +func_cont: + /* Don't propogate Linux or HW status to upper layers */ + if (status < 0) { + /* + * Roll out the mapped pages incase it failed in middle of + * mapping + */ + if (pg_i) + ducati_mem_unmap(ul_virt_addr, (pg_i * PAGE_SIZE)); + } + WARN_ON(status < 0); + DPRINTK("< WMD_BRD_MemMap status %x\n", status); + return status; + +} + + /*========================================= + * Decides a TLB entry size + * + */ +static int get_mmu_entry_size(u32 pa, u32 size, enum pagetype *size_tlb, + u32 *entry_size) +{ + int status = 0; + bool page_align_4kb = false; + bool page_align_64kb = false; + bool page_align_1mb = false; + bool page_align_16mb = false; + u32 phys_addr = pa; + + /* First check the page alignment*/ + if ((phys_addr % PAGE_SIZE_4KB) == 0) + page_align_4kb = true; + if ((phys_addr % PAGE_SIZE_64KB) == 0) + page_align_64kb = true; + if ((phys_addr % PAGE_SIZE_1MB) == 0) + page_align_1mb = true; + if ((phys_addr % PAGE_SIZE_16MB) == 0) + page_align_16mb = true; + + if ((!page_align_64kb) && (!page_align_1mb) && (!page_align_4kb)) { + status = -EINVAL; + goto error_exit; + } + /* Now decide the entry size */ + if (size >= PAGE_SIZE_16MB) { + if (page_align_16mb) { + *size_tlb = SUPER_SECTION; + *entry_size = PAGE_SIZE_16MB; + } else if (page_align_1mb) { + *size_tlb = SECTION; + *entry_size = PAGE_SIZE_1MB; + } else if (page_align_64kb) { + *size_tlb = LARGE_PAGE; + *entry_size = PAGE_SIZE_64KB; + } else if (page_align_4kb) { + *size_tlb = SMALL_PAGE; + *entry_size = PAGE_SIZE_4KB; + } else { + status = -EINVAL; + goto error_exit; + } + } else if (size >= PAGE_SIZE_1MB && size < PAGE_SIZE_16MB) { + if (page_align_1mb) { + *size_tlb = SECTION; + *entry_size = PAGE_SIZE_1MB; + } else if (page_align_64kb) { + *size_tlb = LARGE_PAGE; + *entry_size = PAGE_SIZE_64KB; + } else if (page_align_4kb) { + *size_tlb = SMALL_PAGE; + *entry_size = PAGE_SIZE_4KB; + } else { + status = -EINVAL; + goto error_exit; + } + } else if (size > PAGE_SIZE_4KB && + size < PAGE_SIZE_1MB) { + if (page_align_64kb) { + *size_tlb = LARGE_PAGE; + *entry_size = PAGE_SIZE_64KB; + } else if (page_align_4kb) { + *size_tlb = SMALL_PAGE; + *entry_size = PAGE_SIZE_4KB; + } else { + status = -EINVAL; + goto error_exit; + } + } else if (size == PAGE_SIZE_4KB) { + if (page_align_4kb) { + *size_tlb = SMALL_PAGE; + *entry_size = PAGE_SIZE_4KB; + } else { + status = -EINVAL; + goto error_exit; + } + } else { + status = -EINVAL; + goto error_exit; + } + + DPRINTK("< GetMMUEntrySize status %x\n", status); + return 0; +error_exit: + DPRINTK("< GetMMUEntrySize FAILED !!!!!!\n"); + return status; +} + +/*========================================= + * Add DSP MMU entries corresponding to given MPU-Physical address + * and DSP-virtual address + */ +static int add_dsp_mmu_entry(u32 *phys_addr, u32 *dsp_addr, + u32 size) +{ + u32 mapped_size = 0; + enum pagetype size_tlb = SECTION; + u32 entry_size = 0; + int status = 0; + struct iotlb_entry tlb_entry; + int retval = 0; + + + DPRINTK("Entered add_dsp_mmu_entry phys_addr = " + "0x%x, dsp_addr = 0x%x,size = 0x%x\n", + *phys_addr, *dsp_addr, size); + + while ((mapped_size < size) && (status == 0)) { + status = get_mmu_entry_size(*phys_addr, + (size - mapped_size), &size_tlb, &entry_size); + if (status < 0) + goto error_exit; + + if (size_tlb == SUPER_SECTION) + tlb_entry.pgsz = MMU_CAM_PGSZ_16M; + + else if (size_tlb == SECTION) + tlb_entry.pgsz = MMU_CAM_PGSZ_1M; + + else if (size_tlb == LARGE_PAGE) + tlb_entry.pgsz = MMU_CAM_PGSZ_64K; + + else if (size_tlb == SMALL_PAGE) + tlb_entry.pgsz = MMU_CAM_PGSZ_4K; + + tlb_entry.elsz = MMU_RAM_ELSZ_16; + tlb_entry.endian = MMU_RAM_ENDIAN_LITTLE; + tlb_entry.mixed = MMU_RAM_MIXED; + tlb_entry.prsvd = MMU_CAM_P; + tlb_entry.valid = MMU_CAM_V; + + tlb_entry.da = *dsp_addr; + tlb_entry.pa = *phys_addr; + DPRINTK("pte set ducati_iommu_ptr = 0x%x, tlb_entry = 0x%x \n", + ducati_iommu_ptr, tlb_entry); + retval = load_iotlb_entry(ducati_iommu_ptr, &tlb_entry); + if (retval < 0) + goto error_exit; + mapped_size += entry_size; + *phys_addr += entry_size; + *dsp_addr += entry_size; + } + + return 0; +error_exit: + printk(KERN_ERR "pte set failure retval = 0x%x, status = 0x%x \n", + retval, status); + return retval; +} + + +/*============================================= + * Add DSP MMU entries corresponding to given MPU-Physical address + * and DSP-virtual address + * + */ +#if 0 +static int add_entry_ext(u32 *phys_addr, u32 *dsp_addr, + u32 size) +{ + u32 mapped_size = 0; + enum pagetype size_tlb = SECTION; + u32 entry_size = 0; + int status = 0; + u32 page_size = HW_PAGE_SIZE_1MB; + u32 flags = 0; + + flags = (DSP_MAPELEMSIZE32 | DSP_MAPLITTLEENDIAN | + DSP_MAPPHYSICALADDR); + while ((mapped_size < size) && (status == 0)) { + + /* get_mmu_entry_size fills the size_tlb and entry_size + based on alignment and size of memory to map + to DSP - size */ + status = get_mmu_entry_size(*phys_addr, + (size - mapped_size), + &size_tlb, + &entry_size); + + if (size_tlb == SUPER_SECTION) + page_size = HW_PAGE_SIZE_16MB; + else if (size_tlb == SECTION) + page_size = HW_PAGE_SIZE_1MB; + else if (size_tlb == LARGE_PAGE) + page_size = HW_PAGE_SIZE_64KB; + else if (size_tlb == SMALL_PAGE) + page_size = HW_PAGE_SIZE_4KB; + + if (status == 0) { + + ducati_mem_map(*phys_addr, + *dsp_addr, page_size, flags); + mapped_size += entry_size; + *phys_addr += entry_size; + *dsp_addr += entry_size; + } + } + return status; +} +#endif + +void ducati_tlb_dump(void) +{ +#if defined CONFIG_OMAP_IOMMU_DEBUG_MODULE + char *p; + + p = kmalloc(1000, GFP_KERNEL); + dump_tlb_entries(ducati_iommu_ptr, p, 1000); + printk(KERN_INFO "%8s %8s %2s\n", "cam:", "ram:", "preserved"); + printk(KERN_INFO "-----------------------------------------\n"); + printk(KERN_INFO "%s", p); + kfree(p); +#endif + return; +} + +/*================================ + * Initialize the Ducati MMU. + */ +int ducati_mmu_init(u32 a_phy_addr) +{ + int ret_val = 0; + u32 phys_addr = 0; + u32 num_l4_entries; + u32 i = 0; + u32 num_l3_mem_entries = 0; + u32 virt_addr = 0; + + num_l4_entries = (sizeof(l4_map) / sizeof(struct mmu_entry)); + num_l3_mem_entries = sizeof(l3_memory_regions) / + sizeof(struct memory_entry); + + DPRINTK("\n Programming Ducati MMU using linear address \n"); + + phys_addr = a_phy_addr; + + printk(KERN_ALERT " Programming Ducati memory regions\n"); + printk(KERN_ALERT "=========================================\n"); + for (i = 0; i < num_l3_mem_entries; i++) { + + printk(KERN_ALERT "VA = [0x%x] of size [0x%x] at PA = [0x%x]\n", + l3_memory_regions[i].ul_virt_addr, + l3_memory_regions[i].ul_size, phys_addr); + + /* OMAP4430 SDC code */ + /* Adjust below logic if using cacheable shared memory */ + if (l3_memory_regions[i].ul_virt_addr == \ + DUCATI_MEM_IPC_HEAP0_ADDR) { + shm_phys_addr = phys_addr; + } + virt_addr = l3_memory_regions[i].ul_virt_addr; + ret_val = add_dsp_mmu_entry(&phys_addr, &virt_addr, + (l3_memory_regions[i].ul_size)); + + if (WARN_ON(ret_val < 0)) + goto error_exit; + } + + printk(KERN_ALERT " Programming Ducati L4 peripherals\n"); + printk(KERN_ALERT "=========================================\n"); + for (i = 0; i < num_l4_entries; i++) { + printk(KERN_INFO "PA [0x%x] VA [0x%x] size [0x%x]\n", + l4_map[i].ul_phy_addr, l4_map[i].ul_virt_addr, + l4_map[i].ul_size); + virt_addr = l4_map[i].ul_virt_addr; + phys_addr = l4_map[i].ul_phy_addr; + ret_val = add_dsp_mmu_entry(&phys_addr, + &virt_addr, (l4_map[i].ul_size)); + if (WARN_ON(ret_val < 0)) { + + DPRINTK("**** Failed to map Peripheral ****"); + DPRINTK("Phys addr [0x%x] Virt addr [0x%x] size [0x%x]", + l4_map[i].ul_phy_addr, l4_map[i].ul_virt_addr, + l4_map[i].ul_size); + DPRINTK(" Status [0x%x]", ret_val); + goto error_exit; + } + } + ducati_tlb_dump(); + return 0; +error_exit: + return ret_val; +} + + +/*======================================== + * This sets up the Ducati processor + * + */ +int ducati_setup(void) +{ + int ret_val = 0; + + ducati_iommu_ptr = iommu_get("ducati"); + if (IS_ERR(ducati_iommu_ptr)) { + pr_err("Error iommu_get\n"); + return -EFAULT; + } + ret_val = ducati_mmu_init(DUCATI_BASEIMAGE_PHYSICAL_ADDRESS); + if (WARN_ON(ret_val < 0)) + goto error_exit; + return 0; +error_exit: + WARN_ON(1); + printk(KERN_ERR "DUCATI SETUP FAILED !!!!!\n"); + return ret_val; +} +EXPORT_SYMBOL(ducati_setup); + +/*============================================ + * De-Initialize the Ducati MMU and free the + * memory allocation for L1 and L2 pages + * + */ +void ducati_destroy(void) +{ + iommu_put(ducati_iommu_ptr); + return; +} +EXPORT_SYMBOL(ducati_destroy); + +/*============================================ + * Returns the ducati virtual address for IPC shared memory + * + */ +u32 get_ducati_virt_mem(void) +{ + /*shm_virt_addr = (u32)ioremap(shm_phys_addr, DUCATI_SHARED_IPC_LEN);*/ + shm_virt_addr = (u32)ioremap(shm_phys_addr, DUCATI_MEM_IPC_SHMEM_LEN); + return shm_virt_addr; +} +EXPORT_SYMBOL(get_ducati_virt_mem); + +/*============================================ + * Unmaps the ducati virtual address for IPC shared memory + * + */ +void unmap_ducati_virt_mem(u32 shm_virt_addr) +{ + iounmap((unsigned int *) shm_virt_addr); + return; +} +EXPORT_SYMBOL(unmap_ducati_virt_mem); diff --git a/drivers/dsp/syslink/procmgr/proc4430/hw_mmu.c b/drivers/dsp/syslink/procmgr/proc4430/hw_mmu.c new file mode 100755 index 000000000000..ba0547456ab3 --- /dev/null +++ b/drivers/dsp/syslink/procmgr/proc4430/hw_mmu.c @@ -0,0 +1,661 @@ +/* + * hw_mbox.c + * + * Syslink driver support for OMAP Processors. + * + * Copyright (C) 2008-2009 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#include<linux/kernel.h> +#include<linux/module.h> + +#include <syslink/GlobalTypes.h> +#include <syslink/MMURegAcM.h> +#include <syslink/hw_defs.h> +#include <syslink/hw_mmu.h> + +#define MMU_BASE_VAL_MASK 0xFC00 +#define MMU_PAGE_MAX 3 +#define MMU_ELEMENTSIZE_MAX 3 +#define MMU_ADDR_MASK 0xFFFFF000 +#define MMU_TTB_MASK 0xFFFFC000 +#define MMU_SECTION_ADDR_MASK 0xFFF00000 +#define MMU_SSECTION_ADDR_MASK 0xFF000000 +#define MMU_PAGE_TABLE_MASK 0xFFFFFC00 +#define MMU_LARGE_PAGE_MASK 0xFFFF0000 +#define MMU_SMALL_PAGE_MASK 0xFFFFF000 + +#define MMU_LOAD_TLB 0x00000001 +#define NUM_TLB_ENTRIES 32 + + + +/* +* type: hw_mmu_pgsiz_t +* +* desc: Enumerated Type used to specify the MMU Page Size(SLSS) +* +* +*/ +enum hw_mmu_pgsiz_t { + HW_MMU_SECTION, + HW_MMU_LARGE_PAGE, + HW_MMU_SMALL_PAGE, + HW_MMU_SUPERSECTION + +}; + +/* +* function : mmu_flsh_entry +*/ + +static hw_status mmu_flsh_entry(const u32 base_address); + + /* +* function : mme_set_cam_entry +* +*/ + +static hw_status mme_set_cam_entry(const u32 base_address, + const u32 page_size, + const u32 preserve_bit, + const u32 valid_bit, + const u32 virt_addr_tag); + +/* +* function : mmu_set_ram_entry +*/ +static hw_status mmu_set_ram_entry(const u32 base_address, + const u32 physical_addr, + enum hw_endianism_t endianism, + enum hw_elemnt_siz_t element_size, + enum hw_mmu_mixed_size_t mixedSize); + +/* +* hw functions +* +*/ + +hw_status hw_mmu_enable(const u32 base_address) +{ + hw_status status = RET_OK; + + MMUMMU_CNTLMMUEnableWrite32(base_address, HW_SET); + + return status; +} +EXPORT_SYMBOL(hw_mmu_enable); + +hw_status hw_mmu_disable(const u32 base_address) +{ + hw_status status = RET_OK; + + MMUMMU_CNTLMMUEnableWrite32(base_address, HW_CLEAR); + + return status; +} +EXPORT_SYMBOL(hw_mmu_disable); + +hw_status hw_mmu_autoidle_en(const u32 base_address) +{ + hw_status status; + + status = mmu_sisconf_auto_idle_set32(base_address, HW_SET); + status = RET_OK; + return status; +} +EXPORT_SYMBOL(hw_mmu_autoidle_en); + +hw_status hw_mmu_nulck_set(const u32 base_address, u32 *num_lcked_entries) +{ + hw_status status = RET_OK; + + *num_lcked_entries = MMUMMU_LOCKBaseValueRead32(base_address); + + return status; +} +EXPORT_SYMBOL(hw_mmu_nulck_set); + + +hw_status hw_mmu_numlocked_set(const u32 base_address, u32 num_lcked_entries) +{ + hw_status status = RET_OK; + + MMUMMU_LOCKBaseValueWrite32(base_address, num_lcked_entries); + + return status; +} +EXPORT_SYMBOL(hw_mmu_numlocked_set); + + +hw_status hw_mmu_vctm_numget(const u32 base_address, u32 *vctm_entry_num) +{ + hw_status status = RET_OK; + + *vctm_entry_num = MMUMMU_LOCKCurrentVictimRead32(base_address); + + return status; +} +EXPORT_SYMBOL(hw_mmu_vctm_numget); + + +hw_status hw_mmu_victim_numset(const u32 base_address, u32 vctm_entry_num) +{ + hw_status status = RET_OK; + + mmu_lck_crnt_vctmwite32(base_address, vctm_entry_num); + + return status; +} +EXPORT_SYMBOL(hw_mmu_victim_numset); + +hw_status hw_mmu_tlb_flushAll(const u32 base_address) +{ + hw_status status = RET_OK; + + MMUMMU_GFLUSHGlobalFlushWrite32(base_address, HW_SET); + + return status; +} +EXPORT_SYMBOL(hw_mmu_tlb_flushAll); + +hw_status hw_mmu_eventack(const u32 base_address, u32 irq_mask) +{ + hw_status status = RET_OK; + + MMUMMU_IRQSTATUSWriteRegister32(base_address, irq_mask); + + return status; +} +EXPORT_SYMBOL(hw_mmu_eventack); + +hw_status hw_mmu_event_disable(const u32 base_address, u32 irq_mask) +{ + hw_status status = RET_OK; + u32 irqReg; + irqReg = MMUMMU_IRQENABLEReadRegister32(base_address); + + MMUMMU_IRQENABLEWriteRegister32(base_address, irqReg & ~irq_mask); + + return status; +} +EXPORT_SYMBOL(hw_mmu_event_disable); + +hw_status hw_mmu_event_enable(const u32 base_address, u32 irq_mask) +{ + hw_status status = RET_OK; + u32 irqReg; + + irqReg = MMUMMU_IRQENABLEReadRegister32(base_address); + + MMUMMU_IRQENABLEWriteRegister32(base_address, irqReg | irq_mask); + + return status; +} +EXPORT_SYMBOL(hw_mmu_event_enable); + +hw_status hw_mmu_event_status(const u32 base_address, u32 *irq_mask) +{ + hw_status status = RET_OK; + + *irq_mask = MMUMMU_IRQSTATUSReadRegister32(base_address); + + return status; +} +EXPORT_SYMBOL(hw_mmu_event_status); + +hw_status hw_mmu_flt_adr_rd(const u32 base_address, u32 *addr) +{ + hw_status status = RET_OK; + + /*Check the input Parameters*/ + CHECK_INPUT_PARAM(base_address, 0, RET_BAD_NULL_PARAM, + RES_MMU_BASE + RES_INVALID_INPUT_PARAM); + /* read values from register */ + *addr = MMUMMU_FAULT_ADReadRegister32(base_address); + + return status; +} +EXPORT_SYMBOL(hw_mmu_flt_adr_rd); + + +hw_status hw_mmu_ttbset(const u32 base_address, u32 ttb_phys_addr) +{ + hw_status status = RET_OK; + u32 loadTTB; + + /*Check the input Parameters*/ + CHECK_INPUT_PARAM(base_address, 0, RET_BAD_NULL_PARAM, + RES_MMU_BASE + RES_INVALID_INPUT_PARAM); + + loadTTB = ttb_phys_addr & ~0x7FUL; + /* write values to register */ + MMUMMU_TTBWriteRegister32(base_address, loadTTB); + + return status; +} +EXPORT_SYMBOL(hw_mmu_ttbset); + +hw_status hw_mmu_twl_enable(const u32 base_address) +{ + hw_status status = RET_OK; + + MMUMMU_CNTLTWLEnableWrite32(base_address, HW_SET); + + return status; +} +EXPORT_SYMBOL(hw_mmu_twl_enable); + +hw_status hw_mmu_twl_disable(const u32 base_address) +{ + hw_status status = RET_OK; + + MMUMMU_CNTLTWLEnableWrite32(base_address, HW_CLEAR); + + return status; +} +EXPORT_SYMBOL(hw_mmu_twl_disable); + + +hw_status hw_mmu_tlb_flush(const u32 base_address, + u32 virtual_addr, + u32 page_size) +{ + hw_status status = RET_OK; + u32 virt_addr_tag; + enum hw_mmu_pgsiz_t pg_sizeBits; + + switch (page_size) { + case HW_PAGE_SIZE_4KB: + pg_sizeBits = HW_MMU_SMALL_PAGE; + break; + + case HW_PAGE_SIZE_64KB: + pg_sizeBits = HW_MMU_LARGE_PAGE; + break; + + case HW_PAGE_SIZE_1MB: + pg_sizeBits = HW_MMU_SECTION; + break; + + case HW_PAGE_SIZE_16MB: + pg_sizeBits = HW_MMU_SUPERSECTION; + break; + + default: + return RET_FAIL; + } + + /* Generate the 20-bit tag from virtual address */ + virt_addr_tag = ((virtual_addr & MMU_ADDR_MASK) >> 12); + + mme_set_cam_entry(base_address, pg_sizeBits, 0, 0, virt_addr_tag); + + mmu_flsh_entry(base_address); + + return status; +} +EXPORT_SYMBOL(hw_mmu_tlb_flush); + + +hw_status hw_mmu_tlb_add(const u32 base_address, + u32 physical_addr, + u32 virtual_addr, + u32 page_size, + u32 entryNum, + struct hw_mmu_map_attrs_t *map_attrs, + enum hw_set_clear_t preserve_bit, + enum hw_set_clear_t valid_bit) +{ + hw_status status = RET_OK; + u32 lockReg; + u32 virt_addr_tag; + enum hw_mmu_pgsiz_t mmu_pg_size; + + /*Check the input Parameters*/ + CHECK_INPUT_PARAM(base_address, 0, RET_BAD_NULL_PARAM, + RES_MMU_BASE + RES_INVALID_INPUT_PARAM); + CHECK_INPUT_RANGE_MIN0(page_size, MMU_PAGE_MAX, RET_PARAM_OUT_OF_RANGE, + RES_MMU_BASE + RES_INVALID_INPUT_PARAM); + CHECK_INPUT_RANGE_MIN0(map_attrs->element_size, + MMU_ELEMENTSIZE_MAX, RET_PARAM_OUT_OF_RANGE, + RES_MMU_BASE + RES_INVALID_INPUT_PARAM); + + switch (page_size) { + case HW_PAGE_SIZE_4KB: + mmu_pg_size = HW_MMU_SMALL_PAGE; + break; + + case HW_PAGE_SIZE_64KB: + mmu_pg_size = HW_MMU_LARGE_PAGE; + break; + + case HW_PAGE_SIZE_1MB: + mmu_pg_size = HW_MMU_SECTION; + break; + + case HW_PAGE_SIZE_16MB: + mmu_pg_size = HW_MMU_SUPERSECTION; + break; + + default: + return RET_FAIL; + } + + lockReg = mmu_lckread_reg_32(base_address); + + /* Generate the 20-bit tag from virtual address */ + virt_addr_tag = ((virtual_addr & MMU_ADDR_MASK) >> 12); + + /* Write the fields in the CAM Entry Register */ + mme_set_cam_entry(base_address, mmu_pg_size, preserve_bit, valid_bit, + virt_addr_tag); + + /* Write the different fields of the RAM Entry Register */ + /* endianism of the page,Element Size of the page (8, 16, 32, 64 bit) */ + mmu_set_ram_entry(base_address, physical_addr, + map_attrs->endianism, map_attrs->element_size, map_attrs->mixedSize); + + /* Update the MMU Lock Register */ + /* currentVictim between lockedBaseValue and (MMU_Entries_Number - 1) */ + mmu_lck_crnt_vctmwite32(base_address, entryNum); + + /* Enable loading of an entry in TLB by writing 1 into LD_TLB_REG + register */ + mmu_ld_tlbwrt_reg32(base_address, MMU_LOAD_TLB); + + + mmu_lck_write_reg32(base_address, lockReg); + + return status; +} +EXPORT_SYMBOL(hw_mmu_tlb_add); + + + +hw_status hw_mmu_pte_set(const u32 pg_tbl_va, + u32 physical_addr, + u32 virtual_addr, + u32 page_size, + struct hw_mmu_map_attrs_t *map_attrs) +{ + hw_status status = RET_OK; + u32 pte_addr, pte_val; + long int num_entries = 1; + + switch (page_size) { + + case HW_PAGE_SIZE_4KB: + pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va, virtual_addr & + MMU_SMALL_PAGE_MASK); + pte_val = ((physical_addr & MMU_SMALL_PAGE_MASK) | + (map_attrs->endianism << 9) | + (map_attrs->element_size << 4) | + (map_attrs->mixedSize << 11) | 2 + ); + break; + + case HW_PAGE_SIZE_64KB: + num_entries = 16; + pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va, virtual_addr & + MMU_LARGE_PAGE_MASK); + pte_val = ((physical_addr & MMU_LARGE_PAGE_MASK) | + (map_attrs->endianism << 9) | + (map_attrs->element_size << 4) | + (map_attrs->mixedSize << 11) | 1 + ); + break; + + case HW_PAGE_SIZE_1MB: + pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va, virtual_addr & + MMU_SECTION_ADDR_MASK); + pte_val = ((((physical_addr & MMU_SECTION_ADDR_MASK) | + (map_attrs->endianism << 15) | + (map_attrs->element_size << 10) | + (map_attrs->mixedSize << 17)) & + ~0x40000) | 0x2 + ); + break; + + case HW_PAGE_SIZE_16MB: + num_entries = 16; + pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va, virtual_addr & + MMU_SSECTION_ADDR_MASK); + pte_val = (((physical_addr & MMU_SSECTION_ADDR_MASK) | + (map_attrs->endianism << 15) | + (map_attrs->element_size << 10) | + (map_attrs->mixedSize << 17) + ) | 0x40000 | 0x2 + ); + break; + + case HW_MMU_COARSE_PAGE_SIZE: + pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va, virtual_addr & + MMU_SECTION_ADDR_MASK); + pte_val = (physical_addr & MMU_PAGE_TABLE_MASK) | 1; + break; + + default: + return RET_FAIL; + } + + while (--num_entries >= 0) + ((u32 *)pte_addr)[num_entries] = pte_val; + + + return status; +} +EXPORT_SYMBOL(hw_mmu_pte_set); + +hw_status hw_mmu_pte_clear(const u32 pg_tbl_va, + u32 virtual_addr, + u32 pg_size) +{ + hw_status status = RET_OK; + u32 pte_addr; + long int num_entries = 1; + + switch (pg_size) { + case HW_PAGE_SIZE_4KB: + pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va, + virtual_addr & MMU_SMALL_PAGE_MASK); + break; + + case HW_PAGE_SIZE_64KB: + num_entries = 16; + pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va, + virtual_addr & MMU_LARGE_PAGE_MASK); + break; + + case HW_PAGE_SIZE_1MB: + case HW_MMU_COARSE_PAGE_SIZE: + pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va, + virtual_addr & MMU_SECTION_ADDR_MASK); + break; + + case HW_PAGE_SIZE_16MB: + num_entries = 16; + pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va, + virtual_addr & MMU_SSECTION_ADDR_MASK); + break; + + default: + return RET_FAIL; + } + + while (--num_entries >= 0) + ((u32 *)pte_addr)[num_entries] = 0; + + return status; +} +EXPORT_SYMBOL(hw_mmu_pte_clear); + +/* +* function: mmu_flsh_entry +*/ +static hw_status mmu_flsh_entry(const u32 base_address) +{ + hw_status status = RET_OK; + u32 flushEntryData = 0x1; + + /*Check the input Parameters*/ + CHECK_INPUT_PARAM(base_address, 0, RET_BAD_NULL_PARAM, + RES_MMU_BASE + RES_INVALID_INPUT_PARAM); + + /* write values to register */ + MMUMMU_FLUSH_ENTRYWriteRegister32(base_address, flushEntryData); + + return status; +} +EXPORT_SYMBOL(mmu_flsh_entry); +/* +* function : mme_set_cam_entry +*/ +static hw_status mme_set_cam_entry(const u32 base_address, + const u32 page_size, + const u32 preserve_bit, + const u32 valid_bit, + const u32 virt_addr_tag) +{ + hw_status status = RET_OK; + u32 mmuCamReg; + + /*Check the input Parameters*/ + CHECK_INPUT_PARAM(base_address, 0, RET_BAD_NULL_PARAM, + RES_MMU_BASE + RES_INVALID_INPUT_PARAM); + + mmuCamReg = (virt_addr_tag << 12); + mmuCamReg = (mmuCamReg) | (page_size) | (valid_bit << 2) + | (preserve_bit << 3); + + /* write values to register */ + MMUMMU_CAMWriteRegister32(base_address, mmuCamReg); + + return status; +} +EXPORT_SYMBOL(mme_set_cam_entry); +/* +* function: mmu_set_ram_entry +*/ +static hw_status mmu_set_ram_entry(const u32 base_address, + const u32 physical_addr, + enum hw_endianism_t endianism, + enum hw_elemnt_siz_t element_size, + enum hw_mmu_mixed_size_t mixedSize) +{ + hw_status status = RET_OK; + u32 mmuRamReg; + + /*Check the input Parameters*/ + CHECK_INPUT_PARAM(base_address, 0, RET_BAD_NULL_PARAM, + RES_MMU_BASE + RES_INVALID_INPUT_PARAM); + CHECK_INPUT_RANGE_MIN0(element_size, MMU_ELEMENTSIZE_MAX, + RET_PARAM_OUT_OF_RANGE, + RES_MMU_BASE + RES_INVALID_INPUT_PARAM); + + + mmuRamReg = (physical_addr & MMU_ADDR_MASK); + mmuRamReg = (mmuRamReg) | ((endianism << 9) | (element_size << 7) + | (mixedSize << 6)); + + /* write values to register */ + MMUMMU_RAMWriteRegister32(base_address, mmuRamReg); + + return status; + +} +EXPORT_SYMBOL(mmu_set_ram_entry); + +u32 hw_mmu_fault_dump(const u32 base_address) +{ + u32 reg; + + reg = MMUMMU_FAULT_ADReadRegister32(base_address); + printk(KERN_INFO "Fault Address Address = 0x%x\n", reg); + reg = MMUMMU_FAULT_PCReadRegister32(base_address); + printk(KERN_INFO "Fault PC Register Address = 0x%x\n", reg); + reg = MMUMMU_FAULT_STATUSReadRegister32(base_address); + printk(KERN_INFO "Fault PC address doesn't show right value in DUCATI" + "because of HW limitation\n"); + printk(KERN_INFO "Fault Status Register = 0x%x\n", reg); + reg = MMUMMU_FAULT_EMUAddressReadRegister32(base_address); + printk(KERN_INFO "Fault EMU Address = 0x%x\n", reg); + return 0; +} +EXPORT_SYMBOL(hw_mmu_fault_dump); + +long hw_mmu_tlb_dump(const u32 base_address, bool shw_inv_entries) +{ + u32 i; + u32 lockSave; + u32 cam; + u32 ram; + + + /* Save off the lock register contents, + we'll restore it when we are done */ + + lockSave = mmu_lckread_reg_32(base_address); + + printk(KERN_INFO "TLB locked entries = %u, current victim = %u\n", + ((lockSave & MMU_MMU_LOCK_BaseValue_MASK) + >> MMU_MMU_LOCK_BaseValue_OFFSET), + ((lockSave & MMU_MMU_LOCK_CurrentVictim_MASK) + >> MMU_MMU_LOCK_CurrentVictim_OFFSET)); + printk(KERN_INFO "=============================================\n"); + for (i = 0; i < NUM_TLB_ENTRIES; i++) { + mmu_lck_crnt_vctmwite32(base_address, i); + cam = MMUMMU_CAMReadRegister32(base_address); + ram = MMUMMU_RAMReadRegister32(base_address); + + if ((cam & 0x4) != 0) { + printk(KERN_INFO "TLB Entry [0x%2x]: VA = 0x%8x " + "PA = 0x%8x Protected = 0x%1x\n", + i, (cam & MMU_ADDR_MASK), (ram & MMU_ADDR_MASK), + (cam & 0x8) ? 1 : 0); + + } else if (shw_inv_entries != false) + printk(KERN_ALERT "TLB Entry [0x%x]: <INVALID>\n", i); + } + mmu_lck_write_reg32(base_address, lockSave); + return RET_OK; +} +EXPORT_SYMBOL(hw_mmu_tlb_dump); + +u32 hw_mmu_pte_phyaddr(u32 pte_val, u32 pte_size) +{ + u32 ret_val = 0; + + switch (pte_size) { + + case HW_PAGE_SIZE_4KB: + ret_val = pte_val & MMU_SMALL_PAGE_MASK; + break; + case HW_PAGE_SIZE_64KB: + ret_val = pte_val & MMU_LARGE_PAGE_MASK; + break; + + case HW_PAGE_SIZE_1MB: + ret_val = pte_val & MMU_SECTION_ADDR_MASK; + break; + case HW_PAGE_SIZE_16MB: + ret_val = pte_val & MMU_SSECTION_ADDR_MASK; + break; + default: + /* Invalid */ + break; + + } + + return ret_val; +} +EXPORT_SYMBOL(hw_mmu_pte_phyaddr); diff --git a/drivers/dsp/syslink/procmgr/proc4430/proc4430.c b/drivers/dsp/syslink/procmgr/proc4430/proc4430.c new file mode 100644 index 000000000000..528a7aaf44a7 --- /dev/null +++ b/drivers/dsp/syslink/procmgr/proc4430/proc4430.c @@ -0,0 +1,1053 @@ +/* + * proc4430.c + * + * Syslink driver support functions for TI OMAP processors. + * + * Copyright (C) 2009-2010 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include <linux/types.h> +#include <linux/mm.h> +#include <linux/sched.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/vmalloc.h> +#include <linux/uaccess.h> +#include <linux/io.h> +#include <linux/delay.h> + +/* Module level headers */ +#include "../procdefs.h" +#include "../processor.h" +#include <procmgr.h> +#include "../procmgr_drvdefs.h" +#include "proc4430.h" +#include "dmm4430.h" +#include <syslink/multiproc.h> +#include <syslink/ducatienabler.h> +#include <syslink/platform_mem.h> +#include <syslink/atomic_linux.h> + +#define DUCATI_DMM_START_ADDR 0xa0000000 +#define DUCATI_DMM_POOL_SIZE 0x6000000 + +#define SYS_M3 2 +#define APP_M3 3 +#define CORE_PRM_BASE OMAP2_L4_IO_ADDRESS(0x4a306700) +#define CORE_CM2_DUCATI_CLKSTCTRL OMAP2_L4_IO_ADDRESS(0x4A008900) +#define CORE_CM2_DUCATI_CLKCTRL OMAP2_L4_IO_ADDRESS(0x4A008920) +#define RM_MPU_M3_RSTCTRL_OFFSET 0x210 +#define RM_MPU_M3_RSTST_OFFSET 0x214 +#define RM_MPU_M3_RST1 0x1 +#define RM_MPU_M3_RST2 0x2 +#define RM_MPU_M3_RST3 0x4 + +#define OMAP4430PROC_MODULEID (u16) 0xbbec + +/* Macro to make a correct module magic number with refCount */ +#define OMAP4430PROC_MAKE_MAGICSTAMP(x) ((OMAP4430PROC_MODULEID << 12u) | (x)) + +/*OMAP4430 Module state object */ +struct proc4430_module_object { + u32 config_size; + /* Size of configuration structure */ + struct proc4430_config cfg; + /* OMAP4430 configuration structure */ + struct proc4430_config def_cfg; + /* Default module configuration */ + struct proc4430_params def_inst_params; + /* Default parameters for the OMAP4430 instances */ + void *proc_handles[MULTIPROC_MAXPROCESSORS]; + /* Processor handle array. */ + struct mutex *gate_handle; + /* void * of gate to be used for local thread safety */ + atomic_t ref_count; +}; + +/* + OMAP4430 instance object. + */ +struct proc4430_object { + struct proc4430_params params; + /* Instance parameters (configuration values) */ +}; + + +/* ================================= + * Globals + * ================================= + */ +/* + OMAP4430 state object variable + */ + +static struct proc4430_module_object proc4430_state = { + .config_size = sizeof(struct proc4430_config), + .gate_handle = NULL, + .def_inst_params.num_mem_entries = 0u, + .def_inst_params.mem_entries = NULL, + .def_inst_params.reset_vector_mem_entry = 0 +}; + + +/* ================================= + * APIs directly called by applications + * ================================= + */ +/* + * Function to get the default configuration for the OMAP4430 + * module. + * + * This function can be called by the application to get their + * configuration parameter to proc4430_setup filled in by the + * OMAP4430 module with the default parameters. If the user + * does not wish to make any change in the default parameters, this + * API is not required to be called. + */ +void proc4430_get_config(struct proc4430_config *cfg) +{ + BUG_ON(cfg == NULL); + memcpy(cfg, &(proc4430_state.def_cfg), + sizeof(struct proc4430_config)); +} +EXPORT_SYMBOL(proc4430_get_config); + +/* + * Function to setup the OMAP4430 module. + * + * This function sets up the OMAP4430 module. This function + * must be called before any other instance-level APIs can be + * invoked. + * Module-level configuration needs to be provided to this + * function. If the user wishes to change some specific config + * parameters, then proc4430_get_config can be called to get the + * configuration filled with the default values. After this, only + * the required configuration values can be changed. If the user + * does not wish to make any change in the default parameters, the + * application can simply call proc4430_setup with NULL + * parameters. The default parameters would get automatically used. + */ +int proc4430_setup(struct proc4430_config *cfg) +{ + int retval = 0; + struct proc4430_config tmp_cfg; + atomic_cmpmask_and_set(&proc4430_state.ref_count, + OMAP4430PROC_MAKE_MAGICSTAMP(0), + OMAP4430PROC_MAKE_MAGICSTAMP(0)); + + if (atomic_inc_return(&proc4430_state.ref_count) != + OMAP4430PROC_MAKE_MAGICSTAMP(1)) { + return 1; + } + + if (cfg == NULL) { + proc4430_get_config(&tmp_cfg); + cfg = &tmp_cfg; + } + + dmm_create(); + dmm_create_tables(DUCATI_DMM_START_ADDR, DUCATI_DMM_POOL_SIZE); + + /* Create a default gate handle for local module protection. */ + proc4430_state.gate_handle = + kmalloc(sizeof(struct mutex), GFP_KERNEL); + if (proc4430_state.gate_handle == NULL) { + retval = -ENOMEM; + goto error; + } + + mutex_init(proc4430_state.gate_handle); + + /* Initialize the name to handles mapping array. */ + memset(&proc4430_state.proc_handles, 0, + (sizeof(void *) * MULTIPROC_MAXPROCESSORS)); + + /* Copy the user provided values into the state object. */ + memcpy(&proc4430_state.cfg, cfg, + sizeof(struct proc4430_config)); + + return 0; + +error: + atomic_dec_return(&proc4430_state.ref_count); + dmm_delete_tables(); + dmm_destroy(); + + return retval; +} +EXPORT_SYMBOL(proc4430_setup); + +/* + * Function to destroy the OMAP4430 module. + * + * Once this function is called, other OMAP4430 module APIs, + * except for the proc4430_get_config API cannot be called + * anymore. + */ +int proc4430_destroy(void) +{ + int retval = 0; + u16 i; + + if (atomic_cmpmask_and_lt(&proc4430_state.ref_count, + OMAP4430PROC_MAKE_MAGICSTAMP(0), + OMAP4430PROC_MAKE_MAGICSTAMP(1)) + == true) { + retval = -ENODEV; + goto exit; + } + if (!(atomic_dec_return(&proc4430_state.ref_count) + == OMAP4430PROC_MAKE_MAGICSTAMP(0))) { + + retval = 1; + goto exit; + } + + /* Check if any OMAP4430 instances have not been + * deleted so far. If not,delete them. + */ + + for (i = 0; i < MULTIPROC_MAXPROCESSORS; i++) { + if (proc4430_state.proc_handles[i] == NULL) + continue; + proc4430_delete(&(proc4430_state.proc_handles[i])); + } + + /* Check if the gate_handle was created internally. */ + if (proc4430_state.gate_handle != NULL) { + mutex_destroy(proc4430_state.gate_handle); + kfree(proc4430_state.gate_handle); + } + +exit: + return retval; +} +EXPORT_SYMBOL(proc4430_destroy); + +/*================================================= + * Function to initialize the parameters for this Processor + * instance. + */ +void proc4430_params_init(void *handle, struct proc4430_params *params) +{ + struct proc4430_object *proc_object = (struct proc4430_object *)handle; + + if (atomic_cmpmask_and_lt(&proc4430_state.ref_count, + OMAP4430PROC_MAKE_MAGICSTAMP(0), + OMAP4430PROC_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc4430_params_init failed " + "Module not initialized"); + return; + } + + if (WARN_ON(params == NULL)) { + printk(KERN_ERR "proc4430_params_init failed " + "Argument of type proc4430_params * " + "is NULL"); + return; + } + + if (handle == NULL) + memcpy(params, &(proc4430_state.def_inst_params), + sizeof(struct proc4430_params)); + else + memcpy(params, &(proc_object->params), + sizeof(struct proc4430_params)); +} +EXPORT_SYMBOL(proc4430_params_init); + +/*=================================================== + *Function to create an instance of this Processor. + * + */ +void *proc4430_create(u16 proc_id, const struct proc4430_params *params) +{ + struct processor_object *handle = NULL; + struct proc4430_object *object = NULL; + + BUG_ON(!IS_VALID_PROCID(proc_id)); + BUG_ON(params == NULL); + + if (atomic_cmpmask_and_lt(&proc4430_state.ref_count, + OMAP4430PROC_MAKE_MAGICSTAMP(0), + OMAP4430PROC_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc4430_create failed " + "Module not initialized"); + goto error; + } + + /* Enter critical section protection. */ + WARN_ON(mutex_lock_interruptible(proc4430_state.gate_handle)); + if (proc4430_state.proc_handles[proc_id] != NULL) { + handle = proc4430_state.proc_handles[proc_id]; + goto func_end; + } else { + handle = (struct processor_object *) + vmalloc(sizeof(struct processor_object)); + if (WARN_ON(handle == NULL)) + goto func_end; + + handle->proc_fxn_table.attach = &proc4430_attach; + handle->proc_fxn_table.detach = &proc4430_detach; + handle->proc_fxn_table.start = &proc4430_start; + handle->proc_fxn_table.stop = &proc4430_stop; + handle->proc_fxn_table.read = &proc4430_read; + handle->proc_fxn_table.write = &proc4430_write; + handle->proc_fxn_table.control = &proc4430_control; + handle->proc_fxn_table.translateAddr = + &proc4430_translate_addr; + handle->proc_fxn_table.map = &proc4430_map; + handle->proc_fxn_table.unmap = &proc4430_unmap; + handle->proc_fxn_table.procinfo = &proc4430_proc_info; + handle->proc_fxn_table.virt_to_phys = &proc4430_virt_to_phys; + handle->state = PROC_MGR_STATE_UNKNOWN; + handle->object = vmalloc(sizeof(struct proc4430_object)); + handle->proc_id = proc_id; + object = (struct proc4430_object *)handle->object; + if (params != NULL) { + /* Copy params into instance object. */ + memcpy(&(object->params), (void *)params, + sizeof(struct proc4430_params)); + } + if ((params != NULL) && (params->mem_entries != NULL) + && (params->num_mem_entries > 0)) { + /* Allocate memory for, and copy mem_entries table*/ + object->params.mem_entries = vmalloc(sizeof(struct + proc4430_mem_entry) * + params->num_mem_entries); + memcpy(object->params.mem_entries, + params->mem_entries, + (sizeof(struct proc4430_mem_entry) * + params->num_mem_entries)); + } + handle->boot_mode = PROC_MGR_BOOTMODE_NOLOAD; + /* Set the handle in the state object. */ + proc4430_state.proc_handles[proc_id] = handle; + } + +func_end: + mutex_unlock(proc4430_state.gate_handle); +error: + return (void *)handle; +} +EXPORT_SYMBOL(proc4430_create); + +/*================================================= + * Function to delete an instance of this Processor. + * + * The user provided pointer to the handle is reset after + * successful completion of this function. + * + */ +int proc4430_delete(void **handle_ptr) +{ + int retval = 0; + struct proc4430_object *object = NULL; + struct processor_object *handle; + + BUG_ON(handle_ptr == NULL); + BUG_ON(*handle_ptr == NULL); + + if (atomic_cmpmask_and_lt(&proc4430_state.ref_count, + OMAP4430PROC_MAKE_MAGICSTAMP(0), + OMAP4430PROC_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc4430_delete failed " + "Module not initialized"); + return -ENODEV; + } + + handle = (struct processor_object *)(*handle_ptr); + BUG_ON(!IS_VALID_PROCID(handle->proc_id)); + /* Enter critical section protection. */ + WARN_ON(mutex_lock_interruptible(proc4430_state.gate_handle)); + /* Reset handle in PwrMgr handle array. */ + proc4430_state.proc_handles[handle->proc_id] = NULL; + /* Free memory used for the OMAP4430 object. */ + if (handle->object != NULL) { + object = (struct proc4430_object *)handle->object; + if (object->params.mem_entries != NULL) { + vfree(object->params.mem_entries); + object->params.mem_entries = NULL; + } + vfree(handle->object); + handle->object = NULL; + } + /* Free memory used for the Processor object. */ + vfree(handle); + *handle_ptr = NULL; + /* Leave critical section protection. */ + mutex_unlock(proc4430_state.gate_handle); + return retval; +} +EXPORT_SYMBOL(proc4430_delete); + +/*=================================================== + * Function to open a handle to an instance of this Processor. This + * function is called when access to the Processor is required from + * a different process. + */ +int proc4430_open(void **handle_ptr, u16 proc_id) +{ + int retval = 0; + + BUG_ON(handle_ptr == NULL); + BUG_ON(!IS_VALID_PROCID(proc_id)); + + if (atomic_cmpmask_and_lt(&proc4430_state.ref_count, + OMAP4430PROC_MAKE_MAGICSTAMP(0), + OMAP4430PROC_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc4430_open failed " + "Module not initialized"); + return -ENODEV; + } + + /* Initialize return parameter handle. */ + *handle_ptr = NULL; + + /* Check if the PwrMgr exists and return the handle if found. */ + if (proc4430_state.proc_handles[proc_id] == NULL) { + retval = -ENODEV; + goto func_exit; + } else + *handle_ptr = proc4430_state.proc_handles[proc_id]; +func_exit: + return retval; +} +EXPORT_SYMBOL(proc4430_open); + +/*=============================================== + * Function to close a handle to an instance of this Processor. + * + */ +int proc4430_close(void *handle) +{ + int retval = 0; + + BUG_ON(handle == NULL); + + if (atomic_cmpmask_and_lt(&proc4430_state.ref_count, + OMAP4430PROC_MAKE_MAGICSTAMP(0), + OMAP4430PROC_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc4430_close failed " + "Module not initialized"); + return -ENODEV; + } + + /* nothing to be done for now */ + return retval; +} +EXPORT_SYMBOL(proc4430_close); + +/* ================================= + * APIs called by Processor module (part of function table interface) + * ================================= + */ +/*================================ + * Function to initialize the slave processor + * + */ +int proc4430_attach(void *handle, struct processor_attach_params *params) +{ + int retval = 0; + + struct processor_object *proc_handle = NULL; + struct proc4430_object *object = NULL; + u32 map_count = 0; + u32 i; + memory_map_info map_info; + + if (atomic_cmpmask_and_lt(&proc4430_state.ref_count, + OMAP4430PROC_MAKE_MAGICSTAMP(0), + OMAP4430PROC_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc4430_attach failed" + "Module not initialized"); + return -ENODEV; + } + + if (WARN_ON(handle == NULL)) { + printk(KERN_ERR "proc4430_attach failed" + "Driver handle is NULL"); + return -EINVAL; + } + + if (WARN_ON(params == NULL)) { + printk(KERN_ERR "proc4430_attach failed" + "Argument processor_attach_params * is NULL"); + return -EINVAL; + } + + proc_handle = (struct processor_object *)handle; + + object = (struct proc4430_object *)proc_handle->object; + /* Return memory information in params. */ + for (i = 0; (i < object->params.num_mem_entries); i++) { + /* If the configured master virtual address is invalid, get the + * actual address by mapping the physical address into master + * kernel memory space. + */ + if ((object->params.mem_entries[i].master_virt_addr == (u32)-1) + && (object->params.mem_entries[i].shared == true)) { + map_info.src = object->params.mem_entries[i].phys_addr; + map_info.size = object->params.mem_entries[i].size; + map_info.is_cached = false; + retval = platform_mem_map(&map_info); + if (retval != 0) { + printk(KERN_ERR "proc4430_attach failed\n"); + return -EFAULT; + } + map_count++; + object->params.mem_entries[i].master_virt_addr = + map_info.dst; + params->mem_entries[i].addr + [PROC_MGR_ADDRTYPE_MASTERKNLVIRT] = + map_info.dst; + params->mem_entries[i].addr + [PROC_MGR_ADDRTYPE_SLAVEVIRT] = + (object->params.mem_entries[i].slave_virt_addr); + /* User virtual will be filled by user side. For now, + fill in the physical address so that it can be used + by mmap to remap this region into user-space */ + params->mem_entries[i].addr + [PROC_MGR_ADDRTYPE_MASTERUSRVIRT] = \ + object->params.mem_entries[i].phys_addr; + params->mem_entries[i].size = + object->params.mem_entries[i].size; + } + } + params->num_mem_entries = map_count; + return retval; +} + + +/*========================================== + * Function to detach from the Processor. + * + */ +int proc4430_detach(void *handle) +{ + struct processor_object *proc_handle = NULL; + struct proc4430_object *object = NULL; + u32 i; + memory_unmap_info unmap_info; + + if (atomic_cmpmask_and_lt(&proc4430_state.ref_count, + OMAP4430PROC_MAKE_MAGICSTAMP(0), + OMAP4430PROC_MAKE_MAGICSTAMP(1)) + == true) { + + printk(KERN_ERR "proc4430_detach failed " + "Module not initialized"); + return -ENODEV; + } + + if (WARN_ON(handle == NULL)) { + printk(KERN_ERR "proc4430_detach failed " + "Argument Driverhandle is NULL"); + return -EINVAL; + } + + proc_handle = (struct processor_object *)handle; + object = (struct proc4430_object *)proc_handle->object; + for (i = 0; (i < object->params.num_mem_entries); i++) { + if ((object->params.mem_entries[i].master_virt_addr > 0) + && (object->params.mem_entries[i].shared == true)) { + unmap_info.addr = + object->params.mem_entries[i].master_virt_addr; + unmap_info.size = object->params.mem_entries[i].size; + platform_mem_unmap(&unmap_info); + object->params.mem_entries[i].master_virt_addr = + (u32)-1; + } + } + return 0; +} + +/*========================================== + * Function to start the slave processor + * + * Start the slave processor running from its entry point. + * Depending on the boot mode, this involves configuring the boot + * address and releasing the slave from reset. + * + */ +int proc4430_start(void *handle, u32 entry_pt, + struct processor_start_params *start_params) +{ + u32 reg; + int counter = 10; + if (atomic_cmpmask_and_lt(&proc4430_state.ref_count, + OMAP4430PROC_MAKE_MAGICSTAMP(0), + OMAP4430PROC_MAKE_MAGICSTAMP(1)) + == true) { + + printk(KERN_ERR "proc4430_start failed " + "Module not initialized"); + return -ENODEV; + } + + /*FIXME: Remove handle and entry_pt if not used */ + if (WARN_ON(start_params == NULL)) { + printk(KERN_ERR "proc4430_start failed " + "Argument processor_start_params * is NULL"); + return -EINVAL; + } + + reg = __raw_readl(CORE_PRM_BASE + RM_MPU_M3_RSTST_OFFSET); + printk(KERN_INFO "proc4430_start: Reset Status [0x%x]", reg); + reg = __raw_readl(CORE_PRM_BASE + RM_MPU_M3_RSTCTRL_OFFSET); + printk(KERN_INFO "proc4430_start: Reset Control [0x%x]", reg); + + switch (start_params->params->proc_id) { + case SYS_M3: + /* Module is managed automatically by HW */ + __raw_writel(0x01, CORE_CM2_DUCATI_CLKCTRL); + /* Enable the M3 clock */ + __raw_writel(0x02, CORE_CM2_DUCATI_CLKSTCTRL); + do { + reg = __raw_readl(CORE_CM2_DUCATI_CLKSTCTRL); + if (reg & 0x100) { + printk(KERN_INFO "M3 clock enabled:" + "CORE_CM2_DUCATI_CLKSTCTRL = 0x%x\n", reg); + break; + } + msleep(1); + } while (--counter); + if (counter == 0) { + printk(KERN_ERR "FAILED TO ENABLE DUCATI M3 CLOCK !\n"); + return -EFAULT; + } + /* Check that releasing resets would indeed be effective */ + reg = __raw_readl(CORE_PRM_BASE + RM_MPU_M3_RSTCTRL_OFFSET); + if (reg != 7) { + printk(KERN_ERR "proc4430_start: Resets in not proper state!\n"); + __raw_writel(0x7, + CORE_PRM_BASE + RM_MPU_M3_RSTCTRL_OFFSET); + } + + /* De-assert RST3, and clear the Reset status */ + printk(KERN_INFO "De-assert RST3\n"); + __raw_writel(0x3, CORE_PRM_BASE + RM_MPU_M3_RSTCTRL_OFFSET); + while (!(__raw_readl(CORE_PRM_BASE + RM_MPU_M3_RSTST_OFFSET) + & 0x4)) + ; + printk(KERN_INFO "RST3 released!"); + __raw_writel(0x4, CORE_PRM_BASE + RM_MPU_M3_RSTST_OFFSET); + ducati_setup(); + + /* De-assert RST1, and clear the Reset status */ + printk(KERN_INFO "De-assert RST1\n"); + __raw_writel(0x2, CORE_PRM_BASE + RM_MPU_M3_RSTCTRL_OFFSET); + while (!(__raw_readl(CORE_PRM_BASE + RM_MPU_M3_RSTST_OFFSET) + & 0x1)) + ; + printk(KERN_INFO "RST1 released!"); + __raw_writel(0x1, CORE_PRM_BASE + RM_MPU_M3_RSTST_OFFSET); + break; + case APP_M3: + /* De-assert RST2, and clear the Reset status */ + printk(KERN_INFO "De-assert RST2\n"); + __raw_writel(0x0, CORE_PRM_BASE + RM_MPU_M3_RSTCTRL_OFFSET); + while (!(__raw_readl(CORE_PRM_BASE + RM_MPU_M3_RSTST_OFFSET) + & 0x2)) + ; + printk(KERN_INFO "RST2 released!"); + __raw_writel(0x2, CORE_PRM_BASE + RM_MPU_M3_RSTST_OFFSET); + break; + default: + printk(KERN_ERR "proc4430_start: ERROR input\n"); + break; + } + return 0; +} + + +/* + * Function to stop the slave processor + * + * Stop the execution of the slave processor. Depending on the boot + * mode, this may result in placing the slave processor in reset. + * + * @param handle void * to the Processor instance + * + * @sa proc4430_start, OMAP3530_halResetCtrl + */ +int +proc4430_stop(void *handle, struct processor_stop_params *stop_params) +{ + if (atomic_cmpmask_and_lt(&proc4430_state.ref_count, + OMAP4430PROC_MAKE_MAGICSTAMP(0), + OMAP4430PROC_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc4430_stop failed " + "Module not initialized"); + return -ENODEV; + } + switch (stop_params->params->proc_id) { + case SYS_M3: + ducati_destroy(); + printk(KERN_INFO "Assert RST1 and RST2 and RST3\n"); + __raw_writel(0x7, CORE_PRM_BASE + RM_MPU_M3_RSTCTRL_OFFSET); + /* Disable the M3 clock */ + __raw_writel(0x01, CORE_CM2_DUCATI_CLKSTCTRL); + break; + case APP_M3: + printk(KERN_INFO "Assert RST2\n"); + __raw_writel(0x2, CORE_PRM_BASE + RM_MPU_M3_RSTCTRL_OFFSET); + break; + default: + printk(KERN_ERR "proc4430_stop: ERROR input\n"); + break; + } + return 0; +} + + +/*============================================== + * Function to read from the slave processor's memory. + * + * Read from the slave processor's memory and copy into the + * provided buffer. + */ +int proc4430_read(void *handle, u32 proc_addr, u32 *num_bytes, + void *buffer) +{ + int retval = 0; + if (atomic_cmpmask_and_lt(&proc4430_state.ref_count, + OMAP4430PROC_MAKE_MAGICSTAMP(0), + OMAP4430PROC_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc4430_read failed " + "Module not initialized"); + return -ENODEV; + } + + /* TODO */ + return retval; +} + + +/*============================================== + * Function to write into the slave processor's memory. + * + * Read from the provided buffer and copy into the slave + * processor's memory. + * + */ +int proc4430_write(void *handle, u32 proc_addr, u32 *num_bytes, + void *buffer) +{ + int retval = 0; + + if (atomic_cmpmask_and_lt(&proc4430_state.ref_count, + OMAP4430PROC_MAKE_MAGICSTAMP(0), + OMAP4430PROC_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc4430_write failed " + "Module not initialized"); + return -ENODEV; + } + + /* TODO */ + return retval; +} + + +/*========================================================= + * Function to perform device-dependent operations. + * + * Performs device-dependent control operations as exposed by this + * implementation of the Processor module. + */ +int proc4430_control(void *handle, int cmd, void *arg) +{ + int retval = 0; + + /*FIXME: Remove handle,etc if not used */ + + if (atomic_cmpmask_and_lt(&proc4430_state.ref_count, + OMAP4430PROC_MAKE_MAGICSTAMP(0), + OMAP4430PROC_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc4430_control failed " + "Module not initialized"); + return -ENODEV; + } + + return retval; +} + + +/*===================================================== + * Function to translate between two types of address spaces. + * + * Translate between the specified address spaces. + */ +int proc4430_translate_addr(void *handle, + void **dst_addr, enum proc_mgr_addr_type dst_addr_type, + void *src_addr, enum proc_mgr_addr_type src_addr_type) +{ + int retval = 0; + struct processor_object *proc_handle = NULL; + struct proc4430_object *object = NULL; + struct proc4430_mem_entry *entry = NULL; + bool found = false; + u32 fm_addr_base = (u32)NULL; + u32 to_addr_base = (u32)NULL; + u32 i; + + if (atomic_cmpmask_and_lt(&proc4430_state.ref_count, + OMAP4430PROC_MAKE_MAGICSTAMP(0), + OMAP4430PROC_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc4430_translate_addr failed " + "Module not initialized"); + retval = -ENODEV; + goto error_exit; + } + + if (WARN_ON(handle == NULL)) { + retval = -EINVAL; + goto error_exit; + } + if (WARN_ON(dst_addr == NULL)) { + retval = -EINVAL; + goto error_exit; + } + if (WARN_ON(dst_addr_type > PROC_MGR_ADDRTYPE_ENDVALUE)) { + retval = -EINVAL; + goto error_exit; + } + if (WARN_ON(src_addr == NULL)) { + retval = -EINVAL; + goto error_exit; + } + if (WARN_ON(src_addr_type > PROC_MGR_ADDRTYPE_ENDVALUE)) { + retval = -EINVAL; + goto error_exit; + } + + proc_handle = (struct processor_object *)handle; + object = (struct proc4430_object *)proc_handle->object; + *dst_addr = NULL; + for (i = 0 ; i < object->params.num_mem_entries ; i++) { + entry = &(object->params.mem_entries[i]); + fm_addr_base = + (src_addr_type == PROC_MGR_ADDRTYPE_MASTERKNLVIRT) ? + entry->master_virt_addr : entry->slave_virt_addr; + to_addr_base = + (dst_addr_type == PROC_MGR_ADDRTYPE_MASTERKNLVIRT) ? + entry->master_virt_addr : entry->slave_virt_addr; + /* Determine whether which way to convert */ + if (((u32)src_addr < (fm_addr_base + entry->size)) && + ((u32)src_addr >= fm_addr_base)) { + found = true; + *dst_addr = (void *)(((u32)src_addr - fm_addr_base) + + to_addr_base); + break; + } + } + + /* This check must not be removed even with build optimize. */ + if (WARN_ON(found == false)) { + /*Failed to translate address. */ + retval = -ENXIO; + goto error_exit; + } + return 0; + +error_exit: + return retval; +} + + +/*================================================= + * Function to map slave address to host address space + * + * Map the provided slave address to master address space. This + * function also maps the specified address to slave MMU space. + */ +int proc4430_map(void *handle, u32 proc_addr, + u32 size, u32 *mapped_addr, u32 *mapped_size, u32 map_attribs) +{ + int retval = 0; + u32 da_align; + u32 da; + u32 va_align; + u32 size_align; + + if (atomic_cmpmask_and_lt(&proc4430_state.ref_count, + OMAP4430PROC_MAKE_MAGICSTAMP(0), + OMAP4430PROC_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc4430_map failed " + "Module not initialized"); + retval = -ENODEV; + goto error_exit; + } + + /*FIXME: Remove handle,etc if not used */ + + /* FIX ME: Temporary work around until the dynamic memory mapping + * for Tiler address space is available + */ + if ((map_attribs & DSP_MAPTILERADDR)) { + da_align = user_va2pa(current->mm, proc_addr); + *mapped_addr = (da_align | (proc_addr & (PAGE_SIZE - 1))); + printk(KERN_INFO "proc4430_map -tiler: user_va2pa: mapped_addr" + "= 0x%x\n", *mapped_addr); + return 0; + } + + /* Calculate the page-aligned PA, VA and size */ + va_align = PG_ALIGN_LOW(proc_addr, PAGE_SIZE); + size_align = PG_ALIGN_HIGH(size + (u32)proc_addr - va_align, PAGE_SIZE); + + dmm_reserve_memory(size_align, &da); + da_align = PG_ALIGN_LOW((u32)da, PAGE_SIZE); + retval = ducati_mem_map(va_align, da_align, size_align, map_attribs); + + /* Mapped address = MSB of DA | LSB of VA */ + *mapped_addr = (da_align | (proc_addr & (PAGE_SIZE - 1))); + +error_exit: + return retval; +} + +/*================================================= + * Function to unmap slave address to host address space + * + * UnMap the provided slave address to master address space. This + * function also unmaps the specified address to slave MMU space. + */ +int proc4430_unmap(void *handle, u32 mapped_addr) +{ + int da_align; + int ret_val = 0; + int size_align; + + if (atomic_cmpmask_and_lt(&proc4430_state.ref_count, + OMAP4430PROC_MAKE_MAGICSTAMP(0), + OMAP4430PROC_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc4430_map failed " + "Module not initialized"); + ret_val = -1; + goto error_exit; + } + + /*FIXME: Remove handle,etc if not used */ + + da_align = PG_ALIGN_LOW((u32)mapped_addr, PAGE_SIZE); + ret_val = dmm_unreserve_memory(da_align, &size_align); + if (WARN_ON(ret_val < 0)) + goto error_exit; + ret_val = ducati_mem_unmap(da_align, size_align); + if (WARN_ON(ret_val < 0)) + goto error_exit; + return 0; + +error_exit: + printk(KERN_WARNING "proc4430_unmap failed !!!!\n"); + return ret_val; +} + +/*================================================= + * Function to return list of translated mem entries + * + * This function takes the remote processor address as + * an input and returns the mapped Page entries in the + * buffer passed + */ +int proc4430_virt_to_phys(void *handle, u32 da, u32 *mapped_entries, + u32 num_of_entries) +{ + int da_align; + int i; + int ret_val = 0; + + if (atomic_cmpmask_and_lt(&proc4430_state.ref_count, + OMAP4430PROC_MAKE_MAGICSTAMP(0), + OMAP4430PROC_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc4430_virt_to_phys failed " + "Module not initialized"); + ret_val = -EFAULT; + goto error_exit; + } + + if (handle == NULL || mapped_entries == NULL || num_of_entries == 0) { + ret_val = -EFAULT; + goto error_exit; + } + da_align = PG_ALIGN_LOW((u32)da, PAGE_SIZE); + for (i = 0; i < num_of_entries; i++) { + mapped_entries[i] = ducati_mem_virtToPhys(da_align); + da_align += PAGE_SIZE; + } + return 0; + +error_exit: + printk(KERN_WARNING "proc4430_virtToPhys failed !!!!\n"); + return ret_val; +} + + +/*================================================= + * Function to return PROC4430 mem_entries info + * + */ +int proc4430_proc_info(void *handle, struct proc_mgr_proc_info *procinfo) +{ + struct processor_object *proc_handle = NULL; + struct proc4430_object *object = NULL; + struct proc4430_mem_entry *entry = NULL; + int i; + + if (atomic_cmpmask_and_lt(&proc4430_state.ref_count, + OMAP4430PROC_MAKE_MAGICSTAMP(0), + OMAP4430PROC_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc4430_proc_info failed " + "Module not initialized"); + goto error_exit; + } + + if (WARN_ON(handle == NULL)) + goto error_exit; + if (WARN_ON(procinfo == NULL)) + goto error_exit; + + proc_handle = (struct processor_object *)handle; + + object = (struct proc4430_object *)proc_handle->object; + + for (i = 0 ; i < object->params.num_mem_entries ; i++) { + entry = &(object->params.mem_entries[i]); + procinfo->mem_entries[i].addr[PROC_MGR_ADDRTYPE_MASTERKNLVIRT] + = entry->master_virt_addr; + procinfo->mem_entries[i].addr[PROC_MGR_ADDRTYPE_SLAVEVIRT] + = entry->slave_virt_addr; + procinfo->mem_entries[i].size = entry->size; + } + procinfo->num_mem_entries = object->params.num_mem_entries; + procinfo->boot_mode = proc_handle->boot_mode; + return 0; + +error_exit: + printk(KERN_WARNING "proc4430_proc_info failed !!!!\n"); + return -EFAULT; +} diff --git a/drivers/dsp/syslink/procmgr/proc4430/proc4430.h b/drivers/dsp/syslink/procmgr/proc4430/proc4430.h new file mode 100755 index 000000000000..5903daeadaa3 --- /dev/null +++ b/drivers/dsp/syslink/procmgr/proc4430/proc4430.h @@ -0,0 +1,147 @@ +/* + * proc4430.h + * + * Syslink driver support functions for TI OMAP processors. + * + * Copyright (C) 2009-2010 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + + + + +#ifndef _SYSLINK_PROC_4430_H_ +#define _SYSLINK_PROC_4430_H_ + + +/* Module headers */ +#include <procmgr.h> +#include "../procdefs.h" +#include <linux/types.h> + +/* + Module configuration structure. + */ +struct proc4430_config { + struct mutex *gate_handle; + /* void * of gate to be used for local thread safety */ +}; + +/* + Memory entry for slave memory map configuration + */ +struct proc4430_mem_entry { + char name[PROCMGR_MAX_STRLEN]; + /* Name identifying the memory region. */ + u32 phys_addr; + /* Physical address of the memory region. */ + u32 slave_virt_addr; + /* Slave virtual address of the memory region. */ + u32 master_virt_addr; + /* Master virtual address of the memory region. If specified as -1, + * the master virtual address is assumed to be invalid, and shall be + * set internally within the Processor module. */ + u32 size; + /* Size (in bytes) of the memory region. */ + bool shared; + /* Flag indicating whether the memory region is shared between master + * and slave. */ +}; + +/* + Configuration parameters specific to this processor. + */ +struct proc4430_params { + int num_mem_entries; + /* Number of memory regions to be configured. */ + struct proc4430_mem_entry *mem_entries; + /* Array of information structures for memory regions + * to be configured. */ + u32 reset_vector_mem_entry; + /* Index of the memory entry within the mem_entries array, + * which is the resetVector memory region. */ +}; + + +/* Function to initialize the slave processor */ +int proc4430_attach(void *handle, struct processor_attach_params *params); + +/* Function to finalize the slave processor */ +int proc4430_detach(void *handle); + +/* Function to start the slave processor */ +int proc4430_start(void *handle, u32 entry_pt, + struct processor_start_params *params); + +/* Function to start the stop processor */ +int proc4430_stop(void *handle, + struct processor_stop_params *params); + +/* Function to read from the slave processor's memory. */ +int proc4430_read(void *handle, u32 proc_addr, u32 *num_bytes, + void *buffer); + +/* Function to write into the slave processor's memory. */ +int proc4430_write(void *handle, u32 proc_addr, u32 *num_bytes, + void *buffer); + +/* Function to perform device-dependent operations. */ +int proc4430_control(void *handle, int cmd, void *arg); + +/* Function to translate between two types of address spaces. */ +int proc4430_translate_addr(void *handle, void **dst_addr, + enum proc_mgr_addr_type dst_addr_type, + void *src_addr, enum proc_mgr_addr_type src_addr_type); + +/* Function to map slave address to host address space */ +int proc4430_map(void *handle, u32 proc_addr, u32 size, u32 *mapped_addr, + u32 *mapped_size, u32 map_attribs); + +/* Function to unmap the slave address to host address space */ +int proc4430_unmap(void *handle, u32 mapped_addr); + +/* Function to retrive physical address translations */ +int proc4430_virt_to_phys(void *handle, u32 da, u32 *mapped_entries, + u32 num_of_entries); + +/* ================================================= + * APIs + * ================================================= + */ + +/* Function to get the default configuration for the OMAP4430PROC module */ +void proc4430_get_config(struct proc4430_config *cfg); + +/* Function to setup the OMAP4430PROC module. */ +int proc4430_setup(struct proc4430_config *cfg); + +/* Function to destroy the OMAP4430PROC module. */ +int proc4430_destroy(void); + +/* Function to initialize the parameters for this processor instance. */ +void proc4430_params_init(void *handle, + struct proc4430_params *params); + +/* Function to create an instance of this processor. */ +void *proc4430_create(u16 proc_id, const struct proc4430_params *params); + +/* Function to delete an instance of this processor. */ +int proc4430_delete(void **handle_ptr); + +/* Function to open an instance of this processor. */ +int proc4430_open(void **handle_ptr, u16 proc_id); + +/* Function to close an instance of this processor. */ +int proc4430_close(void *handle); + +/* Function to get the proc info */ +int proc4430_proc_info(void *handle, struct proc_mgr_proc_info *procinfo); + +#endif diff --git a/drivers/dsp/syslink/procmgr/proc4430/proc4430_drv.c b/drivers/dsp/syslink/procmgr/proc4430/proc4430_drv.c new file mode 100755 index 000000000000..fada09919052 --- /dev/null +++ b/drivers/dsp/syslink/procmgr/proc4430/proc4430_drv.c @@ -0,0 +1,400 @@ +/* + * proc4430_drv.c + * + * Syslink driver support functions for TI OMAP processors. + * + * Copyright (C) 2009-2010 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include <generated/autoconf.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/cdev.h> +#include <linux/device.h> +#include <linux/fs.h> +#include <linux/mm.h> +#include <linux/vmalloc.h> +#include <linux/uaccess.h> +#include <linux/platform_device.h> + + +/* Module headers */ +#include "proc4430.h" +#include "proc4430_drvdefs.h" + + + +/** ============================================================================ + * Macros and types + * ============================================================================ + */ +#define PROC4430_NAME "syslink-proc4430" + +static char *driver_name = PROC4430_NAME; + +static s32 driver_major; + +static s32 driver_minor; + +struct proc_4430_dev { + struct cdev cdev; +}; + +static struct proc_4430_dev *proc_4430_device; + +static struct class *proc_4430_class; + + + +/** ============================================================================ + * Forward declarations of internal functions + * ============================================================================ + */ +/* Linux driver function to open the driver object. */ +static int proc4430_drv_open(struct inode *inode, struct file *filp); + +/* Linux driver function to close the driver object. */ +static int proc4430_drv_release(struct inode *inode, struct file *filp); + +/* Linux driver function to invoke the APIs through ioctl. */ +static int proc4430_drv_ioctl(struct inode *inode, + struct file *filp, unsigned int cmd, + unsigned long args); + +/* Linux driver function to map memory regions to user space. */ +static int proc4430_drv_mmap(struct file *filp, + struct vm_area_struct *vma); + +/* Module initialization function for Linux driver. */ +static int __init proc4430_drv_initializeModule(void); + +/* Module finalization function for Linux driver. */ +static void __exit proc4430_drv_finalizeModule(void); + + + +/** ============================================================================ + * Globals + * ============================================================================ + */ + +/* + File operations table for PROC4430. + */ +static const struct file_operations proc_4430_fops = { + .open = proc4430_drv_open, + .release = proc4430_drv_release, + .ioctl = proc4430_drv_ioctl, + .mmap = proc4430_drv_mmap, +}; + +static int proc4430_drv_open(struct inode *inode, struct file *filp) +{ + return 0; +} + +static int proc4430_drv_release(struct inode *inode, struct file *filp) +{ + return 0; +} + + +/* + Linux driver function to invoke the APIs through ioctl. + * + */ +static int proc4430_drv_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long args) +{ + int retval = 0; + struct proc_mgr_cmd_args *cmd_args = (struct proc_mgr_cmd_args *)args; + struct proc_mgr_cmd_args command_args; + + switch (cmd) { + case CMD_PROC4430_GETCONFIG: + { + struct proc4430_cmd_args_get_config *src_args = + (struct proc4430_cmd_args_get_config *)args; + struct proc4430_config cfg; + + /* copy_from_useris not needed for + * proc4430_get_config, since the + * user's config is not used. + */ + proc4430_get_config(&cfg); + + retval = copy_to_user((void *)(src_args->cfg), + (const void *)&cfg, + sizeof(struct proc4430_config)); + if (WARN_ON(retval < 0)) + goto func_exit; + } + break; + + case CMD_PROC4430_SETUP: + { + struct proc4430_cmd_args_setup *src_args = + (struct proc4430_cmd_args_setup *)args; + struct proc4430_config cfg; + + retval = copy_from_user((void *)&cfg, + (const void *)(src_args->cfg), + sizeof(struct proc4430_config)); + if (WARN_ON(retval < 0)) + goto func_exit; + proc4430_setup(&cfg); + } + break; + + case CMD_PROC4430_DESTROY: + { + proc4430_destroy(); + } + break; + + case CMD_PROC4430_PARAMS_INIT: + { + struct proc4430_cmd_args_params_init src_args; + struct proc4430_params params; + + /* Copy the full args from user-side. */ + retval = copy_from_user((void *)&src_args, + (const void *)(args), + sizeof(struct proc4430_cmd_args_params_init)); + if (WARN_ON(retval < 0)) + goto func_exit; + proc4430_params_init(src_args.handle, ¶ms); + retval = copy_to_user((void *)(src_args.params), + (const void *) ¶ms, + sizeof(struct proc4430_params)); + if (WARN_ON(retval < 0)) + goto func_exit; + } + break; + + case CMD_PROC4430_CREATE: + { + struct proc4430_cmd_args_create src_args; + struct proc4430_params params; + struct proc4430_mem_entry *entries = NULL; + + /* Copy the full args from user-side. */ + retval = copy_from_user((void *)&src_args, + (const void *)(args), + sizeof(struct proc4430_cmd_args_create)); + if (WARN_ON(retval < 0)) + goto func_exit; + retval = copy_from_user((void *) ¶ms, + (const void *)(src_args.params), + sizeof(struct proc4430_params)); + if (WARN_ON(retval < 0)) + goto func_exit; + /* Copy the contents of mem_entries from user-side */ + if (params.num_mem_entries) { + entries = vmalloc(params.num_mem_entries * \ + sizeof(struct proc4430_mem_entry)); + if (WARN_ON(!entries)) + goto func_exit; + retval = copy_from_user((void *) (entries), + (const void *)(params.mem_entries), + params.num_mem_entries * \ + sizeof(struct proc4430_mem_entry)); + if (WARN_ON(retval < 0)) { + vfree(entries); + goto func_exit; + } + params.mem_entries = entries; + } + src_args.handle = proc4430_create(src_args.proc_id, + ¶ms); + if (WARN_ON(src_args.handle == NULL)) + goto func_exit; + retval = copy_to_user((void *)(args), + (const void *)&src_args, + sizeof(struct proc4430_cmd_args_create)); + /* Free the memory created */ + if (params.num_mem_entries) + vfree(entries); + } + break; + + case CMD_PROC4430_DELETE: + { + struct proc4430_cmd_args_delete src_args; + + /* Copy the full args from user-side. */ + retval = copy_from_user((void *)&src_args, + (const void *)(args), + sizeof(struct proc4430_cmd_args_delete)); + if (WARN_ON(retval < 0)) + goto func_exit; + retval = proc4430_delete(&(src_args.handle)); + WARN_ON(retval < 0); + } + break; + + case CMD_PROC4430_OPEN: + { + struct proc4430_cmd_args_open src_args; + + /*Copy the full args from user-side. */ + retval = copy_from_user((void *)&src_args, + (const void *)(args), + sizeof(struct proc4430_cmd_args_open)); + if (WARN_ON(retval < 0)) + goto func_exit; + retval = proc4430_open(&(src_args.handle), + src_args.proc_id); + retval = copy_to_user((void *)(args), + (const void *)&src_args, + sizeof(struct proc4430_cmd_args_open)); + WARN_ON(retval < 0); + } + break; + + case CMD_PROC4430_CLOSE: + { + struct proc4430_cmd_args_close src_args; + + /*Copy the full args from user-side. */ + retval = copy_from_user((void *)&src_args, + (const void *)(args), + sizeof(struct proc4430_cmd_args_close)); + if (WARN_ON(retval < 0)) + goto func_exit; + retval = proc4430_close(src_args.handle); + WARN_ON(retval < 0); + } + break; + + default: + { + printk(KERN_ERR "unsupported ioctl\n"); + } + break; + } +func_exit: + /* Set the status and copy the common args to user-side. */ + command_args.api_status = retval; + retval = copy_to_user((void *) cmd_args, + (const void *) &command_args, + sizeof(struct proc_mgr_cmd_args)); + WARN_ON(retval < 0); + return retval; +} + + +/* + Linux driver function to map memory regions to user space. + * + */ +static int proc4430_drv_mmap(struct file *filp, struct vm_area_struct *vma) +{ + vma->vm_page_prot = pgprot_dmacoherent(vma->vm_page_prot); + + if (remap_pfn_range(vma, + vma->vm_start, + vma->vm_pgoff, + vma->vm_end - vma->vm_start, + vma->vm_page_prot)) { + return -EAGAIN; + } + return 0; +} + + +/** ================================================================== + * Functions required for multiple .ko modules configuration + * ================================================================== + */ +/* + Module initialization function for Linux driver. + */ +static int __init proc4430_drv_initializeModule(void) +{ + dev_t dev = 0 ; + int retval; + + /* Display the version info and created date/time */ + printk(KERN_INFO "proc4430_drv_initializeModule\n"); + + if (driver_major) { + dev = MKDEV(driver_major, driver_minor); + retval = register_chrdev_region(dev, 1, driver_name); + } else { + retval = alloc_chrdev_region(&dev, driver_minor, 1, + driver_name); + driver_major = MAJOR(dev); + } + + proc_4430_device = kmalloc(sizeof(struct proc_4430_dev), GFP_KERNEL); + if (!proc_4430_device) { + retval = -ENOMEM; + unregister_chrdev_region(dev, 1); + goto exit; + } + memset(proc_4430_device, 0, sizeof(struct proc_4430_dev)); + cdev_init(&proc_4430_device->cdev, &proc_4430_fops); + proc_4430_device->cdev.owner = THIS_MODULE; + proc_4430_device->cdev.ops = &proc_4430_fops; + + retval = cdev_add(&proc_4430_device->cdev, dev, 1); + + if (retval) { + printk(KERN_ERR "Failed to add the syslink proc_4430 device \n"); + goto exit; + } + + /* udev support */ + proc_4430_class = class_create(THIS_MODULE, "syslink-proc4430"); + + if (IS_ERR(proc_4430_class)) { + printk(KERN_ERR "Error creating bridge class \n"); + goto exit; + } + device_create(proc_4430_class, NULL, MKDEV(driver_major, driver_minor), + NULL, PROC4430_NAME); +exit: + return 0; +} + +/* + function to finalize the driver module. + */ +static void __exit proc4430_drv_finalizeModule(void) +{ + dev_t devno = 0; + + /* FIX ME: THIS MIGHT NOT BE THE RIGHT PLACE TO CALL THE SETUP */ + proc4430_destroy(); + + devno = MKDEV(driver_major, driver_minor); + if (proc_4430_device) { + cdev_del(&proc_4430_device->cdev); + kfree(proc_4430_device); + } + unregister_chrdev_region(devno, 1); + if (proc_4430_class) { + /* remove the device from sysfs */ + device_destroy(proc_4430_class, MKDEV(driver_major, + driver_minor)); + class_destroy(proc_4430_class); + } + return; +} + +/* + Macro calls that indicate initialization and finalization functions + * to the kernel. + */ +MODULE_LICENSE("GPL v2"); +module_init(proc4430_drv_initializeModule); +module_exit(proc4430_drv_finalizeModule); diff --git a/drivers/dsp/syslink/procmgr/proc4430/proc4430_drvdefs.h b/drivers/dsp/syslink/procmgr/proc4430/proc4430_drvdefs.h new file mode 100755 index 000000000000..4176d731f1d4 --- /dev/null +++ b/drivers/dsp/syslink/procmgr/proc4430/proc4430_drvdefs.h @@ -0,0 +1,169 @@ +/* + * proc4430_drvdefs.h + * + * Syslink driver support functions for TI OMAP processors. + * + * Copyright (C) 2009-2010 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + + +#ifndef _SYSLINK_PROC4430_H +#define _SYSLINK_PROC4430_H + + +/* Module headers */ +#include "../procmgr_drvdefs.h" +#include "proc4430.h" + + +/* ---------------------------------------------------------------------------- + * IOCTL command IDs for OMAP4430PROC + * ---------------------------------------------------------------------------- + */ +/* + * Base command ID for OMAP4430PROC + */ +#define PROC4430_BASE_CMD 0x200 + +/* + * Command for PROC4430_getConfig + */ +#define CMD_PROC4430_GETCONFIG (PROC4430_BASE_CMD + 1) + +/* + * Command for PROC4430_setup + */ +#define CMD_PROC4430_SETUP (PROC4430_BASE_CMD + 2) + +/* + * Command for PROC4430_setup + */ +#define CMD_PROC4430_DESTROY (PROC4430_BASE_CMD + 3) + +/* + * Command for PROC4430_destroy + */ +#define CMD_PROC4430_PARAMS_INIT (PROC4430_BASE_CMD + 4) + +/* + * Command for PROC4430_create + */ +#define CMD_PROC4430_CREATE (PROC4430_BASE_CMD + 5) + +/* + * Command for PROC4430_delete + */ +#define CMD_PROC4430_DELETE (PROC4430_BASE_CMD + 6) + +/* + * Command for PROC4430_open + */ +#define CMD_PROC4430_OPEN (PROC4430_BASE_CMD + 7) + +/* + * Command for PROC4430_close + */ +#define CMD_PROC4430_CLOSE (PROC4430_BASE_CMD + 8) + + +/* --------------------------------------------------- + * Command arguments for OMAP4430PROC + * --------------------------------------------------- + */ +/* + * Command arguments for PROC4430_getConfig + */ +struct proc4430_cmd_args_get_config { + struct proc_mgr_cmd_args command_args; + /* Common command args */ + struct proc4430_config *cfg; + /* Pointer to the OMAP4430PROC module configuration structure + * in which the default config is to be returned. */ +}; + +/* + * Command arguments for PROC4430_setup + */ +struct proc4430_cmd_args_setup { + struct proc_mgr_cmd_args command_args; + /* Common command args */ + struct proc4430_config *cfg; + /* Optional OMAP4430PROC module configuration. If provided as NULL, + * default configuration is used. */ +}; + +/* + * Command arguments for PROC4430_destroy + */ +struct proc4430_cmd_args_destroy { + struct proc_mgr_cmd_args command_args; + /* Common command args */ +}; + +/* + * Command arguments for struct struct proc4430_params_init + */ +struct proc4430_cmd_args_params_init { + struct proc_mgr_cmd_args command_args; + /* Common command args */ + void *handle; + /* void * to the processor instance. */ + struct proc4430_params *params; + /* Configuration parameters. */ +}; + +/* + * Command arguments for PROC4430_create + */ +struct proc4430_cmd_args_create { + struct proc_mgr_cmd_args command_args; + /* Common command args */ + u16 proc_id; + /* Processor ID for which this processor instance is required. */ + struct proc4430_params *params; + /*Configuration parameters. */ + void *handle; + /* void * to the created processor instance. */ +}; + +/* + * Command arguments for PROC4430_delete + */ +struct proc4430_cmd_args_delete { + struct proc_mgr_cmd_args command_args; + /* Common command args */ + void *handle; + /* Pointer to handle to the processor instance */ +}; + +/* + * Command arguments for PROC4430_open + */ +struct proc4430_cmd_args_open { + struct proc_mgr_cmd_args command_args; + /* Common command args */ + u16 proc_id; + /* Processor ID addressed by this OMAP4430PROC instance. */ + void *handle; + /* Return parameter: void * to the processor instance */ +}; + +/* + * Command arguments for PROC4430_close + */ +struct proc4430_cmd_args_close { + struct proc_mgr_cmd_args command_args; + /* Common command args */ + void *handle; + /* void * to the processor instance */ +}; + +#endif diff --git a/drivers/dsp/syslink/procmgr/procdefs.h b/drivers/dsp/syslink/procmgr/procdefs.h new file mode 100755 index 000000000000..eb73626d27e1 --- /dev/null +++ b/drivers/dsp/syslink/procmgr/procdefs.h @@ -0,0 +1,203 @@ +/* + * procdefs.h + * + * Syslink driver support functions for TI OMAP processors. + * + * Copyright (C) 2009-2010 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef SYSLINK_PROCDEFS_H +#define SYSLINK_PROCDEFS_H + +#include <linux/types.h> + +/* Module level headers */ +#include <procmgr.h> + + +/* ============================= + * Macros and types + * ============================= + */ +/* + * Enumerates the types of Endianism of slave processor. + */ +enum processor_endian{ + PROCESSOR_ENDIAN_DEFAULT = 0, + /* Default endianism (no conversion required) */ + PROCESSOR_ENDIAN_BIG = 1, + /* Big endian */ + PROCESSOR_ENDIAN_LITTLE = 2, + /* Little endian */ + PROCESSOR_ENDIAN_ENDVALUE = 3 + /* End delimiter indicating start of invalid values for this enum */ +}; + + +/* + * Configuration parameters for attaching to the slave Processor + */ +struct processor_attach_params { + struct proc_mgr_attach_params *params; + /* Common attach parameters for ProcMgr */ + u16 num_mem_entries; + /* Number of valid memory entries */ + struct proc_mgr_addr_info mem_entries[PROCMGR_MAX_MEMORY_REGIONS]; + /* Configuration of memory regions */ +}; + +/* + *Configuration parameters for starting the slave Processor + */ +struct processor_start_params { + struct proc_mgr_start_params *params; + /* Common start parameters for ProcMgr */ +}; + +/* + *Configuration parameters for stopping the slave Processor + */ +struct processor_stop_params { + struct proc_mgr_stop_params *params; + /* Common start parameters for ProcMgr */ +}; +/* + * Function pointer type for the function to attach to the processor. + */ +typedef int (*processor_attach_fxn) (void *handle, + struct processor_attach_params *params); + +/* + * Function pointer type for the function to detach from the + * procssor + */ +typedef int (*processor_detach_fxn) (void *handle); + +/* + * Function pointer type for the function to start the processor. + */ +typedef int (*processor_start_fxn) (void *handle, u32 entry_pt, + struct processor_start_params *params); + +/* + *Function pointer type for the function to stop the processor. + */ +typedef int (*processor_stop_fxn) (void *handle, + struct processor_stop_params *params); + +/* + * Function pointer type for the function to read from the slave + * processor's memory. + */ +typedef int (*processor_read_fxn) (void *handle, u32 proc_addr, + u32 *num_bytes, void *buffer); + +/* + *Function pointer type for the function to write into the slave + *processor's memory. + */ +typedef int (*processor_write_fxn) (void *handle, u32 proc_addr, + u32 *num_bytes, void *buffer); + +/* + *Function pointer type for the function to perform device-dependent + * operations. + */ +typedef int (*processor_control_fxn) (void *handle, int cmd, void *arg); + +/* + *Function pointer type for the function to translate between + * two types of address spaces. + */ +typedef int (*processor_translate_addr_fxn) (void *handle, void **dst_addr, + enum proc_mgr_addr_type dstAddrType, void *srcAddr, + enum proc_mgr_addr_type srcAddrType); + +/* + *Function pointer type for the function to map address to slave + * address space + */ +typedef int (*processor_map_fxn) (void *handle, u32 proc_addr, u32 size, + u32 *mapped_addr, u32 *mapped_size, u32 map_attribs); + +/* + *Function pointer type for the function to map address to slave + * address space + */ +typedef int (*processor_unmap_fxn) (void *handle, u32 mapped_addr); + +/* + *Function pointer type for the function that returns proc info + */ +typedef int (*processor_proc_info) (void *handle, + struct proc_mgr_proc_info *proc_info); + +/* + *Function pointer type for the function that returns proc info + */ +typedef int (*processor_virt_to_phys_fxn) (void *handle, u32 da, + u32 *mapped_entries, u32 num_of_entries); + + +/* ============================= + * Function table interface + * ============================= + */ +/* + *Function table interface for Processor. + */ +struct processor_fxn_table { + processor_attach_fxn attach; + /* Function to attach to the slave processor */ + processor_detach_fxn detach; + /* Function to detach from the slave processor */ + processor_start_fxn start; + /* Function to start the slave processor */ + processor_stop_fxn stop; + /* Function to stop the slave processor */ + processor_read_fxn read; + /* Function to read from the slave processor's memory */ + processor_write_fxn write; + /* Function to write into the slave processor's memory */ + processor_control_fxn control; + /* Function to perform device-dependent control function */ + processor_translate_addr_fxn translateAddr; + /* Function to translate between address ranges */ + processor_map_fxn map; + /* Function to map slave addresses to master address space */ + processor_unmap_fxn unmap; + /* Function to unmap slave addresses to master address space */ + processor_proc_info procinfo; + /* Function to convert Virtual to Physical pages */ + processor_virt_to_phys_fxn virt_to_phys; +}; + +/* ============================= + * Processor structure + * ============================= + */ +/* + * Generic Processor object. This object defines the handle type for all + * Processor operations. + */ +struct processor_object { + struct processor_fxn_table proc_fxn_table; + /* interface function table to plug into the generic Processor. */ + enum proc_mgr_state state; + /* State of the slave processor */ + enum proc_mgr_boot_mode boot_mode; + /* Boot mode for the slave processor. */ + void *object; + /* Pointer to Processor-specific object. */ + u16 proc_id; + /* Processor ID addressed by this Processor instance. */ +}; +#endif diff --git a/drivers/dsp/syslink/procmgr/processor.c b/drivers/dsp/syslink/procmgr/processor.c new file mode 100755 index 000000000000..4548d12ad967 --- /dev/null +++ b/drivers/dsp/syslink/procmgr/processor.c @@ -0,0 +1,398 @@ +/* + * processor.c + * + * Syslink driver support functions for TI OMAP processors. + * + * Copyright (C) 2009-2010 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include <linux/types.h> +#include <linux/module.h> + +/* Module level headers */ +#include "procdefs.h" +#include "processor.h" + + + +/* ========================================= + * Functions called by ProcMgr + * ========================================= + */ +/* + * Function to attach to the Processor. + * + * This function calls into the specific Processor implementation + * to attach to it. + * This function is called from the ProcMgr attach function, and + * hence is used to perform any activities that may be required + * once the slave is powered up. + * Depending on the type of Processor, this function may or may not + * perform any activities. + */ +inline int processor_attach(void *handle, + struct processor_attach_params *params) +{ + int retval = 0; + struct processor_object *proc_handle = + (struct processor_object *)handle; + + BUG_ON(handle == NULL); + BUG_ON(params == NULL); + BUG_ON(proc_handle->proc_fxn_table.attach == NULL); + + proc_handle->boot_mode = params->params->boot_mode; + retval = proc_handle->proc_fxn_table.attach(handle, params); + + if (proc_handle->boot_mode == PROC_MGR_BOOTMODE_BOOT) + proc_handle->state = PROC_MGR_STATE_POWERED; + else if (proc_handle->boot_mode == PROC_MGR_BOOTMODE_NOLOAD) + proc_handle->state = PROC_MGR_STATE_LOADED; + else if (proc_handle->boot_mode == PROC_MGR_BOOTMODE_NOBOOT) + proc_handle->state = PROC_MGR_STATE_RUNNNING; + return retval; +} + + +/* + * Function to detach from the Processor. + * + * This function calls into the specific Processor implementation + * to detach from it. + * This function is called from the ProcMgr detach function, and + * hence is useful to perform any activities that may be required + * before the slave is powered down. + * Depending on the type of Processor, this function may or may not + * perform any activities. + */ +inline int processor_detach(void *handle) +{ + int retval = 0; + struct processor_object *proc_handle = + (struct processor_object *)handle; + + BUG_ON(handle == NULL); + BUG_ON(proc_handle->proc_fxn_table.detach == NULL); + + retval = proc_handle->proc_fxn_table.detach(handle); + /* For all boot modes, at the end of detach, the Processor is in + * unknown state. + */ + proc_handle->state = PROC_MGR_STATE_UNKNOWN; + return retval; +} + + +/* + * Function to start the processor. + * + * This function calls into the specific Processor implementation + * to start the slave processor running. + * This function starts the slave processor running, in most + * devices, by programming its entry point into the boot location + * of the slave processor and releasing it from reset. + * The handle specifies the specific Processor instance to be used. + * + * @param handle void * to the Processor object + * @param entryPt Entry point of the file loaded on the slave Processor + * + * @sa Processor_stop + */ +inline int processor_start(void *handle, u32 entry_pt, + struct processor_start_params *params) +{ + int retval = 0; + struct processor_object *proc_handle = + (struct processor_object *)handle; + + BUG_ON(handle == NULL); + /* entryPt may be 0 for some devices. Cannot check for valid/invalid. */ + BUG_ON(params == NULL); + BUG_ON(proc_handle->proc_fxn_table.start == NULL); + retval = proc_handle->proc_fxn_table.start(handle, entry_pt, params); + + if ((proc_handle->boot_mode == PROC_MGR_BOOTMODE_BOOT) + || (proc_handle->boot_mode == PROC_MGR_BOOTMODE_NOLOAD)) + proc_handle->state = PROC_MGR_STATE_RUNNNING; + + return retval; +} + + +/* + * Function to stop the processor. + * + * This function calls into the specific Processor implementation + * to stop the slave processor. + * This function stops the slave processor running, in most + * devices, by placing it in reset. + * The handle specifies the specific Processor instance to be used. + */ +inline int processor_stop(void *handle, + struct processor_stop_params *params) +{ + int retval = 0; + struct processor_object *proc_handle = + (struct processor_object *)handle; + + BUG_ON(handle == NULL); + BUG_ON(proc_handle->proc_fxn_table.stop == NULL); + + retval = proc_handle->proc_fxn_table.stop(handle, params); + + if ((proc_handle->boot_mode == PROC_MGR_BOOTMODE_BOOT) + || (proc_handle->boot_mode == PROC_MGR_BOOTMODE_NOLOAD)) + proc_handle->state = PROC_MGR_STATE_RESET; + + return retval; +} + + +/* + * Function to read from the slave processor's memory. + * + * This function calls into the specific Processor implementation + * to read from the slave processor's memory. It reads from the + * specified address in the processor's address space and copies + * the required number of bytes into the specified buffer. + * It returns the number of bytes actually read in the num_bytes + * parameter. + * Depending on the processor implementation, it may result in + * reading from shared memory or across a peripheral physical + * connectivity. + * The handle specifies the specific Processor instance to be used. + */ +inline int processor_read(void *handle, u32 proc_addr, + u32 *num_bytes, void *buffer) +{ + int retval = 0; + struct processor_object *proc_handle = + (struct processor_object *)handle; + + BUG_ON(handle == NULL); + BUG_ON(proc_addr == 0); + BUG_ON(num_bytes == 0); + BUG_ON(buffer == NULL); + BUG_ON(proc_handle->proc_fxn_table.read == NULL); + + retval = proc_handle->proc_fxn_table.read(handle, proc_addr, + num_bytes, buffer); + return retval; +} + + +/* + * Function to write into the slave processor's memory. + * + * This function calls into the specific Processor implementation + * to write into the slave processor's memory. It writes into the + * specified address in the processor's address space and copies + * the required number of bytes from the specified buffer. + * It returns the number of bytes actually written in the num_bytes + * parameter. + * Depending on the processor implementation, it may result in + * writing into shared memory or across a peripheral physical + * connectivity. + * The handle specifies the specific Processor instance to be used. + */ +inline int processor_write(void *handle, u32 proc_addr, u32 *num_bytes, + void *buffer) +{ + int retval = 0; + struct processor_object *proc_handle = + (struct processor_object *)handle; + BUG_ON(handle == NULL); + BUG_ON(proc_addr == 0); + BUG_ON(num_bytes == 0); + BUG_ON(buffer == NULL); + BUG_ON(proc_handle->proc_fxn_table.write == NULL); + + retval = proc_handle->proc_fxn_table.write(handle, proc_addr, + num_bytes, buffer); + return retval; +} + + +/* + * Function to get the current state of the slave Processor. + * + * This function gets the state of the slave processor as + * maintained on the master Processor state machine. It does not + * go to the slave processor to get its actual state at the time + * when this API is called. + */ +enum proc_mgr_state processor_get_state(void *handle) +{ + struct processor_object *proc_handle = + (struct processor_object *)handle; + + BUG_ON(handle == NULL); + + return proc_handle->state; +} + + +/* + * Function to set the current state of the slave Processor + * to specified value. + * + * This function is used to set the state of the processor to the + * value as specified. This function may be used by external + * entities that affect the state of the slave processor, such as + * PwrMgr, error handler, or ProcMgr. + */ +void processor_set_state(void *handle, enum proc_mgr_state state) +{ + struct processor_object *proc_handle = + (struct processor_object *)handle; + + BUG_ON(handle == NULL); + proc_handle->state = state; +} + + +/* + * Function to perform device-dependent operations. + * + * This function calls into the specific Processor implementation + * to perform device dependent control operations. The control + * operations supported by the device are exposed directly by the + * specific implementation of the Processor interface. These + * commands and their specific argument types are used with this + * function. + */ +inline int processor_control(void *handle, int cmd, void *arg) +{ + int retval = 0; + struct processor_object *proc_handle = + (struct processor_object *)handle; + + BUG_ON(handle == NULL); + BUG_ON(proc_handle->proc_fxn_table.control == NULL); + + retval = proc_handle->proc_fxn_table.control(handle, cmd, arg); + return retval; +} + + +/* + * Function to translate between two types of address spaces. + * + * This function translates addresses between two types of address + * spaces. The destination and source address types are indicated + * through parameters specified in this function. + */ +inline int processor_translate_addr(void *handle, void **dst_addr, + enum proc_mgr_addr_type dst_addr_type, void *src_addr, + enum proc_mgr_addr_type src_addr_type) +{ + int retval = 0; + struct processor_object *proc_handle = + (struct processor_object *)handle; + + BUG_ON(handle == NULL); + BUG_ON(dst_addr == NULL); + BUG_ON(src_addr == NULL); + BUG_ON(dst_addr_type >= PROC_MGR_ADDRTYPE_ENDVALUE); + BUG_ON(src_addr_type >= PROC_MGR_ADDRTYPE_ENDVALUE); + BUG_ON(proc_handle->proc_fxn_table.translateAddr == NULL); + + retval = proc_handle->proc_fxn_table.translateAddr(handle, + dst_addr, dst_addr_type, src_addr, src_addr_type); + return retval; +} + + +/* + * Function to map address to slave address space. + * + * This function maps the provided slave address to a host address + * and returns the mapped address and size. + */ +inline int processor_map(void *handle, u32 proc_addr, u32 size, + u32 *mapped_addr, u32 *mapped_size, u32 map_attribs) +{ + int retval = 0; + struct processor_object *proc_handle = + (struct processor_object *)handle; + + BUG_ON(handle == NULL); + BUG_ON(proc_addr == 0); + BUG_ON(size == 0); + BUG_ON(mapped_addr == NULL); + BUG_ON(mapped_size == NULL); + BUG_ON(proc_handle->proc_fxn_table.map == NULL); + + retval = proc_handle->proc_fxn_table.map(handle, proc_addr, + size, mapped_addr, mapped_size, map_attribs); + return retval; +} + +/* + * Function to unmap address to slave address space. + * + * This function unmap the provided slave address + */ +inline int processor_unmap(void *handle, u32 mapped_addr) +{ + int retval = 0; + struct processor_object *proc_handle = + (struct processor_object *)handle; + + retval = proc_handle->proc_fxn_table.unmap(handle, mapped_addr); + return retval; +} + +/* + * Function that registers for notification when the slave + * processor transitions to any of the states specified. + * + * This function allows the user application to register for + * changes in processor state and take actions accordingly. + + */ +inline int processor_register_notify(void *handle, proc_mgr_callback_fxn fxn, + void *args, enum proc_mgr_state state[]) +{ + int retval = 0; + + BUG_ON(handle == NULL); + BUG_ON(fxn == NULL); + + /* TODO: TBD: To be implemented. */ + return retval; +} + +/* + * Function that returns the proc instance mem info + */ +int processor_get_proc_info(void *handle, struct proc_mgr_proc_info *procinfo) +{ + struct processor_object *proc_handle = + (struct processor_object *)handle; + int retval; + retval = proc_handle->proc_fxn_table.procinfo(proc_handle, procinfo); + return retval; +} + +/* + * Function that returns the address translations + */ +int processor_virt_to_phys(void *handle, u32 da, u32 *mapped_entries, + u32 num_of_entries) +{ + struct processor_object *proc_handle = + (struct processor_object *)handle; + int retval; + retval = proc_handle->proc_fxn_table.virt_to_phys(handle, da, + mapped_entries, num_of_entries); + return retval; +} diff --git a/drivers/dsp/syslink/procmgr/processor.h b/drivers/dsp/syslink/procmgr/processor.h new file mode 100755 index 000000000000..b4f78581839e --- /dev/null +++ b/drivers/dsp/syslink/procmgr/processor.h @@ -0,0 +1,84 @@ +/* + * processor.h + * + * Syslink driver support functions for TI OMAP processors. + * + * Copyright (C) 2009-2010 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef SYSLINK_PROCESSOR_H_ +#define SYSLINK_PROCESSOR_H_ + +#include <linux/types.h> + +/* Module level headers */ +#include "procdefs.h" + +/* =================================== + * APIs + * =================================== + */ +/* Function to attach to the Processor. */ +int processor_attach(void *handle, struct processor_attach_params *params); + +/* Function to detach from the Processor. */ +int processor_detach(void *handle); + +/* Function to start the processor. */ +int processor_start(void *handle, u32 entry_pt, + struct processor_start_params *params); + +/* Function to stop the processor. */ +int processor_stop(void *handle, + struct processor_stop_params *params); + +/* Function to read from the slave processor's memory. */ +int processor_read(void *handle, u32 proc_addr, u32 *num_bytes, void *buffer); + +/* Function to read write into the slave processor's memory. */ +int processor_write(void *handle, u32 proc_addr, u32 *num_bytes, void *buffer); + +/* Function to get the current state of the slave Processor as maintained on + * the master Processor state machine. + */ +enum proc_mgr_state processor_get_state(void *handle); + +/* Function to set the current state of the slave Processor to specified value. + */ +void processor_set_state(void *handle, enum proc_mgr_state state); + +/* Function to perform device-dependent operations. */ +int processor_control(void *handle, int cmd, void *arg); + +/* Function to translate between two types of address spaces. */ +int processor_translate_addr(void *handle, void **dst_addr, + enum proc_mgr_addr_type dst_addr_type, void *src_addr, + enum proc_mgr_addr_type src_addr_type); + +/* Function to map address to slave address space */ +int processor_map(void *handle, u32 proc_addr, u32 size, u32 *mapped_addr, + u32 *mapped_size, u32 map_attribs); +/* Function to unmap address to slave address space */ +int processor_unmap(void *handle, u32 mapped_addr); + +/* Function that registers for notification when the slave processor + * transitions to any of the states specified. + */ +int processor_register_notify(void *handle, proc_mgr_callback_fxn fxn, + void *args, enum proc_mgr_state state[]); + +/* Function that returns the return value of specific processor info + */ +int processor_get_proc_info(void *handle, struct proc_mgr_proc_info *procinfo); + +int processor_virt_to_phys(void *handle, u32 da, u32 *mapped_entries, + u32 num_of_entries); +#endif diff --git a/drivers/dsp/syslink/procmgr/procmgr.c b/drivers/dsp/syslink/procmgr/procmgr.c new file mode 100755 index 000000000000..a7124c5b9028 --- /dev/null +++ b/drivers/dsp/syslink/procmgr/procmgr.c @@ -0,0 +1,957 @@ +/* + * procmgr.c + * + * Syslink driver support functions for TI OMAP processors. + * + * Copyright (C) 2009-2010 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include <linux/types.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/vmalloc.h> +#include <asm/atomic.h> + +/* Module level headers */ +#include <procmgr.h> +#include "procdefs.h" +#include "processor.h" +#include <syslink/atomic_linux.h> + +/* ================================ + * Macros and types + * ================================ + */ +/*! @brief Macro to make a correct module magic number with refCount */ +#define PROCMGR_MAKE_MAGICSTAMP(x) ((PROCMGR_MODULEID << 12u) | (x)) + +/* + * ProcMgr Module state object + */ +struct proc_mgr_module_object { + atomic_t ref_count; + u32 config_size; + /* Size of configuration structure */ + struct proc_mgr_config cfg; + /* ProcMgr configuration structure */ + struct proc_mgr_config def_cfg; + /* Default module configuration */ + struct proc_mgr_params def_inst_params; + /* Default parameters for the ProcMgr instances */ + struct proc_mgr_attach_params def_attach_params; + /* Default parameters for the ProcMgr attach function */ + struct proc_mgr_start_params def_start_params; + /* Default parameters for the ProcMgr start function */ + struct proc_mgr_stop_params def_stop_params; + /* Default parameters for the ProcMgr stop function */ + struct mutex *gate_handle; + /* handle of gate to be used for local thread safety */ + void *proc_handles[MULTIPROC_MAXPROCESSORS]; + /* Array of handles of ProcMgr instances */ +}; + +/* + * ProcMgr instance object + */ +struct proc_mgr_object { + u16 proc_id; + /* Processor ID associated with this ProcMgr. */ + struct processor_object *proc_handle; + /* Processor ID of the processor being represented by this instance. */ + void *loader_handle; + /*!< Handle to the Loader object associated with this ProcMgr. */ + void *pwr_handle; + /*!< Handle to the PwrMgr object associated with this ProcMgr. */ + /*!< Processor ID of the processor being represented by this instance */ + struct proc_mgr_params params; + /* ProcMgr instance params structure */ + struct proc_mgr_attach_params attach_params; + /* ProcMgr attach params structure */ + struct proc_mgr_start_params start_params; + /* ProcMgr start params structure */ + struct proc_mgr_stop_params stop_params; + /* ProcMgr start params structure */ + u32 file_id; + /*!< File ID of the loaded static executable */ + u16 num_mem_entries; + /* Number of valid memory entries */ + struct proc_mgr_addr_info mem_entries[PROCMGR_MAX_MEMORY_REGIONS]; + /* Configuration of memory regions */ +}; + +struct proc_mgr_module_object proc_mgr_obj_state = { + .config_size = sizeof(struct proc_mgr_config), + .def_cfg.gate_handle = NULL, + .gate_handle = NULL, + .def_inst_params.proc_handle = NULL, + .def_attach_params.boot_mode = PROC_MGR_BOOTMODE_BOOT, + .def_start_params.proc_id = 0 +}; + + +/*====================================== + * Function to get the default configuration for the ProcMgr + * module. + * +* This function can be called by the application to get their +* configuration parameter to ProcMgr_setup filled in by the +* ProcMgr module with the default parameters. If the user does +* not wish to make any change in the default parameters, this API +* is not required to be called. + */ +void proc_mgr_get_config(struct proc_mgr_config *cfg) +{ + BUG_ON(cfg == NULL); + memcpy(cfg, &proc_mgr_obj_state.def_cfg, + sizeof(struct proc_mgr_config)); + return; +} +EXPORT_SYMBOL(proc_mgr_get_config); + +/* + * Function to setup the ProcMgr module. + * + *This function sets up the ProcMgr module. This function must + *be called before any other instance-level APIs can be invoked. + *Module-level configuration needs to be provided to this + *function. If the user wishes to change some specific config + *parameters, then ProcMgr_getConfig can be called to get the + *configuration filled with the default values. After this, only + *the required configuration values can be changed. If the user + *does not wish to make any change in the default parameters, the + *application can simply call ProcMgr_setup with NULL parameters. + *The default parameters would get automatically used. + */ +int proc_mgr_setup(struct proc_mgr_config *cfg) +{ + int retval = 0; + struct proc_mgr_config tmp_cfg; + + /* This sets the refCount variable is not initialized, upper 16 bits is + * written with module Id to ensure correctness of refCount variable. + */ + atomic_cmpmask_and_set(&proc_mgr_obj_state.ref_count, + PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(0)); + + if (atomic_inc_return(&proc_mgr_obj_state.ref_count) + != PROCMGR_MAKE_MAGICSTAMP(1u)) + return 0; + if (cfg == NULL) { + proc_mgr_get_config(&tmp_cfg); + cfg = &tmp_cfg; + } + if (cfg->gate_handle != NULL) { + proc_mgr_obj_state.gate_handle = cfg->gate_handle; + } else { + /* User has not provided any gate handle, so create a + *default handle. + */ + proc_mgr_obj_state.gate_handle = kmalloc(sizeof(struct mutex), + GFP_KERNEL); + mutex_init(proc_mgr_obj_state.gate_handle); + } + memcpy(&proc_mgr_obj_state.cfg, cfg, sizeof(struct proc_mgr_config)); + /* Initialize the procHandles array. */ + memset(&proc_mgr_obj_state.proc_handles, 0, + (sizeof(void *) * MULTIPROC_MAXPROCESSORS)); + return retval; +} +EXPORT_SYMBOL(proc_mgr_setup); + +/*================================== + * Function to destroy the ProcMgr module. + * + * Once this function is called, other ProcMgr module APIs, except + * for the proc_mgr_get_config API cannot be called anymore. + */ +int proc_mgr_destroy(void) +{ + int retval = 0; + int i; + + if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count), + PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc_mgr_destroy: Error - module not initialized\n"); + return -EFAULT; + } + if (atomic_dec_return(&proc_mgr_obj_state.ref_count) + == PROCMGR_MAKE_MAGICSTAMP(0)) { + + /* Check if any ProcMgr instances have not been deleted so far + *. If not,delete them + */ + for (i = 0 ; i < MULTIPROC_MAXPROCESSORS; i++) { + if (proc_mgr_obj_state.proc_handles[i] != NULL) + proc_mgr_delete + (&(proc_mgr_obj_state.proc_handles[i])); + } + + mutex_destroy(proc_mgr_obj_state.gate_handle); + kfree(proc_mgr_obj_state.gate_handle); + /* Decrease the refCount */ + atomic_set(&proc_mgr_obj_state.ref_count, + PROCMGR_MAKE_MAGICSTAMP(0)); + } + return retval;; +} +EXPORT_SYMBOL(proc_mgr_destroy); + +/*===================================== + * Function to initialize the parameters for the ProcMgr instance. + * + * This function can be called by the application to get their + * configuration parameter to ProcMgr_create filled in by the + * ProcMgr module with the default parameters. + */ +void proc_mgr_params_init(void *handle, struct proc_mgr_params *params) +{ + struct proc_mgr_object *proc_handle = (struct proc_mgr_object *)handle; + + if (WARN_ON(params == NULL)) + goto exit; + if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count), + PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc_mgr_params_init: Error - module not initialized\n"); + } + if (handle == NULL) { + memcpy(params, &(proc_mgr_obj_state.def_inst_params), + sizeof(struct proc_mgr_params)); + } else { + /* Return updated ProcMgr instance specific parameters. */ + memcpy(params, &(proc_handle->params), + sizeof(struct proc_mgr_params)); + } +exit: + return; +} +EXPORT_SYMBOL(proc_mgr_params_init); + +/*===================================== + * Function to create a ProcMgr object for a specific slave + * processor. + * + * This function creates an instance of the ProcMgr module and + * returns an instance handle, which is used to access the + * specified slave processor. The processor ID specified here is + * the ID of the slave processor as configured with the MultiProc + * module. + * Instance-level configuration needs to be provided to this + * function. If the user wishes to change some specific config + * parameters, then struct proc_mgr_params_init can be called to get the + * configuration filled with the default values. After this, only + * the required configuration values can be changed. For this + * API, the params argument is not optional, since the user needs + * to provide some essential values such as loader, PwrMgr and + * Processor instances to be used with this ProcMgr instance. + */ +void *proc_mgr_create(u16 proc_id, const struct proc_mgr_params *params) +{ + struct proc_mgr_object *handle = NULL; + + BUG_ON(!IS_VALID_PROCID(proc_id)); + BUG_ON(params == NULL); + BUG_ON(params->proc_handle == NULL); + if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count), + PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc_mgr_create: Error - module not initialized\n"); + return NULL; + } + if (proc_mgr_obj_state.proc_handles[proc_id] != NULL) { + handle = proc_mgr_obj_state.proc_handles[proc_id]; + printk(KERN_WARNING "proc_mgr_create:" + "Processor already exists for specified" + "%d proc_id, handle = 0x%x\n", proc_id, (u32)handle); + return handle; + } + WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle)); + handle = (struct proc_mgr_object *) + vmalloc(sizeof(struct proc_mgr_object)); + BUG_ON(handle == NULL); + memset(handle, 0, sizeof(struct proc_mgr_object)); + memcpy(&(handle->params), params, sizeof(struct proc_mgr_params)); + handle->proc_id = proc_id; + handle->proc_handle = params->proc_handle; + handle->loader_handle = params->loader_handle; + handle->pwr_handle = params->pwr_handle; + proc_mgr_obj_state.proc_handles[proc_id] = handle; + mutex_unlock(proc_mgr_obj_state.gate_handle); + return handle; +} +EXPORT_SYMBOL(proc_mgr_create); + +/*=================================== + * Function to delete a ProcMgr object for a specific slave + * processor. + * + * Once this function is called, other ProcMgr instance level APIs + * that require the instance handle cannot be called. + * + */ +int +proc_mgr_delete(void **handle_ptr) +{ + int retval = 0; + struct proc_mgr_object *handle; + + BUG_ON(handle_ptr == NULL); + if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count), + PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc_mgr_delete: Error - module not initialized\n"); + return -EFAULT; + } + + handle = (struct proc_mgr_object *)(*handle_ptr); + WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle)); + proc_mgr_obj_state.proc_handles[handle->proc_id] = NULL; + vfree(handle); + *handle_ptr = NULL; + mutex_unlock(proc_mgr_obj_state.gate_handle); + return retval; +} +EXPORT_SYMBOL(proc_mgr_delete); + +/*====================================== + * Function to open a handle to an existing ProcMgr object handling + * the proc_id. + * + * This function returns a handle to an existing ProcMgr instance + * created for this proc_id. It enables other entities to access + * and use this ProcMgr instance. + */ +int proc_mgr_open(void **handle_ptr, u16 proc_id) +{ + int retval = 0; + + BUG_ON(handle_ptr == NULL); + BUG_ON(!IS_VALID_PROCID(proc_id)); + if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count), + PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc_mgr_open: Error - module not initialized\n"); + return -EFAULT; + } + + WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle)); + *handle_ptr = proc_mgr_obj_state.proc_handles[proc_id]; + mutex_unlock(proc_mgr_obj_state.gate_handle); + return retval; +} +EXPORT_SYMBOL(proc_mgr_open); + +/*===================================== + * Function to close this handle to the ProcMgr instance. + * + * This function closes the handle to the ProcMgr instance + * obtained through proc_mgr_open call made earlier. + */ +int proc_mgr_close(void *handle) +{ + int retval = 0; + + BUG_ON(handle == NULL); + if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count), + PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc_mgr_close: Error - module not initialized\n"); + return -EFAULT; + } + /* Nothing to be done for closing the handle. */ + return retval; +} +EXPORT_SYMBOL(proc_mgr_close); + +/*======================================== + * Function to initialize the parameters for the ProcMgr attach + * function. + * + * This function can be called by the application to get their + * configuration parameter to proc_mgr_attach filled in by the + * ProcMgr module with the default parameters. If the user does + * not wish to make any change in the default parameters, this API + * is not required to be called. + */ +void proc_mgr_get_attach_params(void *handle, + struct proc_mgr_attach_params *params) +{ + struct proc_mgr_object *proc_mgr_handle = + (struct proc_mgr_object *)handle; + BUG_ON(params == NULL); + if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count), + PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc_mgr_get_attach_params:" + "Error - module not initialized\n"); + } + if (handle == NULL) { + memcpy(params, &(proc_mgr_obj_state.def_attach_params), + sizeof(struct proc_mgr_attach_params)); + } else { + /* Return updated ProcMgr instance specific parameters. */ + memcpy(params, &(proc_mgr_handle->attach_params), + sizeof(struct proc_mgr_attach_params)); + } + return; +} +EXPORT_SYMBOL(proc_mgr_get_attach_params); + +/* + * Function to attach the client to the specified slave and also + * initialize the slave (if required). + * + * This function attaches to an instance of the ProcMgr module and + * performs any hardware initialization required to power up the + * slave device. This function also performs the required state + * transitions for this ProcMgr instance to ensure that the local + * object representing the slave device correctly indicates the + * state of the slave device. Depending on the slave boot mode + * being used, the slave may be powered up, in reset, or even + * running state. + * Configuration parameters need to be provided to this + * function. If the user wishes to change some specific config + * parameters, then proc_mgr_get_attach_params can be called to get + * the configuration filled with the default values. After this, + * only the required configuration values can be changed. If the + * user does not wish to make any change in the default parameters, + * the application can simply call proc_mgr_attach with NULL + * parameters. + * The default parameters would get automatically used. + */ +int proc_mgr_attach(void *handle, struct proc_mgr_attach_params *params) +{ + int retval = 0; + struct proc_mgr_object *proc_mgr_handle = + (struct proc_mgr_object *)handle; + struct proc_mgr_attach_params tmp_params; + struct processor_attach_params proc_attach_params; + + if (params == NULL) { + proc_mgr_get_attach_params(handle, &tmp_params); + params = &tmp_params; + } + if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count), + PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc_mgr_attach:" + "Error - module not initialized\n"); + return -EFAULT; + } + if (WARN_ON(handle == NULL)) { + retval = -EFAULT; + goto exit; + } + if (WARN_ON(params->boot_mode == PROC_MGR_BOOTMODE_ENDVALUE)) { + retval = -EINVAL; + goto exit; + } + WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle)); + /* Copy the user provided values into the instance object. */ + memcpy(&(proc_mgr_handle->attach_params), params, + sizeof(struct proc_mgr_attach_params)); + proc_attach_params.params = params; + proc_attach_params.num_mem_entries = 0; + /* Attach to the specified Processor instance. */ + retval = processor_attach(proc_mgr_handle->proc_handle, + &proc_attach_params); + proc_mgr_handle->num_mem_entries = proc_attach_params.num_mem_entries; + printk(KERN_INFO "proc_mgr_attach:proc_mgr_handle->num_mem_entries = %d\n", + proc_mgr_handle->num_mem_entries); + /* Store memory information in local object.*/ + memcpy(&(proc_mgr_handle->mem_entries), + &(proc_attach_params.mem_entries), + sizeof(proc_mgr_handle->mem_entries)); + mutex_unlock(proc_mgr_obj_state.gate_handle); +exit: + return retval; +} +EXPORT_SYMBOL(proc_mgr_attach); + +/*=================================== + * Function to detach the client from the specified slave and also + * finalze the slave (if required). + * + * This function detaches from an instance of the ProcMgr module + * and performs any hardware finalization required to power down + * the slave device. This function also performs the required state + * transitions for this ProcMgr instance to ensure that the local + * object representing the slave device correctly indicates the + * state of the slave device. Depending on the slave boot mode + * being used, the slave may be powered down, in reset, or left in + * its original state. +*/ +int proc_mgr_detach(void *handle) +{ + int retval = 0; + struct proc_mgr_object *proc_mgr_handle = + (struct proc_mgr_object *)handle; + if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count), + PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc_mgr_detach:" + "Error - module not initialized\n"); + return -EFAULT; + } + BUG_ON(handle == NULL); + WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle)); + /* Detach from the Processor. */ + retval = processor_detach(proc_mgr_handle->proc_handle); + mutex_unlock(proc_mgr_obj_state.gate_handle); + return retval; +} +EXPORT_SYMBOL(proc_mgr_detach); + +/*=============================== + * Function to initialize the parameters for the ProcMgr start + * function. + * + * This function can be called by the application to get their + * configuration parameter to proc_mgr_start filled in by the + * ProcMgr module with the default parameters. If the user does + * not wish to make any change in the default parameters, this API + * is not required to be called. + * + */ +void proc_mgr_get_start_params(void *handle, + struct proc_mgr_start_params *params) +{ + struct proc_mgr_object *proc_mgr_handle = + (struct proc_mgr_object *)handle; + if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count), + PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc_mgr_get_start_params:" + "Error - module not initialized\n"); + } + BUG_ON(params == NULL); + + if (handle == NULL) { + memcpy(params, &(proc_mgr_obj_state.def_start_params), + sizeof(struct proc_mgr_start_params)); + } else { + /* Return updated ProcMgr instance specific parameters. */ + memcpy(params, &(proc_mgr_handle->start_params), + sizeof(struct proc_mgr_start_params)); + } + return; +} +EXPORT_SYMBOL(proc_mgr_get_start_params); + +/*========================================== + * Function to start the slave processor running. + * + * Function to start execution of the loaded code on the slave + * from the entry point specified in the slave executable loaded + * earlier by call to proc_mgr_load (). + * After successful completion of this function, the ProcMgr + * instance is expected to be in the proc_mgr_State_Running state. + */ +int proc_mgr_start(void *handle, u32 entry_point, + struct proc_mgr_start_params *params) +{ + int retval = 0; + struct proc_mgr_object *proc_mgr_handle = + (struct proc_mgr_object *)handle; + struct proc_mgr_start_params tmp_params; + struct processor_start_params proc_params; + + if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count), + PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc_mgr_start:" + "Error - module not initialized\n"); + return -EFAULT; + } + BUG_ON(handle == NULL); + + if (params == NULL) { + proc_mgr_get_start_params(handle, &tmp_params); + params = &tmp_params; + } + WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle)); + memcpy(&(proc_mgr_handle->start_params), params, + sizeof(struct proc_mgr_start_params)); + /* Start the slave processor running. */ + proc_params.params = params; + retval = processor_start(proc_mgr_handle->proc_handle, + entry_point, &proc_params); + + mutex_unlock(proc_mgr_obj_state.gate_handle); + return retval;; +} +EXPORT_SYMBOL(proc_mgr_start); + +/*======================================== + * Function to stop the slave processor. + * + * Function to stop execution of the slave processor. + * Depending on the boot mode, after successful completion of this + * function, the ProcMgr instance may be in the proc_mgr_State_Reset + * state. + * + */ +int proc_mgr_stop(void *handle, struct proc_mgr_stop_params *params) +{ + int retval = 0; + struct proc_mgr_object *proc_mgr_handle = + (struct proc_mgr_object *)handle; + struct processor_stop_params proc_params; + if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count), + PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc_mgr_stop:" + "Error - module not initialized\n"); + return -EFAULT; + } + BUG_ON(handle == NULL); + WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle)); + proc_params.params = params; + retval = processor_stop(proc_mgr_handle->proc_handle, + &proc_params); + mutex_unlock(proc_mgr_obj_state.gate_handle); + return retval;; +} +EXPORT_SYMBOL(proc_mgr_stop); + +/*=================================== + * Function to get the current state of the slave Processor. + * + * This function gets the state of the slave processor as + * maintained on the master Processor state machine. It does not + * go to the slave processor to get its actual state at the time + * when this API is called. + * + */ +enum proc_mgr_state proc_mgr_get_state(void *handle) +{ + struct proc_mgr_object *proc_mgr_handle = + (struct proc_mgr_object *)handle; + enum proc_mgr_state state = PROC_MGR_STATE_UNKNOWN; + if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count), + PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc_mgr_get_state:" + "Error - module not initialized\n"); + return -EFAULT; + } + BUG_ON(handle == NULL); + + WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle)); + state = processor_get_state(proc_mgr_handle->proc_handle); + mutex_unlock(proc_mgr_obj_state.gate_handle); + return state; +} +EXPORT_SYMBOL(proc_mgr_get_state); + +/*================================================== + * Function to read from the slave processor's memory. + * + * This function reads from the specified address in the + * processor's address space and copies the required number of + * bytes into the specified buffer. + * It returns the number of bytes actually read in thenum_bytes + * parameter. + */ +int proc_mgr_read(void *handle, u32 proc_addr, u32 *num_bytes, void *buffer) +{ + int retval = 0; + struct proc_mgr_object *proc_mgr_handle = + (struct proc_mgr_object *)handle; + if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count), + PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc_mgr_read:" + "Error - module not initialized\n"); + return -EFAULT; + } + BUG_ON(handle == NULL); + BUG_ON(proc_addr == 0); + BUG_ON(num_bytes == NULL); + BUG_ON(buffer == NULL); + + WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle)); + + retval = processor_read(proc_mgr_handle->proc_handle, proc_addr, + num_bytes, buffer); + WARN_ON(retval < 0); + mutex_unlock(proc_mgr_obj_state.gate_handle); + return retval; +} +EXPORT_SYMBOL(proc_mgr_read); + +/* + * Function to write into the slave processor's memory. + * + * This function writes into the specified address in the + * processor's address space and copies the required number of + * bytes from the specified buffer. + * It returns the number of bytes actually written in thenum_bytes + * parameter. + */ +int proc_mgr_write(void *handle, u32 proc_addr, u32 *num_bytes, void *buffer) +{ + int retval = 0; + struct proc_mgr_object *proc_mgr_handle = + (struct proc_mgr_object *)handle; + if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count), + PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc_mgr_write:" + "Error - module not initialized\n"); + return -EFAULT; + } + BUG_ON(proc_addr == 0); + BUG_ON(num_bytes == NULL); + BUG_ON(buffer == NULL); + + WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle)); + retval = processor_write(proc_mgr_handle->proc_handle, proc_addr, + num_bytes, buffer); + WARN_ON(retval < 0); + mutex_unlock(proc_mgr_obj_state.gate_handle); + return retval;; +} +EXPORT_SYMBOL(proc_mgr_write); + + +/*=================================== + * Function to perform device-dependent operations. + * + * This function performs control operations supported by the + * as exposed directly by the specific implementation of the + * Processor interface. These commands and their specific argument + * types are used with this function. + */ +int proc_mgr_control(void *handle, int cmd, void *arg) +{ + int retval = 0; + struct proc_mgr_object *proc_mgr_handle + = (struct proc_mgr_object *)handle; + if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count), + PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc_mgr_control:" + "Error - module not initialized\n"); + return -EFAULT; + } + BUG_ON(handle == NULL); + WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle)); + /* Perform device-dependent control operation. */ + retval = processor_control(proc_mgr_handle->proc_handle, cmd, arg); + WARN_ON(retval < 0); + mutex_unlock(proc_mgr_obj_state.gate_handle); + return retval;; +} +EXPORT_SYMBOL(proc_mgr_control); + +/*======================================== + * Function to translate between two types of address spaces. + * + * This function translates addresses between two types of address + * spaces. The destination and source address types are indicated + * through parameters specified in this function. + */ +int proc_mgr_translate_addr(void *handle, void **dst_addr, + enum proc_mgr_addr_type dst_addr_type, void *src_addr, + enum proc_mgr_addr_type src_addr_type) +{ + int retval = 0; + struct proc_mgr_object *proc_mgr_handle = + (struct proc_mgr_object *)handle; + if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count), + PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc_mgr_translate_addr:" + "Error - module not initialized\n"); + return -EFAULT; + } + BUG_ON(dst_addr == NULL); + BUG_ON(handle == NULL); + BUG_ON(dst_addr_type > PROC_MGR_ADDRTYPE_ENDVALUE); + BUG_ON(src_addr == NULL); + BUG_ON(src_addr_type > PROC_MGR_ADDRTYPE_ENDVALUE); + + WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle)); + /* Translate the address. */ + retval = processor_translate_addr(proc_mgr_handle->proc_handle, + dst_addr, dst_addr_type, src_addr, src_addr_type); + WARN_ON(retval < 0); + mutex_unlock(proc_mgr_obj_state.gate_handle); + return retval;; +} +EXPORT_SYMBOL(proc_mgr_translate_addr); + +/*============================================ + * Function to map address to slave address space. + * + * This function maps the provided slave address to a host address + * and returns the mapped address and size. + * + */ +int proc_mgr_map(void *handle, u32 proc_addr, u32 size, u32 *mapped_addr, + u32 *mapped_size, u32 map_attribs) +{ + int retval = 0; + struct proc_mgr_object *proc_mgr_handle = + (struct proc_mgr_object *)handle; + if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count), + PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc_mgr_map:" + "Error - module not initialized\n"); + return -EFAULT; + } + BUG_ON(handle == NULL); + BUG_ON(proc_addr == 0); + BUG_ON(mapped_addr == NULL); + BUG_ON(mapped_size == NULL); + + WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle)); + + /* Map to host address space. */ + retval = processor_map(proc_mgr_handle->proc_handle, proc_addr, + size, mapped_addr, mapped_size, map_attribs); + WARN_ON(retval < 0); + mutex_unlock(proc_mgr_obj_state.gate_handle); + return retval;; +} +EXPORT_SYMBOL(proc_mgr_map); + +/*============================================ + * Function to unmap address to slave address space. + * + * This function unmaps the provided slave address to a host address + * + */ +int proc_mgr_unmap(void *handle, u32 mapped_addr) +{ + int retval = 0; + struct proc_mgr_object *proc_mgr_handle = + (struct proc_mgr_object *)handle; + if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count), + PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc_mgr_unmap:" + "Error - module not initialized\n"); + return -EFAULT; + } + WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle)); + + /* Map to host address space. */ + retval = processor_unmap(proc_mgr_handle->proc_handle, mapped_addr); + WARN_ON(retval < 0); + mutex_unlock(proc_mgr_obj_state.gate_handle); + return retval;; +} +EXPORT_SYMBOL(proc_mgr_unmap); + +/*================================= + * Function that registers for notification when the slave + * processor transitions to any of the states specified. + * + * This function allows the user application to register for + * changes in processor state and take actions accordingly. + * + */ +int proc_mgr_register_notify(void *handle, proc_mgr_callback_fxn fxn, + void *args, enum proc_mgr_state state[]) +{ + int retval = 0; + struct proc_mgr_object *proc_mgr_handle + = (struct proc_mgr_object *)handle; + if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count), + PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc_mgr_register_notify:" + "Error - module not initialized\n"); + return -EFAULT; + } + BUG_ON(handle == NULL); + BUG_ON(fxn == NULL); + WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle)); + retval = processor_register_notify(proc_mgr_handle->proc_handle, fxn, + args, state); + WARN_ON(retval < 0); + mutex_unlock(proc_mgr_obj_state.gate_handle); + return retval; +} +EXPORT_SYMBOL(proc_mgr_register_notify); + +/* + * Function that returns information about the characteristics of + * the slave processor. + */ +int proc_mgr_get_proc_info(void *handle, struct proc_mgr_proc_info *proc_info) +{ + struct proc_mgr_object *proc_mgr_handle = + (struct proc_mgr_object *)handle; + struct processor_object *proc_handle; + + struct proc_mgr_proc_info proc_info_test; + + if (atomic_cmpmask_and_lt(&(proc_mgr_obj_state.ref_count), + PROCMGR_MAKE_MAGICSTAMP(0), PROCMGR_MAKE_MAGICSTAMP(1)) + == true) { + printk(KERN_ERR "proc_mgr_get_proc_info:" + "Error - module not initialized\n"); + return -EFAULT; + } + if (WARN_ON(handle == NULL)) + goto error_exit; + if (WARN_ON(proc_info == NULL)) + goto error_exit; + proc_handle = proc_mgr_handle->proc_handle; + if (WARN_ON(proc_handle == NULL)) + goto error_exit; + + WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle)); + + processor_get_proc_info(proc_handle, &proc_info_test); + /* Return bootMode information. */ + proc_info->boot_mode = proc_mgr_handle->attach_params.boot_mode; + /* Return memory information. */ + proc_info->num_mem_entries = proc_mgr_handle->num_mem_entries; + memcpy(&(proc_info->mem_entries), + &(proc_mgr_handle->mem_entries), + sizeof(proc_mgr_handle->mem_entries)); + mutex_unlock(proc_mgr_obj_state.gate_handle); + return 0; +error_exit: + return -EFAULT; +} +EXPORT_SYMBOL(proc_mgr_get_proc_info); + +/*============================================ + * Function to get virtual to physical address translations + * + * This function retrieves physical entries + * + */ +int proc_mgr_virt_to_phys(void *handle, u32 da, u32 *mapped_entries, + u32 num_of_entries) +{ + int retval = 0; + struct proc_mgr_object *proc_mgr_handle = + (struct proc_mgr_object *)handle; + + WARN_ON(mutex_lock_interruptible(proc_mgr_obj_state.gate_handle)); + + /* Map to host address space. */ + retval = processor_virt_to_phys(proc_mgr_handle->proc_handle, da, + mapped_entries, num_of_entries); + WARN_ON(retval < 0); + mutex_unlock(proc_mgr_obj_state.gate_handle); + return retval;; +} +EXPORT_SYMBOL(proc_mgr_virt_to_phys); + diff --git a/drivers/dsp/syslink/procmgr/procmgr_drv.c b/drivers/dsp/syslink/procmgr/procmgr_drv.c new file mode 100755 index 000000000000..59de4eed1058 --- /dev/null +++ b/drivers/dsp/syslink/procmgr/procmgr_drv.c @@ -0,0 +1,758 @@ +/* + * procmgr_drv.c + * + * Syslink driver support functions for TI OMAP processors. + * + * Copyright (C) 2009-2010 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + + +#include <generated/autoconf.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/cdev.h> +#include <linux/device.h> +#include <linux/fs.h> +#include <linux/mm.h> +#include <linux/uaccess.h> +#include <linux/platform_device.h> + +/* Module headers */ +#include <procmgr.h> +#include "procmgr_drvdefs.h" + +#define PROCMGR_NAME "syslink-procmgr" + +static char *driver_name = PROCMGR_NAME; + +static s32 driver_major; + +static s32 driver_minor; + +struct procmgr_dev { + struct cdev cdev; +}; + +struct platform_device *omap_proc_dev; +static struct platform_device *procmgr_pdev; +static struct procmgr_dev *procmgr_device; + +static struct class *proc_mgr_class; + + +/** ==================================== + * Forward declarations of internal functions + * ==================================== + */ +/* Linux driver function to open the driver object. */ +static int proc_mgr_drv_open(struct inode *inode, struct file *filp); + +/* Linux driver function to close the driver object. */ +static int proc_mgr_drv_release(struct inode *inode, struct file *filp); + +/* Linux driver function to invoke the APIs through ioctl. */ +static int proc_mgr_drv_ioctl(struct inode *inode, + struct file *filp, + unsigned int cmd, + unsigned long args); + +/* Linux driver function to map memory regions to user space. */ +static int proc_mgr_drv_mmap(struct file *filp, struct vm_area_struct *vma); + +/* Module initialization function for Linux driver. */ +static int __init proc_mgr_drv_initialize_module(void); + +/* Module finalization function for Linux driver. */ +static void __exit proc_mgr_drv_finalize_module(void); + +/* Platform driver probe function */ +static int __devinit proc_mgr_probe(struct platform_device *pdev); + +/* Platform driver remove function */ +static int __devexit proc_mgr_remove(struct platform_device *pdev); + +/* + * name DriverOps + * + * desc Function to invoke the APIs through ioctl + * + */ +static const struct file_operations procmgr_fops = { + .open = proc_mgr_drv_open, + .ioctl = proc_mgr_drv_ioctl, + .release = proc_mgr_drv_release, + .mmap = proc_mgr_drv_mmap, +} ; + +/* Imtiaz changed places */ +static struct platform_driver procmgr_driver = { + .driver = { + .owner = THIS_MODULE, + .name = PROCMGR_NAME, + }, + .probe = proc_mgr_probe, + .remove = __devexit_p(proc_mgr_remove), + .shutdown = NULL, + .suspend = NULL, + .resume = NULL, +}; + +/* +* brief Linux specific function to open the driver. + */ +static int proc_mgr_drv_open(struct inode *inode, struct file *filp) +{ + return 0; +} + +/* +* brief Linux driver function to close the driver object. + */ +static int proc_mgr_drv_release(struct inode *inode, struct file *filp) +{ + return 0; +} + +/* +* Linux driver function to invoke the APIs through ioctl. + */ +static int proc_mgr_drv_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long args) +{ + int retval = 0; + struct proc_mgr_cmd_args *cmd_args = (struct proc_mgr_cmd_args *)args; + struct proc_mgr_cmd_args command_args; + + switch (cmd) { + case CMD_PROCMGR_GETCONFIG: + { + struct proc_mgr_cmd_args_get_config *src_args = + (struct proc_mgr_cmd_args_get_config *)args; + struct proc_mgr_config cfg; + + /* copy_from_user is not needed for proc_mgr_get_config, + * since the user's config is not used. + */ + proc_mgr_get_config(&cfg); + + retval = copy_to_user((void *)(src_args->cfg), + (const void *)&cfg, + sizeof(struct proc_mgr_config)); + + WARN_ON(retval < 0); + } + break; + + case CMD_PROCMGR_SETUP: + { + struct proc_mgr_cmd_args_setup *src_args = + (struct proc_mgr_cmd_args_setup *)args; + struct proc_mgr_config cfg; + + retval = copy_from_user((void *)&cfg, + (const void *)(src_args->cfg), + sizeof(struct proc_mgr_config)); + + /* This check is needed at run-time also since it + * depends on run environment. + * It must not be optimized out. + */ + if (WARN_ON(retval != 0)) + goto func_exit; + + retval = proc_mgr_setup(&cfg); + } + break; + + case CMD_PROCMGR_DESTROY: + { + retval = proc_mgr_destroy(); + WARN_ON(retval < 0); + } + break; + + case CMD_PROCMGR_PARAMS_INIT: + { + struct proc_mgr_cmd_args_params_init src_args; + struct proc_mgr_params params; + + /* Copy the full args from user-side. */ + retval = copy_from_user((void *)&src_args, + (const void *)(args), + sizeof(struct proc_mgr_cmd_args_params_init)); + + if (WARN_ON(retval != 0)) + goto func_exit; + + proc_mgr_params_init(src_args.handle, ¶ms); + + /* Copy only the params to user-side */ + retval = copy_to_user((void *)(src_args.params), + (const void *)¶ms, + sizeof(struct proc_mgr_params)); + WARN_ON(retval < 0); + } + break; + + case CMD_PROCMGR_CREATE: + { + struct proc_mgr_cmd_args_create src_args; + + /* Copy the full args from user-side. */ + retval = copy_from_user((void *)&src_args, + (const void *)(args), + sizeof(struct proc_mgr_cmd_args_create)); + + src_args.handle = proc_mgr_create(src_args.proc_id, + &(src_args.params)); + if (src_args.handle == NULL) { + retval = -EFAULT; + goto func_exit; + } + retval = copy_to_user((void *)(args), + (const void *)&src_args, + sizeof(struct proc_mgr_cmd_args_create)); + WARN_ON(retval < 0); + } + break; + + case CMD_PROCMGR_DELETE: + { + struct proc_mgr_cmd_args_delete src_args; + + /* Copy the full args from user-side. */ + retval = copy_from_user((void *)&src_args, + (const void *)(args), + sizeof(struct proc_mgr_cmd_args_delete)); + if (WARN_ON(retval != 0)) + goto func_exit; + + retval = proc_mgr_delete(&(src_args.handle)); + } + break; + + case CMD_PROCMGR_OPEN: + { + struct proc_mgr_cmd_args_open src_args; + + /* Copy the full args from user-side. */ + retval = copy_from_user((void *)&src_args, + (const void *)(args), + sizeof(struct proc_mgr_cmd_args_open)); + + if (WARN_ON(retval != 0)) + goto func_exit; + retval = proc_mgr_open(&(src_args.handle), + src_args.proc_id); + if (WARN_ON(retval < 0)) + goto func_exit; + retval = proc_mgr_get_proc_info(src_args.handle, + &(src_args.proc_info)); + if (WARN_ON(retval < 0)) + goto func_exit; + retval = copy_to_user((void *)(args), (const void *)&src_args, + sizeof(struct proc_mgr_cmd_args_open)); + WARN_ON(retval); + } + break; + + case CMD_PROCMGR_CLOSE: + { + struct proc_mgr_cmd_args_close src_args; + + /* Copy the full args from user-side. */ + retval = copy_from_user((void *)&src_args, + (const void *)(args), + sizeof(struct proc_mgr_cmd_args_close)); + if (WARN_ON(retval != 0)) + goto func_exit; + retval = proc_mgr_close(&(src_args.handle)); + } + break; + + case CMD_PROCMGR_GETATTACHPARAMS: + { + struct proc_mgr_cmd_args_get_attach_params src_args; + struct proc_mgr_attach_params params; + + /* Copy the full args from user-side. */ + retval = copy_from_user((void *)&src_args, + (const void *)(args), + sizeof(struct proc_mgr_cmd_args_get_attach_params)); + if (WARN_ON(retval != 0)) + goto func_exit; + proc_mgr_get_attach_params(src_args.handle, ¶ms); + retval = copy_to_user((void *)(src_args.params), + (const void *)¶ms, + sizeof(struct proc_mgr_attach_params)); + WARN_ON(retval); + } + break; + + case CMD_PROCMGR_ATTACH: + { + struct proc_mgr_cmd_args_attach src_args; + struct proc_mgr_attach_params params; + + /* Copy the full args from user-side. */ + retval = copy_from_user((void *)&src_args, + (const void *)(args), + sizeof(struct proc_mgr_cmd_args_attach)); + if (WARN_ON(retval != 0)) + goto func_exit; + /* Copy params from user-side. */ + retval = copy_from_user((void *)¶ms, + (const void *)(src_args.params), + sizeof(struct proc_mgr_attach_params)); + retval = proc_mgr_attach(src_args.handle, ¶ms); + if (WARN_ON(retval < 0)) + goto func_exit; + /* Get memory information. */ + retval = proc_mgr_get_proc_info(src_args.handle, + &(src_args.proc_info)); + if (WARN_ON(retval < 0)) + goto func_exit; + retval = copy_to_user((void *)(args), + (const void *)&src_args, + sizeof(struct proc_mgr_cmd_args_attach)); + } + break; + + case CMD_PROCMGR_DETACH: + { + struct proc_mgr_cmd_args_detach src_args; + + /* Copy the full args from user-side. */ + retval = copy_from_user((void *)&src_args, + (const void *)(args), + sizeof(struct proc_mgr_cmd_args_detach)); + if (WARN_ON(retval != 0)) + goto func_exit; + retval = proc_mgr_detach(src_args.handle); + if (WARN_ON(retval < 0)) + goto func_exit; + } + break; + + case CMD_PROCMGR_GETSTARTPARAMS: + { + struct proc_mgr_cmd_args_get_start_params src_args; + struct proc_mgr_start_params params; + + /* Copy the full args from user-side. */ + retval = copy_from_user((void *)&src_args, + (const void *)(args), + sizeof(struct proc_mgr_cmd_args_get_start_params)); + if (WARN_ON(retval != 0)) + goto func_exit; + proc_mgr_get_start_params(src_args.handle, ¶ms); + if (WARN_ON(retval < 0)) + goto func_exit; + retval = copy_to_user((void *)(src_args.params), + (const void *)¶ms, + sizeof(struct proc_mgr_start_params)); + WARN_ON(retval); + } + break; + + case CMD_PROCMGR_START: + { + struct proc_mgr_cmd_args_start src_args; + struct proc_mgr_start_params params; + + /* Copy the full args from user-side. */ + retval = copy_from_user((void *)&src_args, + (const void *)(args), + sizeof(struct proc_mgr_cmd_args_start)); + /* Copy params from user-side. */ + retval = copy_from_user((void *)¶ms, + (const void *)(src_args.params), + sizeof(struct proc_mgr_start_params)); + if (WARN_ON(retval != 0)) + goto func_exit; + retval = proc_mgr_start(src_args.handle, + src_args.entry_point, ¶ms); + + WARN_ON(retval); + } + break; + + case CMD_PROCMGR_STOP: + { + struct proc_mgr_cmd_args_stop src_args; + + struct proc_mgr_stop_params params; + /* Copy the full args from user-side. */ + retval = copy_from_user((void *)&src_args, + (const void *)(args), + sizeof(struct proc_mgr_cmd_args_stop)); + /* Copy params from user-side. */ + retval = copy_from_user((void *)¶ms, + (const void *)(src_args.params), + sizeof(struct proc_mgr_stop_params)); + + if (WARN_ON(retval != 0)) + goto func_exit; + retval = proc_mgr_stop(src_args.handle, ¶ms); + WARN_ON(retval < 0); + } + break; + + case CMD_PROCMGR_GETSTATE: + { + struct proc_mgr_cmd_args_get_state src_args; + enum proc_mgr_state procmgrstate; + + /* Copy the full args from user-side. */ + retval = copy_from_user((void *)&src_args, + (const void *)(args), + sizeof(struct proc_mgr_cmd_args_get_state)); + if (WARN_ON(retval != 0)) + goto func_exit; + procmgrstate = proc_mgr_get_state(src_args.handle); + src_args.proc_mgr_state = procmgrstate; + retval = copy_to_user((void *)(args), (const void *)&src_args, + sizeof(struct proc_mgr_cmd_args_get_state)); + WARN_ON(retval < 0); + } + break; + + case CMD_PROCMGR_READ: + { + struct proc_mgr_cmd_args_read src_args; + + /* Copy the full args from user-side. */ + retval = copy_from_user((void *)&src_args, + (const void *)(args), + sizeof(struct proc_mgr_cmd_args_read)); + if (WARN_ON(retval != 0)) + goto func_exit; + retval = proc_mgr_read(src_args.handle, + src_args.proc_addr, &(src_args.num_bytes), + src_args.buffer); + if (WARN_ON(retval < 0)) + goto func_exit; + retval = copy_to_user((void *)(args), + (const void *)&src_args, + sizeof(struct proc_mgr_cmd_args_read)); + WARN_ON(retval < 0); + } + break; + + case CMD_PROCMGR_WRITE: + { + struct proc_mgr_cmd_args_write src_args; + + /* Copy the full args from user-side. */ + retval = copy_from_user((void *)&src_args, + (const void *)(args), + sizeof(struct proc_mgr_cmd_args_write)); + if (WARN_ON(retval != 0)) + goto func_exit; + retval = proc_mgr_write(src_args.handle, + src_args.proc_addr, &(src_args.num_bytes), + src_args.buffer); + if (WARN_ON(retval < 0)) + goto func_exit; + retval = copy_to_user((void *)(args), + (const void *)&src_args, + sizeof(struct proc_mgr_cmd_args_write)); + WARN_ON(retval < 0); + } + break; + + case CMD_PROCMGR_CONTROL: + { + struct proc_mgr_cmd_args_control src_args; + + /* Copy the full args from user-side. */ + retval = copy_from_user((void *)&src_args, + (const void *)(args), + sizeof(struct proc_mgr_cmd_args_control)); + if (WARN_ON(retval != 0)) + goto func_exit; + retval = proc_mgr_control(src_args.handle, + src_args.cmd, src_args.arg); + WARN_ON(retval < 0); + } + break; + + case CMD_PROCMGR_TRANSLATEADDR: + { + struct proc_mgr_cmd_args_translate_addr src_args; + + /* Copy the full args from user-side. */ + retval = copy_from_user((void *)&src_args, + (const void *)(args), + sizeof(struct proc_mgr_cmd_args_translate_addr)); + if (WARN_ON(retval != 0)) + goto func_exit; + retval = proc_mgr_translate_addr(src_args.handle, + &(src_args.dst_addr), src_args.dst_addr_type, + src_args.src_addr, src_args.src_addr_type); + if (WARN_ON(retval < 0)) + goto func_exit; + retval = copy_to_user((void *)(args), + (const void *)&src_args, sizeof + (struct proc_mgr_cmd_args_translate_addr)); + WARN_ON(retval < 0); + } + break; + + case CMD_PROCMGR_MAP: + { + struct proc_mgr_cmd_args_map src_args; + + /* Copy the full args from user-side. */ + retval = copy_from_user((void *)&src_args, + (const void *)(args), + sizeof(struct proc_mgr_cmd_args_map)); + if (WARN_ON(retval != 0)) + goto func_exit; + retval = proc_mgr_map(src_args.handle, + src_args.proc_addr, src_args.size, + &(src_args.mapped_addr), + &(src_args.mapped_size), + src_args.map_attribs); + if (WARN_ON(retval < 0)) + goto func_exit; + retval = copy_to_user((void *)(args), + (const void *)&src_args, + sizeof(struct proc_mgr_cmd_args_map)); + WARN_ON(retval < 0); + } + break; + + case CMD_PROCMGR_UNMAP: + { + struct proc_mgr_cmd_args_unmap src_args; + + /* Copy the full args from user-side. */ + retval = copy_from_user((void *)&src_args, + (const void *)(args), + sizeof(struct proc_mgr_cmd_args_unmap)); + if (WARN_ON(retval != 0)) + goto func_exit; + retval = proc_mgr_unmap(src_args.handle, + (src_args.mapped_addr)); + WARN_ON(retval < 0); + } + + case CMD_PROCMGR_REGISTERNOTIFY: + { + struct proc_mgr_cmd_args_register_notify src_args; + + /* Copy the full args from user-side. */ + retval = copy_from_user((void *)&src_args, + (const void *)(args), + sizeof(struct proc_mgr_cmd_args_register_notify)); + if (WARN_ON(retval != 0)) + goto func_exit; + retval = proc_mgr_register_notify(src_args.handle, + src_args.callback_fxn, + src_args.args, src_args.state); + WARN_ON(retval < 0); + } + break; + + case CMD_PROCMGR_GETPROCINFO: + { + struct proc_mgr_cmd_args_get_proc_info src_args; + struct proc_mgr_proc_info proc_info; + + /* Copy the full args from user-side. */ + retval = copy_from_user((void *)&src_args, + (const void *)(args), + sizeof(struct proc_mgr_cmd_args_get_proc_info)); + if (WARN_ON(retval != 0)) + goto func_exit; + retval = proc_mgr_get_proc_info + (src_args.handle, &proc_info); + if (WARN_ON(retval < 0)) + goto func_exit; + retval = copy_to_user((void *)(src_args.proc_info), + (const void *) &proc_info, + sizeof(struct proc_mgr_proc_info)); + WARN_ON(retval < 0); + } + break; + + case CMD_PROCMGR_GETVIRTTOPHYS: + { + struct proc_mgr_cmd_args_get_virt_to_phys src_args; + + retval = copy_from_user((void *)&src_args, + (const void *)(args), + sizeof(struct proc_mgr_cmd_args_get_virt_to_phys)); + retval = proc_mgr_virt_to_phys(src_args.handle, + src_args.da, (src_args.mem_entries), + src_args.num_of_entries); + if (WARN_ON(retval < 0)) + goto func_exit; + retval = copy_to_user((void *)(args), (const void *)&src_args, + sizeof(struct proc_mgr_cmd_args_get_virt_to_phys)); + WARN_ON(retval < 0); + } + break; + + default: + printk(KERN_ERR"PROC_MGR_DRV: WRONG IOCTL !!!!\n"); + BUG_ON(1); + break; + } +func_exit: + /* Set the retval and copy the common args to user-side. */ + command_args.api_status = retval; + retval = copy_to_user((void *)cmd_args, + (const void *)&command_args, sizeof(struct proc_mgr_cmd_args)); + + WARN_ON(retval < 0); + return retval; +} + + +/* + Driver function to map memory regions to user space. + */ +static int proc_mgr_drv_mmap(struct file *filp, struct vm_area_struct *vma) +{ + vma->vm_page_prot = pgprot_dmacoherent(vma->vm_page_prot); + vma->vm_flags |= VM_RESERVED; + + if (remap_pfn_range(vma, + vma->vm_start, + vma->vm_pgoff, + vma->vm_end - vma->vm_start, + vma->vm_page_prot)) { + return -EAGAIN; + } + return 0; +} + +static int __devinit proc_mgr_probe(struct platform_device *pdev) +{ + dev_t dev = 0 ; + int retval = -ENOMEM; + + /* Display the version info and created date/time */ + dev_dbg(&omap_proc_dev->dev, "Entering %s function\n\n", __func__); + + if (driver_major) { + dev = MKDEV(driver_major, driver_minor); + retval = register_chrdev_region(dev, 1, driver_name); + } else { + retval = alloc_chrdev_region(&dev, driver_minor, 1, + driver_name); + driver_major = MAJOR(dev); + } + + procmgr_device = kmalloc(sizeof(struct procmgr_dev), GFP_KERNEL); + if (!procmgr_device) { + retval = -ENOMEM; + unregister_chrdev_region(dev, 1); + goto exit; + } + memset(procmgr_device, 0, sizeof(struct procmgr_dev)); + cdev_init(&procmgr_device->cdev, &procmgr_fops); + procmgr_device->cdev.owner = THIS_MODULE; + procmgr_device->cdev.ops = &procmgr_fops; + + retval = cdev_add(&procmgr_device->cdev, dev, 1); + + if (retval) { + printk(KERN_ERR "Failed to add the syslink procmgr device \n"); + goto exit; + } + + /* udev support */ + proc_mgr_class = class_create(THIS_MODULE, "syslink-procmgr"); + + if (IS_ERR(proc_mgr_class)) { + printk(KERN_ERR "Error creating bridge class \n"); + goto exit; + } + device_create(proc_mgr_class, NULL, MKDEV(driver_major, driver_minor), + NULL, PROCMGR_NAME); + +exit: + dev_dbg(&omap_proc_dev->dev, "Leaving %s function\n\n", __func__); + return retval; +} + + +static int __devexit proc_mgr_remove(struct platform_device *pdev) +{ + dev_t devno = 0; + + dev_dbg(&omap_proc_dev->dev, "Entering %s function\n", __func__); + devno = MKDEV(driver_major, driver_minor); + if (procmgr_device) { + cdev_del(&procmgr_device->cdev); + kfree(procmgr_device); + } + unregister_chrdev_region(devno, 1); + if (proc_mgr_class) { + /* remove the device from sysfs */ + device_destroy(proc_mgr_class, MKDEV(driver_major, + driver_minor)); + class_destroy(proc_mgr_class); + } + dev_dbg(&omap_proc_dev->dev, "Entering %s function\n", __func__); + return 0; +} + +/* +* Module initialization function for Linux driver. + */ +static int __init proc_mgr_drv_initialize_module(void) +{ + int retval = -ENOMEM; + + procmgr_pdev = platform_device_alloc(PROCMGR_NAME, -1); + if (!procmgr_pdev) { + printk(KERN_ERR "%s:device allocation failed\n", __func__); + return -ENOMEM; + } + retval = platform_device_add(procmgr_pdev); + if (retval) + goto err_out; + + /*Saving the context for future use*/ + omap_proc_dev = procmgr_pdev; + + retval = platform_driver_register(&procmgr_driver); + if (!retval) + return retval; +err_out: + platform_device_put(procmgr_pdev); + return retval; +} + +/* +* driver function to finalize the driver module. + */ +static void __exit proc_mgr_drv_finalize_module(void) +{ + + dev_dbg(&omap_proc_dev->dev, "Entering %s function\n", __func__); + platform_device_unregister(procmgr_pdev); + platform_driver_unregister(&procmgr_driver); + dev_dbg(&omap_proc_dev->dev, "Leaving %s function\n", __func__); +} + +/* +* brief Macro calls that indicate initialization and finalization functions + * to the kernel. + */ +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Mugdha Kamoolkar"); +module_init(proc_mgr_drv_initialize_module); +module_exit(proc_mgr_drv_finalize_module); diff --git a/drivers/dsp/syslink/procmgr/procmgr_drvdefs.h b/drivers/dsp/syslink/procmgr/procmgr_drvdefs.h new file mode 100755 index 000000000000..2be14bf7a20e --- /dev/null +++ b/drivers/dsp/syslink/procmgr/procmgr_drvdefs.h @@ -0,0 +1,541 @@ +/* + * procmgr_drvdefs.h + * + * Syslink driver support functions for TI OMAP processors. + * + * Copyright (C) 2009-2010 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + + +#ifndef SYSLINK_PROCMGR_DRVDEFS_H +#define SYSLINK_PROCMGR_DRVDEFS_H + +#include <linux/types.h> + +/* Module headers */ +#include <procmgr.h> + + +/* ================================= + * Macros and types + * ================================= + */ +/* + * Base structure for ProcMgr command args. This needs to be the first + * field in all command args structures. + */ +struct proc_mgr_cmd_args { + int api_status; + /*Status of the API being called. */ +}; + +/* -------------------------------------- + * IOCTL command IDs for ProcMgr + * --------------------------------------- + */ +/* + * Base command ID for ProcMgr + */ +#define PROCMGR_BASE_CMD 0x100 + +/* + * Command for ProcMgr_getConfig + */ +#define CMD_PROCMGR_GETCONFIG (PROCMGR_BASE_CMD + 1) + +/* + * Command for ProcMgr_setup + */ +#define CMD_PROCMGR_SETUP (PROCMGR_BASE_CMD + 2) + +/* + * Command for ProcMgr_setup + */ +#define CMD_PROCMGR_DESTROY (PROCMGR_BASE_CMD + 3) + +/* + * Command for ProcMgr_destroy + */ +#define CMD_PROCMGR_PARAMS_INIT (PROCMGR_BASE_CMD + 4) + +/* + * Command for ProcMgr_create + */ +#define CMD_PROCMGR_CREATE (PROCMGR_BASE_CMD + 5) + +/* + * Command for ProcMgr_delete + */ +#define CMD_PROCMGR_DELETE (PROCMGR_BASE_CMD + 6) + +/* + * Command for ProcMgr_open + */ +#define CMD_PROCMGR_OPEN (PROCMGR_BASE_CMD + 7) + +/* + * Command for ProcMgr_close + */ +#define CMD_PROCMGR_CLOSE (PROCMGR_BASE_CMD + 8) + +/* + * Command for ProcMgr_getAttachParams + */ +#define CMD_PROCMGR_GETATTACHPARAMS (PROCMGR_BASE_CMD + 9) + +/* + * Command for ProcMgr_attach + */ +#define CMD_PROCMGR_ATTACH (PROCMGR_BASE_CMD + 10) + +/* + * Command for ProcMgr_detach + */ +#define CMD_PROCMGR_DETACH (PROCMGR_BASE_CMD + 11) + +/* + * Command for ProcMgr_load + */ +#define CMD_PROCMGR_LOAD (PROCMGR_BASE_CMD + 12) + +/* + * Command for ProcMgr_unload + */ +#define CMD_PROCMGR_UNLOAD (PROCMGR_BASE_CMD + 13) + +/* + * Command for ProcMgr_getStartParams + */ +#define CMD_PROCMGR_GETSTARTPARAMS (PROCMGR_BASE_CMD + 14) + +/* + * Command for ProcMgr_start + */ +#define CMD_PROCMGR_START (PROCMGR_BASE_CMD + 15) + +/* + * Command for ProcMgr_stop + */ +#define CMD_PROCMGR_STOP (PROCMGR_BASE_CMD + 16) + +/* + * Command for ProcMgr_getState + */ +#define CMD_PROCMGR_GETSTATE (PROCMGR_BASE_CMD + 17) + +/* + * Command for ProcMgr_read + */ +#define CMD_PROCMGR_READ (PROCMGR_BASE_CMD + 18) + +/* + * Command for ProcMgr_write + */ +#define CMD_PROCMGR_WRITE (PROCMGR_BASE_CMD + 19) + +/* + * Command for ProcMgr_control + */ +#define CMD_PROCMGR_CONTROL (PROCMGR_BASE_CMD + 20) + +/* + * Command for ProcMgr_translateAddr + */ +#define CMD_PROCMGR_TRANSLATEADDR (PROCMGR_BASE_CMD + 22) + +/* + * Command for ProcMgr_getSymbolAddress + */ +#define CMD_PROCMGR_GETSYMBOLADDRESS (PROCMGR_BASE_CMD + 23) + +/* + * Command for ProcMgr_map + */ +#define CMD_PROCMGR_MAP (PROCMGR_BASE_CMD + 24) + +/* + * Command for ProcMgr_registerNotify + */ +#define CMD_PROCMGR_REGISTERNOTIFY (PROCMGR_BASE_CMD + 25) + +/* + * Command for ProcMgr_getProcInfo + */ +#define CMD_PROCMGR_GETPROCINFO (PROCMGR_BASE_CMD + 26) + +/* + * Command for ProcMgr_unmap + */ +#define CMD_PROCMGR_UNMAP (PROCMGR_BASE_CMD + 27) + +/* + * Command for ProcMgr_getVirtToPhysPages + */ +#define CMD_PROCMGR_GETVIRTTOPHYS (PROCMGR_BASE_CMD + 28) + + + + +/* ---------------------------------------------------------------------------- + * Command arguments for ProcMgr + * ---------------------------------------------------------------------------- + */ +/* + * Command arguments for ProcMgr_getConfig + */ +struct proc_mgr_cmd_args_get_config { + struct proc_mgr_cmd_args commond_args; + /*Common command args */ + struct proc_mgr_config *cfg; + /*Pointer to the ProcMgr module configuration structure in which the + default config is to be returned. */ +}; + +/* + * Command arguments for ProcMgr_setup + */ +struct proc_mgr_cmd_args_setup { + struct proc_mgr_cmd_args commond_args; + /*Common command args */ + struct proc_mgr_config *cfg; + /*Optional ProcMgr module configuration. If provided as NULL, default + configuration is used. */ +}; + +/* + * Command arguments for ProcMgr_destroy + */ +struct proc_mgr_cmd_args_destroy { + struct proc_mgr_cmd_args commond_args; + /*Common command args */ +}; + +/* + * Command arguments for ProcMgr_Params_init + */ +struct proc_mgr_cmd_args_params_init { + struct proc_mgr_cmd_args commond_args; + /*Common command args */ + void *handle; + /*Handle to the ProcMgr object. */ + struct proc_mgr_params *params; + /*Pointer to the ProcMgr instance params structure in which the default + params is to be returned. */ +}; + +/* + * Command arguments for ProcMgr_create + */ +struct proc_mgr_cmd_args_create { + struct proc_mgr_cmd_args commond_args; + /*Common command args */ + u16 proc_id; + /*Processor ID represented by this ProcMgr instance */ + struct proc_mgr_params params; + /*ProcMgr instance configuration parameters. */ + void *handle; + /*Handle to the created ProcMgr object */ +}; + +/* + * Command arguments for ProcMgr_delete + */ +struct proc_mgr_cmd_args_delete{ + struct proc_mgr_cmd_args commond_args; + /*Common command args */ + void *handle; + /*Pointer to Handle to the ProcMgr object */ +}; + +/* + * Command arguments for ProcMgr_open + */ +struct proc_mgr_cmd_args_open { + struct proc_mgr_cmd_args commond_args; + /*Common command args */ + u16 proc_id; + /*Processor ID represented by this ProcMgr instance */ + void *handle; + /*Handle to the opened ProcMgr object. */ + struct proc_mgr_proc_info proc_info; + /*Processor information. */ +}; + +/* + * Command arguments for ProcMgr_close + */ +struct proc_mgr_cmd_args_close{ + struct proc_mgr_cmd_args commond_args; + /*Common command args */ + void *handle; + /*Handle to the ProcMgr object */ + struct proc_mgr_proc_info proc_info; + /*Processor information. */ +}; + +/* + * Command arguments for ProcMgr_getAttachParams + */ +struct proc_mgr_cmd_args_get_attach_params{ + struct proc_mgr_cmd_args commond_args; + /*Common command args */ + void *handle; + /*Handle to the ProcMgr object. */ + struct proc_mgr_attach_params *params; + /*Pointer to the ProcMgr attach params structure in which the default + params is to be returned. */ +}; + +/* + * Command arguments for ProcMgr_attach + */ +struct proc_mgr_cmd_args_attach { + struct proc_mgr_cmd_args commond_args; + /*Common command args */ + void *handle; + /*Handle to the ProcMgr object. */ + struct proc_mgr_attach_params *params; + /*Optional ProcMgr attach parameters. */ + struct proc_mgr_proc_info proc_info; + /*Processor information. */ +}; + +/* + * Command arguments for ProcMgr_detach + */ +struct proc_mgr_cmd_args_detach { + struct proc_mgr_cmd_args commond_args; + /*Common command args */ + void *handle; + /*Handle to the ProcMgr object */ + struct proc_mgr_proc_info proc_info; + /*Processor information. */ +}; + + +/* + * Command arguments for ProcMgr_getStartParams + */ +struct proc_mgr_cmd_args_get_start_params { + struct proc_mgr_cmd_args commond_args; + /*Common command args */ + void *handle; + /*Entry point for the image*/ + u32 entry_point; + /*Handle to the ProcMgr object */ + struct proc_mgr_start_params *params; + /*Pointer to the ProcMgr start params structure in which the default + params is to be returned. */ +}; + +/* + * Command arguments for ProcMgr_start + */ +struct proc_mgr_cmd_args_start { + struct proc_mgr_cmd_args commond_args; + /*Common command args */ + void *handle; + /*Entry point for the image*/ + u32 entry_point; + /*Handle to the ProcMgr object */ + struct proc_mgr_start_params *params; + /*Optional ProcMgr start parameters. */ +}; + +/* + * Command arguments for ProcMgr_stop + */ +struct proc_mgr_cmd_args_stop { + struct proc_mgr_cmd_args commond_args; + /*Common command args */ + void *handle; + /*Handle to the ProcMgr object */ + struct proc_mgr_stop_params *params; + /*Optional ProcMgr stop parameters. */ +}; + +/* + * Command arguments for ProcMgr_getState + */ +struct proc_mgr_cmd_args_get_state { + struct proc_mgr_cmd_args commond_args; + /*Common command args */ + void *handle; + /* Handle to the ProcMgr object */ + enum proc_mgr_state proc_mgr_state; + /*Current state of the ProcMgr object. */ +}; + +/* + * Command arguments for ProcMgr_read + */ +struct proc_mgr_cmd_args_read { + struct proc_mgr_cmd_args commond_args; + /*Common command args */ + void *handle; + /*Handle to the ProcMgr object */ + u32 proc_addr; + /*Address in space processor's address space of the memory region to + read from. */ + u32 num_bytes; + /*IN/OUT parameter. As an IN-parameter, it takes in the number of bytes + to be read. When the function returns, this parameter contains the + number of bytes actually read. */ + void *buffer; + /*User-provided buffer in which the slave processor's memory contents + are to be copied. */ +}; + +/* + * Command arguments for ProcMgr_write + */ +struct proc_mgr_cmd_args_write { + struct proc_mgr_cmd_args commond_args; + /*Common command args */ + void *handle; + /*Handle to the ProcMgr object */ + u32 proc_addr; + /*Address in space processor's address space of the memory region to + write into. */ + u32 num_bytes; + /*IN/OUT parameter. As an IN-parameter, it takes in the number of bytes + to be written. When the function returns, this parameter contains the + number of bytes actually written. */ + void *buffer; + /*User-provided buffer from which the data is to be written into the + slave processor's memory. */ +}; + +/* + * Command arguments for ProcMgr_control + */ +struct proc_mgr_cmd_args_control { + struct proc_mgr_cmd_args commond_args; + /*Common command args */ + void *handle; + /*Handle to the ProcMgr object */ + int cmd; + /*Device specific processor command */ + void *arg; + /*Arguments specific to the type of command. */ +}; + +/* + * Command arguments for ProcMgr_translateAddr + */ +struct proc_mgr_cmd_args_translate_addr { + struct proc_mgr_cmd_args commond_args; + /*Common command args */ + void *handle; + /*Handle to the ProcMgr object */ + void *dst_addr; + /*Return parameter: Pointer to receive the translated address. */ + enum proc_mgr_addr_type dst_addr_type; + /*Destination address type requested */ + void *src_addr; + /*Source address in the source address space */ + enum proc_mgr_addr_type src_addr_type; + /*Source address type */ +}; + +/* + * Command arguments for ProcMgr_getSymbolAddress + */ +struct proc_mgr_cmd_args_get_symbol_address { + struct proc_mgr_cmd_args commond_args; + /*Common command args */ + void *handle; + /*Handle to the ProcMgr object */ + u32 file_id; + /*ID of the file received from the load function */ + char *symbol_name; + /*Name of the symbol */ + u32 sym_value; + /*Return parameter: Symbol address */ +}; + +/* + * Command arguments for ProcMgr_map + */ +struct proc_mgr_cmd_args_map { + struct proc_mgr_cmd_args commond_args; + /*Common command args */ + void *handle; + /*Handle to the ProcMgr object */ + u32 proc_addr; + /*Slave address to be mapped */ + u32 size; + /*Size (in bytes) of region to be mapped */ + u32 mapped_addr; + /*Return parameter: Mapped address in host address space */ + u32 mapped_size; + /*Return parameter: Mapped size */ + u32 map_attribs; + /*Type of mapping. */ +}; + +/* + * Command arguments for ProcMgr_map + */ +struct proc_mgr_cmd_args_unmap { + struct proc_mgr_cmd_args commond_args; + /*Common command args */ + void *handle; + /*Handle to the ProcMgr object */ + u32 mapped_addr; + /* Mapped address in host address space */ +}; + +/* + * Command arguments for ProcMgr_registerNotify + */ +struct proc_mgr_cmd_args_register_notify { + struct proc_mgr_cmd_args commond_args; + /*Common command args */ + void *handle; + /*Handle to the ProcMgr object */ + int (*callback_fxn)(u16 proc_id, void *handle, + enum proc_mgr_state from_state, enum proc_mgr_state to_state); + /*Handling function to be registered. */ + void *args; + /*Optional arguments associated with the handler fxn. */ + enum proc_mgr_state state[]; + /*Array of target states for which registration is required. */ +}; + +/* + * Command arguments for ProcMgr_getProcInfo + */ +struct proc_mgr_cmd_args_get_proc_info { + struct proc_mgr_cmd_args commond_args; + /*Common command args */ + void *handle; + /*Handle to the ProcMgr object */ + struct proc_mgr_proc_info *proc_info; + /*Pointer to the ProcInfo object to be populated. */ +}; + +/* + * Command arguments for ProcMgr_virtToPhys + */ +struct proc_mgr_cmd_args_get_virt_to_phys { + struct proc_mgr_cmd_args commond_args; + /*Common command args */ + void *handle; + u32 da; + /* mem entries buffer */ + u32 *mem_entries; + /* number of entries */ + u32 num_of_entries; +}; + +#endif + diff --git a/drivers/media/video/dmm/dmm.h b/drivers/media/video/dmm/dmm.h index 2ad6c325ee5b..a3adddbf9fd6 100644 --- a/drivers/media/video/dmm/dmm.h +++ b/drivers/media/video/dmm/dmm.h @@ -113,4 +113,16 @@ u32 dmm_get_page(void); */ void dmm_free_page(u32 page_addr); +/** + * Request a set of pages from the DMM free page stack. + * @return a pointer to a list of physical page addresses. + */ +u32 *dmm_get_pages(s32 n); + +/** + * Return a set of used pages to the DMM free page stack. + * @param list a pointer to a list of physical page addresses. + */ +void dmm_free_pages(u32 *list); + #endif diff --git a/drivers/media/video/dmm/dmm_mem.c b/drivers/media/video/dmm/dmm_mem.c index 23ea2018ac48..f91c561b4a99 100644 --- a/drivers/media/video/dmm/dmm_mem.c +++ b/drivers/media/video/dmm/dmm_mem.c @@ -31,6 +31,17 @@ #define DMM_PAGE 0x1000 /** + * Used to keep track of mem per + * dmm_get_pages call. + */ +struct fast { + struct list_head list; + u32 *mem; + u32 *pa; + u32 num; +}; + +/** * Used to keep track of the page struct ptrs * and physical addresses of each page. */ @@ -40,10 +51,32 @@ struct mem { u32 pa; }; +static struct fast fast_list; static struct mem free_list; static struct mem used_list; static struct mutex mtx; +static void dmm_free_fast_list(struct fast *fast) +{ + struct list_head *pos = NULL, *q = NULL; + struct fast *f = NULL; + s32 i = 0; + + mutex_lock(&mtx); + list_for_each_safe(pos, q, &fast->list) { + f = list_entry(pos, struct fast, list); + for (i = 0; i < f->num; i++) { + list_add(&((struct mem *)f->mem[i])->list, + &free_list.list); + } + kfree(f->pa); + kfree(f->mem); + list_del(pos); + kfree(f); + } + mutex_unlock(&mtx); +} + static u32 fill_page_stack(struct mem *mem) { s32 i = 0; @@ -112,7 +145,10 @@ u32 dmm_get_page(void) } mutex_unlock(&mtx); - return m->pa; + if (m != NULL) + return m->pa; + else + return 0x0; } EXPORT_SYMBOL(dmm_get_page); @@ -139,6 +175,7 @@ u32 dmm_init_mem() { INIT_LIST_HEAD(&free_list.list); INIT_LIST_HEAD(&used_list.list); + INIT_LIST_HEAD(&fast_list.list); mutex_init(&mtx); if (list_empty_careful(&free_list.list)) @@ -150,8 +187,121 @@ u32 dmm_init_mem() void dmm_release_mem() { + dmm_free_fast_list(&fast_list); dmm_free_page_stack(&free_list); dmm_free_page_stack(&used_list); mutex_destroy(&mtx); } +u32 *dmm_get_pages(s32 n) +{ + s32 i = 0; + struct list_head *pos = NULL, *q = NULL; + struct mem *m = NULL; + struct fast *f = NULL; + + if (n <= 0 || n > 0x8000) + return NULL; + + if (list_empty_careful(&free_list.list)) + if (fill_page_stack(&free_list)) + return NULL; + + f = kmalloc(sizeof(struct fast), GFP_KERNEL); + if (!f) + return NULL; + memset(f, 0x0, sizeof(struct fast)); + + /* array of mem struct pointers */ + f->mem = kmalloc(n * 4, GFP_KERNEL); + if (!f->mem) { + kfree(f); return NULL; + } + memset(f->mem, 0x0, n * 4); + + /* array of physical addresses */ + f->pa = kmalloc(n * 4, GFP_KERNEL); + if (!f->pa) { + kfree(f->mem); kfree(f); return NULL; + } + memset(f->pa, 0x0, n * 4); + + /* + * store the number of mem structs so that we + * know how many to free later. + */ + f->num = n; + + for (i = 0; i < n; i++) { + if (list_empty_careful(&free_list.list)) + if (fill_page_stack(&free_list)) + goto cleanup; + + mutex_lock(&mtx); + pos = NULL; + q = NULL; + + /* + * remove one mem struct from the free list and + * add the address to the fast struct mem array + */ + list_for_each_safe(pos, q, &free_list.list) { + m = list_entry(pos, struct mem, list); + f->mem[i] = (u32)m; + list_del(pos); + break; + } + mutex_unlock(&mtx); + + if (m != NULL) + f->pa[i] = m->pa; + else + goto cleanup; + } + + mutex_lock(&mtx); + list_add(&f->list, &fast_list.list); + mutex_unlock(&mtx); + + if (f != NULL) + return f->pa; +cleanup: + for (; i > 0; i--) { + mutex_lock(&mtx); + list_add(&((struct mem *)f->mem[i - 1])->list, &free_list.list); + mutex_unlock(&mtx); + } + kfree(f->pa); + kfree(f->mem); + kfree(f); + return NULL; +} +EXPORT_SYMBOL(dmm_get_pages); + +void dmm_free_pages(u32 *list) +{ + struct list_head *pos = NULL, *q = NULL; + struct fast *f = NULL; + s32 i = 0; + + mutex_lock(&mtx); + pos = NULL; + q = NULL; + list_for_each_safe(pos, q, &fast_list.list) { + f = list_entry(pos, struct fast, list); + if (f->pa[0] == list[0]) { + for (i = 0; i < f->num; i++) { + list_add(&((struct mem *)f->mem[i])->list, + &free_list.list); + } + list_del(pos); + kfree(f->pa); + kfree(f->mem); + kfree(f); + break; + } + } + mutex_unlock(&mtx); +} +EXPORT_SYMBOL(dmm_free_pages); + diff --git a/drivers/media/video/tiler/Makefile b/drivers/media/video/tiler/Makefile index 66971c6cfcc7..e6dbe24ce9d3 100644 --- a/drivers/media/video/tiler/Makefile +++ b/drivers/media/video/tiler/Makefile @@ -1,3 +1,4 @@ +obj-$(CONFIG_TILER_OMAP) += tcm/ obj-$(CONFIG_TILER_OMAP) += tiler_omap.o -tiler_omap-objs = tiler.o dmm_2d_alloc.o tiler_pack.o tiler_rot.o +tiler_omap-objs = tiler.o tiler_pack.o tiler_rot.o diff --git a/drivers/media/video/tiler/dmm_2d_alloc.c b/drivers/media/video/tiler/dmm_2d_alloc.c deleted file mode 100755 index 583aea2514e5..000000000000 --- a/drivers/media/video/tiler/dmm_2d_alloc.c +++ /dev/null @@ -1,1717 +0,0 @@ -/* - * dmm_2d_alloc.c - * - * DMM driver support functions for TI OMAP processors. - * - * Copyright (C) 2009-2010 Texas Instruments, Inc. - * - * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include <linux/module.h> -#include <linux/mm.h> -#include <linux/mmzone.h> -#include <linux/io.h> -#include <linux/dma-mapping.h> -#include <linux/hardirq.h> -#include <linux/mutex.h> - -#include "dmm_2d_alloc.h" -#include "tiler_def.h" -#include "../dmm/dmm.h" - -#define __USE_DMM_MEM__ -#define DMM_ASSERT_BREAK printk(KERN_ERR "DMM Assert(Fail)\n"); while (1); - -/* ========================================================================== */ -/** - * overlapping_test() - * - * @brief Performs an area overlap test for errors. Debug only. - * - * @param tlrCtx - struct dmmTILERContCtxT* - [in] TILER context structure. - * - * @return MSP_BOOL: MSP_TRUE if overlapping is detected. - * - * @pre There is no pre conditions. - * - * @post There is no post conditions. - * - * @see - */ -/* ========================================================================== */ -void overlapping_test(struct dmmTILERContCtxT *dmmTilerCtx) -{ - struct dmmTILERContPageLstT *itr1 = dmmTilerCtx->usdArList; - - while (itr1 != NULL) { - struct dmmTILERContPageAreaT *chkPage = &(itr1->pgAr); - struct dmmTILERContPageLstT *itr2 = dmmTilerCtx->usdArList; - - while (itr2 != NULL) { - if (chkPage != &(itr2->pgAr)) { - if ((itr2->pgAr.x0 <= chkPage->x1 && - itr2->pgAr.x1 >= chkPage->x0) && - (itr2->pgAr.y0 <= chkPage->y1 && - itr2->pgAr.y1 >= chkPage->y0)) { - DMM_ASSERT_BREAK - } - } - - itr2 = itr2->pgArNext; - } - - itr1 = itr1->pgArNext; - } - return; -} - -/* ========================================================================== */ -/** - * point_free_test() - * - * @brief Tests if a page on a given coordinate is unoccupied. - * - * @param tlrCtx - struct dmmTILERContCtxT* - [in] TILER context structure. - * - * @param X - signed long - [in] X page coordinate. - * - * @param Y - signed long - [in] Y page coordinate. - * - * @param areaHit - struct dmmTILERContPageAreaT** - [out] Returns a pointer to - * the allocated area that was hit by the specified coordinate. - * - * @return MSP_BOOL: MSP_TRUE if the selected coordinate page is unoccupied. - * - * @pre There is no pre conditions. - * - * @post There is no post conditions. - * - * @see - */ -/* ========================================================================== */ -inline enum MSP_BOOL point_free_test(struct dmmTILERContCtxT *tlrCtx, - signed long X, - signed long Y, - struct dmmTILERContPageAreaT **areaHit) -{ - struct dmmTILERContPageLstT *arUsd = tlrCtx->usdArList; - *areaHit = NULL; - while (arUsd != NULL) { - if (arUsd->pgAr.x0 <= X && arUsd->pgAr.x1 >= X && - arUsd->pgAr.y0 <= Y && arUsd->pgAr.y1 >= Y) { - *areaHit = &(arUsd->pgAr); - return MSP_FALSE; - } - - arUsd = arUsd->pgArNext; - } - return MSP_TRUE; -} - -/* ========================================================================== */ -/** - * pointAreaHit() - * - * @brief Tests if a given coordinate is within a given area. - * - * @param X - signed long - [in] X page coordinate. - * - * @param Y - signed long - [in] Y page coordinate. - * - * @param areaHit - struct dmmTILERContPageAreaT* - [in] Given area to check if - * contains the given coordinate point. - * - * @return MSP_BOOL: MSP_TRUE if the given coordinate is contained in the - * given area. - * - * @pre There is no pre conditions. - * - * @post There is no post conditions. - * - * @see - */ -/* ========================================================================== */ -/* -inline enum MSP_BOOL pointAreaHit(signed long X, - signed long Y, - struct dmmTILERContPageAreaT* area) -{ - if ((area->x0 <= X && area->x1 >= X) && (area->y0 <= Y && area->y1 >= Y)) - { - return MSP_TRUE; - } - return MSP_FALSE; -} -*/ - -/* ========================================================================== */ -/** - * zone_area_overlap() - * - * @brief Tests if two areas overlap. - * - * @param X - signed long - [in] X page coordinate. - * - * @param Y - signed long - [in] Y page coordinate. - * - * @param SizeX - signed long - [in] Page width. - * - * @param SizeY - signed long - [in] Page height. - * - * @param areaHit - struct dmmTILERContPageAreaT* - [in] Given area to check. - * - * @return MSP_BOOL: MSP_TRUE if the given areas overlap. - * - * @pre There is no pre conditions. - * - * @post There is no post conditions. - * - * @see - */ -/* ========================================================================== */ -inline enum MSP_BOOL zone_area_overlap(signed long X, - signed long Y, - signed long SizeX, - signed long SizeY, - struct dmmTILERContPageAreaT *area) -{ - if ((area->x0 <= X + SizeX && area->x1 >= X) && - (area->y0 <= Y + SizeY && area->y1 >= Y)) { - return MSP_TRUE; - } - - return MSP_FALSE; -} - -/* ========================================================================== */ -/** - * lineAreaHit() - * - * @brief Tests if a page line overlaps with an area. Either width or height - * can be used to perform checks in both coordinates. - * - * @param X - signed long - [in] X page coordinate. - * - * @param Y - signed long - [in] Y page coordinate. - * - * @param SizeX - signed long - [in] Page width. - * - * @param SizeY - signed long - [in] Page height. - * - * @param areaHit - struct dmmTILERContPageAreaT* - [in] Given area to check. - * - * @return MSP_BOOL: MSP_TRUE if the given areas overlap. - * - * @pre There is no pre conditions. - * - * @post There is no post conditions. - * - * @see - */ -/* ========================================================================== */ -/* -inline enum MSP_BOOL lineAreaHit(signed long X, - signed long Y, - signed long SizeX, - signed long SizeY, - struct dmmTILERContPageAreaT* area) -{ - if (((area->x0 <= X && area->x1 >= X) || - (area->x0 <= X + SizeX && area->x1 >= X + SizeX)) && - ((area->y0 <= Y && area->y1 >= Y) || - (area->y0 <= Y + SizeY && area->y1 >= Y + SizeY))) - { - return MSP_TRUE; - } - - return MSP_FALSE; -} -*/ - -/* ========================================================================== */ -/** - * expand_right() - * - * @brief Finds all of the unocupied pages ("expansion") along the specified - * coordinate line (1D check). - * - * @param tlrCtx - struct dmmTILERContCtxT* - [in] TILER context structure. - * - * @param X - signed long - [in] X page coordinate. - * - * @param Y - signed long - [in] Y page coordinate. - * - * @param areaHit - struct dmmTILERContPageAreaT** - [out] Returns a pointer to - * the allocated area that was hit during the "expansion" along the specified - * coordinate line. - * - * @return signed long the calculated coordinate point. - * - * @pre There is no pre conditions. - * - * @post There is no post conditions. - * - * @see - */ -/* ========================================================================== */ -inline signed long expand_right(struct dmmTILERContCtxT *tlrCtx, - signed long X, - signed long Y, - struct dmmTILERContPageAreaT **areaHit) -{ - *areaHit = NULL; - while (X < tlrCtx->contSizeX) { - if (MSP_FALSE == point_free_test(tlrCtx, X, Y, areaHit)) - return X - 1; - X++; - } - - return X - 1; -} - -/* ========================================================================== */ -/** - * expand_left() - * - * @brief Finds all of the unocupied pages ("expansion") along the specified - * coordinate line (1D check). - * - * @param tlrCtx - struct dmmTILERContCtxT* - [in] TILER context structure. - * - * @param X - signed long - [in] X page coordinate. - * - * @param Y - signed long - [in] Y page coordinate. - * - * @param areaHit - struct dmmTILERContPageAreaT** - [out] Returns a pointer to - * the allocated area that was hit during the "expansion" along the specified - * coordinate line. - * - * @return signed long the calculated coordinate point. - * - * @pre There is no pre conditions. - * - * @post There is no post conditions. - * - * @see - */ -/* ========================================================================== */ -inline signed long expand_left(struct dmmTILERContCtxT *tlrCtx, - signed long X, - signed long Y, - struct dmmTILERContPageAreaT **areaHit) -{ - *areaHit = NULL; - while (X >= 0) { - if (MSP_FALSE == point_free_test(tlrCtx, X, Y, areaHit)) - return X + 1; - X--; - } - - return X + 1; -} - -/* ========================================================================== */ -/** - * expand_bottom() - * - * @brief Finds all of the unocupied pages ("expansion") along the specified - * coordinate line (1D check). - * - * @param tlrCtx - struct dmmTILERContCtxT* - [in] TILER context structure. - * - * @param X - signed long - [in] X page coordinate. - * - * @param Y - signed long - [in] Y page coordinate. - * - * @param areaHit - struct dmmTILERContPageAreaT** - [out] Returns a pointer to - * the allocated area that was hit during the "expansion" along the specified - * coordinate line. - * - * @return signed long the calculated coordinate point. - * - * @pre There is no pre conditions. - * - * @post There is no post conditions. - * - * @see - */ -/* ========================================================================== */ -inline signed long expand_bottom(struct dmmTILERContCtxT *tlrCtx, - signed long X, - signed long Y, - struct dmmTILERContPageAreaT **areaHit) -{ - *areaHit = NULL; - while (Y < tlrCtx->contSizeY) { - if (MSP_FALSE == point_free_test(tlrCtx, X, Y, areaHit)) - return Y - 1; - Y++; - } - - return Y - 1; -} - -/* ========================================================================== */ -/** - * expand_top() - * - * @brief Finds all of the unocupied pages ("expansion") along the specified - * coordinate line (1D check). - * - * @param tlrCtx - struct dmmTILERContCtxT* - [in] TILER context structure. - * - * @param X - signed long - [in] X page coordinate. - * - * @param Y - signed long - [in] Y page coordinate. - * - * @param areaHit - struct dmmTILERContPageAreaT** - [out] Returns a pointer to - * the allocated area that was hit during the "expansion" along the specified - * coordinate line. - * - * @return signed long the calculated coordinate point. - * - * @pre There is no pre conditions. - * - * @post There is no post conditions. - * - * @see - */ -/* ========================================================================== */ -inline signed long expand_top(struct dmmTILERContCtxT *tlrCtx, - signed long X, - signed long Y, - struct dmmTILERContPageAreaT **areaHit) -{ - *areaHit = NULL; - while (Y >= 0) { - if (MSP_FALSE == point_free_test(tlrCtx, X, Y, areaHit)) - return Y + 1; - Y--; - } - - return Y + 1; -} - -/* ========================================================================== */ -/** - * expand_line_on_bottom_to_right() - * - * @brief Finds all of the unocupied pages ("expansion") along the specified - * coordinate line area (2D check). - * - * @param tlrCtx - struct dmmTILERContCtxT* - [in] TILER context structure. - * - * @param X - signed long - [in] X page coordinate. - * - * @param Y - signed long - [in] Y page coordinate. - * - * @param elSizeY - signed long - [in] Size of the area to check. - * - * @return signed long the calculated coordinate point. - * - * @pre There is no pre conditions. - * - * @post There is no post conditions. - * - * @see - */ -/* ========================================================================== */ -inline signed long expand_line_on_bottom_to_right( - struct dmmTILERContCtxT *tlrCtx, - signed long X, - signed long Y, - signed long elSizeY) -{ - struct dmmTILERContPageLstT *iter; - int elSizeX = 0; - - while (elSizeX < tlrCtx->contSizeX) { - iter = tlrCtx->usdArList; - while (iter != NULL) { - if (1 == zone_area_overlap(X, Y, elSizeX, - elSizeY, &(iter->pgAr))) { - return X + elSizeX - 1; - } - iter = iter->pgArNext; - } - elSizeX++; - } - - return tlrCtx->contSizeX - 1; -} - -/* ========================================================================== */ -/** - * expand_line_on_bottom_to_left() - * - * @brief Finds all of the unocupied pages ("expansion") along the specified - * coordinate line area (2D check). - * - * @param tlrCtx - struct dmmTILERContCtxT* - [in] TILER context structure. - * - * @param X - signed long - [in] X page coordinate. - * - * @param Y - signed long - [in] Y page coordinate. - * - * @param elSizeY - signed long - [in] Size of the area to check. - * - * @return signed long the calculated coordinate point. - * - * @pre There is no pre conditions. - * - * @post There is no post conditions. - * - * @see - */ -/* ========================================================================== */ -inline signed long expand_line_on_bottom_to_left( - struct dmmTILERContCtxT *tlrCtx, - signed long X, - signed long Y, - signed long elSizeY) -{ - struct dmmTILERContPageLstT *iter; - int elSizeX = 0; - - while (X >= 0) { - iter = tlrCtx->usdArList; - while (iter != NULL) { - if (1 == zone_area_overlap(X - elSizeX, - Y, elSizeX, elSizeY, &(iter->pgAr))) { - return X + 1; - } - iter = iter->pgArNext; - } - X--; - elSizeX++; - } - - return 0; -} - -/* ========================================================================== */ -/** - * expandLineOnTopToRight() - * - * @brief Finds all of the unocupied pages ("expansion") along the specified - * coordinate line area (2D check). - * - * @param tlrCtx - struct dmmTILERContCtxT* - [in] TILER context structure. - * - * @param X - signed long - [in] X page coordinate. - * - * @param Y - signed long - [in] Y page coordinate. - * - * @param elSizeY - signed long - [in] Size of the area to check. - * - * @return signed long the calculated coordinate point. - * - * @pre There is no pre conditions. - * - * @post There is no post conditions. - * - * @see - */ -/* ========================================================================== */ -/* -inline signed long expandLineOnTopToRight(struct dmmTILERContCtxT* tlrCtx, - signed long X, signed long Y, - signed long elSizeY) -{ - struct dmmTILERContPageLstT* iter; - int elSizeX = 0; - - while (elSizeX < tlrCtx->contSizeX) - { - iter = tlrCtx->usdArList; - while (iter != NULL) - { - if (1 == zone_area_overlap(X, Y, elSizeX, elSizeY, - &(iter->pgAr))) - return X + elSizeX - 1; - iter = iter->pgArNext; - } - elSizeX++; - } - - return tlrCtx->contSizeX - 1; -} -*/ - -/* ========================================================================== */ -/** - * expandLineOnTopToLeft() - * - * @brief Finds all of the unocupied pages ("expansion") along the specified - * coordinate line area (2D check). - * - * @param tlrCtx - struct dmmTILERContCtxT* - [in] TILER context structure. - * - * @param X - signed long - [in] X page coordinate. - * - * @param Y - signed long - [in] Y page coordinate. - * - * @param elSizeY - signed long - [in] Size of the area to check. - * - * @return signed long the calculated coordinate point. - * - * @pre There is no pre conditions. - * - * @post There is no post conditions. - * - * @see - */ -/* ========================================================================== */ -/* -inline signed long expandLineOnTopToLeft(struct dmmTILERContCtxT* tlrCtx, - signed long X, signed long Y, - signed long elSizeY) -{ - struct dmmTILERContPageLstT* iter; - int elSizeX = 0; - - while (X >= 0) - { - iter = tlrCtx->usdArList; - while (iter != NULL) - { - if (1 == zone_area_overlap(X - elSizeX, - Y - elSizeY, elSizeX, elSizeY, - &(iter->pgAr))) - return X + 1; - iter = iter->pgArNext; - } - X--; - elSizeX++; - } - return 0; -} -*/ - -/* ========================================================================== */ -/** - * expand_line_on_right_to_bottom() - * - * @brief Finds all of the unocupied pages ("expansion") along the specified - * coordinate line area (2D check). - * - * @param tlrCtx - struct dmmTILERContCtxT* - [in] TILER context structure. - * - * @param X - signed long - [in] X page coordinate. - * - * @param Y - signed long - [in] Y page coordinate. - * - * @param elSizeX - signed long - [in] Size of the area to check. - * - * @return signed long the calculated coordinate point. - * - * @pre There is no pre conditions. - * - * @post There is no post conditions. - * - * @see - */ -/* ========================================================================== */ -inline signed long expand_line_on_right_to_bottom( - struct dmmTILERContCtxT *tlrCtx, - signed long X, - signed long Y, - signed long elSizeX) -{ - struct dmmTILERContPageLstT *iter; - int elSizeY = 0; - - while (elSizeY < tlrCtx->contSizeY) { - iter = tlrCtx->usdArList; - while (iter != NULL) { - if (1 == zone_area_overlap( - X, Y, elSizeX, elSizeY, &(iter->pgAr))) { - return Y + elSizeY - 1; - } - iter = iter->pgArNext; - } - elSizeY++; - } - - return tlrCtx->contSizeY - 1; -} - -/* ========================================================================== */ -/** - * expand_line_on_right_to_top() - * - * @brief Finds all of the unocupied pages ("expansion") along the specified - * coordinate line area (2D check). - * - * @param tlrCtx - struct dmmTILERContCtxT* - [in] TILER context structure. - * - * @param X - signed long - [in] X page coordinate. - * - * @param Y - signed long - [in] Y page coordinate. - * - * @param elSizeX - signed long - [in] Size of the area to check. - * - * @return signed long the calculated coordinate point. - * - * @pre There is no pre conditions. - * - * @post There is no post conditions. - * - * @see - */ -/* ========================================================================== */ -inline signed long expand_line_on_right_to_top(struct dmmTILERContCtxT *tlrCtx, - signed long X, signed long Y, - signed long elSizeX) -{ - struct dmmTILERContPageLstT *iter; - int elSizeY = 0; - - while (Y >= 0) { - iter = tlrCtx->usdArList; - while (iter != NULL) { - if (1 == zone_area_overlap(X, Y - elSizeY, - elSizeX, elSizeY, &(iter->pgAr))) { - return Y + 1; - } - iter = iter->pgArNext; - } - Y--; - elSizeY++; - } - - return 0; -} - -/* ========================================================================== */ -/** - * expandLineOnLeftToBottom() - * - * @brief Finds all of the unocupied pages ("expansion") along the specified - * coordinate line area (2D check). - * - * @param tlrCtx - struct dmmTILERContCtxT* - [in] TILER context structure. - * - * @param X - signed long - [in] X page coordinate. - * - * @param Y - signed long - [in] Y page coordinate. - * - * @param elSizeX - signed long - [in] Size of the area to check. - * - * @return signed long the calculated coordinate point. - * - * @pre There is no pre conditions. - * - * @post There is no post conditions. - * - * @see - */ -/* ========================================================================== */ -/* -inline signed long expandLineOnLeftToBottom(struct dmmTILERContCtxT* tlrCtx, - signed long X, signed long Y, - signed long elSizeX) -{ - struct dmmTILERContPageLstT* iter; - int elSizeY = 0; - - while (elSizeY < tlrCtx->contSizeY) - { - iter = tlrCtx->usdArList; - while (iter != NULL) - { - if (1 == zone_area_overlap(X, Y, elSizeX, elSizeY, - &(iter->pgAr))) - return Y + elSizeY - 1; - iter = iter->pgArNext; - } - elSizeY++; - } - return tlrCtx->contSizeY - 1; -} -*/ - -/* ========================================================================== */ -/** - * expandLineOnLeftToTop() - * - * @brief Finds all of the unocupied pages ("expansion") along the specified - * coordinate line area (2D check). - * - * @param tlrCtx - struct dmmTILERContCtxT* - [in] TILER context structure. - * - * @param X - signed long - [in] X page coordinate. - * - * @param Y - signed long - [in] Y page coordinate. - * - * @param elSizeX - signed long - [in] Size of the area to check. - * - * @return signed long the calculated coordinate point. - * - * @pre There is no pre conditions. - * - * @post There is no post conditions. - * - * @see - */ -/* ========================================================================== */ -/* -inline signed long expandLineOnLeftToTop(struct dmmTILERContCtxT* tlrCtx, - signed long X, signed long Y, - signed long elSizeX) -{ - struct dmmTILERContPageLstT* iter; - int elSizeY = 0; - - while (Y >= 0) - { - iter = tlrCtx->usdArList; - while (iter != NULL) - { - if (1 == zone_area_overlap(X - elSizeX, Y - elSizeY, - elSizeX, elSizeY, &(iter->pgAr))) - return Y + 1; - iter = iter->pgArNext; - } - Y--; - elSizeY++; - } - return 0; -} -*/ - -/* ========================================================================== */ -/** - * area_required_to_allocated() - * - * @brief Given the required area to be allcoted, total area present and anchor - * points along a side of attachemnt, calculates the actual position of the new - * new 2D area that is allocated. - * - * @param areaReq - struct dmmTILERContPageAreaT* - [in] Required 2D area to be - * allocated. - * - * @param areaTotal - struct dmmTILERContPageAreaT* - [in] Total 2D area - * allocated for this area attachment. - * - * @param areaAlloc - struct dmmTILERContPageAreaT* - [out] The actual - * allocated area. - * - * @param anchorX - signed long - [in] X page coordinate anchor point. - * - * @param anchorY - signed long - [in] Y page coordinate anchor point. - * - * @param side - enum SideAffinity - [in] Side of attachment. - * - * @return none - * - * @pre There is no pre conditions. - * - * @post There is no post conditions. - * - * @see - */ -/* ========================================================================== */ -void area_required_to_allocated(struct dmmTILERContPageAreaT *areaReq, - struct dmmTILERContPageAreaT *areaTotal, - struct dmmTILERContPageAreaT *areaAlloc, - signed long anchorX, - signed long anchorY, - enum SideAffinity side) -{ - switch (side) { - case PSA_BOTTOM: - if (areaTotal->x1 - anchorX < areaReq->x1) { - if (areaTotal->x1 - areaTotal->x0 >= areaReq->x1) { - areaAlloc->x0 = - (unsigned short)(areaTotal->x1 - areaReq->x1); - areaAlloc->x1 = - (unsigned short)(areaAlloc->x0 + areaReq->x1); - } else { - areaAlloc->x0 = areaTotal->x0; - areaAlloc->x1 = areaTotal->x1; - } - } else { - areaAlloc->x0 = (unsigned short)(anchorX); - areaAlloc->x1 = (unsigned short)(anchorX + areaReq->x1); - } - - areaAlloc->y0 = (unsigned short)(anchorY); - if (areaAlloc->y0 + areaReq->y1 <= areaTotal->y1) { - areaAlloc->y1 = (unsigned short) - (areaAlloc->y0 + areaReq->y1); - } else { - areaAlloc->y1 = areaTotal->y1; - } - areaAlloc->fitToSide = PSA_BOTTOM; - break; - - case PSA_TOP: - if (areaTotal->x1 - anchorX < areaReq->x1) { - if (areaTotal->x1 - areaTotal->x0 >= areaReq->x1) { - areaAlloc->x0 = - (unsigned short) - (areaTotal->x1 - areaReq->x1); - areaAlloc->x1 = - (unsigned short) - (areaAlloc->x0 + areaReq->x1); - } else { - areaAlloc->x0 = areaTotal->x0; - areaAlloc->x1 = areaTotal->x1; - } - } else { - areaAlloc->x0 = (unsigned short)(anchorX); - areaAlloc->x1 = (unsigned short)(anchorX + areaReq->x1); - } - - areaAlloc->y1 = (unsigned short)(anchorY); - if (areaAlloc->y1 - areaReq->y1 >= areaTotal->y0) { - areaAlloc->y0 = (unsigned short) - (areaAlloc->y1 - areaReq->y1); - } else { - areaAlloc->y0 = areaTotal->y0; - } - areaAlloc->fitToSide = PSA_TOP; - break; - - case PSA_RIGHT: - if (areaTotal->y1 - anchorY < areaReq->y1) { - if (areaTotal->y1 - areaTotal->y0 >= areaReq->y1) { - areaAlloc->y0 = - (unsigned short) - (areaTotal->y1 - areaReq->y1); - areaAlloc->y1 = - (unsigned short) - (areaAlloc->y0 + areaReq->y1); - } else { - areaAlloc->y0 = areaTotal->y0; - areaAlloc->y1 = areaTotal->y1; - } - } else { - areaAlloc->y0 = (unsigned short)(anchorY); - areaAlloc->y1 = (unsigned short)(anchorY + areaReq->y1); - } - - areaAlloc->x0 = (unsigned short)(anchorX); - if (areaAlloc->x0 + areaReq->x1 <= areaTotal->x1) { - areaAlloc->x1 = (unsigned short) - (areaAlloc->x0 + areaReq->x1); - } else { - areaAlloc->x1 = areaTotal->x1; - } - areaAlloc->fitToSide = PSA_RIGHT; - break; - - case PSA_LEFT: - if (areaTotal->y1 - anchorY < areaReq->y1) { - if (areaTotal->y1 - areaTotal->y0 >= areaReq->y1) { - areaAlloc->y0 = - (unsigned short) - (areaTotal->y1 - areaReq->y1); - areaAlloc->y1 = - (unsigned short) - (areaAlloc->y0 + areaReq->y1); - } else { - areaAlloc->y0 = areaTotal->y0; - areaAlloc->y1 = areaTotal->y1; - } - } else { - areaAlloc->y0 = (unsigned short)(anchorY); - areaAlloc->y1 = (unsigned short)(anchorY + areaReq->y1); - } - - areaAlloc->x1 = (unsigned short)(anchorX); - if (areaAlloc->x1 - areaReq->x1 >= areaTotal->x0) { - areaAlloc->x0 = (unsigned short) - (areaAlloc->x1 - areaReq->x1); - } else { - areaAlloc->x0 = areaTotal->x0; - } - areaAlloc->fitToSide = PSA_LEFT; - break; - case PSA_NONE: - break; - } -} - -/* ========================================================================== */ -/** - * area_check_for_fit() - * - * @brief Checks if a specified free area is big enough for the required - * allocation, and if the specified free area is the best (smallest) choice - * of all discovered free areas. - * - * @param tmpArea - struct dmmTILERContPageAreaSpecT * - [in] A free area that - * has been discovered and needs to be checked if it is big and small enough - * for the required allocation area. - * - * @param tlrCtx - struct dmmTILERContCtxT* - [in] TILER context structure. - * - * @param areaReq - struct dmmTILERContPageAreaT* - [in] Required allcoation - * area. - * - * @return MSP_BOOL: True if the specified area is the new best fit. - * - * @pre There is no pre conditions. - * - * @post There is no post conditions. - * - * @see - */ -/* ========================================================================== */ -enum MSP_BOOL area_check_for_fit(struct dmmTILERContPageAreaSpecT *tmpArea, - struct dmmTILERContCtxT *tlrCtx, - struct dmmTILERContPageAreaT *areaReq) -{ - if ((tmpArea->ttlExpndAr.x1 - tmpArea->ttlExpndAr.x0) >= areaReq->x1 && - (tmpArea->ttlExpndAr.y1 - tmpArea->ttlExpndAr.y0) >= - areaReq->y1) { - if (/*The area of the just found total expanded space that may - house the new 2D area to be allocated */ - (tmpArea->ttlExpndAr.x1 - tmpArea->ttlExpndAr.x0) * - (tmpArea->ttlExpndAr.y1 - tmpArea->ttlExpndAr.y0) < - /* The current smallest area found among all expanded - spaces that can house the new 2D area to be allocated */ - (tlrCtx->tmpArSelect.ttlExpndAr.x1 - - tlrCtx->tmpArSelect.ttlExpndAr.x0) * - (tlrCtx->tmpArSelect.ttlExpndAr.y1 - - tlrCtx->tmpArSelect.ttlExpndAr.y0)) { - /* If the just found area is smaller than the current - "smallest"... */ - tlrCtx->tmpArSelect.ttlExpndAr.x0 = - tmpArea->ttlExpndAr.x0; - tlrCtx->tmpArSelect.ttlExpndAr.y0 = - tmpArea->ttlExpndAr.y0; - tlrCtx->tmpArSelect.ttlExpndAr.x1 = - tmpArea->ttlExpndAr.x1; - tlrCtx->tmpArSelect.ttlExpndAr.y1 = - tmpArea->ttlExpndAr.y1; - tlrCtx->tmpArSelect.ttlExpndAr.fitToSide = - tmpArea->ttlExpndAr.fitToSide; - - tlrCtx->tmpArSelect.plmntAr.x0 = tmpArea->plmntAr.x0; - tlrCtx->tmpArSelect.plmntAr.y0 = tmpArea->plmntAr.y0; - tlrCtx->tmpArSelect.plmntAr.x1 = tmpArea->plmntAr.x1; - tlrCtx->tmpArSelect.plmntAr.y1 = tmpArea->plmntAr.y1; - tlrCtx->tmpArSelect.plmntAr.fitToSide = - tmpArea->plmntAr.fitToSide; - - tlrCtx->tmpArSelect.anchrAr = tmpArea->anchrAr; - - return MSP_TRUE; - } - } - - return MSP_FALSE; -} - -/* ========================================================================== */ -/** - * area_fit_to_left() - * - * @brief Checks if a specified free area is big enough for the required - * allocation, and if the specified free area is the best (smallest) choice - * of all discovered free areas. - * - * @param areaReq - struct dmmTILERContPageAreaT* - [in] Required allcoation - * area. - * - * @param atchAr - struct dmmTILERContPageAreaT* - [in] Area along which - * specified side the search for a new free area is performed. - * - * @param tlrCtx - struct dmmTILERContCtxT* - [in] TILER context structure. - * - * @return MSP_BOOL: True if a qualified free zones is discovered. - * - * @pre There is no pre conditions. - * - * @post There is no post conditions. - * - * @see - */ -/* ========================================================================== */ -enum MSP_BOOL area_fit_to_left(struct dmmTILERContPageAreaT *areaReq, - struct dmmTILERContPageAreaT *atchAr, - struct dmmTILERContCtxT *tlrCtx) -{ - struct dmmTILERContPageAreaT *areaHit; - struct dmmTILERContPageAreaSpecT fitArea; - signed long X; - signed long Y; - signed long anchorX; - signed long anchorY; - enum MSP_BOOL fit; - - areaHit = NULL; - fitArea.anchrAr = atchAr; - X = atchAr->x0 - 1; - Y = atchAr->y0; - anchorX = X; - anchorY = Y; - fit = MSP_FALSE; - - if (X >= 0 && X <= tlrCtx->contSizeX && Y >= 0 && Y <= - tlrCtx->contSizeY) { - while (Y <= atchAr->y1) { - anchorY = Y; - if (1 == point_free_test(tlrCtx, X, Y, &areaHit)) { - if (Y == atchAr->y0) { - /* If this is the first attempt to start - "expanding" a 2D space, then it should - be checked to the respective left,top, - right or bottom directions if there is - more points that can be concatenated to - the area to discover. This "expansion" - in certain direction is causing some - interesting behaviour patterns. */ - Y = (unsigned short)expand_top(tlrCtx, - X, Y, &areaHit); - } - - /* Once the vertical "top" and "bottom" free - points along the side of the current area - are found a "line" of free points is defined. */ - fitArea.ttlExpndAr.y0 = (unsigned short)(Y); - fitArea.ttlExpndAr.y1 = - (unsigned short)expand_bottom - (tlrCtx, X, Y, &areaHit); - /* The just defined line - of free points is then "expanded" in the - opposite direction of the side of the current - area to witch the 2D space is being defined. */ - fitArea.ttlExpndAr.x0 = - (unsigned short)expand_line_on_bottom_to_left( - tlrCtx, X, Y, fitArea.ttlExpndAr.y1 - Y); - fitArea.ttlExpndAr.x1 = (unsigned short)(X); - - fitArea.ttlExpndAr.fitToSide = PSA_LEFT; - /* Once the new 2D space is defined along the - specified side of the current 2D area, the - required 2D area to be allocated has to be - placed in the total expanded space as close to - the current 2D area as possible (aligning to - one of the corners of the new expanded space - along the side of the current 2D area). - Manipulating this function can change the - allocation behaviour pattern drastically, and - after further investigation will probably be - target of changes. */ - area_required_to_allocated(areaReq, - &(fitArea.ttlExpndAr), &(fitArea.plmntAr), - anchorX, anchorY, PSA_LEFT); - - fit |= area_check_for_fit(&fitArea, - tlrCtx, areaReq); - - break; - } else if (areaHit != NULL) { - /* If an area is hit when the first free point - is being determined, it is safe to "jump" over - it and start the new checks for free points. */ - Y = areaHit->y1 + 1; - areaHit = NULL; - } else { - DMM_ASSERT_BREAK - } - } - } - return fit; -} - -/* ========================================================================== */ -/** - * area_fit_to_right() - * - * @brief Checks if a specified free area is big enough for the required - * allocation, and if the specified free area is the best (smallest) choice - * of all discovered free areas. - * - * @param areaReq - struct dmmTILERContPageAreaT* - [in] Required allcoation - * area. - * - * @param atchAr - struct dmmTILERContPageAreaT* - [in] Area along which - * specified side the search for a new free area is performed. - * - * @param tlrCtx - struct dmmTILERContCtxT* - [in] TILER context structure. - * - * @return MSP_BOOL: True if a qualified free zones is discovered. - * - * @pre There is no pre conditions. - * - * @post There is no post conditions. - * - * @see - */ -/* ========================================================================== */ -enum MSP_BOOL area_fit_to_right(struct dmmTILERContPageAreaT *areaReq, - struct dmmTILERContPageAreaT *atchAr, - struct dmmTILERContCtxT *tlrCtx) -{ - struct dmmTILERContPageAreaT *areaHit; - struct dmmTILERContPageAreaSpecT fitArea; - signed long X; - signed long Y; - signed long anchorX; - signed long anchorY; - enum MSP_BOOL fit; - - areaHit = NULL; - fitArea.anchrAr = atchAr; - X = atchAr->x1 + 1; - Y = atchAr->y0; - anchorX = X; - anchorY = Y; - fit = MSP_FALSE; - - if (X >= 0 && X <= tlrCtx->contSizeX && Y >= 0 && Y <= - tlrCtx->contSizeY) { - while (Y <= atchAr->y1) { - anchorY = Y; - if (1 == point_free_test(tlrCtx, X, Y, &areaHit)) { - if (Y == atchAr->y0) { - /*If this is the first attempt to start - "expanding" a 2D space, then it should - be checked to the respective left,top, - right or bottom directions if there is - more points that can be concatenated to - the area to discover. This "expansion" - in certain direction is causing some - interesting behaviour patterns. */ - Y = (unsigned short)expand_top(tlrCtx, - X, Y, &areaHit); - } - - /* Once the vertical "top" and "bottom" free - points along the side of the current area - are found a "line" of free points is - defined. */ - fitArea.ttlExpndAr.y0 = (unsigned short)(Y); - fitArea.ttlExpndAr.y1 = - (unsigned short)expand_bottom(tlrCtx, X, Y, - &areaHit); - /* The just defined line of free points is then - "expanded" in the opposite direction of - the side of the current area to witch the 2D - space is being defined. */ - fitArea.ttlExpndAr.x0 = (unsigned short)(X); - fitArea.ttlExpndAr.x1 = - (unsigned short)expand_line_on_bottom_to_right( - tlrCtx, X, Y, fitArea.ttlExpndAr.y1 - Y); - - fitArea.ttlExpndAr.fitToSide = PSA_RIGHT; - /* Once the new 2D space is defined along the - specified side of the current 2D area, the - required 2D area to be allocated has to be - placed in the total expanded space as close to - the current 2D area as possible (aligning to one - of the corners of the new expanded space along - the side of the current 2D area). Manipulating - this function can change the allocation - behaviour pattern drastically, and after further - investigation will probably be target of - changes. */ - area_required_to_allocated(areaReq, - &(fitArea.ttlExpndAr), &(fitArea.plmntAr), - anchorX, anchorY, PSA_RIGHT); - - fit |= area_check_for_fit(&fitArea, - tlrCtx, areaReq); - - break; - } else if (areaHit != NULL) { - /* If an area is hit when the first free point - is being determined, it is safe to "jump" over - it and start the new checks for free points. */ - Y = areaHit->y1 + 1; - areaHit = NULL; - } else { - DMM_ASSERT_BREAK - } - } - } - return fit; -} - -/* ========================================================================== */ -/** - * area_fit_to_top() - * - * @brief Checks if a specified free area is big enough for the required - * allocation, and if the specified free area is the best (smallest) choice - * of all discovered free areas. - * - * @param areaReq - struct dmmTILERContPageAreaT* - [in] Required allcoation - * area. - * - * @param atchAr - struct dmmTILERContPageAreaT* - [in] Area along which - * specified side the search for a new free area is performed. - * - * @param tlrCtx - struct dmmTILERContCtxT* - [in] TILER context structure. - * - * @return MSP_BOOL: True if a qualified free zones is discovered. - * - * @pre There is no pre conditions. - * - * @post There is no post conditions. - * - * @see - */ -/* ========================================================================== */ -enum MSP_BOOL area_fit_to_top(struct dmmTILERContPageAreaT *areaReq, - struct dmmTILERContPageAreaT *atchAr, - struct dmmTILERContCtxT *tlrCtx) -{ - struct dmmTILERContPageAreaT *areaHit; - struct dmmTILERContPageAreaSpecT fitArea; - signed long X; - signed long Y; - signed long anchorX; - signed long anchorY; - enum MSP_BOOL fit; - - areaHit = NULL; - fitArea.anchrAr = atchAr; - X = atchAr->x0; - Y = atchAr->y0 - 1; - anchorX = X; - anchorY = Y; - fit = MSP_FALSE; - - if (X >= 0 && X < tlrCtx->contSizeX && Y >= 0 && - Y < tlrCtx->contSizeY) { - while (X <= atchAr->x1) { - anchorX = X; - if (1 == point_free_test(tlrCtx, X, Y, &areaHit)) { - if (X == atchAr->x0) { - /* If this is the first attempt to start - "expanding" a 2D space, then it should - be checked to the respective left,top, - right or bottom directions if there is - more points that can be concatenated to - the area to discover. This "expansion" - in certain direction is causing some - interesting behaviour patterns. */ - X = (unsigned short)expand_left( - tlrCtx, X, Y, &areaHit); - } - - /* Once the vertical "left" and "right" free - points along the side of the current area - are found a "line" of free points is defined. */ - fitArea.ttlExpndAr.x0 = (unsigned short)(X); - fitArea.ttlExpndAr.x1 = - (unsigned short)expand_right(tlrCtx, - X, Y, &areaHit); - /* The just defined line of free points is then - "expanded" in the opposite direction of - the side of the current area to witch the 2D - space is being defined. */ - fitArea.ttlExpndAr.y0 = - (unsigned short)expand_line_on_right_to_top( - tlrCtx, X, Y, fitArea.ttlExpndAr.x1 - X); - fitArea.ttlExpndAr.y1 = (unsigned short)(Y); - - fitArea.ttlExpndAr.fitToSide = PSA_TOP; - /* Once the new 2D space is defined along the - specified side of the current 2D area, the - required 2D area to be allocated has to be - placed in the total expanded space as close - to the current 2D area as possible (aligning - to one of the corners of the new expanded space - along the side of the current 2D area). - Manipulating this function can change the - allocation behaviour pattern drastically, and - after further investigation will probably be - target of changes. */ - area_required_to_allocated(areaReq, - &(fitArea.ttlExpndAr), &(fitArea.plmntAr), - anchorX, anchorY, PSA_TOP); - - fit |= area_check_for_fit(&fitArea, tlrCtx, - areaReq); - - break; - } else if (areaHit != NULL) { - /* If an area is hit when the first free point - is being determined, it is safe to "jump" over - it and start the new checks for free points. */ - X = areaHit->x1 + 1; - areaHit = NULL; - } else { - DMM_ASSERT_BREAK - } - } - } - return fit; -} - -/* ========================================================================== */ -/** - * area_fit_to_bottom() - * - * @brief Checks if a specified free area is big enough for the required - * allocation, and if the specified free area is the best (smallest) choice - * of all discovered free areas. - * - * @param areaReq - struct dmmTILERContPageAreaT* - [in] Required allcoation - * area. - * - * @param atchAr - struct dmmTILERContPageAreaT* - [in] Area along which - * specified side the search for a new free area is performed. - * - * @param tlrCtx - struct dmmTILERContCtxT* - [in] TILER context structure. - * - * @return MSP_BOOL: True if a qualified free zones is discovered. - * - * @pre There is no pre conditions. - * - * @post There is no post conditions. - * - * @see - */ -/* ========================================================================== */ -enum MSP_BOOL area_fit_to_bottom(struct dmmTILERContPageAreaT *areaReq, - struct dmmTILERContPageAreaT *atchAr, - struct dmmTILERContCtxT *tlrCtx) -{ - struct dmmTILERContPageAreaT *areaHit; - struct dmmTILERContPageAreaSpecT fitArea; - signed long X; - signed long Y; - signed long anchorX; - signed long anchorY; - enum MSP_BOOL fit; - - areaHit = NULL; - fitArea.anchrAr = atchAr; - X = atchAr->x0; - Y = atchAr->y1 + 1; - anchorX = X; - anchorY = Y; - fit = MSP_FALSE; - - if (X >= 0 && X < tlrCtx->contSizeX && Y >= 0 && - Y < tlrCtx->contSizeY) { - while (X <= atchAr->x1) { - if (1 == point_free_test(tlrCtx, X, Y, &areaHit)) { - anchorX = X; - if (X == atchAr->x0) { - /* If this is the first attempt to start - "expanding" a 2D space, then it should - be checked to the respective left,top, - right or bottom directions if there is - more points that can be concatenated to - the area to discover. This "expansion" - in certain direction is causing some - interesting behaviour patterns. */ - X = (unsigned short)expand_left( - tlrCtx, X, Y, &areaHit); - } - - /* Once the vertical "left" and "right" free - points along the side of the current area - are found a "line" of free points is defined. */ - fitArea.ttlExpndAr.x0 = (unsigned short)(X); - fitArea.ttlExpndAr.x1 = - (unsigned short)expand_right(tlrCtx, - X, Y, &areaHit); - /* The just defined line of free points is then - "expanded" in the opposite direction of - the side of the current area to witch the 2D - space is being defined. */ - fitArea.ttlExpndAr.y0 = (unsigned short)(Y); - fitArea.ttlExpndAr.y1 = - (unsigned short)expand_line_on_right_to_bottom( - tlrCtx, X, Y, fitArea.ttlExpndAr.x1 - X); - - fitArea.ttlExpndAr.fitToSide = PSA_BOTTOM; - /* Once the new 2D space is defined along the - specified side of the current 2D area, the - required 2D area to be allocated has to be - placed in the total expanded space as close to - the current 2D area as possible (aligning to - one of the corners of the new expanded space - along the side of the current 2D area). - Manipulating this function can change the - allocation behaviour pattern drastically, and - after further investigation will probably be - target of changes. */ - area_required_to_allocated(areaReq, - &(fitArea.ttlExpndAr), &(fitArea.plmntAr), - anchorX, anchorY, PSA_BOTTOM); - - fit |= area_check_for_fit(&fitArea, tlrCtx, - areaReq); - - break; - } else if (areaHit != NULL) { - /* If an area is hit when the first free point - is being determined, it is safe to "jump" over - it and start the new checks for free points. */ - X = areaHit->x1 + 1; - areaHit = NULL; - } else { - DMM_ASSERT_BREAK - } - } - } - return fit; -} - -/* ========================================================================== */ -/** - * alloc_2D_area() - * - * @brief Allocates a 2D area and returns a pointer to it. - * - * @param tlrCtx - struct dmmTILERContCtxT* - [in] TILER context structure. - * - * @param areaReq - struct dmmTILERContPageAreaT* - [in] Required area for - * allcoation. - * - * @return struct dmmTILERContPageAreaT*: pointer to the allocated area. - * - * @pre There is no pre conditions. - * - * @post There is no post conditions. - * - * @see - */ -/* ========================================================================== */ -struct dmmTILERContPageAreaT * -alloc_2d_area(struct dmmTILERContCtxT *dmmTilerCtx, - struct dmmTILERContPageAreaT *areaReq) -{ - struct dmmTILERContPageLstT *allocatedArea = NULL; - struct dmmTILERContPageLstT *usedIter; - - usedIter = dmmTilerCtx->usdArList; - - dmmTilerCtx->tmpArSelect.ttlExpndAr.x0 = 0; - dmmTilerCtx->tmpArSelect.ttlExpndAr.y0 = 0; - dmmTilerCtx->tmpArSelect.ttlExpndAr.x1 = dmmTilerCtx->contSizeX - 1; - dmmTilerCtx->tmpArSelect.ttlExpndAr.y1 = dmmTilerCtx->contSizeY - 1; - - mutex_lock(&dmmTilerCtx->mtx); - if (usedIter != NULL) { - int fit = 0; - while (usedIter != NULL) { - fit |= area_fit_to_top(areaReq, - &(usedIter->pgAr), dmmTilerCtx); - fit |= area_fit_to_right(areaReq, - &(usedIter->pgAr), dmmTilerCtx); - fit |= area_fit_to_bottom(areaReq, - &(usedIter->pgAr), dmmTilerCtx); - fit |= area_fit_to_left(areaReq, - &(usedIter->pgAr), dmmTilerCtx); - usedIter = usedIter->pgArNext; - } - - if (fit > 0) { - allocatedArea = kmalloc - (sizeof(struct dmmTILERContPageLstT), GFP_KERNEL); - if (!allocatedArea) - return NULL; - memset(allocatedArea, 0x0, - sizeof(struct dmmTILERContPageLstT)); - allocatedArea->pgAr.x0 = - dmmTilerCtx->tmpArSelect.plmntAr.x0; - allocatedArea->pgAr.y0 = - dmmTilerCtx->tmpArSelect.plmntAr.y0; - allocatedArea->pgAr.x1 = - dmmTilerCtx->tmpArSelect.plmntAr.x1; - allocatedArea->pgAr.y1 = - dmmTilerCtx->tmpArSelect.plmntAr.y1; - allocatedArea->pgAr.fitToSide = - dmmTilerCtx->tmpArSelect.plmntAr.fitToSide; - allocatedArea->anchrAr = - dmmTilerCtx->tmpArSelect.anchrAr; - - usedIter = dmmTilerCtx->usdArList; - - while (usedIter->pgArNext != NULL) - usedIter = usedIter->pgArNext; - - usedIter->pgArNext = allocatedArea; - } - } else { - allocatedArea = kmalloc - (sizeof(struct dmmTILERContPageLstT), GFP_KERNEL); - if (!allocatedArea) - return NULL; - memset(allocatedArea, 0x0, sizeof(struct dmmTILERContPageLstT)); - allocatedArea->pgAr.x0 = 0; - allocatedArea->pgAr.y0 = 0; - allocatedArea->pgAr.x1 = areaReq->x1; - allocatedArea->pgAr.y1 = areaReq->y1; - allocatedArea->pgAr.fitToSide = PSA_BOTTOM; - allocatedArea->anchrAr = NULL; - allocatedArea->pgArNext = NULL; - dmmTilerCtx->usdArList = allocatedArea; - } - - mutex_unlock(&dmmTilerCtx->mtx); - - if (allocatedArea == NULL) - return NULL; - else - return &(allocatedArea->pgAr); -} - -/* ========================================================================== */ -/** - * dealloc_2D_area() - * - * @brief Deletes a 2D area from the TILER context. - * - * @param tlrCtx - struct dmmTILERContCtxT* - [in] TILER context structure. - * - * @param areaRem - struct dmmTILERContPageAreaT* - [in] Area to remove. - * - * @return MSP_BOOL: True if the specified area is successfuly deleted. - * - * @pre There is no pre conditions. - * - * @post There is no post conditions. - * - * @see - */ -/* ========================================================================== */ -enum MSP_BOOL dealloc_2d_area(struct dmmTILERContCtxT *dmmTilerCtx, - struct dmmTILERContPageAreaT *areaRem) -{ - struct dmmTILERContPageLstT *delItm; - struct dmmTILERContPageLstT *usedIter; - struct dmmTILERContPageLstT *usedPrev; - - mutex_lock(&dmmTilerCtx->mtx); - - delItm = NULL; - usedIter = dmmTilerCtx->usdArList; - usedPrev = NULL; - - while (usedIter != NULL) { - if (areaRem->x0 == usedIter->pgAr.x0 && - areaRem->y0 == usedIter->pgAr.y0) { - delItm = usedIter; - if (usedPrev != NULL) - usedPrev->pgArNext = usedIter->pgArNext; - else - dmmTilerCtx->usdArList = - dmmTilerCtx->usdArList->pgArNext; - - break; - } - - usedPrev = usedIter; - usedIter = usedIter->pgArNext; - } - - mutex_unlock(&dmmTilerCtx->mtx); - - if (delItm != NULL) { -#ifndef __USE_DMM_MEM__ - signed long i; -#endif - enum errorCodeT eCode = DMM_NO_ERROR; - unsigned long numPages = 0x0; - - /* If the memory pages are provided by the dmm pages memory - pool, then free them. Otherwise leave them for the user - to free them. - */ - if (delItm->pgAr.patCustomPages == MSP_FALSE) { - numPages = (delItm->pgAr.x1 - delItm->pgAr.x0 + 1)* - (delItm->pgAr.y1 - delItm->pgAr.y0 + 1); - /* Get the area to free associated physical memory pages - and free them - how can they be obtained from the - PAT lut?! - */ - /* Is it viable and easier that each allocated area has - a list of all the physical pages mapped to it? - */ - /* As currently the system is working with a memory page - pool leave it be. - */ -#ifndef __USE_DMM_MEM__ - for (i = 0; - i < numPages && eCode == DMM_NO_ERROR; i++) { - dmm_free_phys_page((unsigned long) - (delItm->pgAr.patPageEntries[i])); - } -#endif - } - - if (eCode == DMM_NO_ERROR && delItm->pgAr.patCustomPages == 0) { -#ifndef __USE_DMM_MEM__ - dma_free_coherent(NULL, delItm->pgAr.dma_size, - delItm->pgAr.dma_va, - delItm->pgAr.dma_pa); - delItm->pgAr.patPageEntries = NULL; - delItm->pgAr.patPageEntriesSpace = NULL; -#endif - } - - kfree(delItm); - - return MSP_TRUE; - } else { - return MSP_FALSE; - } -} - -/* ========================================================================== */ -/** - * search_2D_area() - * - * @brief Deletes a 2D area from the TILER context. - * - * @param tlrCtx - struct dmmTILERContCtxT* - [in] TILER context structure. - * - * @param X - signed long - [in] X coordinate inside the search area. - * - * @param Y - signed long - [in] X coordinate inside the search area. - * - * @param xInvert - MSP_BOOL - [in] X coordinate is inverted. - * - * @param yInvert - MSP_BOOL - [in] Y coordinate is inverted. - * - * @return struct dmmTILERContPageAreaT*: pointer to the discovered 2D area - * or NULL if no such area is found. - * - * @pre There is no pre conditions. - * - * @post There is no post conditions. - * - * @see - */ -/* ========================================================================== */ -struct dmmTILERContPageAreaT * -search_2d_area(struct dmmTILERContCtxT *dmmTilerCtx, - signed long X, - signed long Y, - enum MSP_BOOL xInvert, - enum MSP_BOOL yInvert) -{ - struct dmmTILERContPageLstT *usedIter; - usedIter = dmmTilerCtx->usdArList; - - while (usedIter != NULL) { - if (usedIter->pgAr.x0 <= X && X <= usedIter->pgAr.x1 && - usedIter->pgAr.y0 <= Y && Y <= usedIter->pgAr.y1) { - return &(usedIter->pgAr); - } - - usedIter = usedIter->pgArNext; - } - - return NULL; -} diff --git a/drivers/media/video/tiler/dmm_2d_alloc.h b/drivers/media/video/tiler/dmm_2d_alloc.h deleted file mode 100644 index 50dd980d0941..000000000000 --- a/drivers/media/video/tiler/dmm_2d_alloc.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * dmm_2d_alloc.h - * - * DMM driver support functions for TI OMAP processors. - * - * Copyright (C) 2009-2010 Texas Instruments, Inc. - * - * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef _DMM_2D_ALLOC_H -#define _DMM_2D_ALLOC_H - -#include <linux/dma-mapping.h> - -enum errorCodeT { - DMM_NO_ERROR, - DMM_WRONG_PARAM, - DMM_HRDW_CONFIG_FAILED, - DMM_HRDW_NOT_READY, - DMM_SYS_ERROR -}; - -enum MSP_BOOL { - MSP_FALSE = 0, - MSP_TRUE -}; - -enum SideAffinity { - PSA_NONE, - PSA_LEFT, - PSA_TOP, - PSA_BOTTOM, - PSA_RIGHT -}; - -struct dmmTILERContPageAreaT { - u16 x0; - u16 y0; - u16 x1; - u16 y1; - u16 xPageOfst; - u16 yPageOfst; - u16 xPageCount; - u16 yPageCount; - enum SideAffinity fitToSide; - int patCustomPages; - u32 *patPageEntriesSpace; - struct page *page_list; - u32 *page_list_virt; - void *dma_va; - u32 dma_size; - dma_addr_t dma_pa; - u32 *patPageEntries; -}; - -struct dmmTILERContPageAreaSpecT { - struct dmmTILERContPageAreaT ttlExpndAr; - struct dmmTILERContPageAreaT plmntAr; - struct dmmTILERContPageAreaT *anchrAr; -}; - -struct dmmTILERContPageLstT { - struct dmmTILERContPageLstT *pgArNext; - struct dmmTILERContPageAreaT *anchrAr; - struct dmmTILERContPageAreaT pgAr; -}; - -struct dmmTILERContCtxT { - signed long contSizeX; - signed long contSizeY; - struct dmmTILERContPageLstT *usdArList; - struct dmmTILERContPageAreaSpecT tmpArSelect; - struct mutex mtx; -}; - -/* ========================================================================== */ -/** - * alloc2DArea() - * - * @brief Allocates a 2D area and returns a pointer to it. - * - * @param tlrCtx - dmmTILERContCtxT* - [in] TILER context structure. - * - * @param areaReq - dmmTILERContPageAreaT* - [in] Required area for allcoation. - * - * @return dmmTILERContPageAreaT*: pointer to the allocated area. - * - * @pre There is no pre conditions. - * - * @post There is no post conditions. - * - * @see - */ -/* ========================================================================== */ -struct dmmTILERContPageAreaT *alloc_2d_area( - struct dmmTILERContCtxT *dmmTilerCtx, - struct dmmTILERContPageAreaT *areaReq); - -/* ========================================================================== */ -/** - * deAlloc2DArea() - * - * @brief Deletes a 2D area from the TILER context. - * - * @param tlrCtx - dmmTILERContCtxT* - [in] TILER context structure. - * - * @param areaRem - dmmTILERContPageAreaT* - [in] Area to remove. - * - * @return int: True if the specified area is successfuly deleted. - * - * @pre There is no pre conditions. - * - * @post There is no post conditions. - * - * @see - */ -/* ========================================================================== */ -enum MSP_BOOL dealloc_2d_area(struct dmmTILERContCtxT *dmmTilerCtx, - struct dmmTILERContPageAreaT *areaRem); - -/* ========================================================================== */ -/** - * search2DArea() - * - * @brief Deletes a 2D area from the TILER context. - * - * @param tlrCtx - dmmTILERContCtxT* - [in] TILER context structure. - * - * @param X - signed long - [in] X coordinate of the search area. - * - * @param Y - signed long - [in] X coordinate of the search area. - * - * @param xInvert - int - [in] X coordinate is inverted. - * - * @param yInvert - int - [in] Y coordinate is inverted. - * - * @return dmmTILERContPageAreaT*: pointer to the discovered 2D area - * or NULL if no such area is found. - * - * @pre There is no pre conditions. - * - * @post There is no post conditions. - * - * @see - */ -/* ========================================================================== */ -struct dmmTILERContPageAreaT *search_2d_area( - struct dmmTILERContCtxT *dmmTilerCtx, - signed long X, - signed long Y, - enum MSP_BOOL xInvert, - enum MSP_BOOL yInvert); - -#endif /* _DMM_2D_ALLOC_H */ - diff --git a/drivers/media/video/tiler/tcm/Makefile b/drivers/media/video/tiler/tcm/Makefile new file mode 100644 index 000000000000..bde1d9c31a83 --- /dev/null +++ b/drivers/media/video/tiler/tcm/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_TILER_OMAP) += tcm_omap.o +tcm_omap-objs = tcm.o tcm_utils.o + diff --git a/drivers/media/video/tiler/tcm/tcm.c b/drivers/media/video/tiler/tcm/tcm.c new file mode 100644 index 000000000000..9f4f7ced9588 --- /dev/null +++ b/drivers/media/video/tiler/tcm/tcm.c @@ -0,0 +1,1770 @@ +/* +* tcm.c +* +* Author: Ravi Ramachandra <r.ramachandra@ti.com> +* +* Tiler 2D and 1D Container Management Algorithm. +* +* Copyright (C) 2009-2010 Texas Instruments, Inc. +* +* This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. +* +*/ + +#include <linux/init.h> +#include <linux/module.h> +#include "tcm_pri.h" +#include "tcm.h" +#include "tcm_utils.h" + +/********************************************* + * POSITIONING & OPTIMIZATION TWEAKS +*********************************************/ + +/* Restricts scanning unecessary tiles */ + +/*By enabling this X_SCAN LIMITER, we scan consective line only till the +previous found x0, thus eliminating candidates for selection during scan only */ +#define X_SCAN_LIMITER +/*By enabling this Y_SCAN_LIMITER we limit scan going down(or up) if we found +that the candidate's y0 is same as scan area's start scan */ +#define Y_SCAN_LIMITER + +/* Enabling this will HARD restrict 1D to as specified in g_div_ln...'s y1 */ +/* #define RESTRICT_1D */ + +/*********************************************/ + + +/* ******************************************** + * GLOBALS + *********************************************/ +/* global Container that keeps a map of which tile is occupied +and which tiler is not occupied */ +static struct tiler_page g_area_container[MAX_X_DIMMENSION][MAX_Y_DIMMENSION]; + +/* This list keeps a track of all the allocations that happened in terms +of area allocated, this list is checked for removing any allocations */ +struct area_spec_list *g_allocation_list; + +/*Vertical line divider between 64 and 32 aligned scan areas */ +struct area_spec g_div_ln_btw_64_and_32_align = {192, 0, 192, 96}; + +/* Just some temp ID, which will roll over 32K */ +u32 g_id; + +static struct mutex g_mutex; + + +/* Individual selection criteria for different scan areas */ +static s32 g_scan_criteria_l2r_t2b = CR_BIAS_HORIZONTAL; +static s32 g_scan_criteria_l2r_b2t = CR_DIAGONAL_BALANCE; +static s32 g_scan_criteria_r2l_t2b = CR_DIAGONAL_BALANCE; +static s32 g_scan_criteria_r2l_b2t = CR_FIRST_FOUND; + +/*********************************************/ + + +/********************************************* + * LOCAL METHODS + *********************************************/ +static s32 scan_areas_and_find_fit(u16 w, u16 h, u16 stride, + struct area_spec *allocated_area); +static s32 scan_l2r_t2b(u16 w, u16 h, u16 stride, struct area_spec *scan_area, + struct area_spec *alloc_area); +static s32 scan_r2l_t2b(u16 w, u16 h, u16 stride, struct area_spec *scan_area, + struct area_spec *alloc_area); +static s32 scan_l2r_b2t(u16 w, u16 h, u16 stride, struct area_spec *scan_area, + struct area_spec *alloc_area); +static s32 scan_r2l_b2t(u16 w, u16 h, u16 stride, struct area_spec *scan_area, + struct area_spec *alloc_area); +static s32 scan_r2l_b2t_one_dim(u32 num_of_pages, struct area_spec *scan_area, + struct area_spec *alloc_area); + +/* Support Infrastructure functions */ +static s32 check_fit_r_and_b(u16 w, u16 h, u16 left_x, u16 top_y); +static s32 check_fit_r_one_dim(u16 x, u16 y, u32 num_of_pages, u16 *busy_x, + u16 *busy_y); +static s32 select_candidate(IN u16 w, IN u16 h, IN u16 num_short_listed, + IN struct area_spec_list *short_listed, IN struct area_spec *scan_area, + IN s32 criteria, OUT struct area_spec *alloc_area); +/* old selecte candidate will be deprecated after testing new one */ +static s32 get_nearness_factor(struct area_spec *scan_area, + struct area_spec *candidate, struct nearness_factor *nf); +static s32 get_busy_neigh_stats(u16 width, u16 height, + struct area_spec *top_left_corner, + struct neighbour_stats *neighbour_stat); +static s32 insert_area_with_tiler_page(struct area_spec *area, + struct tiler_page tile); +static s32 insert_pages_with_tiler_page(struct area_spec *area, + struct tiler_page tile); + +/*********************************************/ + + +/** + * @description: Initializes tiler container. + * + * @input: None + * + * @return 0 on success, non-0 error value on failure. + */ +s32 init_tiler(void) +{ + struct tiler_page init_tile; + struct area_spec area = {0}; + + init_tile.is_occupied = 0; + init_tile.parent_area.x0 = 0; + init_tile.parent_area.x1 = 0; + init_tile.parent_area.y0 = 0; + init_tile.parent_area.y1 = 0; + init_tile.reserved = 0; + init_tile.type = 0; + + area.x1 = MAX_X_DIMMENSION - 1; + area.y1 = MAX_Y_DIMMENSION - 1; + + mutex_init(&g_mutex); + MUTEX_LOCK(&g_mutex); + insert_area_with_tiler_page(&area, init_tile); + MUTEX_REL(&g_mutex); + return TilerErrorNone; +} + + +/** + * @description: DeInitializes tiler container. + * removes existing allocations + * + * @input: None + * + * @return 0 on success, non-0 error value on failure. + */ +s32 deinit_tiler(void) +{ + struct tiler_page init_tile; + struct area_spec area = {0}; + /* Cleaning all the entries in the list and marking tiler container + as free */ + + init_tile.is_occupied = 0; + init_tile.parent_area.x0 = 0; + init_tile.parent_area.x1 = 0; + init_tile.parent_area.y0 = 0; + init_tile.parent_area.y1 = 0; + init_tile.reserved = 0; + init_tile.type = 0; + + area.x1 = MAX_X_DIMMENSION - 1; + area.y1 = MAX_Y_DIMMENSION - 1; + + MUTEX_LOCK(&g_mutex); + insert_area_with_tiler_page(&area, init_tile); + clean_list(&g_allocation_list); + MUTEX_REL(&g_mutex); + mutex_destroy(&g_mutex); + return TilerErrorNone; +} + +/** + * @description: Allocate 1d pages if the required number of pages are + * available in the container + * + * @input:num_of_pages to be allocated + * + * @return 0 on success, non-0 error value on failure. On success + * allocated_pages contain co-ordinates of start and end Tiles(inclusive) + */ +s32 allocate_1d_pages(u32 num_of_pages, struct area_spec *allocated_pages) +{ + s32 ret = TilerErrorNone; + struct area_spec scan_area = {0, 0, 0, 0}; + struct tiler_page tile; + + memset(&tile, 0, sizeof(struct tiler_page)); + P1("Allocate %d pages\n", num_of_pages); + + /* Basic checks */ + if (allocated_pages == NULL) { + PE("NULL input found\n"); + return TilerErrorInvalidArg; + } + /* Delibrately checking outside to give out relavent error info */ + if (num_of_pages > (MAX_X_DIMMENSION * MAX_Y_DIMMENSION)) { + PE("num_of_pages exceed maximum pages available(%d)\n", + (MAX_X_DIMMENSION * MAX_Y_DIMMENSION)); + return TilerErrorNoRoom; + } + MUTEX_LOCK(&g_mutex); +#ifdef RESTRICT_1D + /*scan within predefine 1D boundary */ + assign(&scan_area, (MAX_X_DIMMENSION-1), (MAX_Y_DIMMENSION - 1), 0, + g_div_ln_btw_64_and_32_align.y1); +#else + /* Scanning entire container */ + assign(&scan_area, MAX_X_DIMMENSION - 1, MAX_Y_DIMMENSION - 1, 0, 0); +#endif + ret = scan_r2l_b2t_one_dim(num_of_pages, &scan_area, allocated_pages); + + /* There is not much to select, we pretty much give the first one which + accomodates */ + if (ret != TilerErrorNone) { + PE("Failed to Allocate 1D Pages\n"); + } else { + P("Yahoo found a fit: %s\n", AREA_STR(a_str, allocated_pages)); + tile.is_occupied = OCCUPIED; + assign(&tile.parent_area, allocated_pages->x0, + allocated_pages->y0, allocated_pages->x1, + allocated_pages->y1); + /* some id, not useful now */ + tile.reserved = g_id++; + /* Saying that type is 1d */ + tile.type = ONE_D; + /* inserting into tiler container */ + insert_pages_with_tiler_page(allocated_pages, tile); + /*updating the list of allocations */ + insert_element(&g_allocation_list, allocated_pages, ONE_D); + } + MUTEX_REL(&g_mutex); + return ret; +} + + +/** + * @description: Allocate 2d area on availability in the container + * + * @input:'w'idth and 'h'eight of the 2d area, 'align'ment specification + * + * @return 0 on success, non-0 error value on failure. On success + * allocated_area contain co-ordinates of TL corner Tile and BR corner Tile of + * the rectangle (inclusive) + */ +s32 allocate_2d_area(u16 w, u16 h, enum alignment align, + struct area_spec *allocated_area) +{ + s32 ret = TilerErrorNone; + u16 stride = ALIGN_STRIDE(align); + struct tiler_page tile; + + P1("\n\nStart of allocation 2D Area for WxH : (%d x %d) with Alignment\ + %d \n", w, h, stride); + + /* Checking for input arguments */ + if (allocated_area == NULL) { + PE("NULL input found\n"); + return TilerErrorInvalidArg; + } + /* ALIGN_16 is currently NOT supported*/ + if (align == ALIGN_16) { + PE("Align 16 NOT supported \n"); + return TilerErrorNotSupported; + } + /*check if width and height are within limits */ + if (w > MAX_X_DIMMENSION || w == 0 || h > MAX_Y_DIMMENSION || h == 0) { + PE("Invalid dimension:: %d x %d\n", w, h); + return TilerErrorInvalidDimension; + } + MUTEX_LOCK(&g_mutex); + ret = scan_areas_and_find_fit(w, h, stride, allocated_area); + if (ret != TilerErrorNone) { + PE("Did not find anything in the given area\n"); + } else { + P("Yahoo found a fit: %s\n", AREA_STR(a_str, allocated_area)); + tile.is_occupied = OCCUPIED; + assign(&tile.parent_area, allocated_area->x0, + allocated_area->y0, allocated_area->x1, + allocated_area->y1); + + /* some id, not useful now */ + tile.reserved = g_id++; + /* Saying that type is 2D */ + tile.type = TWO_D; + /* inserting into tiler container */ + ret = insert_area_with_tiler_page(allocated_area, tile); + if (ret == TilerErrorNone) { + /*updating the list of allocations */ + insert_element(&g_allocation_list, + allocated_area, TWO_D); + } else { + PE("Could not insert area\n %s\n", AREA_STR(a_str, + allocated_area)); + } + } + MUTEX_REL(&g_mutex); + return ret; +} + +/** + * @description: Deallocate 2d or 1D allocations if previously allocated + * + * @input:'to_be_removed_area' specification: for 2D this should contain + * TL Corner and BR Corner of the 2D area, or for 1D allocation this should + * contain the start and end Tiles + * + * @return 0 on success, non-0 error value on failure. On success + * the to_be_removed_area is removed from g_allocation_list and the + * corresponding tiles are marked 'NOT_OCCUPIED' + * + */ +s32 deallocate(struct area_spec *to_be_removed_area) +{ + s32 ret = TilerErrorNone; + struct tiler_page reset_tile = { NOT_OCCUPIED, {0, 0, 0, 0}, 0, 0}; + u16 area_type; + + MUTEX_LOCK(&g_mutex); + /*First we check if the given Area is aleast valid in our list*/ + ret = rem_element_with_match(&g_allocation_list, to_be_removed_area, + &area_type); + + /* If we found a positive match & removed the area details from list + * then we clear the contents of the associated tiles in the global + * container*/ + if (ret == TilerErrorNone) { + if (area_type == TWO_D) { + P1("De-allocating TWO_D allocation %s\n", + AREA_STR(a_str, to_be_removed_area)); + /*Reset tiles are inserted, ignoring ret values + delibrately */ + ret = insert_area_with_tiler_page( + to_be_removed_area, reset_tile); + } else { + P1("De-allocating ONE_D allocation %s\n", + AREA_STR(a_str, to_be_removed_area)); + ret = insert_pages_with_tiler_page(to_be_removed_area, + reset_tile); + } + } else { + PE("Did not find a Match to remove\n"); + } + + MUTEX_REL(&g_mutex); + return ret; + +} + + + +/** + * @description: raster scan right to left from top to bottom; find if there is + * a free area to fit a given w x h inside the 'scan area'. If there is a free + * area, then adds to short_listed candidates, which later is sent for selection + * as per pre-defined criteria. + * + * @input:'w x h' width and height of the allocation area. + * 'stride' - 64/32/None for start address alignment + * 'scan_area' - area in which the scan operation should take place + * + * @return 0 on success, non-0 error value on failure. On success + * the 'alloc_area' area contains TL and BR corners of the allocated area + * + */ +s32 scan_r2l_t2b(u16 w, u16 h, u16 stride, struct area_spec *scan_area, + struct area_spec *alloc_area) +{ + + s32 xx = 0, yy = 0; + s16 start_x = -1, end_x = -1, start_y = -1, end_y = -1; + s16 found_x = -1, found_y = -1; + u16 remainder; + struct area_spec_list *short_listed = NULL; + struct area_spec candidate_area = {0, 0, 0, 0}; + u16 num_short_listed = 0; + s32 ret = TilerErrorNone; + + P2("Scanning From Right 2 Left Top 2 Bottom: ScanArea: %s\n", + AREA_STR(a_str, scan_area)); + + /*Basic checks */ + if (scan_area == NULL || alloc_area == NULL) { + PE("Null value found\n"); + return TilerErrorInvalidArg; + } + + /*Check if the scan area co-ordinates are valid */ + if ((scan_area->x0 < scan_area->x1) || + (scan_area->y1 < scan_area->y0)) { + PE("Invalid scan area: %s\n", AREA_STR(a_str, scan_area)); + return TilerErrorInvalidScanArea; + } + + start_x = scan_area->x0; + end_x = scan_area->x1; + start_y = scan_area->y0; + end_y = scan_area->y1; + + /* Check if we have a scan area bigger than the given input width and + height */ + if (w > INCL_LEN(start_x, end_x) || h > INCL_LEN(end_y, start_y)) { + PE("Scan area smaller than width and height\n"); + return TilerErrorInvalidDimension; + } + + /*Adjusting start_x and end_y, why scan beyond a point where we cant + allocate given wxh area */ + start_x = start_x - w + 1; /* - 1 to be inclusive */ + end_y = end_y - h + 1; + + + /* calculating remainder */ + remainder = (start_x % stride); + /* P("remainder = %d\n",remainder); */ + + /* if start_x is not divisible by stride, then skip to PREV aligned + column */ + start_x -= remainder ? (remainder) : 0 ; + /* P("StartX = %d\n",start_x); */ + + + /* check if we have enough width to accomodate the request from the + aligned (start_y) column */ + if (start_x < end_x) { + PE("No room to allocate at aligned lengths\n"); + return TilerErrorNoRoom; + } + + P2("Final stride : %d\n, start_x : %d end_x : %d start_y :\ + %d end_y : %d\n", stride, start_x, end_x, start_y, + end_y); + + /* Start scanning: These scans are always inclusive ones so if we are + given a start x = 0 is a valid value so if we have a end_x = 255, + 255th element is also checked + */ + for (yy = start_y; yy <= end_y; ++yy) { + for (xx = start_x; xx >= end_x; xx -= stride) { + if (g_area_container[xx][yy].is_occupied == + NOT_OCCUPIED) { + if (FIT == check_fit_r_and_b(w, h, xx, yy)) { + P3("Found Free Shoulder at:\ + (%d, %d)\n", xx, yy); + found_x = xx; + found_y = yy; + /* Insert this candidate, it is just a + co-ordinate, reusing Area */ + assign(&candidate_area, xx, yy, 0, 0); + insert_element(&short_listed, + &candidate_area, TWO_D); + num_short_listed++; + /*changing upper bound on x direction */ +#ifdef X_SCAN_LIMITER + end_x = xx + 1; +#endif + break; + } + } else { + /* Optimization required only for Non Aligned, + Aligned anyways skip by 32/64 tiles at a time */ + if (stride == 1 && + g_area_container[xx][yy].type == + TWO_D) { + xx = g_area_container + [xx][yy].parent_area.x0; + P3("Moving to parent location start_x\ + (%d %d)\n", xx, yy); + } + } + + + } + + /* if you find a free area shouldering the given scan area on + then we can break + */ +#ifdef Y_SCAN_LIMITER + if (found_x == start_x) + break; +#endif + } + + + if (!short_listed) { + PE("No candidates found in a given scan area\n"); + return TilerErrorNoRoom; + } + + /*Now if we are here it implies we have potential candidates*/ + ret = select_candidate(w, h, num_short_listed, short_listed, scan_area, + g_scan_criteria_r2l_t2b, alloc_area); + + if (ret != TilerErrorNone) + PE("Error in Selecting a Candidate\n"); + /*Just clean up resources */ + clean_list(&short_listed); + + /* dump_list_entries(short_listed); */ + return ret; + +} + + +/** + * @description: raster scan right to left from bottom to top; find if there is + * a free area to fit a given w x h inside the 'scan area'. If there is a free + * area, then adds to short_listed candidates, which later is sent for selection + * as per pre-defined criteria. + * + * @input:'w x h' width and height of the allocation area. + * 'stride' - 64/32/None for start address alignment + * 'scan_area' - area in which the scan operation should take place + * + * @return 0 on success, non-0 error value on failure. On success + * the 'alloc_area' area contains TL and BR corners of the allocated area + * + */ +s32 scan_r2l_b2t(u16 w, u16 h, u16 stride, struct area_spec *scan_area, + struct area_spec *alloc_area) +{ + + /* TO DO: Should i check scan area? + Might have to take it as input during initialization + */ + s32 xx = 0, yy = 0; + s16 start_x = -1, end_x = -1, start_y = -1, end_y = -1; + s16 found_x = -1, found_y = -1; + u16 remainder; + struct area_spec_list *short_listed = NULL; + struct area_spec candidate_area = {0, 0, 0, 0}; + u16 num_short_listed = 0; + s32 ret = TilerErrorNone; + + P2("Scanning From Right 2 Left Bottom 2 Top, ScanArea: %s\n", + AREA_STR(a_str, scan_area)); + start_x = scan_area->x0; + end_x = scan_area->x1; + start_y = scan_area->y0; + end_y = scan_area->y1; + + + /*Basic checks */ + if (scan_area == NULL || alloc_area == NULL) { + PE("Null value found\n"); + return TilerErrorInvalidArg; + } + + /*Check if the scan area co-ordinates are valid */ + if ((scan_area->x1 < scan_area->x0) || + (scan_area->y1 < scan_area->y0)) { + PE("Invalid scan area: %s\n", AREA_STR(a_str, scan_area)); + return TilerErrorInvalidScanArea; + } + + /* Check if we have a scan area bigger than the given input width + and height */ + if (w > INCL_LEN(start_x, end_x) || h > INCL_LEN(start_y, end_y)) { + PE("Scan area smaller than width and height\n"); + return TilerErrorInvalidDimension; + } + + /*Adjusting start_x and end_y, why scan beyond a point where we cant + allocate given wxh area */ + start_x = start_x - w + 1; /* + 1 to be inclusive */ + start_y = start_y - h + 1; + + + /* calculating remainder */ + remainder = (start_x % stride); + /* P("remainder = %d\n",remainder); */ + + /* if start_x is not divisible by stride, then skip to PREV aligned + column */ + start_x -= remainder ? (remainder) : 0 ; + /* P("StartX = %d\n",start_x); */ + + + /* check if we have enough width to accomodate the request from the + aligned (start_y) column */ + if (start_x < end_x) { + PE("No room to allocate at aligned lengths\n"); + return TilerErrorNoRoom; + } + + P2("Final stride : %d\n, start_x : %d end_x : %d start_y : %d end_y :\ + %d\n", stride, start_x, end_x, start_y, end_y); + + /* Start scanning: These scans are always inclusive ones so if we are + given a start x = 0 is a valid value so if we have a end_x = 255, + 255th element is also checked + */ + for (yy = start_y; yy >= end_y; --yy) { + for (xx = start_x; xx >= end_x; xx -= stride) { + if (!g_area_container[xx][yy].is_occupied) { + if (check_fit_r_and_b(w, h, xx, yy) == FIT) { + P3("Found Free Shoulder at: (%d, %d)\n", + xx, yy); + found_x = xx; + found_y = yy; + /* Insert this candidate, it is just a + co-ordinate, reusing Area */ + assign(&candidate_area, xx, yy, 0, 0); + insert_element(&short_listed, + &candidate_area, TWO_D); + num_short_listed++; + /*changing upper bound on x direction */ +#ifdef X_SCAN_LIMITER + end_x = xx + 1; +#endif + break; + } + } else { + /* Optimization required only for Non Aligned, + Aligned anyways skip by 32/64 tiles at a time */ + if (stride == 1 && g_area_container + [xx][yy].type == TWO_D) { + xx = g_area_container + [xx][yy].parent_area.x0; + P3("Moving to parent location start_x\ + (%d %d)\n", xx, yy); + } + } + + } + + /* if you find a free area shouldering the given scan area on + then we can break + */ +#ifdef Y_SCAN_LIMITER + if (found_x == start_x) + break; +#endif + } + + + if (!short_listed) { + PE("No candidates found in a given scan area\n"); + return TilerErrorNoRoom; + } + + /*Now if we are here it implies we have potential candidates*/ + ret = select_candidate(w, h, num_short_listed, short_listed, scan_area, + g_scan_criteria_r2l_b2t, alloc_area); + + if (ret != TilerErrorNone) + PE("Error in Selecting a Candidate\n"); + /*Just clean up resources */ + clean_list(&short_listed); + + /* dump_list_entries(short_listed); */ + return ret; + +} + + + +/** + * @description: raster scan left to right from top to bottom; find if there is + * a free area to fit a given w x h inside the 'scan area'. If there is a free + * area, then adds to short_listed candidates, which later is sent for selection + * as per pre-defined criteria. + * + * @input:'w x h' width and height of the allocation area. + * 'stride' - 64/32/None for start address alignment + * 'scan_area' - area in which the scan operation should take place + * + * @return 0 on success, non-0 error value on failure. On success + * the 'alloc_area' area contains TL and BR corners of the allocated area + * + */ + +s32 scan_l2r_t2b(u16 w, u16 h, u16 stride, struct area_spec *scan_area, + struct area_spec *alloc_area) +{ + s32 xx = 0, yy = 0; + s16 start_x = -1, end_x = -1, start_y = -1, end_y = -1; + s16 found_x = -1, found_y = -1; + u16 remainder; + struct area_spec_list *short_listed = NULL; + struct area_spec candidate_area = {0, 0, 0, 0}; + u16 num_short_listed = 0; + s32 ret = TilerErrorNone; + + P2("Scanning From Left 2 Right Top 2 Bottom, ScanArea: %s\n", + AREA_STR(a_str, scan_area)); + + start_x = scan_area->x0; + end_x = scan_area->x1; + start_y = scan_area->y0; + end_y = scan_area->y1; + + /*Basic checks */ + if (scan_area == NULL || alloc_area == NULL) { + PE("Null value found\n"); + return TilerErrorInvalidArg; + } + + /*Check if the scan area co-ordinates are valid */ + if ((scan_area->x1 < scan_area->x0) || + (scan_area->y1 < scan_area->y0)) { + PE("Invalid scan area: %s\n", AREA_STR(a_str, scan_area)); + return TilerErrorInvalidScanArea; + } + + /* Check if we have a scan area bigger than the given input width and + height */ + if (w > INCL_LEN(end_x, start_x) || h > INCL_LEN(end_y, start_y)) { + PE("Scan area smaller than width and height\n"); + return TilerErrorInvalidDimension; + } + + /* calculating remainder */ + remainder = (start_x % stride); + + /* if start_x is not divisible by stride, then skip to next aligned + column */ + start_x += remainder ? (stride - remainder) : 0 ; + + /* check if we have enough width to accomodate the request from the + aligned (start_y) column */ + if (w > INCL_LEN(end_x, start_x)) { + PE("No room to allocate at aligned lengths\n"); + return TilerErrorNoRoom; + } + + /*Adjusting end_x and end_y, why scan beyond a point where we cant + allocate given wxh area */ + end_x = end_x - w + 1; /* + 1 to be inclusive */ + end_y = end_y - h + 1; + + /* Just updating start and ends */ + + /* P(" stride : %d\n, start_x : %d end_x : %d start_y : %d end_y : %d\n" + ,stride, start_x,end_x,start_y,end_y);*/ + + /* Start scanning: These scans are always inclusive ones so if we are + given a start x = 0 is a valid value so if we have a end_x = 255, + 255th element is also checked + */ + for (yy = start_y; yy <= end_y; ++yy) { + for (xx = start_x; xx <= end_x; xx += stride) { + /* if NOT occupied */ + if (g_area_container[xx][yy].is_occupied == + NOT_OCCUPIED) { + if (FIT == check_fit_r_and_b(w, h, xx, yy)) { + P3("Found Free Shoulder at: (%d, %d)\n", + xx, yy); + found_x = xx; + found_y = yy; + /* Insert this candidate, it is just a + co-ordinate, reusing Area */ + assign(&candidate_area, xx, yy, 0, 0); + insert_element(&short_listed, + &candidate_area, TWO_D); + num_short_listed++; + /*changing upper bound on x direction */ +#ifdef X_SCAN_LIMITER + end_x = xx - 1; +#endif + break; + } + } else { + /* Optimization required only for Non Aligned, + Aligned anyways skip by 32/64 tiles at a time */ + if (stride == 1 && g_area_container + [xx][yy].type == TWO_D) { + xx = g_area_container + [xx][yy].parent_area.x1; + P3("Moving to parent location end_x\ + (%d %d)\n", xx, yy); + } + } + } + /* if you find a free area shouldering the given scan area on + then we can break + */ +#ifdef Y_SCAN_LIMITER + if (found_x == start_x) + break; +#endif + } + + if (!short_listed) { + PE("No candidates found in a given scan area\n"); + return TilerErrorNoRoom; + } + + /*Now if we are here it implies we have potential candidates*/ + ret = select_candidate(w, h, num_short_listed, short_listed, scan_area, + g_scan_criteria_l2r_t2b, alloc_area); + + if (ret != TilerErrorNone) + PE("Error in Selecting a Candidate\n"); + /*Just clean up resources */ + clean_list(&short_listed); + + /* dump_list_entries(short_listed); */ + return ret; +} + +/** + * @description: raster scan left to right from bottom to top; find if there is + * a free area to fit a given w x h inside the 'scan area'. If there is a free + * area, then adds to short_listed candidates, which later is sent for selection + * as per pre-defined criteria. + * + * @input:'w x h' width and height of the allocation area. + * 'stride' - 64/32/None for start address alignment + * 'scan_area' - area in which the scan operation should take place + * + * @return 0 on success, non-0 error value on failure. On success + * the 'alloc_area' area contains TL and BR corners of the allocated area + * + */ +s32 scan_l2r_b2t(u16 w, u16 h, u16 stride, struct area_spec *scan_area, + struct area_spec *alloc_area) +{ + s32 xx = 0, yy = 0; + s16 start_x = -1, end_x = -1, start_y = -1, end_y = -1; + s16 found_x = -1, found_y = -1; + u16 remainder; + struct area_spec_list *short_listed = NULL; + struct area_spec candidate_area = {0, 0, 0, 0}; + u16 num_short_listed = 0; + s32 ret = TilerErrorNone; + + P2("Scanning From Left 2 Right Bottom 2 Top, ScanArea: %s\n", + AREA_STR(a_str, scan_area)); + + start_x = scan_area->x0; + end_x = scan_area->x1; + start_y = scan_area->y0; + end_y = scan_area->y1; + + /*Basic checks */ + if (scan_area == NULL || alloc_area == NULL) { + PE("Null value found\n"); + return TilerErrorInvalidArg; + } + + /*Check if the scan area co-ordinates are valid */ + if ((scan_area->x1 < scan_area->x0) || + (scan_area->y0 < scan_area->y1)) { + PE("Invalid scan area: %s\n", AREA_STR(a_str, scan_area)); + return TilerErrorInvalidScanArea; + } + + /* Check if we have a scan area bigger than the given input width and + height */ + if (w > INCL_LEN(end_x, start_x) || h > INCL_LEN(start_y, end_y)) { + PE("Scan area smaller than width and height\n"); + return TilerErrorInvalidDimension; + } + + /* calculating remainder */ + remainder = (start_x % stride); + + /* if start_x is not divisible by stride, then skip to next aligned + column */ + start_x += remainder ? (stride - remainder) : 0 ; + + /* check if we have enough width to accomodate the request from the + aligned (start_x) column */ + if (w > INCL_LEN(end_x, start_x)) { + PE("No room to allocate at aligned lengths\n"); + return TilerErrorNoRoom; + } + + /*Adjusting end_x and end_y, why scan beyond a point where we cant + allocate given wxh area */ + end_x = end_x - w + 1; /* + 1 to be inclusive */ + start_y = start_y - h + 1; + + /* Just updating start and ends */ + + P2(" stride : %d\n, start_x : %d end_x : %d start_y : %d end_y : %d\n", + stride, start_x, end_x, start_y, end_y); + + /* Start scanning: These scans are always inclusive ones so if we are + given a start x = 0 is a valid value so if we have a end_x = 255, + 255th element is also checked + */ + for (yy = start_y; yy >= end_y; --yy) { + for (xx = start_x; xx <= end_x; xx += stride) { + /* if NOT occupied */ + if (!g_area_container[xx][yy].is_occupied) { + if (check_fit_r_and_b(w, h, xx, yy) == FIT) { + P3("Found Free Shoulder at: (%d, %d)\n", + xx, yy); + found_x = xx; + found_y = yy; + /* Insert this candidate, it is just a + co-ordinate, reusing Area */ + assign(&candidate_area, xx, yy, 0, 0); + insert_element(&short_listed, + &candidate_area, TWO_D); + num_short_listed++; + /*changing upper bound on x direction */ +#ifdef X_SCAN_LIMITER + end_x = xx - 1; +#endif + break; + } + } else { + /* Optimization required only for Non Aligned, + Aligned anyways skip by 32/64 tiles at a time */ + if (stride == 1 && g_area_container + [xx][yy].type == TWO_D) { + xx = g_area_container + [xx][yy].parent_area.x1; + P3("Moving to parent location end_x\ + (%d %d)\n", xx, yy); + } + } + } + + /* if you find a free area shouldering the given scan area on + then we can break + */ +#ifdef Y_SCAN_LIMITER + if (found_x == start_x) + break; +#endif + } + + if (!short_listed) { + PE("No candidates found in a given scan area\n"); + return TilerErrorNoRoom; + } + + /*Now if we are here it implies we have potential candidates*/ + ret = select_candidate(w, h, num_short_listed, short_listed, scan_area, + g_scan_criteria_l2r_b2t, alloc_area); + + if (ret != TilerErrorNone) + PE("Error in Selecting a Candidate\n"); + /*Just clean up resources */ + clean_list(&short_listed); + + /* dump_list_entries(short_listed); */ + return ret; +} + +/* +Note: In General the cordinates specified in the scan area area relavent to the +scan sweep directions. i.e A scan Area from Top Left Corner will have x0 <= x1 +and y0 <= y1. Where as A scan Area from bottom Right Corner will have x1 <= x0 +and y1 <= y0 +*/ + +/** + * @description: raster scan right to left from bottom to top; find if there are + * continuous free pages(one tile is one page, continuity always from left to + * right) inside the 'scan area'. If there are enough continous free pages, + * then it returns the start and end Tile/page co-ordinates inside 'alloc_area' + * + * @input:'num_of_pages' required, + * 'scan_area' - area in which the scan operation should take place + * + * @return 0 on success, non-0 error value on failure. On success + * the 'alloc_area' area contains start and end tile (inclusive). + * + */ +s32 scan_r2l_b2t_one_dim(u32 num_of_pages, struct area_spec *scan_area, + struct area_spec *alloc_area) +{ + u16 x, y; + u16 left_x, left_y, busy_x, busy_y; + s32 ret = TilerErrorNone; + s32 fit = NO_FIT; + + /*Basic checks */ + if (scan_area == NULL || alloc_area == NULL) { + PE("Null arguments found\n"); + return TilerErrorInvalidArg; + } + + if (scan_area->y0 < scan_area->y1) { + PE("Invalid scan area: %s\n", AREA_STR(a_str, scan_area)); + return TilerErrorInvalidScanArea; + } + + P2("Scanning From Right 2 Left Bottom 2 Top for 1D: ScanArea: %s\n", + AREA_STR(a_str, scan_area)); + + /* Note: Checking sanctity of scan area + * The reason for checking this that 1D allocations assume that the X + ranges the entire TilerSpace X ie ALL Columns + * The scan area can limit only the Y ie, Num of Rows for 1D allocation. + We also expect we could have only 1 row for 1D allocation + * i.e our scan_area y0 and y1 may have a same value. + */ + + /* + Thinking Aloud: Should i even worry about width (X dimension)?? + Can't i just ignore X and then take the u16 (Y dimension) and assume X + to range from MAX_X_DIMEN to 0 ?? + */ + if (MAX_X_DIMMENSION != (1 + (scan_area->x0 - scan_area->x1))) { + PE("Not a valid Scan Area, for 1D the width should be entire\ + Tiler u16 (%d) but it is (%d)\n", + MAX_X_DIMMENSION, 1 + (scan_area->x0 - scan_area->x1)); + return TilerErrorInvalidDimension; + } + + + /* checking if scan area can accomodate the num_of_pages */ + if (num_of_pages > MAX_X_DIMMENSION * INCL_LEN(scan_area->y0, + scan_area->y1)) { + PE("Num of Pages exceed Max possible (%d) for a given scan area\ + %s\n", MAX_X_DIMMENSION *\ + (scan_area->y0 - scan_area->y1), + AREA_STR(a_str, scan_area)); + return TilerErrorNoRoom; + } + + /* Ah we are here, it implies we can try fitting now after we have + checked everything */ + left_x = scan_area->x0; + left_y = scan_area->y0; + while (ret == TilerErrorNone) { + x = left_x; + y = left_y; + + /* P("Checking if (%d %d) is Occupied\n",x,y); */ + if (g_area_container[x][y].is_occupied == NOT_OCCUPIED) { + ret = move_left(x, y, (num_of_pages - 1), + &left_x, &left_y); + if (ret == TilerErrorNone) { + P3("Moved left to (%d %d) for num_of_pages (%d)\ + ,checking for fit\n", left_x, + left_y, (num_of_pages - 1)); + fit = check_fit_r_one_dim(left_x, left_y, + num_of_pages, &busy_x, &busy_y); + if (fit == FIT) { + /*Implies we are fine, we found a place + to put our 1D alloc */ + assign(alloc_area, left_x, left_y, + busy_x, busy_y); + P3("Allocated 1D area: %s\n", + AREA_STR(a_str, alloc_area)); + break; + } else { + /* Implies it did not fit, the busy_x, + busy_y will now be pointing to the Tile + that was found busy/Occupied */ + x = busy_x; + y = busy_y; + } + } else { + PE("Error in Moving left: Error Code %d,\ + Breaking....\n", ret); + break; + } + } + + /* Ah if we are here then we the Tile is occupied, now we might + move to the start of parent locations */ + if (g_area_container[x][y].type == ONE_D) { + busy_x = g_area_container[x][y].parent_area.x0; + busy_y = g_area_container[x][y].parent_area.y0; + } else { + busy_x = g_area_container[x][y].parent_area.x0; + busy_y = y; + } + x = busy_x; + y = busy_y; + + P3("Busy Tile found moving to ParentArea start :\ + (%d %d)\n", x, y); + ret = move_left(x, y, 1, &left_x, &left_y); + } + + + if (!fit) + ret = TilerErrorNoRoom; + + return ret; +} + + + +/** + * @description: + * + * + * + * + * @input: + * + * + * @return 0 on success, non-0 error value on failure. On success + * + * + */ +s32 scan_areas_and_find_fit(u16 w, u16 h, u16 stride, + struct area_spec *allocated_area) +{ + /* Checking for input arguments */ + /* No need to do this check, we have checked it in the parent call */ + struct area_spec scan_area = {0, 0, 0, 0}; + s32 ret = TilerErrorGeneral; + u16 boundary_x = 0, boundary_y = 0; + s32 need_scan_flag = 2; + + if (stride == 64) { + boundary_x = g_div_ln_btw_64_and_32_align.x1 - 1; + boundary_y = g_div_ln_btw_64_and_32_align.y1 - 1; + + /* more intelligence here */ + if (w > g_div_ln_btw_64_and_32_align.x1) { + boundary_x = MAX_X_DIMMENSION - 1; + --need_scan_flag; + } + if (h > g_div_ln_btw_64_and_32_align.y1) { + boundary_y = MAX_Y_DIMMENSION - 1; + --need_scan_flag; + } + + assign(&scan_area, 0, 0, boundary_x, boundary_y); + ret = scan_l2r_t2b(w, h, stride, &scan_area, allocated_area); + + if (ret != TilerErrorNone && need_scan_flag) { + /*Fall back Scan the entire Tiler area*/ + assign(&scan_area, 0, 0, MAX_X_DIMMENSION - 1, + MAX_Y_DIMMENSION - 1); + ret = scan_l2r_t2b(w, h, stride, &scan_area, + allocated_area); + } + } else if (stride == 32) { + + boundary_x = g_div_ln_btw_64_and_32_align.x1; + boundary_y = g_div_ln_btw_64_and_32_align.y1-1; + + /* more intelligence here */ + if (w > (MAX_X_DIMMENSION - g_div_ln_btw_64_and_32_align.x1)) { + boundary_x = 0; + --need_scan_flag; + } + if (h > g_div_ln_btw_64_and_32_align.y1) { + boundary_y = MAX_Y_DIMMENSION - 1; + --need_scan_flag; + } + + assign(&scan_area, MAX_X_DIMMENSION - 1, 0, boundary_x, + boundary_y); + ret = scan_r2l_t2b(w, h, stride, &scan_area, allocated_area); + + if (ret != TilerErrorNone && need_scan_flag) { + /*Fall back Scan the entire Tiler area*/ + assign(&scan_area, MAX_X_DIMMENSION - 1, 0, 0, + MAX_Y_DIMMENSION - 1); + ret = scan_r2l_t2b(w, h, stride, &scan_area, + allocated_area); + } + } else if (stride == 1) { + + /*The reason we use 64-Align area is because we dont want to + grow down and reduced 1D space */ + if (h > g_div_ln_btw_64_and_32_align.y1) { + need_scan_flag -= 2; + assign(&scan_area, 0, 0, MAX_X_DIMMENSION - 1, + MAX_Y_DIMMENSION - 1); + ret = scan_l2r_t2b(w, h, stride, &scan_area, + allocated_area); + } else { + assign(&scan_area, 0, + g_div_ln_btw_64_and_32_align.y1 - 1, + MAX_X_DIMMENSION - 1, 0); + /*Scans Up in 64 and 32 areas accross the whole width */ + ret = scan_l2r_b2t(w, h, stride, &scan_area, + allocated_area); + } + + if (ret != TilerErrorNone && need_scan_flag) { + assign(&scan_area, 0, 0, MAX_X_DIMMENSION - 1, + MAX_Y_DIMMENSION - 1); + ret = scan_l2r_t2b(w, h, stride, &scan_area, + allocated_area); + } + } + + return ret; + +} + + +s32 check_fit_r_and_b(u16 w, u16 h, u16 left_x, u16 top_y) +{ + u16 xx = 0, yy = 0; + s32 ret = FIT; + for (yy = top_y; yy < top_y+h; ++yy) { + for (xx = left_x; xx < left_x+w; ++xx) { + /*P("Checking Occ: (%d %d) - %d\n",xx,yy, + g_area_container[xx][yy].is_occupied); */ + if (g_area_container[xx][yy].is_occupied == OCCUPIED) { + ret = NO_FIT; + return ret; + } + } + } + return ret; +} + +s32 check_fit_r_one_dim(u16 x, u16 y, u32 num_of_pages, u16 *busy_x, + u16 *busy_y) +{ + s32 fit = FIT; + s32 ret = TilerErrorNone; + s32 i = 0; + + *busy_x = x; + *busy_y = y; + + P2("checking Fit for (%d) pages from (%d %d)\n ", num_of_pages, x, y); + while (i < num_of_pages) { + /* P("Checking if occupied (%d %d)\n",x, y); */ + if (g_area_container[x][y].is_occupied) { + /*Oh the Tile is occupied so we break and let know that + we encoutered a BUSY tile */ + fit = NO_FIT; + + /* Now going to the start of the parent allocation + so we avoid unecessary checking */ + + if (g_area_container[x][y].type == ONE_D) { + *busy_x = g_area_container[x][y].parent_area.x0; + *busy_y = g_area_container[x][y].parent_area.y0; + } else { + *busy_x = g_area_container[x][y].parent_area.x0; + *busy_y = y; + } + /* To Do: */ + /*Could also move left in case of TWO_D*/ + + P2("Busy Tile found moving to ParentArea start :\ + (%d %d)\n", *busy_x, *busy_y); + break; + } + + i++; + /* Sorry for this ugly code, i had to break before moving right + unecessarily */ + /* This also helps my dual purpose busy_x and busy_y with the + end co-ordinates of 1D allocations*/ + if (i == num_of_pages) + break; + + ret = move_right(x, y, 1, busy_x, busy_y); + if (ret != TilerErrorNone) { + PE("Error in Moving Right.. Breaking...\n"); + fit = NO_FIT; + break; + } else { + x = *busy_x; + y = *busy_y; + } + } + + return fit; +} + + + + +s32 insert_area_with_tiler_page(struct area_spec *area, struct tiler_page tile) +{ + s32 x, y; + if (area->x0 < 0 || area->x1 >= MAX_X_DIMMENSION || area->y0 < 0 || + area->y1 >= MAX_Y_DIMMENSION) { + PE("Invalid dimensions\n"); + return TilerErrorInvalidDimension; + } + P2("Inserting Tiler Page at (%d %d) (%d %d)\n", area->x0, area->y0, + area->x1, area->y1); + + /*If you are here: basic checks are done */ + for (x = area->x0; x <= area->x1; ++x) + for (y = area->y0; y <= area->y1; ++y) + g_area_container[x][y] = tile; + return TilerErrorNone; +} + + +s32 insert_pages_with_tiler_page(struct area_spec *area, struct tiler_page tile) +{ + + u16 x = 0, y = 0; + u16 right_x = 0, right_y = 0; + s32 ret = TilerErrorNone; + if (area == NULL) { + PE("Null input received\n"); + return TilerErrorInvalidArg; + } + + /*Note: By the way I expect Pages specified from Right to Left */ + /* TO DO: + *Do i really need to check integrity of area specs? + */ + + P2("Inserting Tiler Pages from (%d %d) to (%d %d)\n", area->x0, + area->y0, area->x1, area->y1); + + + x = area->x0; + y = area->y0; + while (!(x == area->x1 && y == area->y1)) { + /* P("(%d %d)\n",x,y); */ + g_area_container[x][y] = tile; + ret = move_right(x, y, 1, &right_x, &right_y); + if (ret == TilerErrorNone) { + x = right_x; + y = right_y; + } else { + PE("Error in Moving right\n"); + return ret; + } + } + /*Of course since this is inclusive we need to set the last tile too */ + g_area_container[x][y] = tile; + return TilerErrorNone; +} + +static s32 select_candidate(IN u16 w, IN u16 h, IN u16 num_short_listed, + IN struct area_spec_list *short_listed, IN struct area_spec *scan_area, + IN s32 criteria, OUT struct area_spec *alloc_area) +{ + /* book keeping the winner */ + struct area_spec_list *win_candidate = NULL; + struct nearness_factor win_near_factor = {0.0, 0.0}; + struct neighbour_stats win_neigh_stats = {0, 0, 0, 0, 0, 0, 0, 0}; + u16 win_total_neighs = 0; + + /*book keeping the current one being evaluated */ + struct area_spec_list *cur_candidate = NULL; + struct area_spec *cur_area = NULL; + struct nearness_factor cur_near_factor = {0.0, 0.0}; + struct neighbour_stats cur_neigh_stats = {0, 0, 0, 0, 0, 0, 0, 0}; + u16 cur_total_neighs = 0; + + /*Should i swap_flag? */ + u8 swap_flag = NO; + + /* I am sure that Alloc Area == NULL is checked earlier, but still + checking */ + if (alloc_area == NULL || scan_area == NULL) { + PE("NULL input found\n"); + return TilerErrorInvalidArg; + } + + /*if there is only one candidate then that is the selection*/ + if (num_short_listed == 1) { + /* Note: Sure we could have done this in the previous function, + but just wanted this to be cleaner so having + * one place where the selection is made. Here I am returning + the first one + */ + assign(alloc_area, short_listed->area.x0, short_listed->area.y0, + short_listed->area.x0 + w - 1, short_listed->area.y0 + h - 1); + return TilerErrorNone; + } + + /* If first found is enabled then we just provide bluntly the first + found candidate + * NOTE: For Horizontal bias we just give the first found, because our + * scan is Horizontal raster based and the first candidate will always + * be the same as if selecting the Horizontal one. + */ + if (criteria & CR_FIRST_FOUND || criteria & CR_BIAS_HORIZONTAL) { + assign(alloc_area, short_listed->area.x0, short_listed->area.y0, + short_listed->area.x0 + w - 1, short_listed->area.y0 + h - 1); + return TilerErrorNone; + } + + /* lets calculate for the first candidate and assign him the winner and + replace with the one who has better credentials w/ to the criteria */ + + win_candidate = short_listed; + get_busy_neigh_stats(w, h, &short_listed->area, &win_neigh_stats); + win_total_neighs = TOTAL_BOUNDARY(&win_neigh_stats) + + TOTAL_OCCUPIED(&win_neigh_stats); + get_nearness_factor(scan_area, &short_listed->area, &win_near_factor); + /* now check from second candidate onwards */ + cur_candidate = short_listed->next; + + while (cur_candidate != NULL) { + + /* Calculating all the required statistics, though not using + * all of them in all Criteria, but makes simpler code + */ + cur_area = &cur_candidate->area; + get_busy_neigh_stats(w, h, cur_area, &cur_neigh_stats); + get_nearness_factor(scan_area, cur_area, &cur_near_factor); + /* Check against the winner, if this one is better */ + cur_total_neighs = TOTAL_BOUNDARY(&cur_neigh_stats) + + TOTAL_OCCUPIED(&cur_neigh_stats); + + + + /* PREFER MAX NEIGHBOURS */ + if (criteria & CR_MAX_NEIGHS) { + if (cur_total_neighs > win_total_neighs) + swap_flag = YES; + } + + /* I am not checking for the condition where both + * INCL_LENS are same, because the logic does not find new + * shoulders on the same row after it finds a fit + */ + if (criteria & CR_BIAS_VERTICAL) { + P("cur distance :%d win distance: %d\n", + INCL_LEN_MOD(cur_area->y0, scan_area->y0), + INCL_LEN_MOD(win_candidate->area.y0, + scan_area->y0)) + if (INCL_LEN_MOD(cur_area->y0, scan_area->y0) > + INCL_LEN_MOD(win_candidate->area.y0, + scan_area->y0)) { + swap_flag = YES; + } + } + + + if (criteria & CR_DIAGONAL_BALANCE) { + + /* Check against the winner, if this one is better */ + cur_total_neighs = TOTAL_BOUNDARY(&cur_neigh_stats) + + TOTAL_OCCUPIED(&cur_neigh_stats); + + if (win_total_neighs <= cur_total_neighs) { + P3("Logic: Oh win_total_neighs(%d) <=\ + cur_total_neighs(%d)\n", + win_total_neighs, cur_total_neighs); + if (win_total_neighs < cur_total_neighs || + (TOTAL_OCCUPIED(&win_neigh_stats) < + TOTAL_OCCUPIED(&cur_neigh_stats))) { + P3("Logic: Found one with more\ + neighbours win_total_neighs:%d\ + cur_total_neighs:%d WinOcc: %d,\ + CurOcc: %d\n", win_total_neighs, + cur_total_neighs, + TOTAL_OCCUPIED( + &win_neigh_stats), + TOTAL_OCCUPIED( + &cur_neigh_stats)); + swap_flag = YES; + } else if ((TOTAL_OCCUPIED(&win_neigh_stats) == + TOTAL_OCCUPIED(&cur_neigh_stats))) { + /*If we are here implies that + win_total_neighs == cur_total_neighs + && Total_Occupied(win) == + TotalOccupied(cur) */ + /*Now we check the nearness factor */ + P3("Logic: Ah WinOcc(%d) == CurOcc:\ + (%d), so checking Nearness factor\n", + TOTAL_OCCUPIED(&win_neigh_stats), + TOTAL_OCCUPIED(&cur_neigh_stats)); + P3("Logic: Hmm winNF (%3f) & curNF\ + (%3f)\n", + (double)(win_near_factor.nf_x + + win_near_factor.nf_y), + (double)(cur_near_factor.nf_x + + cur_near_factor.nf_y)); + if ((s32)(win_near_factor.nf_x + + win_near_factor.nf_y) > + (s32)(cur_near_factor.nf_x + + cur_near_factor.nf_y)) { + P3("Logic: So, nearness factor\ + of Cur is <\ + than Win\n"); + swap_flag = YES; + } + + } + + } + + + } + + /* Swap the win candidate with cur-candidate with better + * credentials + */ + if (swap_flag) { + win_candidate = cur_candidate; + win_near_factor = cur_near_factor; + win_neigh_stats = cur_neigh_stats; + win_total_neighs = cur_total_neighs; + swap_flag = NO; + } + + /*Go to next candidate */ + cur_candidate = cur_candidate->next; + + } + + + assign(alloc_area, win_candidate->area.x0, win_candidate->area.y0, + win_candidate->area.x0+w - 1, win_candidate->area.y0 + h - 1); + return TilerErrorNone; +} + +s32 get_nearness_factor(struct area_spec *scan_area, + struct area_spec *candidate, struct nearness_factor *nf) +{ + if (nf == NULL || scan_area == NULL || candidate == NULL) { + PE("NULL input found\n"); + return TilerErrorInvalidArg; + } + + /* For the following calculation we need worry of +/- sign, the + relative distances take of this */ + nf->nf_x = (s32)(candidate->x0 - scan_area->x0)/ + (scan_area->x1 - scan_area->x0); + nf->nf_y = (s32)(candidate->y0 - scan_area->y0)/ + (scan_area->y1 - scan_area->y0); + return TilerErrorNone; + +} + +/*Neighbours + + |<-----T------>| + _ _______________ _ + L | Area | R + _ |______________|_ + |<-----B------>| +*/ +s32 get_busy_neigh_stats(u16 width, u16 height, +struct area_spec *top_left_corner, struct neighbour_stats *neighbour_stat) +{ + s16 xx = 0, yy = 0; + struct area_spec left_edge; + struct area_spec right_edge; + struct area_spec top_edge; + struct area_spec bottom_edge; + + if (neighbour_stat == NULL) { + PE("Null input received\n"); + return TilerErrorInvalidArg; + } + + if (width == 0 || height == 0) { + PE("u16 or height is Zero \n"); + return TilerErrorInvalidArg; + } + + /*Clearing any exisiting values */ + memset(neighbour_stat, 0, sizeof(struct neighbour_stats)); + + /* Finding Top Edge */ + assign(&top_edge, top_left_corner->x0, top_left_corner->y0, + top_left_corner->x0 + width - 1, top_left_corner->y0); + + /* Finding Bottom Edge */ + assign(&bottom_edge, top_left_corner->x0, + top_left_corner->y0+height - 1, + top_left_corner->x0 + width - 1, + top_left_corner->y0 + height - 1); + + /* Finding Left Edge */ + assign(&left_edge, top_left_corner->x0, top_left_corner->y0, + top_left_corner->x0, top_left_corner->y0 + height - 1); + + /* Finding Right Edge */ + assign(&right_edge, top_left_corner->x0 + width - 1, + top_left_corner->y0, + top_left_corner->x0 + width - 1, top_left_corner->y0 + height - 1); + + /* dump_area(&top_edge); + dump_area(&right_edge); + dump_area(&bottom_edge); + dump_area(&left_edge); + */ + + /*Parsing through top & bottom edge*/ + for (xx = top_edge.x0; xx <= top_edge.x1; ++xx) { + if ((top_edge.y0 - 1) < 0) { + neighbour_stat->top_boundary++; + } else { + if (g_area_container[xx][top_edge.y0 - 1].is_occupied) + neighbour_stat->top_occupied++; + } + + /* Realized that we need to pass through the same iters for + bottom edge. So trying to reduce passes by manipulating the + checks */ + if ((bottom_edge.y0 + 1) > (MAX_Y_DIMMENSION - 1)) { + neighbour_stat->bottom_boundary++; + } else { + if (g_area_container[xx][bottom_edge.y0+1].is_occupied) + neighbour_stat->bottom_occupied++; + } + + } + + /* Parsing throught left and right edge */ + for (yy = left_edge.y0; yy <= left_edge.y1; ++yy) { + if ((left_edge.x0 - 1) < 0) { + neighbour_stat->left_boundary++; + } else { + if (g_area_container[left_edge.x0 - 1][yy].is_occupied) + neighbour_stat->left_occupied++; + } + + if ((right_edge.x0 + 1) > (MAX_X_DIMMENSION - 1)) { + neighbour_stat->right_boundary++; + } else { + if (g_area_container[right_edge.x0 + 1][yy].is_occupied) + neighbour_stat->right_occupied++; + } + + } + return TilerErrorNone; +} + +/* Test insert + * Dummy insertion, No Error Checking. + */ +s32 test_insert(IN struct area_spec_list *new_area) +{ + struct tiler_page tile; + struct area_spec area = new_area->area; + + if (new_area == NULL) + return TilerErrorInvalidArg; + + tile.is_occupied = OCCUPIED; + tile.reserved = 0; + tile.parent_area.x0 = area.x0; + tile.parent_area.y0 = area.y0; + tile.parent_area.x1 = area.x1; + tile.parent_area.y1 = area.y1; + tile.type = new_area->area_type; + + if (new_area->area_type == TWO_D) + return insert_area_with_tiler_page(&area, tile); + + return insert_pages_with_tiler_page(&area, tile); +} + +s32 test_dump_alloc_list() +{ + dump_list_entries(g_allocation_list); + return TilerErrorNone; +} + + + +s32 test_allocate_2D_area(IN u16 w, IN u16 h, IN enum alignment align, + u16 corner, OUT struct area_spec *allocated_area) +{ + + struct area_spec scan_area = {0, 0, 0, 0}; + s32 ret = TilerErrorNone; + u16 stride = ALIGN_STRIDE(align); + struct tiler_page tile; + + /*check if width and height are within limits */ + if (w > MAX_X_DIMMENSION || w == 0 || h > MAX_Y_DIMMENSION || h == 0) { + PE("Invalid dimension:: %d x %d\n", w, h); + return TilerErrorInvalidDimension; + } + + /* Checking for input arguments */ + if (allocated_area == NULL) { + PE("NULL input found\n"); + return TilerErrorInvalidArg; + } + + if (corner == TL_CORNER) { + assign(&scan_area, 0, 0, (MAX_X_DIMMENSION - 1), + (MAX_Y_DIMMENSION - 1)); + ret = scan_l2r_t2b(w, h, stride, &scan_area, allocated_area); + } else if (corner == TR_CORNER) { + assign(&scan_area, (MAX_X_DIMMENSION-1), 0, 0, + (MAX_Y_DIMMENSION - 1)); + ret = scan_r2l_t2b(w, h, stride, &scan_area, allocated_area); + } else if (corner == BL_CORNER) { + assign(&scan_area, 0, (MAX_Y_DIMMENSION - 1), + (MAX_X_DIMMENSION - 1), 0); + ret = scan_l2r_b2t(w, h, stride, &scan_area, allocated_area); + } else { + assign(&scan_area, (MAX_X_DIMMENSION - 1), + (MAX_Y_DIMMENSION - 1), 0, 0); + ret = scan_r2l_b2t(w, h, stride, &scan_area, allocated_area); + } + + MUTEX_LOCK(&g_mutex); + + if (ret != TilerErrorNone) { + PE("Did not find anything in the given area\n"); + } else { + P2("Yahoo found a fit: %s\n", AREA_STR(a_str, allocated_area)); + tile.is_occupied = OCCUPIED; + assign(&tile.parent_area, allocated_area->x0, + allocated_area->y0, allocated_area->x1, allocated_area->y1); + + /* some id, not useful now */ + tile.reserved = g_id++; + + /* Saying that type is 2D */ + tile.type = TWO_D; + + /* inserting into tiler container */ + insert_area_with_tiler_page(allocated_area, tile); + + /*updating the list of allocations */ + insert_element(&g_allocation_list, allocated_area, TWO_D); + } + + MUTEX_REL(&g_mutex); + return ret; + +} + +s32 test_get_busy_neigh_stats(u16 width, u16 height, + struct area_spec *top_left_corner, + struct neighbour_stats *neighbour_stat) +{ + return get_busy_neigh_stats(width, height, top_left_corner, + neighbour_stat); +} + + +s32 test_check_busy(IN u16 x, u16 y) +{ + return (s32)g_area_container[x][y].is_occupied; +} + +/** + @description: Retrieves the parent area of the page at x0, y0 if + occupied + @input:co-ordinates of the page (x0, y0) whoes parent area is required + @return 0 on success, non-0 error value on failure. On success + + parent_area will contain co-ordinates (TL & BR corner) of the parent + area +*/ +s32 retrieve_parent_area(u16 x0, u16 y0, struct area_spec *parent_area) +{ + if (parent_area == NULL) { + PE("NULL input found\n"); + return TilerErrorInvalidArg; + } + + if (x0 < 0 || x0 >= MAX_X_DIMMENSION || y0 < 0 || + y0 >= MAX_Y_DIMMENSION){ + PE("Invalid dimensions\n"); + return TilerErrorInvalidDimension; + } + + MUTEX_LOCK(&g_mutex); + + assign(parent_area, 0, 0, 0, 0); + + if (g_area_container[x0][y0].is_occupied) { + parent_area->x0 = g_area_container[x0][y0].parent_area.x0; + parent_area->y0 = g_area_container[x0][y0].parent_area.y0; + parent_area->x1 = g_area_container[x0][y0].parent_area.x1; + parent_area->y1 = g_area_container[x0][y0].parent_area.y1; + } + + MUTEX_REL(&g_mutex); + return TilerErrorNone; +} + diff --git a/drivers/media/video/tiler/tcm/tcm.h b/drivers/media/video/tiler/tcm/tcm.h new file mode 100644 index 000000000000..c01799722fa2 --- /dev/null +++ b/drivers/media/video/tiler/tcm/tcm.h @@ -0,0 +1,103 @@ +/* + * tcm.h + * + * Author: Ravi Ramachandra <r.ramachandra@ti.com> + * + * Tiler Container manager functions for TI OMAP processors. + * + * Copyright (C) 2009-2010 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef _TCM_H_ +#define _TCM_H_ + +#include "tcm_pri.h" +#include "tcm_utils.h" + +#define OCCUPIED YES +#define NOT_OCCUPIED NO + +#define FIT YES +#define NO_FIT NO + + +/*Provide inclusive length between co-ordinates */ +#define INCL_LEN(high, low) (high - low + 1) + +#define INCL_LEN_MOD(start, end) ((start > end) ? (start-end + 1) : \ +(end - start + 1)) + +#define TOTAL_BOUNDARY(stat) ((stat)->top_boundary + (stat)->bottom_boundary + \ + (stat)->left_boundary + (stat)->right_boundary) +#define TOTAL_OCCUPIED(stat) ((stat)->top_occupied + (stat)->bottom_occupied + \ + (stat)->left_occupied + (stat)->right_occupied) + + +#define TILER_USER_SPACE + +#ifdef TILER_USER_SPACE +#define MUTEX_LOCK(m) (mutex_lock(m)) +#define MUTEX_REL(m) (mutex_unlock(m)) +#endif + +enum Criteria { + CR_MAX_NEIGHS = 0x01, + CR_FIRST_FOUND = 0x10, + CR_BIAS_HORIZONTAL = 0x20, + CR_BIAS_VERTICAL = 0x40, + CR_DIAGONAL_BALANCE = 0x80 +}; + +struct nearness_factor { + s32 nf_x; + s32 nf_y; +}; + + + +struct tiler_page { + u8 is_occupied; /* is tiler_page Occupied */ + /* Parent area to which this tiler_page belongs */ + struct area_spec parent_area; + u32 type; /* 1D or 2D */ + u32 reserved; +}; + + +/*@descrption: init_tiler + *Initializes the tiler container + */ +s32 init_tiler(void); + +s32 deinit_tiler(void); + +s32 allocate_2d_area(IN u16 w, IN u16 h, IN enum alignment align, + OUT struct area_spec *allocated_area); + +s32 allocate_1d_pages(IN u32 num_of_pages, + OUT struct area_spec *allocated_pages); + +s32 deallocate(IN struct area_spec *to_be_removed_area); + +s32 test_dump_alloc_list(void); + +s32 test_allocate_2D_area(IN u16 w, IN u16 h, IN enum alignment align, + u16 corner, OUT struct area_spec *allocated_area); + +s32 test_get_busy_neigh_stats(u16 width, u16 height, + struct area_spec *top_left_corner, + struct neighbour_stats *neighbour_stat); + +s32 test_check_busy_tile(IN u16 x, u16 y); + +s32 retrieve_parent_area(u16 x0, u16 y0, struct area_spec *parent_area); + +#endif diff --git a/drivers/media/video/tiler/tcm/tcm_dbg.h b/drivers/media/video/tiler/tcm/tcm_dbg.h new file mode 100644 index 000000000000..072c18d66124 --- /dev/null +++ b/drivers/media/video/tiler/tcm/tcm_dbg.h @@ -0,0 +1,61 @@ +/* + * tcm_dbg.h + * + * Debug Utility definitions. + * + * Copyright (C) 2008-2010 Texas Instruments, Inc. + * + * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + + +#ifndef _TILER_DEBUG_ +#define _TILER_DEBUG_ + +#undef DEBUG +/* #define DEBUG_ENTRY_EXIT */ + +#undef DEBUG_ALL + + +#ifdef DEBUG +#define P(fmt, args...) printk(KERN_NOTICE "%s()::[%d]\n", __func__, __LINE__); + +#else +#define P(fmt, args...) +#endif + +#define PE(fmt, args...) printk(KERN_ERR "%s()::[%d]\n", __func__, __LINE__); + +#ifdef DEBUG_ALL +#define L1 +#define L2 +#define L3 +#endif + + +#ifdef L1 +#define P1 P +#else +#define P1(args...) +#endif + +#ifdef L2 +#define P2 P +#else +#define P2(args...) +#endif + +#ifdef L3 +#define P3 P +#else +#define P3(args...) +#endif +#endif + diff --git a/drivers/media/video/tiler/tcm/tcm_pri.h b/drivers/media/video/tiler/tcm/tcm_pri.h new file mode 100644 index 000000000000..6f4a33c6801b --- /dev/null +++ b/drivers/media/video/tiler/tcm/tcm_pri.h @@ -0,0 +1,87 @@ +#ifndef _TCM_PRIVATE_H_ +#define _TCM_PRIVATE_H_ + +#define IN +#define OUT +#define INOUT + +#define MAX_X_DIMMENSION 256 +#define MAX_Y_DIMMENSION 128 + +#define YES 1 +#define NO 0 + +#define TL_CORNER 0 +#define TR_CORNER 1 +#define BL_CORNER 3 +#define BR_CORNER 4 + + +/*Note Alignment 64 gets the highest priority */ +#define ALIGN_STRIDE(align)((align == ALIGN_64) ? 64 : ((align == ALIGN_32) ? \ + 32 : ((align == ALIGN_16) ? 16 : 1))) + +enum tiler_error { + TilerErrorNone = 0, + TilerErrorGeneral = -1, + TilerErrorInvalidDimension = -2, + TilerErrorNoRoom = -3, + TilerErrorInvalidArg = -4, + TilerErrorMatchNotFound = -5, + TilerErrorOverFlow = -6, + TilerErrorInvalidScanArea = -7, + TilerErrorNotSupported = -8, +}; + +enum alignment { + ALIGN_NONE = 0, + /*ALIGN_16 = 0x1,*/ + ALIGN_32 = 0x1, /*0x2 */ + ALIGN_64 = 0x2, /*0x4 */ + ALIGN_16 = 0x3 /* 0x1*/ +}; + +enum dim_type { + ONE_D = 1, + TWO_D = 2 +}; + + +struct area_spec { + u16 x0; + u16 y0; + u16 x1; + u16 y1; +}; + + +struct area_spec_list; + +struct area_spec_list { + struct area_spec area; + u16 area_type; + struct area_spec_list *next; +}; + + +/*Everything is a rectangle with four sides and on + * each side you could have a boundaryor another Tile. + * The tile could be Occupied or Not. These info is stored + */ +struct neighbour_stats { + /* num of tiles on left touching the boundary */ + u16 left_boundary; + /* num of tiles on left that are occupied */ + u16 left_occupied; + + u16 top_boundary; + u16 top_occupied; + + u16 right_boundary; + u16 right_occupied; + + u16 bottom_boundary; + u16 bottom_occupied; +}; + +#endif diff --git a/drivers/media/video/tiler/tcm/tcm_utils.c b/drivers/media/video/tiler/tcm/tcm_utils.c new file mode 100644 index 000000000000..b3980d861324 --- /dev/null +++ b/drivers/media/video/tiler/tcm/tcm_utils.c @@ -0,0 +1,261 @@ +#include <linux/init.h> +#include <linux/module.h> + +#include "tcm_utils.h" +#include "tcm_dbg.h" + +/* +* Assignment Utility Function +*/ +void assign(IN struct area_spec *a, IN u16 x0, IN u16 y0, IN u16 x1, IN u16 y1) +{ + a->x0 = x0; + a->x1 = x1; + a->y1 = y1; + a->y0 = y0; +} + +void dump_area(struct area_spec *area) +{ + printk(KERN_NOTICE "(%d %d) - (%d %d)\n", area->x0, area->y0, area->x1, + area->y1); +} + + +/* + * Inserts a given area at the end of a given list + */ +s32 insert_element(INOUT struct area_spec_list **list, + IN struct area_spec *newArea, IN u16 area_type) +{ + struct area_spec_list *list_iter = *list; + struct area_spec_list *new_elem = NULL; + if (list_iter == NULL) { + list_iter = kmalloc(sizeof(struct area_spec_list), GFP_KERNEL); + /* P("Created new List: 0x%x\n",list_iter); */ + assign(&list_iter->area, newArea->x0, newArea->y0, + newArea->x1, newArea->y1); + list_iter->area_type = area_type; + list_iter->next = NULL; + *list = list_iter; + return TilerErrorNone; + } + + /* move till you find the last element */ + while (list_iter->next != NULL) + list_iter = list_iter->next; + + /* now we are the last one */ + /* P("Adding to the end of list\n"); */ + /*To Do: Check for malloc failures */ + new_elem = kmalloc(sizeof(struct area_spec_list), GFP_KERNEL); + assign(&new_elem->area, newArea->x0, newArea->y0, newArea->x1, + newArea->y1); + new_elem->area_type = area_type; + new_elem->next = NULL; + list_iter->next = new_elem; + return TilerErrorNone; +} + +s32 rem_element_with_match(struct area_spec_list **listHead, + struct area_spec *to_be_removed, u16 *area_type) +{ + struct area_spec_list *temp_list = NULL; + struct area_spec_list *matched_elem = NULL; + struct area_spec *cur_area = NULL; + u8 found_flag = NO; + + /*If the area to be removed matchs the list head itself, + we need to put the next one as list head */ + if (*listHead != NULL) { + cur_area = &(*listHead)->area; + if (cur_area->x0 == to_be_removed->x0 && cur_area->y0 == + to_be_removed->y0 && cur_area->x1 == + to_be_removed->x1 && cur_area->y1 == + to_be_removed->y1) { + *area_type = (*listHead)->area_type; + P1("Match found, Now Removing Area : %s\n", + AREA_STR(a_str, cur_area)); + + temp_list = (*listHead)->next; + kfree(*listHead); + *listHead = temp_list; + return TilerErrorNone; + } + } + + temp_list = *listHead; + while (temp_list != NULL) { + /* we have already checked the list head, + we check for the second in list */ + if (temp_list->next != NULL) { + cur_area = &temp_list->next->area; + if (cur_area->x0 == to_be_removed->x0 && cur_area->y0 == + to_be_removed->y0 && cur_area->x1 == + to_be_removed->x1 && cur_area->y1 == + to_be_removed->y1) { + P1("Match found, Now Removing Area : %s\n", + AREA_STR(a_str, cur_area)); + matched_elem = temp_list->next; + *area_type = matched_elem->area_type; + temp_list->next = matched_elem->next; + kfree(matched_elem); + matched_elem = NULL; + found_flag = YES; + break; + } + } + temp_list = temp_list->next; + } + + if (found_flag) + return TilerErrorNone; + + PE("Match Not found :%s\n", AREA_STR(a_str, to_be_removed)); + + return TilerErrorMatchNotFound; +} + +s32 clean_list(struct area_spec_list **list) +{ + struct area_spec_list *temp_list = NULL; + struct area_spec_list *to_be_rem_elem = NULL; + + if (*list != NULL) { + temp_list = (*list)->next; + while (temp_list != NULL) { + /*P("Freeing :"); + dump_area(&temp_list->area);*/ + to_be_rem_elem = temp_list->next; + kfree(temp_list); + temp_list = to_be_rem_elem; + } + + /* freeing the head now */ + kfree(*list); + *list = NULL; + } + + return TilerErrorNone; +} + +s32 dump_list_entries(IN struct area_spec_list *list) +{ + struct area_spec_list *list_iter = NULL; + char a_str[32] = {'\0'}; + P("Printing List Entries:\n"); + + if (list == NULL) { + PE("NULL List found\n"); + return TilerErrorInvalidArg; + } + + /*Now if we have a valid list, let us print the values */ + list_iter = list; + do { + printk(KERN_NOTICE "%dD:%s\n", list_iter->area_type, + AREA_STR(a_str, &list_iter->area)); + /* dump_area(&list_iter->area); */ + list_iter = list_iter->next; + } while (list_iter != NULL); + + return TilerErrorNone; +} + + + +s32 dump_neigh_stats(struct neighbour_stats *neighbour) +{ + P("Top Occ:Boundary %d:%d\n", neighbour->top_occupied, + neighbour->top_boundary); + P("Bot Occ:Boundary %d:%d\n", neighbour->bottom_occupied, + neighbour->bottom_boundary); + P("Left Occ:Boundary %d:%d\n", neighbour->left_occupied, + neighbour->left_boundary); + P("Rigt Occ:Boundary %d:%d\n", neighbour->right_occupied, + neighbour->right_boundary); + return TilerErrorNone; +} + +s32 move_left(u16 x, u16 y, u32 num_of_pages, u16 *xx, u16 *yy) +{ + /* Num of Pages remaining to the left of the same ROW. */ + u16 num_of_pages_left = x; + u16 remain_pages = 0; + + /* I want this function to be really fast and dont take too much time, + so i will not do detailed checks */ + if (x > MAX_X_DIMMENSION || y > MAX_Y_DIMMENSION || xx == NULL || + yy == NULL) { + PE("Error in input arguments\n"); + return TilerErrorInvalidArg; + } + + /*Checking if we are going to go out of bound with the given + num_of_pages */ + if (num_of_pages > x + (y * MAX_X_DIMMENSION)) { + PE("Overflows off the top left corner, can go at the Max (%d)\ + to left from (%d, %d)\n", (x + y * MAX_X_DIMMENSION), + x, y); + return TilerErrorOverFlow; + } + + if (num_of_pages > num_of_pages_left) { + /* we fit the num of Pages Left on the same column */ + remain_pages = num_of_pages - num_of_pages_left; + + if (0 == remain_pages % MAX_X_DIMMENSION) { + *xx = 0; + *yy = y - remain_pages / MAX_X_DIMMENSION; + } else { + *xx = MAX_X_DIMMENSION - remain_pages % + MAX_X_DIMMENSION; + *yy = y - (1 + remain_pages / MAX_X_DIMMENSION); + } + } else { + *xx = x - num_of_pages; + *yy = y; + } + + return TilerErrorNone; +} + +s32 move_right(u16 x, u16 y, u32 num_of_pages, u16 *xx, u16 *yy) +{ + u32 avail_pages = (MAX_X_DIMMENSION - x - 1) + + (MAX_Y_DIMMENSION - y - 1) * MAX_X_DIMMENSION; + /* Num of Pages remaining to the Right of the same ROW. */ + u16 num_of_pages_right = MAX_X_DIMMENSION - 1 - x; + u16 remain_pages = 0; + + if (x > MAX_X_DIMMENSION || y > MAX_Y_DIMMENSION || xx == NULL || + yy == NULL) { + PE("Error in input arguments"); + return TilerErrorInvalidArg; + } + + /*Checking if we are going to go out of bound with the given + num_of_pages */ + if (num_of_pages > avail_pages) { + PE("Overflows off the top Right corner, can go at the Max (%d)\ + to Right from (%d, %d)\n", avail_pages, x, y); + return TilerErrorOverFlow; + } + + if (num_of_pages > num_of_pages_right) { + remain_pages = num_of_pages - num_of_pages_right; + + if (0 == remain_pages % MAX_X_DIMMENSION) { + *xx = MAX_X_DIMMENSION - 1; + *yy = y + remain_pages / MAX_X_DIMMENSION; + } else { + *xx = remain_pages % MAX_X_DIMMENSION - 1; + *yy = y + (1 + remain_pages / MAX_X_DIMMENSION); + } + } else { + *xx = x + num_of_pages; + *yy = y; + } + + return TilerErrorNone; +} diff --git a/drivers/media/video/tiler/tcm/tcm_utils.h b/drivers/media/video/tiler/tcm/tcm_utils.h new file mode 100644 index 000000000000..ac6a02d2cb43 --- /dev/null +++ b/drivers/media/video/tiler/tcm/tcm_utils.h @@ -0,0 +1,29 @@ +#ifndef _TILER_UTILS_H +#define _TILER_UTILS_H + +#include "tcm_pri.h" +#include "tcm_dbg.h" + +#define AREA_STR(a_str, area) ({ \ + sprintf(a_str, "(%03d %03d)-(%03d %03d)", (area)->x0, (area)->y0, \ + (area)->x1, (area)->y1); a_str; }) + +void assign(struct area_spec *a, u16 x0, u16 y0, u16 x1, u16 y1); +void dump_area(struct area_spec *area); + +s32 insert_element(INOUT struct area_spec_list **list, + IN struct area_spec *newArea, IN u16 area_type); + +s32 dump_list_entries(IN struct area_spec_list *list); + +s32 dump_neigh_stats(struct neighbour_stats *neighbour); + +s32 rem_element_with_match(struct area_spec_list **list, + struct area_spec *to_be_removed, u16 *area_type); + +s32 clean_list(struct area_spec_list **list); + +s32 move_left(u16 x, u16 y, u32 num_of_pages, u16 *xx, u16 *yy); +s32 move_right(u16 x, u16 y, u32 num_of_pages, u16 *xx, u16 *yy); + +#endif diff --git a/drivers/media/video/tiler/tiler.c b/drivers/media/video/tiler/tiler.c index 0e0c572b08da..13841678bf5b 100644 --- a/drivers/media/video/tiler/tiler.c +++ b/drivers/media/video/tiler/tiler.c @@ -28,12 +28,13 @@ #include <linux/sched.h> #include <linux/errno.h> #include <linux/mutex.h> +#include <linux/dma-mapping.h> #include <linux/pagemap.h> /* page_cache_release() */ #include "tiler.h" #include "tiler_def.h" -#include "dmm_2d_alloc.h" #include "../dmm/dmm.h" +#include "tcm/tcm.h" struct tiler_dev { struct cdev cdev; @@ -60,10 +61,12 @@ struct mem_info { u32 *page; /* virt addr to page-list */ dma_addr_t page_pa; /* phys addr to page-list */ u32 size; /* size of page-list */ - u32 num_pgs; /* number of pages in page-list */ + u32 num_pg; /* number of pages in page-list */ s8 mapped; /* flag to indicate user mapped mem */ u32 usr; /* user space address */ u32 *pg_ptr; /* list of struct page pointers */ + struct area_spec area; /* return struct from tiler area mgr */ + u32 *mem; /* pointer to list of phys addresses */ }; static s32 tiler_major; @@ -75,11 +78,8 @@ static struct __buf_info buf_list; static struct mem_info mem_list; static struct mutex mtx; -/* required by container manager */ -static struct dmmTILERContCtxT *tilctx; - -static s32 __set_area(enum tiler_fmt fmt, u32 width, u32 height, u32 *x_area, - u32 *y_area) +static s32 __set_area(enum tiler_fmt fmt, u32 width, u32 height, u8 *x_area, + u8 *y_area) { s32 x_pagedim = 0, y_pagedim = 0; u16 tiled_pages_per_ss_page = 0; @@ -125,12 +125,12 @@ static s32 __set_area(enum tiler_fmt fmt, u32 width, u32 height, u32 *x_area, break; } - *x_area = (width + x_pagedim - 1) / x_pagedim - 1; - *y_area = (height + y_pagedim - 1) / y_pagedim - 1; + *x_area = (u8)((width + x_pagedim - 1) / x_pagedim - 1); + *y_area = (u8)((height + y_pagedim - 1) / y_pagedim - 1); tiled_pages_per_ss_page = 64; - *x_area = ((*x_area + tiled_pages_per_ss_page) & - ~(tiled_pages_per_ss_page - 1)) - 1; + *x_area = (u8)(((*x_area + tiled_pages_per_ss_page) & + ~(tiled_pages_per_ss_page - 1)) - 1); if (*x_area > TILER_WIDTH || *y_area > TILER_HEIGHT) return -1; @@ -260,9 +260,9 @@ static s32 tiler_mmap(struct file *filp, struct vm_area_struct *vma) static s32 map_buffer(enum tiler_fmt fmt, u32 width, u32 height, u32 *sys_addr, u32 usr_addr) { - u32 num_pages = -1, x_area = -1, y_area = -1, tmp = -1, write = 0; - s32 i = -1; - struct dmmTILERContPageAreaT *area_desc = NULL, __area_desc = {0}; + u16 num_page = 0, x_page = 0, y_page = 0; + u32 i = 0, tmp = -1; + u8 x_area = 0, y_area = 0, write = 0; struct pat pat_desc = {0}; struct mem_info *mi = NULL; struct page *page = NULL; @@ -278,27 +278,25 @@ static s32 map_buffer(enum tiler_fmt fmt, u32 width, u32 height, u32 *sys_addr, if (__set_area(fmt, width, height, &x_area, &y_area)) return -EFAULT; - __area_desc.x1 = (u16)x_area; - __area_desc.y1 = (u16)y_area; - - area_desc = alloc_2d_area(tilctx, &__area_desc); - if (!area_desc) - return -ENOMEM; - - /* formulate system space address */ - *sys_addr = __get_alias_addr(fmt, area_desc->x0, area_desc->y0); - - /* get user pages */ - area_desc->patCustomPages = 1; - area_desc->xPageCount = area_desc->x1 - area_desc->x0 + 1; - area_desc->yPageCount = area_desc->y1 - area_desc->y0 + 1; - num_pages = area_desc->xPageCount * area_desc->yPageCount; - mi = kmalloc(sizeof(struct mem_info), GFP_KERNEL); if (!mi) return -ENOMEM; memset(mi, 0x0, sizeof(struct mem_info)); + if (allocate_1d_pages(ROUND_UP((x_area + 1) * (y_area + 1), 256), + &mi->area)) { + kfree(mi); return -ENOMEM; } + + /* formulate system space address */ + *sys_addr = __get_alias_addr(fmt, mi->area.x0, mi->area.y0); + + /* allocate pages */ + /* TODO: page count should be u8 @ 256 max */ + /* TODO: num_pages should be u16 @ 32k max */ + x_page = mi->area.x1 - mi->area.x0 + 1; + y_page = mi->area.y1 - mi->area.y0 + 1; + num_page = x_page * y_page; + mi->sys_addr = *sys_addr; mi->usr = usr_addr; @@ -330,14 +328,14 @@ static s32 map_buffer(enum tiler_fmt fmt, u32 width, u32 height, u32 *sys_addr, return -EFAULT; } - mi->num_pgs = width / TILER_PAGE; - tmp = (mi->num_pgs + 63) & ~63; + mi->num_pg = width / TILER_PAGE; + tmp = ROUND_UP(mi->num_pg, 256); /* (mi->num_pg + 63) & ~63; */ /* * Check that the number of user pages match what * the container manager calculates. */ - if (num_pages != tmp) + if (num_page != tmp) goto free; mi->size = tmp * 4; @@ -359,7 +357,7 @@ static s32 map_buffer(enum tiler_fmt fmt, u32 width, u32 height, u32 *sys_addr, write = 1; tmp = mi->usr; - for (i = 0; i < mi->num_pgs; i++) { + for (i = 0; i < mi->num_pg; i++) { if (get_user_pages(curr_task, mm, tmp, 1, write, 1, &page, NULL)) { if (page_count(page) < 1) { @@ -383,12 +381,10 @@ static s32 map_buffer(enum tiler_fmt fmt, u32 width, u32 height, u32 *sys_addr, mutex_unlock(&mtx); /* send pat descriptor to dmm driver */ - pat_desc.area.x0 = area_desc->x0 + area_desc->xPageOfst; - pat_desc.area.y0 = area_desc->y0 + area_desc->yPageOfst; - pat_desc.area.x1 = area_desc->x0 + area_desc->xPageOfst + - area_desc->xPageCount - 1; - pat_desc.area.y1 = area_desc->y0 + area_desc->yPageOfst + - area_desc->yPageCount - 1; + pat_desc.area.x0 = mi->area.x0; + pat_desc.area.y0 = mi->area.y0; + pat_desc.area.x1 = mi->area.x1; + pat_desc.area.y1 = mi->area.y1; pat_desc.ctrl.dir = 0; pat_desc.ctrl.ini = 0; pat_desc.ctrl.lut_id = 0; @@ -403,7 +399,7 @@ static s32 map_buffer(enum tiler_fmt fmt, u32 width, u32 height, u32 *sys_addr, goto release; return 0; release: - for (i = 0; i < mi->num_pgs; i++) { + for (i = 0; i < mi->num_pg; i++) { page = (struct page *)mi->pg_ptr[i]; if (!PageReserved(page)) SetPageDirty(page); @@ -419,32 +415,22 @@ free: s32 tiler_free(u32 sys_addr) { - u32 x_area = -1, y_area = -1, i = -1; - struct dmmTILERContPageAreaT *area_desc = NULL; + u32 i = 0; struct list_head *pos = NULL, *q = NULL; struct mem_info *mi = NULL; struct page *page = NULL; - if (get_area(sys_addr, &x_area, &y_area)) - return -EFAULT; - - area_desc = search_2d_area(tilctx, x_area, y_area, 0, 0); - if (!area_desc) - return -EFAULT; - - /* freeing of physical pages should *not* happen in this next API */ - if (!(dealloc_2d_area(tilctx, area_desc))) - return -EFAULT; - mutex_lock(&mtx); list_for_each_safe(pos, q, &mem_list.list) { mi = list_entry(pos, struct mem_info, list); if (mi->sys_addr == sys_addr) { + if (deallocate(&mi->area)) + printk(KERN_NOTICE "warning: failed to\ + unreserve tiler area.\n"); if (!mi->mapped) { - for (i = 0; i < mi->num_pgs; i++) - dmm_free_page(mi->page[i]); + dmm_free_pages(mi->mem); } else { - for (i = 0; i < mi->num_pgs; i++) { + for (i = 0; i < mi->num_pg; i++) { page = (struct page *)mi->pg_ptr[i]; if (!PageReserved(page)) SetPageDirty(page); @@ -473,56 +459,56 @@ EXPORT_SYMBOL(tiler_free); which is the real reason for this ioctl */ s32 tiler_find_buf(u32 sys_addr, struct tiler_block_info *blk) { - struct dmmTILERContPageAreaT *area_desc = NULL; + struct area_spec area = {0}; u32 x_area = -1, y_area = -1; + u16 x_page = 0, y_page = 0; + s32 mode = -1; - if (get_area(sys_addr, &x_area, &y_area)) + if (get_area(sys_addr & 0x0FFFF1000, &x_area, &y_area)) return -EFAULT; - area_desc = search_2d_area(tilctx, x_area, y_area, 0, 0); - if (!area_desc) + if (retrieve_parent_area(x_area, y_area, &area)) return -EFAULT; + x_page = area.x1 - area.x0 + 1; + y_page = area.y1 - area.y0 + 1; + blk->ptr = NULL; - if (area_desc != NULL) { - s32 mode = TILER_GET_ACC_MODE(sys_addr); - blk->fmt = (mode + 1); - if (blk->fmt == TILFMT_PAGE) { - blk->dim.len = area_desc->xPageCount * - area_desc->yPageCount * TILER_PAGE; - blk->stride = 0; - blk->ssptr = (u32)TIL_ALIAS_ADDR(((area_desc->x0 | - (area_desc->y0 << 8)) << 12), mode); + + mode = TILER_GET_ACC_MODE(sys_addr); + blk->fmt = (mode + 1); + if (blk->fmt == TILFMT_PAGE) { + blk->dim.len = x_page * y_page * TILER_PAGE; + if (blk->dim.len == 0) + goto error; + blk->stride = 0; + blk->ssptr = (u32)TIL_ALIAS_ADDR(((area.x0 | + (area.y0 << 8)) << 12), mode); + } else { + blk->stride = blk->dim.area.width = x_page * TILER_BLOCK_WIDTH; + blk->dim.area.height = y_page * TILER_BLOCK_HEIGHT; + if (blk->dim.area.width == 0 || blk->dim.area.height == 0) + goto error; + if (blk->fmt == TILFMT_8BIT) { + blk->ssptr = (u32)TIL_ALIAS_ADDR(((area.x0 << 6) | + (area.y0 << 20)), mode); } else { - blk->stride = blk->dim.area.width = - area_desc->xPageCount * TILER_BLOCK_WIDTH; - blk->dim.area.height = - area_desc->yPageCount * TILER_BLOCK_HEIGHT; - if (blk->fmt == TILFMT_8BIT) { - blk->ssptr = (u32)TIL_ALIAS_ADDR( - ((area_desc->x0 << 6) | - (area_desc->y0 << 20)), - mode); - } else { - blk->ssptr = (u32)TIL_ALIAS_ADDR( - ((area_desc->x0 << 7) | - (area_desc->y0 << 20)), - mode); - blk->stride <<= 1; - blk->dim.area.height >>= 1; - if (blk->fmt == TILFMT_32BIT) - blk->dim.area.width >>= 1; - } - blk->stride = (blk->stride + TILER_PAGE - 1) & - ~(TILER_PAGE - 1); + blk->ssptr = (u32)TIL_ALIAS_ADDR(((area.x0 << 7) | + (area.y0 << 20)), mode); + blk->stride <<= 1; + blk->dim.area.height >>= 1; + if (blk->fmt == TILFMT_32BIT) + blk->dim.area.width >>= 1; } - } else { + blk->stride = (blk->stride + TILER_PAGE - 1) & + ~(TILER_PAGE - 1); + } + return 0; + +error: blk->fmt = TILFMT_INVALID; blk->dim.len = blk->stride = blk->ssptr = 0; return -EFAULT; - } - - return 0; } static s32 tiler_ioctl(struct inode *ip, struct file *filp, u32 cmd, @@ -642,8 +628,9 @@ static s32 tiler_ioctl(struct inode *ip, struct file *filp, u32 cmd, memset(_b, 0x0, sizeof(struct __buf_info)); if (copy_from_user(&_b->buf_info, (void __user *)arg, - sizeof(struct tiler_buf_info))) - return -EFAULT; + sizeof(struct tiler_buf_info))) { + kfree(_b); return -EFAULT; + } _b->buf_info.offset = id; id += 0x1000; @@ -653,8 +640,9 @@ static s32 tiler_ioctl(struct inode *ip, struct file *filp, u32 cmd, mutex_unlock(&mtx); if (copy_to_user((void __user *)arg, &_b->buf_info, - sizeof(struct tiler_buf_info))) - return -EFAULT; + sizeof(struct tiler_buf_info))) { + kfree(_b); return -EFAULT; + } break; case TILIOC_URBUF: if (copy_from_user(&buf_info, (void __user *)arg, @@ -694,8 +682,8 @@ static s32 tiler_ioctl(struct inode *ip, struct file *filp, u32 cmd, s32 tiler_alloc(enum tiler_fmt fmt, u32 width, u32 height, u32 *sys_addr) { - u32 num_pages = -1, i = -1, x_area = -1, y_area = -1; - struct dmmTILERContPageAreaT *area_desc = NULL, __area_desc = {0}; + u16 num_page = 0, x_page = 0, y_page = 0; + u8 x_area = 0, y_area = 0; struct pat pat_desc = {0}; struct mem_info *mi = NULL; @@ -703,39 +691,53 @@ s32 tiler_alloc(enum tiler_fmt fmt, u32 width, u32 height, u32 *sys_addr) if (__set_area(fmt, width, height, &x_area, &y_area)) return -EFAULT; - __area_desc.x1 = (u16)x_area; - __area_desc.y1 = (u16)y_area; + mi = kmalloc(sizeof(struct mem_info), GFP_KERNEL); + if (!mi) + return -ENOMEM; + memset(mi, 0x0, sizeof(struct mem_info)); - area_desc = alloc_2d_area(tilctx, &__area_desc); - if (!area_desc) + switch (fmt) { + case TILFMT_8BIT: + case TILFMT_16BIT: + case TILFMT_32BIT: + if (allocate_2d_area(x_area + 1, y_area + 1, ALIGN_64, + &mi->area)) { + kfree(mi); return -ENOMEM; } + break; + case TILFMT_PAGE: + if (allocate_1d_pages( + ROUND_UP((x_area + 1) * (y_area + 1), 256), + &mi->area)) { + kfree(mi); return -ENOMEM; } + break; + default: + kfree(mi); return -ENOMEM; + } /* formulate system space address */ - *sys_addr = __get_alias_addr(fmt, area_desc->x0, area_desc->y0); + *sys_addr = __get_alias_addr(fmt, mi->area.x0, mi->area.y0); /* allocate pages */ - area_desc->xPageCount = area_desc->x1 - area_desc->x0 + 1; - area_desc->yPageCount = area_desc->y1 - area_desc->y0 + 1; - num_pages = area_desc->xPageCount * area_desc->yPageCount; - - mi = kmalloc(sizeof(struct mem_info), GFP_KERNEL); - if (!mi) - return -ENOMEM; - memset(mi, 0x0, sizeof(struct mem_info)); + /* TODO: page count should be u8 @ 256 max */ + /* TODO: num_pages should be u16 @ 32k max */ + x_page = mi->area.x1 - mi->area.x0 + 1; + y_page = mi->area.y1 - mi->area.y0 + 1; + num_page = x_page * y_page; - mi->size = num_pages * 4 + 16; + mi->size = num_page * 4; mi->page = dma_alloc_coherent(NULL, mi->size, &mi->page_pa, GFP_ATOMIC); if (!mi->page) { kfree(mi); return -ENOMEM; } memset(mi->page, 0x0, mi->size); - for (i = 0; i < num_pages; i++) { - mi->page[i] = dmm_get_page(); - if (mi->page[i] == 0x0) - goto cleanup; - } - mi->num_pgs = num_pages; + mi->mem = dmm_get_pages(num_page); + if (!mi->mem) + goto cleanup; + memcpy(mi->page, mi->mem, mi->size); + + mi->num_pg = num_page; mi->sys_addr = *sys_addr; mutex_lock(&mtx); @@ -743,13 +745,10 @@ s32 tiler_alloc(enum tiler_fmt fmt, u32 width, u32 height, u32 *sys_addr) mutex_unlock(&mtx); /* send pat descriptor to dmm driver */ - pat_desc.area.x0 = area_desc->x0 + area_desc->xPageOfst; - pat_desc.area.y0 = area_desc->y0 + area_desc->yPageOfst; - pat_desc.area.x1 = area_desc->x0 + area_desc->xPageOfst + - area_desc->xPageCount - 1; - pat_desc.area.y1 = area_desc->y0 + area_desc->yPageOfst + - area_desc->yPageCount - 1; - + pat_desc.area.x0 = mi->area.x0; + pat_desc.area.y0 = mi->area.y0; + pat_desc.area.x1 = mi->area.x1; + pat_desc.area.y1 = mi->area.y1; pat_desc.ctrl.dir = 0; pat_desc.ctrl.ini = 0; pat_desc.ctrl.lut_id = 0; @@ -778,10 +777,7 @@ static void __exit tiler_exit(void) struct list_head *pos = NULL, *q = NULL; u32 i = -1; - /* TODO: remove when replacing container algorithm */ - mutex_destroy(&tilctx->mtx); - kfree(tilctx); - /* ------------ */ + deinit_tiler(); /* remove any leftover info structs that haven't been unregistered */ mutex_lock(&mtx); @@ -798,7 +794,7 @@ static void __exit tiler_exit(void) pos = NULL, q = NULL; list_for_each_safe(pos, q, &mem_list.list) { mi = list_entry(pos, struct mem_info, list); - for (i = 0; i < mi->num_pgs; i++) + for (i = 0; i < mi->num_pg; i++) dmm_free_page(mi->page[i]); dma_free_coherent(NULL, mi->size, mi->page, mi->page_pa); list_del(pos); @@ -873,20 +869,11 @@ static s32 __init tiler_init(void) r = platform_driver_register(&tiler_driver_ldm); - /* tiler context structure required by container algorithm */ - tilctx = kmalloc(sizeof(struct dmmTILERContCtxT), GFP_KERNEL); - if (!tilctx) - return -ENOMEM; - memset(tilctx, 0x0, sizeof(struct dmmTILERContCtxT)); - tilctx->contSizeX = TILER_WIDTH; - tilctx->contSizeY = TILER_HEIGHT; - mutex_init(&tilctx->mtx); - /* ------------------------------------------------------- */ - mutex_init(&mtx); INIT_LIST_HEAD(&buf_list.list); INIT_LIST_HEAD(&mem_list.list); id = 0xda7a000; + init_tiler(); EXIT: return r; diff --git a/drivers/media/video/tiler/tiler_def.h b/drivers/media/video/tiler/tiler_def.h index da9f6cbb4d4b..de73b8eccb42 100644 --- a/drivers/media/video/tiler/tiler_def.h +++ b/drivers/media/video/tiler/tiler_def.h @@ -17,6 +17,12 @@ #ifndef TILER_DEF_H #define TILER_DEF_H +#define ROUND_UP_2P(a, b) (((a) + (b) - 1) & ~((b) - 1)) +#define DIVIDE_UP(a, b) (((a) + (b) - 1) / (b)) +#define ROUND_UP(a, b) (DIVIDE_UP(a, b) * (b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + #define TILER_ACC_MODE_SHIFT (27) #define TILER_ACC_MODE_MASK (3) #define TILER_GET_ACC_MODE(x) ((enum tiler_fmt)\ diff --git a/drivers/media/video/tiler/tiler_pack.c b/drivers/media/video/tiler/tiler_pack.c index 8838e7d56c30..7c3c6d95ca0f 100644 --- a/drivers/media/video/tiler/tiler_pack.c +++ b/drivers/media/video/tiler/tiler_pack.c @@ -17,12 +17,7 @@ #include <linux/init.h> #include <linux/module.h> #include "tiler.h" - -#define ROUND_UP_2P(a, b) (((a) + (b) - 1) & ~((b) - 1)) -#define DIVIDE_UP(a, b) (((a) + (b) - 1) / (b)) -#define ROUND_UP(a, b) (DIVIDE_UP(a, b) * (b)) -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#include "tiler_def.h" void tiler_alloc_packed(s32 *count, enum tiler_fmt fmt, u32 width, u32 height, void **sysptr, void **allocptr, s32 aligned) @@ -212,6 +207,7 @@ void tiler_alloc_packed_nv12(s32 *count, u32 width, u32 height, void **y_sysptr, !uv_sysptr || !uv_allocptr || *count <= 0) { if (count) *count = 0; + return; } y_width = DIVIDE_UP(width, 64); diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 514e1e4b1dd7..0c085e860587 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -118,7 +118,8 @@ #define twl_has_watchdog() false #endif -#if defined(CONFIG_TWL4030_CODEC) || defined(CONFIG_TWL4030_CODEC_MODULE) +#if defined(CONFIG_TWL4030_CODEC) || defined(CONFIG_TWL4030_CODEC_MODULE) ||\ + defined(CONFIG_SND_SOC_ABE_TWL6040) || defined(CONFIG_SND_SOC_TWL6040_MODULE) #define twl_has_codec() true #else #define twl_has_codec() false @@ -735,8 +736,19 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) return PTR_ERR(child); } - if (twl_has_codec() && pdata->codec) { - child = add_child(1, "twl4030_codec", + if (twl_has_codec() && pdata->codec && twl_class_is_4030()) { + sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid; + child = add_child(sub_chip_id, "twl4030_codec", + pdata->codec, sizeof(*pdata->codec), + false, 0, 0); + if (IS_ERR(child)) + return PTR_ERR(child); + } + + /* Phoenix*/ + if (twl_has_codec() && pdata->codec && twl_class_is_6030()) { + sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid; + child = add_child(sub_chip_id, "twl6040_codec", pdata->codec, sizeof(*pdata->codec), false, 0, 0); if (IS_ERR(child)) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 30acd5265821..249b4346135a 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1328,6 +1328,17 @@ EXPORT_SYMBOL(mmc_resume_host); #endif +#ifdef CONFIG_TIWLAN_SDIO +void mmc_set_embedded_sdio_data(struct mmc_host *host, + struct sdio_cis *cis, + struct sdio_embedded_func *funcs) +{ + host->embedded_sdio_data.cis = cis; + host->embedded_sdio_data.funcs = funcs; +} +EXPORT_SYMBOL(mmc_set_embedded_sdio_data); +#endif + static int __init mmc_init(void) { int ret; diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 06b64085a355..26c5ab3a22f8 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -24,6 +24,10 @@ #include "sdio_ops.h" #include "sdio_cis.h" +#ifdef CONFIG_TIWLAN_SDIO +#include <linux/mmc/sdio_ids.h> +#endif + static int sdio_read_fbr(struct sdio_func *func) { int ret; @@ -286,6 +290,12 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, if (err) goto remove; +#ifdef CONFIG_TIWLAN_SDIO + if (host->embedded_sdio_data.cis) + memcpy(&card->cis, host->embedded_sdio_data.cis, + sizeof(struct sdio_cis)); + else { +#endif /* * Read the common CIS tuples. */ @@ -293,6 +303,10 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, if (err) goto remove; +#ifdef CONFIG_TIWLAN_SDIO + } +#endif + if (oldcard) { int same = (card->cis.vendor == oldcard->cis.vendor && card->cis.device == oldcard->cis.device); @@ -530,9 +544,29 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr) * Initialize (but don't add) all present functions. */ for (i = 0; i < funcs; i++, card->sdio_funcs++) { +#ifdef CONFIG_TIWLAN_SDIO + if (host->embedded_sdio_data.funcs) { + struct sdio_func *tmp; + + tmp = sdio_alloc_func(host->card); + if (IS_ERR(tmp)) + goto remove; + tmp->num = (i + 1); + card->sdio_func[i] = tmp; + tmp->class = host->embedded_sdio_data.funcs[i].f_class; + tmp->max_blksize = + host->embedded_sdio_data.funcs[i].f_maxblksize; + tmp->vendor = card->cis.vendor; + tmp->device = card->cis.device; + } else { +#endif + err = sdio_init_func(host->card, i + 1); if (err) goto remove; +#ifdef CONFIG_TIWLAN_SDIO + } +#endif } mmc_release_host(host); diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index 9e060c87e64d..11d8bf15d589 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c @@ -20,6 +20,10 @@ #include "sdio_cis.h" #include "sdio_bus.h" +#ifdef CONFIG_TIWLAN_SDIO +#include <linux/mmc/host.h> +#endif + /* show configuration fields */ #define sdio_config_attr(field, format_string) \ static ssize_t \ @@ -199,6 +203,13 @@ static void sdio_release_func(struct device *dev) { struct sdio_func *func = dev_to_sdio_func(dev); +#ifdef CONFIG_TIWLAN_SDIO + /* + * If this device is embedded then we never allocated + * cis tables for this func + */ + if (!func->card->host->embedded_sdio_data.funcs) +#endif sdio_free_func_cis(func); if (func->info) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 9266e2897047..c175d66914ff 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1111,6 +1111,7 @@ static int mmc_populate_adma_desc_table(struct omap_hsmmc_host *host, static void omap_hsmmc_start_adma_transfer(struct omap_hsmmc_host *host) { + wmb(); OMAP_HSMMC_WRITE(host->base, ADMA_SAL, host->phy_adma_table); } @@ -1361,6 +1362,28 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) mmc_host_lazy_disable(host->mmc); } +#ifdef CONFIG_TIWLAN_SDIO +static void omap_hsmmc_status_notify_cb(int card_present, void *dev_id) +{ + struct omap_hsmmc_host *host = dev_id; + struct omap_mmc_slot_data *slot = &mmc_slot(host); + int carddetect; + + printk(KERN_DEBUG "%s: card_present %d\n", mmc_hostname(host->mmc), + card_present); + + carddetect = slot->card_detect(slot->card_detect_irq); + + sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch"); + if (carddetect) { + mmc_detect_change(host->mmc, (HZ * 200) / 1000); + } else { + omap_hsmmc_reset_controller_fsm(host, SRD); + mmc_detect_change(host->mmc, (HZ * 50) / 1000); + } +} +#endif + static int omap_hsmmc_get_cd(struct mmc_host *mmc) { struct omap_hsmmc_host *host = mmc_priv(mmc); @@ -1806,6 +1829,15 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) } dev_dbg(mmc_dev(host->mmc), "DMA Mode=%d\n", host->dma_type); +#ifdef CONFIG_TIWLAN_SDIO + if (pdev->id == CONFIG_TIWLAN_MMC_CONTROLLER-1) { + if (pdata->slots[0].embedded_sdio != NULL) { + mmc_set_embedded_sdio_data(mmc, + &pdata->slots[0].embedded_sdio->cis, + pdata->slots[0].embedded_sdio->funcs); + } + } +#endif platform_set_drvdata(pdev, host); INIT_WORK(&host->mmc_carddetect_work, omap_hsmmc_detect); @@ -1958,6 +1990,15 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) } } +#ifdef CONFIG_TIWLAN_SDIO + else if (mmc_slot(host).register_status_notify) { + if (pdev->id == CONFIG_TIWLAN_MMC_CONTROLLER-1) { + mmc_slot(host).register_status_notify( + omap_hsmmc_status_notify_cb, host); + } + } +#endif + OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK); OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK); diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 866526e43a58..fd7b967bbc98 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -49,6 +49,7 @@ struct twlreg_info { /* chip constraints on regulator behavior */ u16 min_mV; + u16 max_mV; /* used by regulator core */ struct regulator_desc desc; @@ -318,31 +319,8 @@ static const u16 VIO_VSEL_table[] = { static const u16 VINTANA2_VSEL_table[] = { 2500, 2750, }; -static const u16 VAUX1_6030_VSEL_table[] = { - 1000, 1300, 1800, 2500, - 2800, 2900, 3000, 3000, -}; -static const u16 VAUX2_6030_VSEL_table[] = { - 1200, 1800, 2500, 2750, - 2800, 2800, 2800, 2800, -}; -static const u16 VAUX3_6030_VSEL_table[] = { - 1000, 1200, 1300, 1800, - 2500, 2800, 3000, 3000, -}; -static const u16 VMMC_VSEL_table[] = { - 1200, 1800, 2800, 2900, - 3000, 3000, 3000, 3000, -}; -static const u16 VPP_VSEL_table[] = { - 1800, 1900, 2000, 2100, - 2200, 2300, 2400, 2500, -}; -static const u16 VUSIM_VSEL_table[] = { - 1200, 1800, 2500, 2900, -}; -static int twlldo_list_voltage(struct regulator_dev *rdev, unsigned index) +static int twl4030ldo_list_voltage(struct regulator_dev *rdev, unsigned index) { struct twlreg_info *info = rdev_get_drvdata(rdev); int mV = info->table[index]; @@ -351,7 +329,7 @@ static int twlldo_list_voltage(struct regulator_dev *rdev, unsigned index) } static int -twlldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) +twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) { struct twlreg_info *info = rdev_get_drvdata(rdev); int vsel; @@ -367,21 +345,15 @@ twlldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) /* REVISIT for VAUX2, first match may not be best/lowest */ /* use the first in-range value */ - if (min_uV <= uV && uV <= max_uV) { - if (twl_class_is_6030()) - /* - * Use the below formula to calculate vsel - * mV = 1000mv + 100mv * (vsel - 1) - */ - vsel = (LDO_MV(mV) - 1000)/100 + 1; + if (min_uV <= uV && uV <= max_uV) return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE, vsel); - } } + return -EDOM; } -static int twlldo_get_voltage(struct regulator_dev *rdev) +static int twl4030ldo_get_voltage(struct regulator_dev *rdev) { struct twlreg_info *info = rdev_get_drvdata(rdev); int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, @@ -390,24 +362,71 @@ static int twlldo_get_voltage(struct regulator_dev *rdev) if (vsel < 0) return vsel; - if (twl_class_is_4030()) { - vsel &= info->table_len - 1; - return LDO_MV(info->table[vsel]) * 1000; - } else if (twl_class_is_6030()) { - /* - * Use the below formula to calculate vsel - * mV = 1000mv + 100mv * (vsel - 1) - */ - return (1000 + (100 * (vsel - 1))) * 1000; - } - return -EDOM; + vsel &= info->table_len - 1; + return LDO_MV(info->table[vsel]) * 1000; } -static struct regulator_ops twlldo_ops = { - .list_voltage = twlldo_list_voltage, +static struct regulator_ops twl4030ldo_ops = { + .list_voltage = twl4030ldo_list_voltage, - .set_voltage = twlldo_set_voltage, - .get_voltage = twlldo_get_voltage, + .set_voltage = twl4030ldo_set_voltage, + .get_voltage = twl4030ldo_get_voltage, + + .enable = twlreg_enable, + .disable = twlreg_disable, + .is_enabled = twlreg_is_enabled, + + .set_mode = twlreg_set_mode, + + .get_status = twlreg_get_status, +}; + +static int twl6030ldo_list_voltage(struct regulator_dev *rdev, unsigned index) +{ + struct twlreg_info *info = rdev_get_drvdata(rdev); + + return (info->min_mV + (index * 100)) * 1000; +} + +static int +twl6030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) +{ + struct twlreg_info *info = rdev_get_drvdata(rdev); + int vsel; + + if ((min_uV/1000 < info->min_mV) || (max_uV/1000 > info->max_mV)) + return -EDOM; + + /* + * Use the below formula to calculate vsel + * mV = 1000mv + 100mv * (vsel - 1) + */ + vsel = (min_uV/1000 - 1000)/100 + 1; + return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE, vsel); + +} + +static int twl6030ldo_get_voltage(struct regulator_dev *rdev) +{ + struct twlreg_info *info = rdev_get_drvdata(rdev); + int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, + VREG_VOLTAGE); + + if (vsel < 0) + return vsel; + + /* + * Use the below formula to calculate vsel + * mV = 1000mv + 100mv * (vsel - 1) + */ + return (1000 + (100 * (vsel - 1))) * 1000; +} + +static struct regulator_ops twl6030ldo_ops = { + .list_voltage = twl6030ldo_list_voltage, + + .set_voltage = twl6030ldo_set_voltage, + .get_voltage = twl6030ldo_get_voltage, .enable = twlreg_enable, .disable = twlreg_disable, @@ -453,24 +472,16 @@ static struct regulator_ops twlfixed_ops = { /*----------------------------------------------------------------------*/ -#define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) \ - TWL_ADJUSTABLE_LDO(label, offset, num, turnon_delay, \ - remap_conf, TWL4030) #define TWL4030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ remap_conf) \ TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ remap_conf, TWL4030) -#define TWL6030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, \ - remap_conf) \ - TWL_ADJUSTABLE_LDO(label, offset, num, turnon_delay, \ - remap_conf, TWL6030) #define TWL6030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ remap_conf) \ TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ remap_conf, TWL6030) -#define TWL_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf, \ - family) { \ +#define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) { \ .base = offset, \ .id = num, \ .table_len = ARRAY_SIZE(label##_VSEL_table), \ @@ -479,14 +490,32 @@ static struct regulator_ops twlfixed_ops = { .remap = remap_conf, \ .desc = { \ .name = #label, \ - .id = family##_REG_##label, \ + .id = TWL4030_REG_##label, \ .n_voltages = ARRAY_SIZE(label##_VSEL_table), \ - .ops = &twlldo_ops, \ + .ops = &twl4030ldo_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + }, \ + } + +#define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts, num, \ + remap_conf) { \ + .base = offset, \ + .id = num, \ + .min_mV = min_mVolts, \ + .max_mV = max_mVolts, \ + .remap = remap_conf, \ + .desc = { \ + .name = #label, \ + .id = TWL6030_REG_##label, \ + .n_voltages = (max_mVolts - min_mVolts)/100, \ + .ops = &twl6030ldo_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ }, \ } + #define TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, remap_conf, \ family) { \ .base = offset, \ @@ -534,12 +563,13 @@ static struct twlreg_info twl_regs[] = { /* 6030 REG with base as PMC Slave Misc : 0x0030 */ /* Turnon-delay and remap configuration values for 6030 are not verified since the specification is not public */ - TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 37, 0, 0x21), - TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 38, 0, 0x21), - TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 39, 0, 0x21), - TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 40, 0, 0x21), - TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 41, 0, 0x21), - TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 42, 0, 0x21), + TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1000, 3300, 37, 0x21), + TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 1000, 3300, 38, 0x21), + TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 1000, 3300, 39, 0x21), + TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 1000, 3300, 40, 0x21), + TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 1000, 3300, 41, 0x21), + TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 1000, 3300, 42, 0x21), + TWL6030_FIXED_LDO(VANA, 0x50, 2100, 43, 0, 0x21), TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 44, 0, 0x21), TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 45, 0, 0x21), diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index ce9112f60c04..1091d6d89c03 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c @@ -168,7 +168,7 @@ static int twl_rtc_read(u8 *value, u8 reg, unsigned num_bytes) int ret = 0, i = 0; for (i = 0; i < num_bytes; i++) - if (twl_rtc_read_u8(value + i, (rtc_reg_map[reg + i]))) + if (twl_rtc_read_u8(value + i, (reg + i))) return ret; return ret; diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 9ff47db0b2ce..95055e72d6b2 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -1366,6 +1366,33 @@ config SERIAL_OF_PLATFORM Currently, only 8250 compatible ports are supported, but others can easily be added. +config SERIAL_OMAP + tristate "OMAP serial port support" + depends on ARCH_OMAP3 || ARCH_OMAP4 + select SERIAL_CORE + help + If you have a machine based on an Texas Instruments OMAP CPU you + can enable its onboard serial ports by enabling this option. + + By enabling this option you take advantage of dma feature available + with the omap-serial driver. DMA support can be enabled from platform + data. + +config SERIAL_OMAP_CONSOLE + bool "Console on OMAP serial port" + depends on SERIAL_OMAP + select SERIAL_CORE_CONSOLE + help + Select this option if you would like to use omap serial port as + console. + + Even if you say Y here, the currently visible virtual console + (/dev/tty0) will still be used as the system console by default, but + you can alter that using a kernel command line option such as + "console=ttyOx". (Try "man bootparam" or see the documentation of + your boot loader about how to pass options to the kernel at + boot time.) + config SERIAL_OF_PLATFORM_NWPSERIAL tristate "NWP serial port driver" depends on PPC_OF && PPC_DCR diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 5548fe7df61d..42962b3a2040 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -82,3 +82,4 @@ obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o obj-$(CONFIG_SERIAL_QE) += ucc_uart.o obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o obj-$(CONFIG_SERIAL_GRLIB_GAISLER_APBUART) += apbuart.o +obj-$(CONFIG_SERIAL_OMAP) += omap-serial.o diff --git a/drivers/serial/omap-serial.c b/drivers/serial/omap-serial.c new file mode 100644 index 000000000000..288a3591db61 --- /dev/null +++ b/drivers/serial/omap-serial.c @@ -0,0 +1,1323 @@ +/* + * Driver for OMAP-UART controller. + * Based on drivers/serial/8250.c + * + * Copyright (C) 2010 Texas Instruments. + * + * Authors: + * Govindraj R <govindraj.raja@ti.com> + * Thara Gopinath <thara@ti.com> + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Note: This driver is made seperate from 8250 driver as we cannot + * over load 8250 driver with omap platform specific configuration for + * features like DMA, it makes easier to implement features like DMA and + * hardware flow control and software flow control configuration with + * this driver as required for the omap-platform. + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/console.h> +#include <linux/serial_reg.h> +#include <linux/delay.h> +#include <linux/tty.h> +#include <linux/tty_flip.h> +#include <linux/io.h> +#include <linux/dma-mapping.h> +#include <linux/clk.h> +#include <linux/serial_core.h> + +#include <asm/irq.h> +#include <plat/dma.h> +#include <plat/dmtimer.h> +#include <plat/omap-serial.h> + +static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS]; + +/* Forward declaration of functions */ +static void uart_tx_dma_callback(int lch, u16 ch_status, void *data); +static void serial_omap_rx_timeout(unsigned long uart_no); +static int serial_omap_start_rxdma(struct uart_omap_port *up); + +static inline unsigned int serial_in(struct uart_omap_port *up, int offset) +{ + offset <<= up->port.regshift; + return readw(up->port.membase + offset); +} + +static inline void serial_out(struct uart_omap_port *up, int offset, int value) +{ + offset <<= up->port.regshift; + writew(value, up->port.membase + offset); +} + +static inline void serial_omap_clear_fifos(struct uart_omap_port *up) +{ + serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); + serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | + UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); + serial_out(up, UART_FCR, 0); +} + +/** + * serial_omap_get_divisor() - calculate divisor value + * @port: uart port info + * @baud: baudrate for which divisor needs to be calculated. + * + * We have written our own function to get the divisor so as to support + * 13x mode. 3Mbps Baudrate as an different divisor. + * Reference OMAP TRM Chapter 17: + * Table 17-1. UART Mode Baud Rates, Divisor Values, and Error Rates + * referring to oversampling - divisor value + * baudrate 460,800 to 3,686,400 all have divisor 13 + * except 3,000,000 which has divisor value 16 + */ +static unsigned int +serial_omap_get_divisor(struct uart_port *port, unsigned int baud) +{ + unsigned int divisor; + + if (baud > OMAP_MODE13X_SPEED && baud != 3000000) + divisor = 13; + else + divisor = 16; + return port->uartclk/(baud * divisor); +} + +static void serial_omap_stop_rxdma(struct uart_omap_port *up) +{ + if (up->uart_dma.rx_dma_used) { + del_timer(&up->uart_dma.rx_timer); + omap_stop_dma(up->uart_dma.rx_dma_channel); + omap_free_dma(up->uart_dma.rx_dma_channel); + up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE; + up->uart_dma.rx_dma_used = false; + } +} + +static void serial_omap_enable_ms(struct uart_port *port) +{ + struct uart_omap_port *up = (struct uart_omap_port *)port; + + dev_dbg(up->port.dev, "serial_omap_enable_ms+%d\n", up->pdev->id); + up->ier |= UART_IER_MSI; + serial_out(up, UART_IER, up->ier); +} + +static void serial_omap_stop_tx(struct uart_port *port) +{ + struct uart_omap_port *up = (struct uart_omap_port *)port; + + if (up->use_dma && + up->uart_dma.tx_dma_channel != OMAP_UART_DMA_CH_FREE) { + /* + * Check if dma is still active. If yes do nothing, + * return. Else stop dma + */ + if (omap_get_dma_active_status(up->uart_dma.tx_dma_channel)) + return; + omap_stop_dma(up->uart_dma.tx_dma_channel); + omap_free_dma(up->uart_dma.tx_dma_channel); + up->uart_dma.tx_dma_channel = OMAP_UART_DMA_CH_FREE; + } + + if (up->ier & UART_IER_THRI) { + up->ier &= ~UART_IER_THRI; + serial_out(up, UART_IER, up->ier); + } +} + +static void serial_omap_stop_rx(struct uart_port *port) +{ + struct uart_omap_port *up = (struct uart_omap_port *)port; + + if (up->use_dma) + serial_omap_stop_rxdma(up); + up->ier &= ~UART_IER_RLSI; + up->port.read_status_mask &= ~UART_LSR_DR; + serial_out(up, UART_IER, up->ier); +} + +static inline void receive_chars(struct uart_omap_port *up, int *status) +{ + struct tty_struct *tty = up->port.state->port.tty; + unsigned int flag; + unsigned char ch, lsr = *status; + int max_count = 256; + + do { + if (likely(lsr & UART_LSR_DR)) + ch = serial_in(up, UART_RX); + flag = TTY_NORMAL; + up->port.icount.rx++; + + if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) { + /* + * For statistics only + */ + if (lsr & UART_LSR_BI) { + lsr &= ~(UART_LSR_FE | UART_LSR_PE); + up->port.icount.brk++; + /* + * We do the SysRQ and SAK checking + * here because otherwise the break + * may get masked by ignore_status_mask + * or read_status_mask. + */ + if (uart_handle_break(&up->port)) + goto ignore_char; + } else if (lsr & UART_LSR_PE) + up->port.icount.parity++; + else if (lsr & UART_LSR_FE) + up->port.icount.frame++; + if (lsr & UART_LSR_OE) + up->port.icount.overrun++; + + /* + * Mask off conditions which should be ignored. + */ + lsr &= up->port.read_status_mask; + +#ifdef CONFIG_SERIAL_OMAP_CONSOLE + if (up->port.line == up->port.cons->index) { + /* Recover the break flag from console xmit */ + lsr |= up->lsr_break_flag; + up->lsr_break_flag = 0; + } +#endif + if (lsr & UART_LSR_BI) + flag = TTY_BREAK; + else if (lsr & UART_LSR_PE) + flag = TTY_PARITY; + else if (lsr & UART_LSR_FE) + flag = TTY_FRAME; + } + + if (uart_handle_sysrq_char(&up->port, ch)) + goto ignore_char; + uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag); +ignore_char: + lsr = serial_in(up, UART_LSR); + } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0)); + spin_unlock(&up->port.lock); + tty_flip_buffer_push(tty); + spin_lock(&up->port.lock); +} + +static void transmit_chars(struct uart_omap_port *up) +{ + struct circ_buf *xmit = &up->port.state->xmit; + int count; + + if (up->port.x_char) { + serial_out(up, UART_TX, up->port.x_char); + up->port.icount.tx++; + up->port.x_char = 0; + return; + } + if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { + serial_omap_stop_tx(&up->port); + return; + } + count = up->port.fifosize / 4; + do { + serial_out(up, UART_TX, xmit->buf[xmit->tail]); + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + up->port.icount.tx++; + if (uart_circ_empty(xmit)) + break; + } while (--count > 0); + + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(&up->port); + + if (uart_circ_empty(xmit)) + serial_omap_stop_tx(&up->port); +} + +static inline void serial_omap_enable_ier_thri(struct uart_omap_port *up) +{ + if (!(up->ier & UART_IER_THRI)) { + up->ier |= UART_IER_THRI; + serial_out(up, UART_IER, up->ier); + } +} + +static void serial_omap_start_tx(struct uart_port *port) +{ + struct uart_omap_port *up = (struct uart_omap_port *)port; + struct circ_buf *xmit; + unsigned int start; + int ret = 0; + + if (!up->use_dma || up->port.x_char) { + serial_omap_enable_ier_thri(up); + return; + } + + xmit = &up->port.state->xmit; + if (uart_circ_empty(xmit) || up->uart_dma.tx_dma_used) + return; + + if (up->uart_dma.tx_dma_channel == OMAP_UART_DMA_CH_FREE) + ret = omap_request_dma(up->uart_dma.uart_dma_tx, + "UART Tx DMA", + (void *)uart_tx_dma_callback, up, + &(up->uart_dma.tx_dma_channel)); + + if (ret < 0) { + serial_omap_enable_ier_thri(up); + return; + } + + start = up->uart_dma.tx_buf_dma_phys + + (xmit->tail & (UART_XMIT_SIZE - 1)); + spin_lock(&(up->uart_dma.tx_lock)); + up->uart_dma.tx_dma_used = true; + spin_unlock(&(up->uart_dma.tx_lock)); + + up->uart_dma.tx_buf_size = uart_circ_chars_pending(xmit); + /* + * It is a circular buffer. See if the buffer has wounded back. + * If yes it will have to be transferred in two separate dma + * transfers + */ + if (start + up->uart_dma.tx_buf_size >= + up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE) + up->uart_dma.tx_buf_size = + (up->uart_dma.tx_buf_dma_phys + + UART_XMIT_SIZE) - start; + + omap_set_dma_dest_params(up->uart_dma.tx_dma_channel, 0, + OMAP_DMA_AMODE_CONSTANT, + up->uart_dma.uart_base, 0, 0); + omap_set_dma_src_params(up->uart_dma.tx_dma_channel, 0, + OMAP_DMA_AMODE_POST_INC, start, 0, 0); + omap_set_dma_transfer_params(up->uart_dma.tx_dma_channel, + OMAP_DMA_DATA_TYPE_S8, + up->uart_dma.tx_buf_size, 1, + OMAP_DMA_SYNC_ELEMENT, + up->uart_dma.uart_dma_tx, 0); + wmb(); + omap_start_dma(up->uart_dma.tx_dma_channel); +} + +static unsigned int check_modem_status(struct uart_omap_port *up) +{ + int status; + status = serial_in(up, UART_MSR); + + status |= up->msr_saved_flags; + up->msr_saved_flags = 0; + + if ((status & UART_MSR_ANY_DELTA) == 0) + return status; + if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI && + up->port.state != NULL) { + if (status & UART_MSR_TERI) + up->port.icount.rng++; + if (status & UART_MSR_DDSR) + up->port.icount.dsr++; + if (status & UART_MSR_DDCD) + uart_handle_dcd_change + (&up->port, status & UART_MSR_DCD); + if (status & UART_MSR_DCTS) + uart_handle_cts_change + (&up->port, status & UART_MSR_CTS); + wake_up_interruptible(&up->port.state->port.delta_msr_wait); + } + + return status; +} + +/** + * serial_omap_irq() - This handles the interrupt from one port + * @irq: uart port irq number + * @dev_id: uart port info + */ +static inline irqreturn_t serial_omap_irq(int irq, void *dev_id) +{ + struct uart_omap_port *up = dev_id; + unsigned int iir, lsr; + unsigned long flags; + + spin_lock_irqsave(&up->port.lock, flags); + iir = serial_in(up, UART_IIR); + if (iir & UART_IIR_NO_INT) + return IRQ_NONE; + + lsr = serial_in(up, UART_LSR); + if (iir & UART_IER_RLSI) { + if (up->use_dma) + up->ier &= ~UART_IER_RDI; + serial_out(up, UART_IER, up->ier); + if (!up->use_dma || + serial_omap_start_rxdma(up) != 0) + if (lsr & UART_LSR_DR) + receive_chars(up, &lsr); + } + + check_modem_status(up); + if ((lsr & UART_LSR_THRE) && (iir & UART_IIR_THRI)) + transmit_chars(up); + + spin_unlock_irqrestore(&up->port.lock, flags); + up->port_activity = jiffies; + return IRQ_HANDLED; +} + +static unsigned int serial_omap_tx_empty(struct uart_port *port) +{ + struct uart_omap_port *up = (struct uart_omap_port *)port; + unsigned long flags = 0; + unsigned int ret = 0; + + dev_dbg(up->port.dev, "serial_omap_tx_empty+%d\n", up->pdev->id); + spin_lock_irqsave(&up->port.lock, flags); + ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; + spin_unlock_irqrestore(&up->port.lock, flags); + + return ret; +} + +static unsigned int serial_omap_get_mctrl(struct uart_port *port) +{ + struct uart_omap_port *up = (struct uart_omap_port *)port; + unsigned char status; + unsigned int ret = 0; + + status = check_modem_status(up); + dev_dbg(up->port.dev, "serial_omap_get_mctrl+%d\n", up->pdev->id); + + if (status & UART_MSR_DCD) + ret |= TIOCM_CAR; + if (status & UART_MSR_RI) + ret |= TIOCM_RNG; + if (status & UART_MSR_DSR) + ret |= TIOCM_DSR; + if (status & UART_MSR_CTS) + ret |= TIOCM_CTS; + return ret; +} + +static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ + struct uart_omap_port *up = (struct uart_omap_port *)port; + unsigned char mcr = 0; + + dev_dbg(up->port.dev, "serial_omap_set_mctrl+%d\n", up->pdev->id); + if (mctrl & TIOCM_RTS) + mcr |= UART_MCR_RTS; + if (mctrl & TIOCM_DTR) + mcr |= UART_MCR_DTR; + if (mctrl & TIOCM_OUT1) + mcr |= UART_MCR_OUT1; + if (mctrl & TIOCM_OUT2) + mcr |= UART_MCR_OUT2; + if (mctrl & TIOCM_LOOP) + mcr |= UART_MCR_LOOP; + + mcr |= up->mcr; + serial_out(up, UART_MCR, mcr); +} + +static void serial_omap_break_ctl(struct uart_port *port, int break_state) +{ + struct uart_omap_port *up = (struct uart_omap_port *)port; + unsigned long flags = 0; + + dev_dbg(up->port.dev, "serial_omap_break_ctl+%d\n", up->pdev->id); + spin_lock_irqsave(&up->port.lock, flags); + if (break_state == -1) + up->lcr |= UART_LCR_SBC; + else + up->lcr &= ~UART_LCR_SBC; + serial_out(up, UART_LCR, up->lcr); + spin_unlock_irqrestore(&up->port.lock, flags); +} + +static int serial_omap_startup(struct uart_port *port) +{ + struct uart_omap_port *up = (struct uart_omap_port *)port; + unsigned long flags = 0; + int retval; + + /* + * Allocate the IRQ + */ + retval = request_irq(up->port.irq, serial_omap_irq, up->port.irqflags, + up->name, up); + if (retval) + return retval; + + dev_dbg(up->port.dev, "serial_omap_startup+%d\n", up->pdev->id); + + /* + * Clear the FIFO buffers and disable them. + * (they will be reenabled in set_termios()) + */ + serial_omap_clear_fifos(up); + /* For Hardware flow control */ + serial_out(up, UART_MCR, UART_MCR_RTS); + + /* + * Clear the interrupt registers. + */ + (void) serial_in(up, UART_LSR); + if (serial_in(up, UART_LSR) & UART_LSR_DR) + (void) serial_in(up, UART_RX); + (void) serial_in(up, UART_IIR); + (void) serial_in(up, UART_MSR); + + /* + * Now, initialize the UART + */ + serial_out(up, UART_LCR, UART_LCR_WLEN8); + spin_lock_irqsave(&up->port.lock, flags); + /* + * Most PC uarts need OUT2 raised to enable interrupts. + */ + up->port.mctrl |= TIOCM_OUT2; + serial_omap_set_mctrl(&up->port, up->port.mctrl); + spin_unlock_irqrestore(&up->port.lock, flags); + + up->msr_saved_flags = 0; + if (up->use_dma) { + free_page((unsigned long)up->port.state->xmit.buf); + up->port.state->xmit.buf = dma_alloc_coherent(NULL, + UART_XMIT_SIZE, + (dma_addr_t *)&(up->uart_dma.tx_buf_dma_phys), + 0); + init_timer(&(up->uart_dma.rx_timer)); + up->uart_dma.rx_timer.function = serial_omap_rx_timeout; + up->uart_dma.rx_timer.data = up->pdev->id; + /* Currently the buffer size is 4KB. Can increase it */ + up->uart_dma.rx_buf = dma_alloc_coherent(NULL, + up->uart_dma.rx_buf_size, + (dma_addr_t *)&(up->uart_dma.rx_buf_dma_phys), 0); + } + /* + * Finally, enable interrupts. Note: Modem status interrupts + * are set via set_termios(), which will be occurring imminently + * anyway, so we don't enable them here. + */ + up->ier = UART_IER_RLSI | UART_IER_RDI; + serial_out(up, UART_IER, up->ier); + + up->port_activity = jiffies; + return 0; +} + +static void serial_omap_shutdown(struct uart_port *port) +{ + struct uart_omap_port *up = (struct uart_omap_port *)port; + unsigned long flags = 0; + + dev_dbg(up->port.dev, "serial_omap_shutdown+%d\n", up->pdev->id); + /* + * Disable interrupts from this port + */ + up->ier = 0; + serial_out(up, UART_IER, 0); + + spin_lock_irqsave(&up->port.lock, flags); + up->port.mctrl &= ~TIOCM_OUT2; + serial_omap_set_mctrl(&up->port, up->port.mctrl); + spin_unlock_irqrestore(&up->port.lock, flags); + + /* + * Disable break condition and FIFOs + */ + serial_out(up, UART_LCR, serial_in(up, UART_LCR) & ~UART_LCR_SBC); + serial_omap_clear_fifos(up); + + /* + * Read data port to reset things, and then free the irq + */ + if (serial_in(up, UART_LSR) & UART_LSR_DR) + (void) serial_in(up, UART_RX); + if (up->use_dma) { + int tmp; + dma_free_coherent(up->port.dev, + UART_XMIT_SIZE, up->port.state->xmit.buf, + up->uart_dma.tx_buf_dma_phys); + up->port.state->xmit.buf = NULL; + serial_omap_stop_rx(port); + dma_free_coherent(up->port.dev, + up->uart_dma.rx_buf_size, up->uart_dma.rx_buf, + up->uart_dma.rx_buf_dma_phys); + up->uart_dma.rx_buf = NULL; + tmp = serial_in(up, UART_OMAP_SYSC) & OMAP_UART_SYSC_RESET; + serial_out(up, UART_OMAP_SYSC, tmp); /* force-idle */ + } + free_irq(up->port.irq, up); +} + +static inline void +serial_omap_configure_xonxoff + (struct uart_omap_port *up, struct ktermios *termios) +{ + unsigned char efr = 0; + + up->lcr = serial_in(up, UART_LCR); + serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB); + up->efr = serial_in(up, UART_EFR); + serial_out(up, UART_EFR, up->efr & ~UART_EFR_ECB); + + serial_out(up, UART_XON1, termios->c_cc[VSTART]); + serial_out(up, UART_XOFF1, termios->c_cc[VSTOP]); + + /* clear SW control mode bits */ + efr = up->efr; + efr &= OMAP_UART_SW_CLR; + + /* + * IXON Flag: + * Enable XON/XOFF flow control on output. + * Transmit XON1, XOFF1 + */ + if (termios->c_iflag & IXON) + efr |= OMAP_UART_SW_TX; + + /* + * IXOFF Flag: + * Enable XON/XOFF flow control on input. + * Receiver compares XON1, XOFF1. + */ + if (termios->c_iflag & IXOFF) + efr |= OMAP_UART_SW_RX; + + serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); + serial_out(up, UART_LCR, UART_LCR_DLAB); + + up->mcr = serial_in(up, UART_MCR); + + /* + * IXANY Flag: + * Enable any character to restart output. + * Operation resumes after receiving any + * character after recognition of the XOFF character + */ + if (termios->c_iflag & IXANY) + up->mcr |= UART_MCR_XONANY; + + serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); + serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB); + serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_TRIG); + /* Enable special char function UARTi.EFR_REG[5] and + * load the new software flow control mode IXON or IXOFF + * and restore the UARTi.EFR_REG[4] ENHANCED_EN value. + */ + serial_out(up, UART_EFR, efr | UART_EFR_SCD); + serial_out(up, UART_LCR, UART_LCR_DLAB); + + serial_out(up, UART_MCR, up->mcr & ~UART_MCR_TCRTLR); + serial_out(up, UART_LCR, up->lcr); +} + +static void +serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, + struct ktermios *old) +{ + struct uart_omap_port *up = (struct uart_omap_port *)port; + unsigned char cval = 0; + unsigned char efr = 0; + unsigned long flags = 0; + unsigned int baud, quot; + + switch (termios->c_cflag & CSIZE) { + case CS5: + cval = UART_LCR_WLEN5; + break; + case CS6: + cval = UART_LCR_WLEN6; + break; + case CS7: + cval = UART_LCR_WLEN7; + break; + default: + case CS8: + cval = UART_LCR_WLEN8; + break; + } + + if (termios->c_cflag & CSTOPB) + cval |= UART_LCR_STOP; + if (termios->c_cflag & PARENB) + cval |= UART_LCR_PARITY; + if (!(termios->c_cflag & PARODD)) + cval |= UART_LCR_EPAR; + + /* + * Ask the core to calculate the divisor for us. + */ + + baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/13); + quot = serial_omap_get_divisor(port, baud); + + up->fcr = UART_FCR_R_TRIG_01 | UART_FCR_T_TRIG_01 | + UART_FCR_ENABLE_FIFO; + if (up->use_dma) + up->fcr |= UART_FCR_DMA_SELECT; + + /* + * Ok, we're now changing the port state. Do it with + * interrupts disabled. + */ + spin_lock_irqsave(&up->port.lock, flags); + + /* + * Update the per-port timeout. + */ + uart_update_timeout(port, termios->c_cflag, baud); + + up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; + if (termios->c_iflag & INPCK) + up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE; + if (termios->c_iflag & (BRKINT | PARMRK)) + up->port.read_status_mask |= UART_LSR_BI; + + /* + * Characters to ignore + */ + up->port.ignore_status_mask = 0; + if (termios->c_iflag & IGNPAR) + up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; + if (termios->c_iflag & IGNBRK) { + up->port.ignore_status_mask |= UART_LSR_BI; + /* + * If we're ignoring parity and break indicators, + * ignore overruns too (for real raw support). + */ + if (termios->c_iflag & IGNPAR) + up->port.ignore_status_mask |= UART_LSR_OE; + } + + /* + * ignore all characters if CREAD is not set + */ + if ((termios->c_cflag & CREAD) == 0) + up->port.ignore_status_mask |= UART_LSR_DR; + + /* + * Modem status interrupts + */ + up->ier &= ~UART_IER_MSI; + if (UART_ENABLE_MS(&up->port, termios->c_cflag)) + up->ier |= UART_IER_MSI; + serial_out(up, UART_IER, up->ier); + serial_out(up, UART_LCR, cval); /* reset DLAB */ + + /* FIFOs and DMA Settings */ + + /* FCR can be changed only when the + * baud clock is not running + * DLL_REG and DLH_REG set to 0. + */ + serial_out(up, UART_LCR, UART_LCR_DLAB); + serial_out(up, UART_DLL, 0); + serial_out(up, UART_DLM, 0); + serial_out(up, UART_LCR, 0); + + serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB); + + up->efr = serial_in(up, UART_EFR); + serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); + + serial_out(up, UART_LCR, 0); + up->mcr = serial_in(up, UART_MCR); + serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); + /* FIFO ENABLE, DMA MODE */ + serial_out(up, UART_FCR, up->fcr); + serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB); + + if (up->use_dma) { + serial_out(up, UART_TI752_TLR, 0); + serial_out(up, UART_OMAP_SCR, + (UART_FCR_TRIGGER_4 | UART_FCR_TRIGGER_8)); + } + + serial_out(up, UART_EFR, up->efr); + serial_out(up, UART_LCR, UART_LCR_DLAB); + serial_out(up, UART_MCR, up->mcr); + + /* Protocol, Baud Rate, and Interrupt Settings */ + + serial_out(up, UART_OMAP_MDR1, OMAP_MDR1_DISABLE); + serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB); + + up->efr = serial_in(up, UART_EFR); + serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); + + serial_out(up, UART_LCR, 0); + serial_out(up, UART_IER, 0); + serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB); + + serial_out(up, UART_DLL, quot & 0xff); /* LS of divisor */ + serial_out(up, UART_DLM, quot >> 8); /* MS of divisor */ + + serial_out(up, UART_LCR, 0); + serial_out(up, UART_IER, up->ier); + serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB); + + serial_out(up, UART_EFR, up->efr); + serial_out(up, UART_LCR, cval); + + if (baud > 230400 && baud != 3000000) + serial_out(up, UART_OMAP_MDR1, OMAP_MDR1_MODE13X); + else + serial_out(up, UART_OMAP_MDR1, OMAP_MDR1_MODE16X); + + /* Hardware Flow Control Configuration */ + + if (termios->c_cflag & CRTSCTS) { + efr |= (UART_EFR_CTS | UART_EFR_RTS); + serial_out(up, UART_LCR, UART_LCR_DLAB); + + up->mcr = serial_in(up, UART_MCR); + serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); + + serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB); + up->efr = serial_in(up, UART_EFR); + serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); + + serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_TRIG); + serial_out(up, UART_EFR, efr); /* Enable AUTORTS and AUTOCTS */ + serial_out(up, UART_LCR, UART_LCR_DLAB); + serial_out(up, UART_MCR, up->mcr | UART_MCR_RTS); + serial_out(up, UART_LCR, cval); + } + + serial_omap_set_mctrl(&up->port, up->port.mctrl); + /* Software Flow Control Configuration */ + if (termios->c_iflag & (IXON | IXOFF)) + serial_omap_configure_xonxoff(up, termios); + + spin_unlock_irqrestore(&up->port.lock, flags); + dev_dbg(up->port.dev, "serial_omap_set_termios+%d\n", up->pdev->id); +} + +static void +serial_omap_pm(struct uart_port *port, unsigned int state, + unsigned int oldstate) +{ + struct uart_omap_port *up = (struct uart_omap_port *)port; + unsigned char efr; + + dev_dbg(up->port.dev, "serial_omap_pm+%d\n", up->pdev->id); + efr = serial_in(up, UART_EFR); + serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB); + serial_out(up, UART_EFR, efr | UART_EFR_ECB); + serial_out(up, UART_LCR, 0); + + serial_out(up, UART_IER, (state != 0) ? UART_IERX_SLEEP : 0); + serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB); + serial_out(up, UART_EFR, efr); + serial_out(up, UART_LCR, 0); + /* Enable module level wake up */ + serial_out(up, UART_OMAP_WER, + (state != 0) ? OMAP_UART_WER_MOD_WKUP : 0); +} + +static void serial_omap_release_port(struct uart_port *port) +{ + dev_dbg(port->dev, "serial_omap_release_port+\n"); +} + +static int serial_omap_request_port(struct uart_port *port) +{ + dev_dbg(port->dev, "serial_omap_request_port+\n"); + return 0; +} + +static void serial_omap_config_port(struct uart_port *port, int flags) +{ + struct uart_omap_port *up = (struct uart_omap_port *)port; + + dev_dbg(up->port.dev, "serial_omap_config_port+%d\n", + up->pdev->id); + up->port.type = PORT_OMAP; +} + +static int +serial_omap_verify_port(struct uart_port *port, struct serial_struct *ser) +{ + /* we don't want the core code to modify any port params */ + dev_dbg(port->dev, "serial_omap_verify_port+\n"); + return -EINVAL; +} + +static const char * +serial_omap_type(struct uart_port *port) +{ + struct uart_omap_port *up = (struct uart_omap_port *)port; + + dev_dbg(up->port.dev, "serial_omap_type+%d\n", up->pdev->id); + return up->name; +} + +#ifdef CONFIG_SERIAL_OMAP_CONSOLE + +static struct uart_omap_port *serial_omap_console_ports[4]; + +static struct uart_driver serial_omap_reg; + +#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) + +static inline void wait_for_xmitr(struct uart_omap_port *up) +{ + unsigned int status, tmout = 10000; + + /* Wait up to 10ms for the character(s) to be sent. */ + do { + status = serial_in(up, UART_LSR); + + if (status & UART_LSR_BI) + up->lsr_break_flag = UART_LSR_BI; + + if (--tmout == 0) + break; + udelay(1); + } while ((status & BOTH_EMPTY) != BOTH_EMPTY); + + /* Wait up to 1s for flow control if necessary */ + if (up->port.flags & UPF_CONS_FLOW) { + tmout = 1000000; + for (tmout = 1000000; tmout; tmout--) { + unsigned int msr = serial_in(up, UART_MSR); + up->msr_saved_flags |= msr & MSR_SAVE_FLAGS; + if (msr & UART_MSR_CTS) + break; + udelay(1); + } + } +} + +static void serial_omap_console_putchar(struct uart_port *port, int ch) +{ + struct uart_omap_port *up = (struct uart_omap_port *)port; + + wait_for_xmitr(up); + serial_out(up, UART_TX, ch); +} + +static void +serial_omap_console_write(struct console *co, const char *s, + unsigned int count) +{ + struct uart_omap_port *up = serial_omap_console_ports[co->index]; + unsigned int ier; + + /* + * First save the IER then disable the interrupts + */ + ier = serial_in(up, UART_IER); + serial_out(up, UART_IER, 0); + + uart_console_write(&up->port, s, count, serial_omap_console_putchar); + + /* + * Finally, wait for transmitter to become empty + * and restore the IER + */ + wait_for_xmitr(up); + serial_out(up, UART_IER, ier); + /* + * The receive handling will happen properly because the + * receive ready bit will still be set; it is not cleared + * on read. However, modem control will not, we must + * call it if we have saved something in the saved flags + * while processing with interrupts off. + */ + if (up->msr_saved_flags) + check_modem_status(up); +} + +static int __init +serial_omap_console_setup(struct console *co, char *options) +{ + struct uart_omap_port *up; + int baud = 115200; + int bits = 8; + int parity = 'n'; + int flow = 'n'; + int r; + + if (serial_omap_console_ports[co->index] == NULL) + return -ENODEV; + up = serial_omap_console_ports[co->index]; + + if (options) + uart_parse_options(options, &baud, &parity, &bits, &flow); + + r = uart_set_options(&up->port, co, baud, parity, bits, flow); + + return r; +} + +static struct console serial_omap_console = { + .name = OMAP_SERIAL_NAME, + .write = serial_omap_console_write, + .device = uart_console_device, + .setup = serial_omap_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, + .data = &serial_omap_reg, +}; + +static void serial_omap_add_console_port(struct uart_omap_port *up) +{ + serial_omap_console_ports[up->pdev->id] = up; +} + +#define OMAP_CONSOLE (&serial_omap_console) + +#else + +#define OMAP_CONSOLE NULL + +static inline void serial_omap_add_console_port(struct uart_omap_port *up) +{} + +#endif + +struct uart_ops serial_omap_pops = { + .tx_empty = serial_omap_tx_empty, + .set_mctrl = serial_omap_set_mctrl, + .get_mctrl = serial_omap_get_mctrl, + .stop_tx = serial_omap_stop_tx, + .start_tx = serial_omap_start_tx, + .stop_rx = serial_omap_stop_rx, + .enable_ms = serial_omap_enable_ms, + .break_ctl = serial_omap_break_ctl, + .startup = serial_omap_startup, + .shutdown = serial_omap_shutdown, + .set_termios = serial_omap_set_termios, + .pm = serial_omap_pm, + .type = serial_omap_type, + .release_port = serial_omap_release_port, + .request_port = serial_omap_request_port, + .config_port = serial_omap_config_port, + .verify_port = serial_omap_verify_port, +}; + +static struct uart_driver serial_omap_reg = { + .owner = THIS_MODULE, + .driver_name = "OMAP-SERIAL", + .dev_name = OMAP_SERIAL_NAME, + .nr = OMAP_MAX_HSUART_PORTS, + .cons = OMAP_CONSOLE, +}; + +static int +serial_omap_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct uart_omap_port *up = platform_get_drvdata(pdev); + + if (up) + uart_suspend_port(&serial_omap_reg, &up->port); + return 0; +} + +static int serial_omap_resume(struct platform_device *dev) +{ + struct uart_omap_port *up = platform_get_drvdata(dev); + + if (up) + uart_resume_port(&serial_omap_reg, &up->port); + return 0; +} + +static void serial_omap_rx_timeout(unsigned long uart_no) +{ + struct uart_omap_port *up = ui[uart_no]; + unsigned int curr_dma_pos, curr_transmitted_size; + unsigned int ret = 0; + + curr_dma_pos = omap_get_dma_dst_pos(up->uart_dma.rx_dma_channel); + if ((curr_dma_pos == up->uart_dma.prev_rx_dma_pos) || + (curr_dma_pos == 0)) { + if (jiffies_to_msecs(jiffies - up->port_activity) < + RX_TIMEOUT) { + mod_timer(&up->uart_dma.rx_timer, jiffies + + usecs_to_jiffies(up->uart_dma.rx_timeout)); + } else { + serial_omap_stop_rxdma(up); + up->ier |= UART_IER_RDI; + serial_out(up, UART_IER, up->ier); + } + return; + } + + curr_transmitted_size = curr_dma_pos - + up->uart_dma.prev_rx_dma_pos; + up->port.icount.rx += curr_transmitted_size; + tty_insert_flip_string(up->port.state->port.tty, + up->uart_dma.rx_buf + + (up->uart_dma.prev_rx_dma_pos - + up->uart_dma.rx_buf_dma_phys), + curr_transmitted_size); + tty_flip_buffer_push(up->port.state->port.tty); + up->uart_dma.prev_rx_dma_pos = curr_dma_pos; + if (up->uart_dma.rx_buf_size + + up->uart_dma.rx_buf_dma_phys == curr_dma_pos) { + ret = serial_omap_start_rxdma(up); + if (ret < 0) { + serial_omap_stop_rxdma(up); + up->ier |= UART_IER_RDI; + serial_out(up, UART_IER, up->ier); + } + } else { + mod_timer(&up->uart_dma.rx_timer, jiffies + + usecs_to_jiffies(up->uart_dma.rx_timeout)); + } + up->port_activity = jiffies; +} + +static void uart_rx_dma_callback(int lch, u16 ch_status, void *data) +{ + return; +} + +static int serial_omap_start_rxdma(struct uart_omap_port *up) +{ + int ret = 0; + + if (up->uart_dma.rx_dma_channel == -1) { + ret = omap_request_dma(up->uart_dma.uart_dma_rx, + "UART Rx DMA", + (void *)uart_rx_dma_callback, up, + &(up->uart_dma.rx_dma_channel)); + if (ret < 0) + return ret; + + omap_set_dma_src_params(up->uart_dma.rx_dma_channel, 0, + OMAP_DMA_AMODE_CONSTANT, + up->uart_dma.uart_base, 0, 0); + omap_set_dma_dest_params(up->uart_dma.rx_dma_channel, 0, + OMAP_DMA_AMODE_POST_INC, + up->uart_dma.rx_buf_dma_phys, 0, 0); + omap_set_dma_transfer_params(up->uart_dma.rx_dma_channel, + OMAP_DMA_DATA_TYPE_S8, + up->uart_dma.rx_buf_size, 1, + OMAP_DMA_SYNC_ELEMENT, + up->uart_dma.uart_dma_rx, 0); + } + up->uart_dma.prev_rx_dma_pos = up->uart_dma.rx_buf_dma_phys; + /* + * TBD: Should be done in omap_start_dma function + * Patch proposed to LO pending in LO. + */ + if (cpu_is_omap44xx()) + omap_writel(0, OMAP44XX_DMA4_BASE + + OMAP_DMA4_CDAC(up->uart_dma.rx_dma_channel)); + else + omap_writel(0, OMAP34XX_DMA4_BASE + + OMAP_DMA4_CDAC(up->uart_dma.rx_dma_channel)); + omap_start_dma(up->uart_dma.rx_dma_channel); + mod_timer(&up->uart_dma.rx_timer, jiffies + + usecs_to_jiffies(up->uart_dma.rx_timeout)); + up->uart_dma.rx_dma_used = true; + return ret; +} + +static void serial_omap_continue_tx(struct uart_omap_port *up) +{ + struct circ_buf *xmit = &up->port.state->xmit; + int start = up->uart_dma.tx_buf_dma_phys + + (xmit->tail & (UART_XMIT_SIZE - 1)); + + if (uart_circ_empty(xmit)) + return; + + up->uart_dma.tx_buf_size = uart_circ_chars_pending(xmit); + /* + * It is a circular buffer. See if the buffer has wounded back. + * If yes it will have to be transferred in two separate dma + * transfers + */ + if (start + up->uart_dma.tx_buf_size >= + up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE) + up->uart_dma.tx_buf_size = + (up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE) - start; + omap_set_dma_dest_params(up->uart_dma.tx_dma_channel, 0, + OMAP_DMA_AMODE_CONSTANT, + up->uart_dma.uart_base, 0, 0); + omap_set_dma_src_params(up->uart_dma.tx_dma_channel, 0, + OMAP_DMA_AMODE_POST_INC, start, 0, 0); + omap_set_dma_transfer_params(up->uart_dma.tx_dma_channel, + OMAP_DMA_DATA_TYPE_S8, + up->uart_dma.tx_buf_size, 1, + OMAP_DMA_SYNC_ELEMENT, + up->uart_dma.uart_dma_tx, 0); + wmb(); + omap_start_dma(up->uart_dma.tx_dma_channel); +} + +static void uart_tx_dma_callback(int lch, u16 ch_status, void *data) +{ + struct uart_omap_port *up = (struct uart_omap_port *)data; + struct circ_buf *xmit = &up->port.state->xmit; + + xmit->tail = (xmit->tail + up->uart_dma.tx_buf_size) & \ + (UART_XMIT_SIZE - 1); + up->port.icount.tx += up->uart_dma.tx_buf_size; + + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(&up->port); + + if (uart_circ_empty(xmit)) { + spin_lock(&(up->uart_dma.tx_lock)); + serial_omap_stop_tx(&up->port); + up->uart_dma.tx_dma_used = false; + spin_unlock(&(up->uart_dma.tx_lock)); + } else { + omap_stop_dma(up->uart_dma.tx_dma_channel); + serial_omap_continue_tx(up); + } + up->port_activity = jiffies; + return; +} + +static int serial_omap_probe(struct platform_device *pdev) +{ + struct uart_omap_port *up; + struct resource *mem, *irq, *dma_tx, *dma_rx; + struct omap_uart_port_info *omap_up_info = pdev->dev.platform_data; + int ret = -ENOSPC; + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem) { + dev_err(&pdev->dev, "no mem resource?\n"); + return -ENODEV; + } + irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!irq) { + dev_err(&pdev->dev, "no irq resource?\n"); + return -ENODEV; + } + + if (!request_mem_region(mem->start, (mem->end - mem->start) + 1, + pdev->dev.driver->name)) { + dev_err(&pdev->dev, "memory region already claimed\n"); + return -EBUSY; + } + + dma_rx = platform_get_resource(pdev, IORESOURCE_DMA, 0); + if (!dma_rx) { + ret = -EINVAL; + goto err; + } + + dma_tx = platform_get_resource(pdev, IORESOURCE_DMA, 1); + if (!dma_tx) { + ret = -EINVAL; + goto err; + } + + up = kzalloc(sizeof(*up), GFP_KERNEL); + if (up == NULL) { + ret = -ENOMEM; + goto do_release_region; + } + sprintf(up->name, "OMAP UART%d", pdev->id); + up->pdev = pdev; + up->port.dev = &pdev->dev; + up->port.type = PORT_OMAP; + up->port.iotype = UPIO_MEM; + up->port.irq = irq->start; + + up->port.regshift = 2; + up->port.fifosize = 64; + up->port.ops = &serial_omap_pops; + up->port.line = pdev->id; + + up->port.membase = omap_up_info->membase; + up->port.mapbase = omap_up_info->mapbase; + up->port.flags = omap_up_info->flags; + up->port.irqflags = omap_up_info->irqflags; + up->port.uartclk = omap_up_info->uartclk; + up->uart_dma.uart_base = mem->start; + + if (omap_up_info->dma_enabled) { + up->uart_dma.uart_dma_tx = dma_tx->start; + up->uart_dma.uart_dma_rx = dma_rx->start; + up->use_dma = 1; + up->uart_dma.rx_buf_size = 4096; + up->uart_dma.rx_timeout = 1; + spin_lock_init(&(up->uart_dma.tx_lock)); + spin_lock_init(&(up->uart_dma.rx_lock)); + up->uart_dma.tx_dma_channel = OMAP_UART_DMA_CH_FREE; + up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE; + } + + ui[pdev->id] = up; + serial_omap_add_console_port(up); + + ret = uart_add_one_port(&serial_omap_reg, &up->port); + if (ret != 0) + goto do_release_region; + + platform_set_drvdata(pdev, up); + return 0; +err: + dev_err(&pdev->dev, "[UART%d]: failure [%s]: %d\n", + pdev->id, __func__, ret); +do_release_region: + release_mem_region(mem->start, (mem->end - mem->start) + 1); + return ret; +} + +static int serial_omap_remove(struct platform_device *dev) +{ + struct uart_omap_port *up = platform_get_drvdata(dev); + + platform_set_drvdata(dev, NULL); + if (up) { + uart_remove_one_port(&serial_omap_reg, &up->port); + kfree(up); + } + return 0; +} + +static struct platform_driver serial_omap_driver = { + .probe = serial_omap_probe, + .remove = serial_omap_remove, + + .suspend = serial_omap_suspend, + .resume = serial_omap_resume, + .driver = { + .name = DRIVER_NAME, + }, +}; + +int __init serial_omap_init(void) +{ + int ret; + + ret = uart_register_driver(&serial_omap_reg); + if (ret != 0) + return ret; + ret = platform_driver_register(&serial_omap_driver); + if (ret != 0) + uart_unregister_driver(&serial_omap_reg); + return ret; +} + +void __exit serial_omap_exit(void) +{ + platform_driver_unregister(&serial_omap_driver); + uart_unregister_driver(&serial_omap_reg); +} + +module_init(serial_omap_init); +module_exit(serial_omap_exit); + +MODULE_DESCRIPTION("OMAP High Speed UART driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Texas Instruments Inc"); diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 0495fa651225..e178cf81c109 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1274,6 +1274,10 @@ static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, if (is_root_hub(urb->dev)) return 0; + if (usb_endpoint_xfer_control(&urb->ep->desc)) + urb->transfer_flags = URB_NO_SETUP_DMA_MAP | + URB_NO_TRANSFER_DMA_MAP; + if (usb_endpoint_xfer_control(&urb->ep->desc) && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) { if (hcd->self.uses_dma) { diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h index 9cf6cd71d2e8..9bfcdcdb2076 100644 --- a/include/linux/i2c/twl.h +++ b/include/linux/i2c/twl.h @@ -556,6 +556,10 @@ struct twl4030_codec_data { unsigned int audio_mclk; struct twl4030_codec_audio_data *audio; struct twl4030_codec_vibra_data *vibra; + + /* twl6040 */ + int audpwron_gpio; /* audio power-on gpio */ + int naudint_irq; /* audio interrupt */ }; struct twl4030_platform_data { diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index eaf36364b7d4..d5ded454c900 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -203,6 +203,13 @@ struct mmc_host { struct dentry *debugfs_root; +#ifdef CONFIG_TIWLAN_SDIO + struct { + struct sdio_cis *cis; + struct sdio_embedded_func *funcs; + } embedded_sdio_data; +#endif + unsigned long private[0] ____cacheline_aligned; }; @@ -211,6 +218,12 @@ extern int mmc_add_host(struct mmc_host *); extern void mmc_remove_host(struct mmc_host *); extern void mmc_free_host(struct mmc_host *); +#ifdef CONFIG_TIWLAN_SDIO +extern void mmc_set_embedded_sdio_data(struct mmc_host *host, + struct sdio_cis *cis, + struct sdio_embedded_func *funcs); +#endif + static inline void *mmc_priv(struct mmc_host *host) { return (void *)host->private; diff --git a/include/linux/mmc/sdio_func.h b/include/linux/mmc/sdio_func.h index ac3ab683fec6..4d77c9cc76e3 100644 --- a/include/linux/mmc/sdio_func.h +++ b/include/linux/mmc/sdio_func.h @@ -20,6 +20,16 @@ struct sdio_func; typedef void (sdio_irq_handler_t)(struct sdio_func *); +#ifdef CONFIG_TIWLAN_SDIO +/* + * Structure used to hold embedded SDIO device data from platform layer + */ +struct sdio_embedded_func { + uint8_t f_class; + uint32_t f_maxblksize; +}; +#endif + /* * SDIO function CIS tuple (unknown to the core) */ diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h index 33b2ea09a4ad..770f311fcdb9 100644 --- a/include/linux/mmc/sdio_ids.h +++ b/include/linux/mmc/sdio_ids.h @@ -35,6 +35,11 @@ #define SDIO_DEVICE_ID_MARVELL_8688WLAN 0x9104 #define SDIO_DEVICE_ID_MARVELL_8688BT 0x9105 +#ifdef CONFIG_TIWLAN_SDIO +#define SDIO_VENDOR_ID_TI 0x104c +#define SDIO_DEVICE_ID_TI_WL12xx 0x9066 +#endif + #define SDIO_VENDOR_ID_SIANO 0x039a #define SDIO_DEVICE_ID_SIANO_NOVA_B0 0x0201 #define SDIO_DEVICE_ID_SIANO_NICE 0x0202 diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 8c3dd36fe91a..e02b945d74c9 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -182,6 +182,9 @@ /* Aeroflex Gaisler GRLIB APBUART */ #define PORT_APBUART 90 +/* TI OMAP-UART */ +#define PORT_OMAP 91 + #ifdef __KERNEL__ #include <linux/compiler.h> diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 52b005f8fed4..6889144d1704 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -33,6 +33,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_TPA6130A2 if I2C select SND_SOC_TLV320DAC33 if I2C select SND_SOC_TWL4030 if TWL4030_CORE + select SND_SOC_ABE_TWL6040 if TWL4030_CORE select SND_SOC_UDA134X select SND_SOC_UDA1380 if I2C select SND_SOC_WM8350 if MFD_WM8350 @@ -155,6 +156,9 @@ config SND_SOC_TWL4030 select TWL4030_CODEC tristate +config SND_SOC_ABE_TWL6040 + tristate + config SND_SOC_UDA134X tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index dbaecb133ac7..9883185bdf93 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -20,6 +20,7 @@ snd-soc-tlv320aic26-objs := tlv320aic26.o snd-soc-tlv320aic3x-objs := tlv320aic3x.o snd-soc-tlv320dac33-objs := tlv320dac33.o snd-soc-twl4030-objs := twl4030.o +snd-soc-abe-twl6040-objs := abe-twl6040.o snd-soc-uda134x-objs := uda134x.o snd-soc-uda1380-objs := uda1380.o snd-soc-wm8350-objs := wm8350.o @@ -76,6 +77,7 @@ obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o +obj-$(CONFIG_SND_SOC_ABE_TWL6040) += snd-soc-abe-twl6040.o abe/ obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o diff --git a/sound/soc/codecs/abe-twl6040.c b/sound/soc/codecs/abe-twl6040.c new file mode 100644 index 000000000000..022a49a0b6ca --- /dev/null +++ b/sound/soc/codecs/abe-twl6040.c @@ -0,0 +1,1718 @@ +/* + * ALSA SoC ABE-TWL6040 codec driver + * + * Author: Misael Lopez Cruz <x0052729@ti.com> + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/pm.h> +#include <linux/i2c.h> +#include <linux/gpio.h> +#include <linux/platform_device.h> +#include <linux/i2c/twl.h> +#include <linux/clk.h> + +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/soc.h> +#include <sound/soc-dapm.h> +#include <sound/initval.h> +#include <sound/tlv.h> + +#include "twl6040.h" +#include "abe-twl6040.h" +#include "abe/abe_main.h" + +#define ABE_FORMATS (SNDRV_PCM_FMTBIT_S32_LE) + +/* codec private data */ +struct twl6040_data { + struct snd_soc_codec codec; + int audpwron; + int naudint; + int codec_powered; + int pll; + int non_lp; + unsigned int sysclk; + struct snd_pcm_hw_constraint_list *sysclk_constraints; + struct completion ready; + int configure; + struct clk *clk; +}; + +/* + * twl6040 register cache & default register settings + */ +static const u8 twl6040_reg[TWL6040_CACHEREGNUM] = { + 0x00, /* not used 0x00 */ + 0x4B, /* TWL6040_ASICID (ro) 0x01 */ + 0x00, /* TWL6040_ASICREV (ro) 0x02 */ + 0x00, /* TWL6040_INTID 0x03 */ + 0x00, /* TWL6040_INTMR 0x04 */ + 0x00, /* TWL6040_NCPCTRL 0x05 */ + 0x00, /* TWL6040_LDOCTL 0x06 */ + 0x60, /* TWL6040_HPPLLCTL 0x07 */ + 0x00, /* TWL6040_LPPLLCTL 0x08 */ + 0x4A, /* TWL6040_LPPLLDIV 0x09 */ + 0x00, /* TWL6040_AMICBCTL 0x0A */ + 0x00, /* TWL6040_DMICBCTL 0x0B */ + 0x18, /* TWL6040_MICLCTL 0x0C - No input selected on Left Mic */ + 0x18, /* TWL6040_MICRCTL 0x0D - No input selected on Right Mic */ + 0x00, /* TWL6040_MICGAIN 0x0E */ + 0x1B, /* TWL6040_LINEGAIN 0x0F */ + 0x00, /* TWL6040_HSLCTL 0x10 */ + 0x00, /* TWL6040_HSRCTL 0x11 */ + 0x00, /* TWL6040_HSGAIN 0x12 */ + 0x00, /* TWL6040_EARCTL 0x13 */ + 0x00, /* TWL6040_HFLCTL 0x14 */ + 0x00, /* TWL6040_HFLGAIN 0x15 */ + 0x00, /* TWL6040_HFRCTL 0x16 */ + 0x00, /* TWL6040_HFRGAIN 0x17 */ + 0x00, /* TWL6040_VIBCTLL 0x18 */ + 0x00, /* TWL6040_VIBDATL 0x19 */ + 0x00, /* TWL6040_VIBCTLR 0x1A */ + 0x00, /* TWL6040_VIBDATR 0x1B */ + 0x00, /* TWL6040_HKCTL1 0x1C */ + 0x00, /* TWL6040_HKCTL2 0x1D */ + 0x02, /* TWL6040_GPOCTL 0x1E */ + 0x00, /* TWL6040_ALB 0x1F */ + 0x00, /* TWL6040_DLB 0x20 */ + 0x00, /* not used 0x21 */ + 0x00, /* not used 0x22 */ + 0x00, /* not used 0x23 */ + 0x00, /* not used 0x24 */ + 0x00, /* not used 0x25 */ + 0x00, /* not used 0x26 */ + 0x00, /* not used 0x27 */ + 0x00, /* TWL6040_TRIM1 0x28 */ + 0x00, /* TWL6040_TRIM2 0x29 */ + 0x00, /* TWL6040_TRIM3 0x2A */ + 0x00, /* TWL6040_HSOTRIM 0x2B */ + 0x00, /* TWL6040_HFOTRIM 0x2C */ + 0x09, /* TWL6040_ACCCTL 0x2D */ + 0x00, /* TWL6040_STATUS (ro) 0x2E */ + 0x00, /* TWL6040_SHADOW 0x2F */ +}; + +/* + * twl6040 vio/gnd registers: + * registers under vio/gnd supply can be accessed + * before the power-up sequence, after NRESPWRON goes high + */ +static const int twl6040_vio_reg[TWL6040_VIOREGNUM] = { + TWL6040_REG_ASICID, + TWL6040_REG_ASICREV, + TWL6040_REG_INTID, + TWL6040_REG_INTMR, + TWL6040_REG_NCPCTL, + TWL6040_REG_LDOCTL, + TWL6040_REG_AMICBCTL, + TWL6040_REG_DMICBCTL, + TWL6040_REG_HKCTL1, + TWL6040_REG_HKCTL2, + TWL6040_REG_GPOCTL, + TWL6040_REG_TRIM1, + TWL6040_REG_TRIM2, + TWL6040_REG_TRIM3, + TWL6040_REG_HSOTRIM, + TWL6040_REG_HFOTRIM, + TWL6040_REG_ACCCTL, + TWL6040_REG_STATUS, +}; + +/* + * twl6040 vdd/vss registers: + * registers under vdd/vss supplies can only be accessed + * after the power-up sequence + */ +static const int twl6040_vdd_reg[TWL6040_VDDREGNUM] = { + TWL6040_REG_HPPLLCTL, + TWL6040_REG_LPPLLCTL, + TWL6040_REG_LPPLLDIV, + TWL6040_REG_MICLCTL, + TWL6040_REG_MICRCTL, + TWL6040_REG_MICGAIN, + TWL6040_REG_LINEGAIN, + TWL6040_REG_HSLCTL, + TWL6040_REG_HSRCTL, + TWL6040_REG_HSGAIN, + TWL6040_REG_EARCTL, + TWL6040_REG_HFLCTL, + TWL6040_REG_HFLGAIN, + TWL6040_REG_HFRCTL, + TWL6040_REG_HFRGAIN, + TWL6040_REG_VIBCTLL, + TWL6040_REG_VIBDATL, + TWL6040_REG_VIBCTLR, + TWL6040_REG_VIBDATR, + TWL6040_REG_ALB, + TWL6040_REG_DLB, +}; + +/* + * read twl6040 register cache + */ +static inline unsigned int twl6040_read_reg_cache(struct snd_soc_codec *codec, + unsigned int reg) +{ + u8 *cache = codec->reg_cache; + + if (reg >= TWL6040_CACHEREGNUM) + return -EIO; + + return cache[reg]; +} + +/* + * write twl6040 register cache + */ +static inline void twl6040_write_reg_cache(struct snd_soc_codec *codec, + u8 reg, u8 value) +{ + u8 *cache = codec->reg_cache; + + if (reg >= TWL6040_CACHEREGNUM) + return; + cache[reg] = value; +} + +/* + * read from twl6040 hardware register + */ +static int twl6040_read_reg_volatile(struct snd_soc_codec *codec, + unsigned int reg) +{ + u8 value; + + if (reg >= TWL6040_CACHEREGNUM) + return -EIO; + + if (likely(reg < TWL6040_REG_SHADOW)) { + twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &value, reg); + twl6040_write_reg_cache(codec, reg, value); + return value; + } else { + return twl6040_read_reg_cache(codec, reg); + } +} + +/* + * write to the twl6040 register space + */ +static int twl6040_write(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value) +{ + if (reg >= TWL6040_CACHEREGNUM) + return -EIO; + + twl6040_write_reg_cache(codec, reg, value); + if (likely(reg < TWL6040_REG_SHADOW)) + return twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, value, reg); + else + return 0; +} + +static void twl6040_init_vio_regs(struct snd_soc_codec *codec) +{ + u8 *cache = codec->reg_cache; + int reg, i; + + /* allow registers to be accessed by i2c */ + twl6040_write(codec, TWL6040_REG_ACCCTL, cache[TWL6040_REG_ACCCTL]); + + for (i = 0; i < TWL6040_VIOREGNUM; i++) { + reg = twl6040_vio_reg[i]; + /* skip read-only registers (ASICID, ASICREV, STATUS) */ + switch (reg) { + case TWL6040_REG_ASICID: + case TWL6040_REG_ASICREV: + case TWL6040_REG_STATUS: + continue; + default: + break; + } + twl6040_write(codec, reg, cache[reg]); + } +} + +static void twl6040_init_vdd_regs(struct snd_soc_codec *codec) +{ + u8 *cache = codec->reg_cache; + int reg, i; + + for (i = 0; i < TWL6040_VDDREGNUM; i++) { + reg = twl6040_vdd_reg[i]; + twl6040_write(codec, reg, cache[reg]); + } +} + +static void abe_init_chip(struct snd_soc_codec *codec) +{ + struct twl6040_data *priv = codec->private_data; + abe_opp_t OPP = ABE_OPP100; + + abe_init_mem(); + /* aess_clk has to be enabled to access hal register. + * Disabel the clk after it has been used. + */ + clk_enable(priv->clk); + abe_reset_hal(); + /* Config OPP 100 for now */ + abe_set_opp_processing(OPP); + /* "tick" of the audio engine */ + abe_write_event_generator(EVENT_TIMER); + + abe_write_mixer(MIXDL1, MUTE_GAIN, RAMP_0MS, MIX_DL1_INPUT_MM_DL); + abe_write_mixer(MIXDL1, MUTE_GAIN, RAMP_0MS, MIX_DL1_INPUT_MM_UL2); + abe_write_mixer(MIXDL1, GAIN_M6dB, RAMP_0MS, MIX_DL1_INPUT_VX_DL); + abe_write_mixer(MIXDL1, MUTE_GAIN, RAMP_0MS, MIX_DL1_INPUT_TONES); + + abe_write_mixer(MIXDL2, GAIN_M6dB, RAMP_0MS, MIX_DL2_INPUT_TONES); + abe_write_mixer(MIXDL2, MUTE_GAIN, RAMP_0MS, MIX_DL2_INPUT_VX_DL); + abe_write_mixer(MIXDL2, GAIN_M6dB, RAMP_0MS, MIX_DL2_INPUT_MM_DL); + abe_write_mixer(MIXDL2, MUTE_GAIN, RAMP_0MS, MIX_DL2_INPUT_MM_UL2); + + /* Vx in HS, MM in HF and Tones in HF */ + twl6040_write(codec, TWL6040_REG_SHADOW, 0x92); + + clk_disable(priv->clk); +} + +/* twl6040 codec manual power-up sequence */ +static void twl6040_power_up(struct snd_soc_codec *codec) +{ + u8 ncpctl, ldoctl, lppllctl, accctl; + + ncpctl = twl6040_read_reg_cache(codec, TWL6040_REG_NCPCTL); + ldoctl = twl6040_read_reg_cache(codec, TWL6040_REG_LDOCTL); + lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL); + accctl = twl6040_read_reg_cache(codec, TWL6040_REG_ACCCTL); + + /* enable reference system */ + ldoctl |= TWL6040_REFENA; + twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl); + msleep(10); + /* enable internal oscillator */ + ldoctl |= TWL6040_OSCENA; + twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl); + udelay(10); + /* enable high-side ldo */ + ldoctl |= TWL6040_HSLDOENA; + twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl); + udelay(244); + /* enable negative charge pump */ + ncpctl |= TWL6040_NCPENA | TWL6040_NCPOPEN; + twl6040_write(codec, TWL6040_REG_NCPCTL, ncpctl); + udelay(488); + /* enable low-side ldo */ + ldoctl |= TWL6040_LSLDOENA; + twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl); + udelay(244); + /* enable low-power pll */ + lppllctl |= TWL6040_LPLLENA; + twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl); + /* reset state machine */ + accctl |= TWL6040_RESETSPLIT; + twl6040_write(codec, TWL6040_REG_ACCCTL, accctl); + mdelay(5); + accctl &= ~TWL6040_RESETSPLIT; + twl6040_write(codec, TWL6040_REG_ACCCTL, accctl); + /* disable internal oscillator */ + ldoctl &= ~TWL6040_OSCENA; + twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl); +} + +/* twl6040 codec manual power-down sequence */ +static void twl6040_power_down(struct snd_soc_codec *codec) +{ + u8 ncpctl, ldoctl, lppllctl, accctl; + + ncpctl = twl6040_read_reg_cache(codec, TWL6040_REG_NCPCTL); + ldoctl = twl6040_read_reg_cache(codec, TWL6040_REG_LDOCTL); + lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL); + accctl = twl6040_read_reg_cache(codec, TWL6040_REG_ACCCTL); + + /* enable internal oscillator */ + ldoctl |= TWL6040_OSCENA; + twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl); + udelay(10); + /* disable low-power pll */ + lppllctl &= ~TWL6040_LPLLENA; + twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl); + /* disable low-side ldo */ + ldoctl &= ~TWL6040_LSLDOENA; + twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl); + udelay(244); + /* disable negative charge pump */ + ncpctl &= ~(TWL6040_NCPENA | TWL6040_NCPOPEN); + twl6040_write(codec, TWL6040_REG_NCPCTL, ncpctl); + udelay(488); + /* disable high-side ldo */ + ldoctl &= ~TWL6040_HSLDOENA; + twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl); + udelay(244); + /* disable internal oscillator */ + ldoctl &= ~TWL6040_OSCENA; + twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl); + /* disable reference system */ + ldoctl &= ~TWL6040_REFENA; + twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl); + msleep(10); +} + +/* set headset dac and driver power mode */ +static int headset_power_mode(struct snd_soc_codec *codec, int high_perf) +{ + int hslctl, hsrctl; + int mask = TWL6040_HSDRVMODEL | TWL6040_HSDACMODEL; + + hslctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSLCTL); + hsrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSRCTL); + + if (high_perf) { + hslctl &= ~mask; + hsrctl &= ~mask; + } else { + hslctl |= mask; + hsrctl |= mask; + } + + twl6040_write(codec, TWL6040_REG_HSLCTL, hslctl); + twl6040_write(codec, TWL6040_REG_HSRCTL, hsrctl); + + return 0; +} + +static int twl6040_power_mode_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + struct twl6040_data *priv = codec->private_data; + + if (SND_SOC_DAPM_EVENT_ON(event)) + priv->non_lp++; + else + priv->non_lp--; + + return 0; +} + +/* audio interrupt handler */ +static irqreturn_t twl6040_naudint_handler(int irq, void *data) +{ + struct snd_soc_codec *codec = data; + struct twl6040_data *priv = codec->private_data; + u8 intid; + + twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &intid, TWL6040_REG_INTID); + + switch (intid) { + case TWL6040_THINT: + dev_alert(codec->dev, "die temp over-limit detection\n"); + break; + case TWL6040_PLUGINT: + case TWL6040_UNPLUGINT: + case TWL6040_HOOKINT: + break; + case TWL6040_HFINT: + dev_alert(codec->dev, "hf drivers over current detection\n"); + break; + case TWL6040_VIBINT: + dev_alert(codec->dev, "vib drivers over current detection\n"); + break; + case TWL6040_READYINT: + complete(&priv->ready); + break; + default: + dev_err(codec->dev, "unknown audio interrupt %d\n", intid); + break; + } + + return IRQ_HANDLED; +} + +static int snd_soc_put_dl1_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); + unsigned int shift = mc->shift; + int mask; + int err; + unsigned short val; + char *name = kcontrol->id.name; + + mask = 1 << shift; + val = (ucontrol->value.integer.value[0] << shift); + + if (strcmp(name, "DL1 Mixer Tones") == 0) { + if (val) + abe_write_mixer(MIXDL1, GAIN_M6dB, + RAMP_0MS, MIX_DL1_INPUT_TONES); + else + abe_write_mixer(MIXDL1, MUTE_GAIN, + RAMP_0MS, MIX_DL1_INPUT_TONES); + } else if (strcmp(name, "DL1 Mixer Voice") == 0) { + if (val) + abe_write_mixer(MIXDL1, GAIN_M6dB, + RAMP_1MS, MIX_DL1_INPUT_VX_DL); + else + abe_write_mixer(MIXDL1, MUTE_GAIN, + RAMP_0MS, MIX_DL1_INPUT_VX_DL); + } else if (strcmp(name, "DL1 Mixer Multimedia") == 0) { + if (val) + abe_write_mixer(MIXDL1, GAIN_M6dB, + RAMP_2MS, MIX_DL1_INPUT_MM_DL); + else + abe_write_mixer(MIXDL1, MUTE_GAIN, + RAMP_0MS, MIX_DL1_INPUT_MM_DL); + } else if (strcmp(name, "DL1 Mixer Multimedia Uplink") == 0) { + if (val) + abe_write_mixer(MIXDL1, GAIN_M6dB, + RAMP_5MS, MIX_DL1_INPUT_MM_UL2); + else + abe_write_mixer(MIXDL1, MUTE_GAIN, + RAMP_0MS, MIX_DL1_INPUT_MM_UL2); + } + + err = snd_soc_update_bits(widget->codec, TWL6040_REG_SHADOW, mask, val); + + return err; +} + +static int snd_soc_put_dl2_mixer(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); + unsigned int shift = mc->shift; + int mask; + int err; + unsigned short val; + char *name = kcontrol->id.name; + + mask = 1 << shift; + val = (ucontrol->value.integer.value[0] << shift); + + if (strcmp(name, "DL2 Mixer Tones") == 0) { + if (val) + abe_write_mixer(MIXDL2, GAIN_M6dB, + RAMP_0MS, MIX_DL2_INPUT_TONES); + else + abe_write_mixer(MIXDL2, MUTE_GAIN, + RAMP_0MS, MIX_DL2_INPUT_TONES); + } else if (strcmp(name, "DL2 Mixer Voice") == 0) { + if (val) + abe_write_mixer(MIXDL2, GAIN_M6dB, + RAMP_1MS, MIX_DL2_INPUT_VX_DL); + else + abe_write_mixer(MIXDL2, MUTE_GAIN, + RAMP_0MS, MIX_DL2_INPUT_VX_DL); + } else if (strcmp(name, "DL2 Mixer Multimedia") == 0) { + if (val) + abe_write_mixer(MIXDL2, GAIN_M6dB, + RAMP_2MS, MIX_DL2_INPUT_MM_DL); + else + abe_write_mixer(MIXDL2, MUTE_GAIN, + RAMP_0MS, MIX_DL2_INPUT_MM_DL); + } else if (strcmp(name, "DL2 Mixer Multimedia Uplink") == 0) { + if (val) + abe_write_mixer(MIXDL2, GAIN_M6dB, + RAMP_5MS, MIX_DL2_INPUT_MM_UL2); + else + abe_write_mixer(MIXDL2, MUTE_GAIN, + RAMP_0MS, MIX_DL2_INPUT_MM_UL2); + } + + err = snd_soc_update_bits(widget->codec, TWL6040_REG_SHADOW, mask, val); + + return err; +} + +/* + * MICATT volume control: + * from -6 to 0 dB in 6 dB steps + */ +static DECLARE_TLV_DB_SCALE(mic_preamp_tlv, -600, 600, 0); + +/* + * MICGAIN volume control: + * from 6 to 30 dB in 6 dB steps + */ +static DECLARE_TLV_DB_SCALE(mic_amp_tlv, 600, 600, 0); + +/* + * HSGAIN volume control: + * from -30 to 0 dB in 2 dB steps + */ +static DECLARE_TLV_DB_SCALE(hs_tlv, -3000, 200, 0); + +/* + * HFGAIN volume control: + * from -52 to 6 dB in 2 dB steps + */ +static DECLARE_TLV_DB_SCALE(hf_tlv, -5200, 200, 0); + +/* + * EPGAIN volume control: + * from -24 to 6 dB in 2 dB steps + */ +static DECLARE_TLV_DB_SCALE(ep_tlv, -2400, 200, 0); + +/* Left analog microphone selection */ +static const char *twl6040_amicl_texts[] = + {"Headset Mic", "Main Mic", "Aux/FM Left", "Off"}; + +/* Right analog microphone selection */ +static const char *twl6040_amicr_texts[] = + {"Headset Mic", "Sub Mic", "Aux/FM Right", "Off"}; + +static const struct soc_enum twl6040_enum[] = { + SOC_ENUM_SINGLE(TWL6040_REG_MICLCTL, 3, 3, twl6040_amicl_texts), + SOC_ENUM_SINGLE(TWL6040_REG_MICRCTL, 3, 3, twl6040_amicr_texts), +}; + +static const struct snd_kcontrol_new amicl_control = + SOC_DAPM_ENUM("Route", twl6040_enum[0]); + +static const struct snd_kcontrol_new amicr_control = + SOC_DAPM_ENUM("Route", twl6040_enum[1]); + +static const struct snd_kcontrol_new dl1_mixer_controls[] = { + SOC_SINGLE_EXT("Tones", TWL6040_REG_SHADOW, 0, 1, 0, + snd_soc_dapm_get_volsw, snd_soc_put_dl1_mixer), + SOC_SINGLE_EXT("Voice", TWL6040_REG_SHADOW, 1, 1, 0, + snd_soc_dapm_get_volsw, snd_soc_put_dl1_mixer), + SOC_SINGLE_EXT("Multimedia Uplink", TWL6040_REG_SHADOW, 2, 1, 0, + snd_soc_dapm_get_volsw, snd_soc_put_dl1_mixer), + SOC_SINGLE_EXT("Multimedia", TWL6040_REG_SHADOW, 3, 1, 0, + snd_soc_dapm_get_volsw, snd_soc_put_dl1_mixer), +}; + +static const struct snd_kcontrol_new dl2_mixer_controls[] = { + SOC_SINGLE_EXT("Tones", TWL6040_REG_SHADOW, 4, 1, 0, + snd_soc_dapm_get_volsw, snd_soc_put_dl2_mixer), + SOC_SINGLE_EXT("Voice", TWL6040_REG_SHADOW, 5, 1, 0, + snd_soc_dapm_get_volsw, snd_soc_put_dl2_mixer), + SOC_SINGLE_EXT("Multimedia Uplink", TWL6040_REG_SHADOW, 6, 1, 0, + snd_soc_dapm_get_volsw, snd_soc_put_dl2_mixer), + SOC_SINGLE_EXT("Multimedia", TWL6040_REG_SHADOW, 7, 1, 0, + snd_soc_dapm_get_volsw, snd_soc_put_dl2_mixer), +}; + + +/* Headset DAC playback switches */ +static const struct snd_kcontrol_new hsdacl_switch_controls = + SOC_DAPM_SINGLE("Switch", TWL6040_REG_HSLCTL, 5, 1, 0); + +static const struct snd_kcontrol_new hsdacr_switch_controls = + SOC_DAPM_SINGLE("Switch", TWL6040_REG_HSRCTL, 5, 1, 0); + +/* Handsfree DAC playback switches */ +static const struct snd_kcontrol_new hfdacl_switch_controls = + SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFLCTL, 2, 1, 0); + +static const struct snd_kcontrol_new hfdacr_switch_controls = + SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFRCTL, 2, 1, 0); + +static const struct snd_kcontrol_new ep_driver_switch_controls = + SOC_DAPM_SINGLE("Switch", TWL6040_REG_EARCTL, 0, 1, 0); + +static const struct snd_kcontrol_new twl6040_snd_controls[] = { + /* Capture gains */ + SOC_DOUBLE_TLV("Capture Preamplifier Volume", + TWL6040_REG_MICGAIN, 6, 7, 1, 1, mic_preamp_tlv), + SOC_DOUBLE_TLV("Capture Volume", + TWL6040_REG_MICGAIN, 0, 3, 4, 0, mic_amp_tlv), + + /* Playback gains */ + SOC_DOUBLE_TLV("Headset Playback Volume", + TWL6040_REG_HSGAIN, 0, 4, 0xF, 1, hs_tlv), + SOC_DOUBLE_R_TLV("Handsfree Playback Volume", + TWL6040_REG_HFLGAIN, TWL6040_REG_HFRGAIN, 0, 0x1D, 1, hf_tlv), + SOC_SINGLE_TLV("Earphone Playback Volume", + TWL6040_REG_EARCTL, 1, 0xF, 1, ep_tlv), +}; + +static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { + /* Inputs */ + SND_SOC_DAPM_INPUT("MAINMIC"), + SND_SOC_DAPM_INPUT("HSMIC"), + SND_SOC_DAPM_INPUT("SUBMIC"), + SND_SOC_DAPM_INPUT("AFML"), + SND_SOC_DAPM_INPUT("AFMR"), + + /* Outputs */ + SND_SOC_DAPM_OUTPUT("HSOL"), + SND_SOC_DAPM_OUTPUT("HSOR"), + SND_SOC_DAPM_OUTPUT("HFL"), + SND_SOC_DAPM_OUTPUT("HFR"), + SND_SOC_DAPM_OUTPUT("EP"), + + /* Analog input muxes for the capture amplifiers */ + SND_SOC_DAPM_MUX("Analog Left Capture Route", + SND_SOC_NOPM, 0, 0, &amicl_control), + SND_SOC_DAPM_MUX("Analog Right Capture Route", + SND_SOC_NOPM, 0, 0, &amicr_control), + + SND_SOC_DAPM_MIXER("DL1 Mixer", + SND_SOC_NOPM, 0, 0, dl1_mixer_controls, + ARRAY_SIZE(dl1_mixer_controls)), + SND_SOC_DAPM_MIXER("DL2 Mixer", + SND_SOC_NOPM, 0, 0, dl2_mixer_controls, + ARRAY_SIZE(dl2_mixer_controls)), + + /* Analog capture PGAs */ + SND_SOC_DAPM_PGA("MicAmpL", + TWL6040_REG_MICLCTL, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("MicAmpR", + TWL6040_REG_MICRCTL, 0, 0, NULL, 0), + + /* ADCs */ + SND_SOC_DAPM_ADC("ADC Left", "Left Front Capture", + TWL6040_REG_MICLCTL, 2, 0), + SND_SOC_DAPM_ADC("ADC Right", "Right Front Capture", + TWL6040_REG_MICRCTL, 2, 0), + + /* Microphone bias */ + SND_SOC_DAPM_MICBIAS("Headset Mic Bias", + TWL6040_REG_AMICBCTL, 0, 0), + SND_SOC_DAPM_MICBIAS("Main Mic Bias", + TWL6040_REG_AMICBCTL, 4, 0), + SND_SOC_DAPM_MICBIAS("Digital Mic1 Bias", + TWL6040_REG_DMICBCTL, 0, 0), + SND_SOC_DAPM_MICBIAS("Digital Mic2 Bias", + TWL6040_REG_DMICBCTL, 4, 0), + + SND_SOC_DAPM_AIF_IN("AIFIN Tones", "Playback", 0, + SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("AIFIN Voice", "Playback", 0, + SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("AIFIN Multimedia Uplink", "Playback", 0, + SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("AIFIN Multimedia", "Playback", 0, + SND_SOC_NOPM, 0, 0), + + /* DACs */ + SND_SOC_DAPM_DAC("HSDAC Left", "Headset Playback", + TWL6040_REG_HSLCTL, 0, 0), + SND_SOC_DAPM_DAC("HSDAC Right", "Headset Playback", + TWL6040_REG_HSRCTL, 0, 0), + SND_SOC_DAPM_DAC_E("HFDAC Left", "Handsfree Playback", + TWL6040_REG_HFLCTL, 0, 0, + twl6040_power_mode_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_DAC_E("HFDAC Right", "Handsfree Playback", + TWL6040_REG_HFRCTL, 0, 0, + twl6040_power_mode_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + /* Analog playback switches */ + SND_SOC_DAPM_SWITCH("HSDAC Left Playback", + SND_SOC_NOPM, 0, 0, &hsdacl_switch_controls), + SND_SOC_DAPM_SWITCH("HSDAC Right Playback", + SND_SOC_NOPM, 0, 0, &hsdacr_switch_controls), + SND_SOC_DAPM_SWITCH("HFDAC Left Playback", + SND_SOC_NOPM, 0, 0, &hfdacl_switch_controls), + SND_SOC_DAPM_SWITCH("HFDAC Right Playback", + SND_SOC_NOPM, 0, 0, &hfdacr_switch_controls), + + /* Analog playback drivers */ + SND_SOC_DAPM_PGA_E("Handsfree Left Driver", + TWL6040_REG_HFLCTL, 4, 0, NULL, 0, + twl6040_power_mode_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("Handsfree Right Driver", + TWL6040_REG_HFRCTL, 4, 0, NULL, 0, + twl6040_power_mode_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA("Headset Left Driver", + TWL6040_REG_HSLCTL, 2, 0, NULL, 0), + SND_SOC_DAPM_PGA("Headset Right Driver", + TWL6040_REG_HSRCTL, 2, 0, NULL, 0), + SND_SOC_DAPM_SWITCH_E("Earphone Driver", + SND_SOC_NOPM, 0, 0, &ep_driver_switch_controls, + twl6040_power_mode_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + + /* Analog playback PGAs */ + SND_SOC_DAPM_PGA("HFDAC Left PGA", + TWL6040_REG_HFLCTL, 1, 0, NULL, 0), + SND_SOC_DAPM_PGA("HFDAC Right PGA", + TWL6040_REG_HFRCTL, 1, 0, NULL, 0), + +}; + +static const struct snd_soc_dapm_route intercon[] = { + /* Capture path */ + {"Analog Left Capture Route", "Headset Mic", "HSMIC"}, + {"Analog Left Capture Route", "Main Mic", "MAINMIC"}, + {"Analog Left Capture Route", "Aux/FM Left", "AFML"}, + + {"Analog Right Capture Route", "Headset Mic", "HSMIC"}, + {"Analog Right Capture Route", "Sub Mic", "SUBMIC"}, + {"Analog Right Capture Route", "Aux/FM Right", "AFMR"}, + + {"MicAmpL", NULL, "Analog Left Capture Route"}, + {"MicAmpR", NULL, "Analog Right Capture Route"}, + + {"ADC Left", NULL, "MicAmpL"}, + {"ADC Right", NULL, "MicAmpR"}, + + /* Headset playback path */ + {"DL1 Mixer", "Tones", "AIFIN Tones"}, + {"DL1 Mixer", "Voice", "AIFIN Voice"}, + {"DL1 Mixer", "Multimedia Uplink", "AIFIN Multimedia Uplink"}, + {"DL1 Mixer", "Multimedia", "AIFIN Multimedia"}, + + {"HSDAC Left", NULL, "DL1 Mixer"}, + {"HSDAC Right", NULL, "DL1 Mixer"}, + + {"HSDAC Left Playback", "Switch", "HSDAC Left"}, + {"HSDAC Right Playback", "Switch", "HSDAC Right"}, + + {"Headset Left Driver", NULL, "HSDAC Left Playback"}, + {"Headset Right Driver", NULL, "HSDAC Right Playback"}, + + {"HSOL", NULL, "Headset Left Driver"}, + {"HSOR", NULL, "Headset Right Driver"}, + + /* Earphone playback path */ + {"Earphone Driver", "Switch", "HSDAC Left"}, + {"EP", NULL, "Earphone Driver"}, + + /* Handsfree playback path */ + {"DL2 Mixer", "Tones", "AIFIN Tones"}, + {"DL2 Mixer", "Voice", "AIFIN Voice"}, + {"DL2 Mixer", "Multimedia Uplink", "AIFIN Multimedia Uplink"}, + {"DL2 Mixer", "Multimedia", "AIFIN Multimedia"}, + + {"HFDAC Left", NULL, "DL2 Mixer"}, + {"HFDAC Right", NULL, "DL2 Mixer"}, + + {"HFDAC Left Playback", "Switch", "HFDAC Left"}, + {"HFDAC Right Playback", "Switch", "HFDAC Right"}, + + {"HFDAC Left PGA", NULL, "HFDAC Left Playback"}, + {"HFDAC Right PGA", NULL, "HFDAC Right Playback"}, + + {"Handsfree Left Driver", "Switch", "HFDAC Left PGA"}, + {"Handsfree Right Driver", "Switch", "HFDAC Right PGA"}, + + {"HFL", NULL, "Handsfree Left Driver"}, + {"HFR", NULL, "Handsfree Right Driver"}, +}; + +static int abe_twl6040_add_widgets(struct snd_soc_codec *codec) +{ + snd_soc_dapm_new_controls(codec, twl6040_dapm_widgets, + ARRAY_SIZE(twl6040_dapm_widgets)); + + snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + + snd_soc_dapm_new_widgets(codec); + + return 0; +} + +static int twl6040_power_up_completion(struct snd_soc_codec *codec, + int naudint) +{ + struct twl6040_data *priv = codec->private_data; + int time_left; + u8 intid; + + time_left = wait_for_completion_timeout(&priv->ready, + msecs_to_jiffies(48)); + + if (!time_left) { + twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &intid, + TWL6040_REG_INTID); + if (!(intid & TWL6040_READYINT)) { + dev_err(codec->dev, "timeout waiting for READYINT\n"); + return -ETIMEDOUT; + } + } + + priv->codec_powered = 1; + + return 0; +} + +static int abe_twl6040_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + struct twl6040_data *priv = codec->private_data; + int audpwron = priv->audpwron; + int naudint = priv->naudint; + int ret; + + switch (level) { + case SND_SOC_BIAS_ON: + break; + case SND_SOC_BIAS_PREPARE: + break; + case SND_SOC_BIAS_STANDBY: + if (priv->codec_powered) + break; + + if (gpio_is_valid(audpwron)) { + /* use AUDPWRON line */ + gpio_set_value(audpwron, 1); + + /* wait for power-up completion */ + ret = twl6040_power_up_completion(codec, naudint); + if (ret) + return ret; + + /* sync registers updated during power-up sequence */ + twl6040_read_reg_volatile(codec, TWL6040_REG_NCPCTL); + twl6040_read_reg_volatile(codec, TWL6040_REG_LDOCTL); + twl6040_read_reg_volatile(codec, TWL6040_REG_LPPLLCTL); + } else { + /* use manual power-up sequence */ + twl6040_power_up(codec); + priv->codec_powered = 1; + } + + /* initialize vdd/vss registers with reg_cache */ + twl6040_init_vdd_regs(codec); + break; + case SND_SOC_BIAS_OFF: + if (!priv->codec_powered) + break; + + if (gpio_is_valid(audpwron)) { + /* use AUDPWRON line */ + gpio_set_value(audpwron, 0); + + /* power-down sequence latency */ + udelay(500); + + /* sync registers updated during power-down sequence */ + twl6040_read_reg_volatile(codec, TWL6040_REG_NCPCTL); + twl6040_read_reg_volatile(codec, TWL6040_REG_LDOCTL); + twl6040_write_reg_cache(codec, TWL6040_REG_LPPLLCTL, + 0x00); + } else { + /* use manual power-down sequence */ + twl6040_power_down(codec); + } + + priv->codec_powered = 0; + break; + } + + codec->bias_level = level; + + return 0; +} + +/* set of rates for each pll: low-power and high-performance */ + +static unsigned int lp_rates[] = { + 44100, + 48000, +}; + +static struct snd_pcm_hw_constraint_list lp_constraints = { + .count = ARRAY_SIZE(lp_rates), + .list = lp_rates, +}; + +static unsigned int hp_rates[] = { + 8000, + 16000, + 48000, +}; + +static struct snd_pcm_hw_constraint_list hp_constraints = { + .count = ARRAY_SIZE(hp_rates), + .list = hp_rates, +}; + +static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai, + int clk_id, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct twl6040_data *priv = codec->private_data; + u8 hppllctl, lppllctl; + + hppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_HPPLLCTL); + lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL); + + switch (clk_id) { + case TWL6040_SYSCLK_SEL_LPPLL: + switch (freq) { + case 32768: + /* headset dac and driver must be in low-power mode */ + headset_power_mode(codec, 0); + + /* clk32k input requires low-power pll */ + lppllctl |= TWL6040_LPLLENA; + twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl); + mdelay(5); + lppllctl &= ~TWL6040_HPLLSEL; + twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl); + hppllctl &= ~TWL6040_HPLLENA; + twl6040_write(codec, TWL6040_REG_HPPLLCTL, hppllctl); + break; + default: + dev_err(codec->dev, "unknown mclk freq %d\n", freq); + return -EINVAL; + } + + /* lppll divider */ + switch (priv->sysclk) { + case 17640000: + lppllctl |= TWL6040_LPLLFIN; + break; + case 19200000: + lppllctl &= ~TWL6040_LPLLFIN; + break; + default: + /* sysclk not yet configured */ + lppllctl &= ~TWL6040_LPLLFIN; + priv->sysclk = 19200000; + break; + } + + twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl); + + priv->pll = TWL6040_LPPLL_ID; + priv->sysclk_constraints = &lp_constraints; + break; + case TWL6040_SYSCLK_SEL_HPPLL: + hppllctl &= ~TWL6040_MCLK_MSK; + + switch (freq) { + case 12000000: + /* mclk input, pll enabled */ + hppllctl |= TWL6040_MCLK_12000KHZ | + TWL6040_HPLLSQRBP | + TWL6040_HPLLENA; + break; + case 19200000: + /* mclk input, pll disabled */ + hppllctl |= TWL6040_MCLK_19200KHZ | + TWL6040_HPLLSQRENA | + TWL6040_HPLLBP; + break; + case 26000000: + /* mclk input, pll enabled */ + hppllctl |= TWL6040_MCLK_26000KHZ | + TWL6040_HPLLSQRBP | + TWL6040_HPLLENA; + break; + case 38400000: + /* clk slicer, pll disabled */ + hppllctl |= TWL6040_MCLK_38400KHZ | + TWL6040_HPLLSQRENA | + TWL6040_HPLLBP; + break; + default: + dev_err(codec->dev, "unknown mclk freq %d\n", freq); + return -EINVAL; + } + + /* headset dac and driver must be in high-performance mode */ + headset_power_mode(codec, 1); + + twl6040_write(codec, TWL6040_REG_HPPLLCTL, hppllctl); + udelay(500); + lppllctl |= TWL6040_HPLLSEL; + twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl); + lppllctl &= ~TWL6040_LPLLENA; + twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl); + + /* high-performance pll can provide only 19.2 MHz */ + priv->pll = TWL6040_HPPLL_ID; + priv->sysclk = 19200000; + priv->sysclk_constraints = &hp_constraints; + break; + default: + dev_err(codec->dev, "unknown clk_id %d\n", clk_id); + return -EINVAL; + } + + return 0; +} + +static int abe_mm_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_device *socdev = rtd->socdev; + struct snd_soc_codec *codec = socdev->card->codec; + struct twl6040_data *priv = codec->private_data; + + if (!priv->sysclk) { + dev_err(codec->dev, + "no mclk configured, call set_sysclk() on init\n"); + return -EINVAL; + } + + /* + * capture is not supported at 17.64 MHz, + * it's reserved for headset low-power playback scenario + */ + if ((priv->sysclk == 17640000) && substream->stream) { + dev_err(codec->dev, + "capture mode is not supported at %dHz\n", + priv->sysclk); + return -EINVAL; + } + + snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + priv->sysclk_constraints); + + if (!priv->configure++) { + clk_enable(priv->clk); + abe_set_router_configuration(UPROUTE, UPROUTE_CONFIG_AMIC, + (abe_router_t *)abe_router_ul_table_preset[UPROUTE_CONFIG_AMIC]); + + abe_write_gain(GAINS_DL1, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_DL1, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + abe_write_gain(GAINS_DL2, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_DL2, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + + abe_write_gain(GAINS_AMIC , GAIN_M6dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_AMIC, GAIN_M6dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + + abe_write_gain(GAINS_SPLIT, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_SPLIT, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + + abe_write_gain(GAINS_DL1, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_DL1, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + abe_write_gain(GAINS_DL2, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_DL2, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + } + return 0; +} + +static int abe_mm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_device *socdev = rtd->socdev; + struct snd_soc_codec *codec = socdev->card->codec; + struct twl6040_data *priv = codec->private_data; + u8 lppllctl; + int rate; + unsigned int sysclk; + abe_data_format_t format; + abe_dma_t dma_sink; + + lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL); + + rate = params_rate(params); + switch (rate) { + case 44100: + lppllctl |= TWL6040_LPLLFIN; + sysclk = 17640000; + break; + case 48000: + /* Select output frequency 19.2 MHz */ + lppllctl &= ~TWL6040_LPLLFIN; + sysclk = 19200000; + break; + default: + dev_err(codec->dev, "unsupported rate %d\n", rate); + return -EINVAL; + } + + if (priv->pll == TWL6040_LPPLL_ID) { + priv->sysclk = sysclk; + twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl); + } + + format.f = rate; + format.samp_format = STEREO_MSB; + if (!substream->stream) + abe_connect_cbpr_dmareq_port(MM_DL_PORT, &format, ABE_CBPR0_IDX, &dma_sink); + else + abe_connect_cbpr_dmareq_port(MM_UL_PORT, &format, ABE_CBPR3_IDX, &dma_sink); + + return 0; +} + +static int abe_mm_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_device *socdev = rtd->socdev; + struct snd_soc_codec *codec = socdev->card->codec; + struct twl6040_data *priv = codec->private_data; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + /* + * low-power playback mode is restricted + * for headset path only + */ + if ((priv->sysclk == 17640000) && priv->non_lp) { + dev_err(codec->dev, + "some enabled paths aren't supported at %dHz\n", + priv->sysclk); + return -EPERM; + } + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + if (!substream->stream) + abe_enable_data_transfer(MM_DL_PORT); + else + abe_enable_data_transfer(MM_UL_PORT); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + if (!substream->stream) + abe_disable_data_transfer(MM_DL_PORT); + else + abe_disable_data_transfer(MM_UL_PORT); + break; + default: + break; + } + + return 0; +} + +static void abe_mm_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_device *socdev = rtd->socdev; + struct snd_soc_codec *codec = socdev->card->codec; + struct twl6040_data *priv = codec->private_data; + + if(!--priv->configure) + clk_disable(priv->clk); +} + +static struct snd_soc_dai_ops abe_mm_dai_ops = { + .startup = abe_mm_startup, + .hw_params = abe_mm_hw_params, + .shutdown = abe_mm_shutdown, + .trigger = abe_mm_trigger, + .set_sysclk = twl6040_set_dai_sysclk, +}; + +static int abe_tones_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_device *socdev = rtd->socdev; + struct snd_soc_codec *codec = socdev->card->codec; + struct twl6040_data *priv = codec->private_data; + u8 lppllctl; + int rate; + unsigned int sysclk; + abe_data_format_t format; + abe_dma_t dma_sink; + + lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL); + + rate = params_rate(params); + switch (rate) { + case 44100: + lppllctl |= TWL6040_LPLLFIN; + sysclk = 17640000; + break; + case 48000: + /* Select output frequency 19.2 MHz */ + lppllctl &= ~TWL6040_LPLLFIN; + sysclk = 19200000; + break; + default: + dev_err(codec->dev, "unsupported rate %d\n", rate); + return -EINVAL; + } + + if (priv->pll == TWL6040_LPPLL_ID) { + priv->sysclk = sysclk; + twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl); + } + + format.f = rate; + format.samp_format = STEREO_MSB; + if (!substream->stream) + abe_connect_cbpr_dmareq_port(TONES_DL_PORT, &format, + ABE_CBPR5_IDX, &dma_sink); + + return 0; +} + +static int abe_tones_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_device *socdev = rtd->socdev; + struct snd_soc_codec *codec = socdev->card->codec; + struct twl6040_data *priv = codec->private_data; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + /* + * low-power playback mode is restricted + * for headset path only + */ + if ((priv->sysclk == 17640000) && priv->non_lp) { + dev_err(codec->dev, + "some enabled paths aren't supported at %dHz\n", + priv->sysclk); + return -EPERM; + } + if (!substream->stream) + abe_enable_data_transfer(TONES_DL_PORT); + break; + case SNDRV_PCM_TRIGGER_STOP: + if (!substream->stream) + abe_disable_data_transfer(TONES_DL_PORT); + break; + default: + break; + } + + return 0; +} + +static struct snd_soc_dai_ops abe_tones_dai_ops = { + .startup = abe_mm_startup, + .hw_params = abe_tones_hw_params, + .trigger = abe_tones_trigger, + .set_sysclk = twl6040_set_dai_sysclk, +}; + +static int abe_voice_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_device *socdev = rtd->socdev; + struct snd_soc_codec *codec = socdev->card->codec; + struct twl6040_data *priv = codec->private_data; + u8 lppllctl; + int rate; + abe_data_format_t format; + abe_dma_t dma_sink; + + rate = params_rate(params); + switch (rate) { + case 16000: + case 8000: + /* Select output frequency 19.2 MHz */ + if (priv->pll == TWL6040_LPPLL_ID) { + lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL); + lppllctl &= ~TWL6040_LPLLFIN; + priv->sysclk = 19200000; + twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl); + } + break; + default: + dev_err(codec->dev, "unsupported rate %d\n", rate); + return -EINVAL; + } + + format.f = rate; + format.samp_format = STEREO_MSB; + if (!substream->stream) + abe_connect_cbpr_dmareq_port(VX_DL_PORT, &format, ABE_CBPR1_IDX, &dma_sink); + else + abe_connect_cbpr_dmareq_port(VX_UL_PORT, &format, ABE_CBPR2_IDX, &dma_sink); + + return 0; +} + +static int abe_voice_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_device *socdev = rtd->socdev; + struct snd_soc_codec *codec = socdev->card->codec; + struct twl6040_data *priv = codec->private_data; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + /* + * low-power playback mode is restricted + * for headset path only + */ + if ((priv->sysclk == 17640000) && priv->non_lp) { + dev_err(codec->dev, + "some enabled paths aren't supported at %dHz\n", + priv->sysclk); + return -EPERM; + } + if (!substream->stream) + abe_enable_data_transfer(VX_DL_PORT); + else + abe_enable_data_transfer(VX_UL_PORT); + break; + case SNDRV_PCM_TRIGGER_STOP: + if (!substream->stream) + abe_disable_data_transfer(VX_DL_PORT); + else + abe_disable_data_transfer(VX_UL_PORT); + break; + default: + break; + } + + return 0; +} + +static struct snd_soc_dai_ops abe_voice_dai_ops = { + .startup = abe_mm_startup, + .hw_params = abe_voice_hw_params, + .shutdown = abe_mm_shutdown, + .trigger = abe_voice_trigger, + .set_sysclk = twl6040_set_dai_sysclk, +}; + +/* Audio Backend DAIs */ +struct snd_soc_dai abe_dai[] = { + /* Multimedia: MM-UL2, MM-DL */ + { + .name = "Multimedia", + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, + .formats = ABE_FORMATS, + }, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_48000, + .formats = ABE_FORMATS, + }, + .ops = &abe_mm_dai_ops, + }, + /* Tones DL: MM-DL2 */ + { + .name = "Tones DL", + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, + .formats = ABE_FORMATS, + }, + .ops = &abe_tones_dai_ops, + }, + /* Voice: VX-UL, VX-DL */ + { + .name = "Voice", + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, + .formats = ABE_FORMATS, + }, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, + .formats = ABE_FORMATS, + }, + .ops = &abe_voice_dai_ops, + }, + /* Digital Uplink: MM-UL */ + { + .name = "Digital Uplink", + .capture = { + .stream_name = "Capture", + .channels_min = 2, + .channels_max = 10, + .rates = SNDRV_PCM_RATE_48000, + .formats = ABE_FORMATS, + }, + }, + /* Vibrator: VIB-DL */ + { + .name = "Vibrator", + .playback = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_48000, + .formats = ABE_FORMATS, + }, + }, +}; + +#ifdef CONFIG_PM +static int abe_twl6040_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->card->codec; + + abe_twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF); + + return 0; +} + +static int abe_twl6040_resume(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->card->codec; + + abe_twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + abe_twl6040_set_bias_level(codec, codec->suspend_bias_level); + + return 0; +} +#else +#define abe_twl6040_suspend NULL +#define abe_twl6040_resume NULL +#endif + +static struct snd_soc_codec *twl6040_codec; + +static int abe_twl6040_probe(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec; + int ret = 0; + + BUG_ON(!twl6040_codec); + + codec = twl6040_codec; + socdev->card->codec = codec; + + /* register pcms */ + ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); + if (ret < 0) { + dev_err(&pdev->dev, "failed to create pcms\n"); + return ret; + } + + abe_init_chip(codec); + snd_soc_add_controls(codec, twl6040_snd_controls, + ARRAY_SIZE(twl6040_snd_controls)); + abe_twl6040_add_widgets(codec); + + return 0; +} + +static int abe_twl6040_remove(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->card->codec; + + abe_twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF); + snd_soc_free_pcms(socdev); + snd_soc_dapm_free(socdev); + kfree(codec); + + return 0; +} + +struct snd_soc_codec_device soc_codec_dev_abe_twl6040 = { + .probe = abe_twl6040_probe, + .remove = abe_twl6040_remove, + .suspend = abe_twl6040_suspend, + .resume = abe_twl6040_resume, +}; +EXPORT_SYMBOL_GPL(soc_codec_dev_abe_twl6040); + +static int __devinit abe_twl6040_codec_probe(struct platform_device *pdev) +{ + struct twl4030_codec_data *twl_codec = pdev->dev.platform_data; + struct snd_soc_codec *codec; + struct twl6040_data *priv; + int audpwron, naudint; + int ret = 0; + + priv = kzalloc(sizeof(struct twl6040_data), GFP_KERNEL); + if (priv == NULL) + return -ENOMEM; + + if (twl_codec) { + audpwron = twl_codec->audpwron_gpio; + naudint = twl_codec->naudint_irq; + } else { + audpwron = -EINVAL; + naudint = 0; + } + + priv->audpwron = audpwron; + priv->naudint = naudint; + + codec = &priv->codec; + codec->pop_time = 1; + codec->dev = &pdev->dev; + codec->name = "twl6040"; + codec->owner = THIS_MODULE; + codec->read = twl6040_read_reg_cache; + codec->write = twl6040_write; + codec->set_bias_level = abe_twl6040_set_bias_level; + codec->private_data = priv; + codec->dai = abe_dai; + codec->num_dai = ARRAY_SIZE(abe_dai); + codec->reg_cache_size = ARRAY_SIZE(twl6040_reg); + codec->reg_cache = kmemdup(twl6040_reg, sizeof(twl6040_reg), + GFP_KERNEL); + if (codec->reg_cache == NULL) { + ret = -ENOMEM; + goto cache_err; + } + + mutex_init(&codec->mutex); + INIT_LIST_HEAD(&codec->dapm_widgets); + INIT_LIST_HEAD(&codec->dapm_paths); + init_completion(&priv->ready); + + if (gpio_is_valid(audpwron)) { + ret = gpio_request(audpwron, "audpwron"); + if (ret) + goto gpio1_err; + + ret = gpio_direction_output(audpwron, 0); + if (ret) + goto gpio2_err; + + priv->codec_powered = 0; + } + + if (naudint) { + /* audio interrupt */ + ret = request_threaded_irq(naudint, NULL, + twl6040_naudint_handler, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + "twl6040_codec", codec); + if (ret) + goto gpio2_err; + } else { + if (gpio_is_valid(audpwron)) { + /* enable only codec ready interrupt */ + twl6040_write_reg_cache(codec, TWL6040_REG_INTMR, + ~TWL6040_READYMSK & TWL6040_ALLINT_MSK); + } else { + /* no interrupts at all */ + twl6040_write_reg_cache(codec, TWL6040_REG_INTMR, + TWL6040_ALLINT_MSK); + } + } + + priv->clk = clk_get(&pdev->dev, "aess_fclk"); + if (IS_ERR(priv->clk)) { + ret = PTR_ERR(priv->clk); + dev_err(&pdev->dev, "unable to get aess_fclk: %d\n", ret); + goto clk_err; + } + + /* init vio registers */ + twl6040_init_vio_regs(codec); + + /* power on device */ + ret = abe_twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + if (ret) + goto irq_err; + + ret = snd_soc_register_codec(codec); + if (ret) + goto reg_err; + + twl6040_codec = codec; + + ret = snd_soc_register_dais(abe_dai, ARRAY_SIZE(abe_dai)); + if (ret) + goto dai_err; + + return 0; + +dai_err: + snd_soc_unregister_codec(codec); + twl6040_codec = NULL; +reg_err: + abe_twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF); +irq_err: + if (naudint) + free_irq(naudint, codec); +gpio2_err: + clk_put(priv->clk); +clk_err: + if (gpio_is_valid(audpwron)) + gpio_free(audpwron); +gpio1_err: + kfree(codec->reg_cache); +cache_err: + kfree(priv); + return ret; +} + +static int __devexit abe_twl6040_codec_remove(struct platform_device *pdev) +{ + struct twl6040_data *priv = twl6040_codec->private_data; + int audpwron = priv->audpwron; + int naudint = priv->naudint; + + if (gpio_is_valid(audpwron)) + gpio_free(audpwron); + + if (naudint) + free_irq(naudint, twl6040_codec); + + clk_put(priv->clk); + + snd_soc_unregister_dais(abe_dai, ARRAY_SIZE(abe_dai)); + snd_soc_unregister_codec(twl6040_codec); + + kfree(twl6040_codec); + twl6040_codec = NULL; + + return 0; +} + +static struct platform_driver abe_twl6040_codec_driver = { + .driver = { + .name = "twl6040_codec", + .owner = THIS_MODULE, + }, + .probe = abe_twl6040_codec_probe, + .remove = __devexit_p(abe_twl6040_codec_remove), +}; + +static int __init abe_twl6040_codec_init(void) +{ + return platform_driver_register(&abe_twl6040_codec_driver); +} +module_init(abe_twl6040_codec_init); + +static void __exit abe_twl6040_codec_exit(void) +{ + platform_driver_unregister(&abe_twl6040_codec_driver); +} +module_exit(abe_twl6040_codec_exit); + +MODULE_DESCRIPTION("ASoC ABE-TWL6040 codec driver"); +MODULE_AUTHOR("Misael Lopez Cruz"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/abe-twl6040.h b/sound/soc/codecs/abe-twl6040.h new file mode 100644 index 000000000000..929d994eb084 --- /dev/null +++ b/sound/soc/codecs/abe-twl6040.h @@ -0,0 +1,32 @@ +/* + * ALSA SoC ABE-TWL6040 codec driver + * + * Author: Misael Lopez Cruz <x0052729@ti.com> + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __ABE_TWL6040_H__ +#define __ABE_TWL6040_H__ + +extern struct snd_soc_dai abe_dai[]; +extern struct snd_soc_codec_device soc_codec_dev_abe_twl6040; + +struct twl6040_setup_data { + void (*codec_enable)(int enable); +}; + +#endif /* End of __ABE_TWL6040_H__ */ diff --git a/sound/soc/codecs/abe/C_ABE_FW.CM b/sound/soc/codecs/abe/C_ABE_FW.CM new file mode 100644 index 000000000000..be2a3d3b1f41 --- /dev/null +++ b/sound/soc/codecs/abe/C_ABE_FW.CM @@ -0,0 +1,1309 @@ +0x000000, +0x000000, +0x001000, +0x001000, +0x001000, +0x001000, +0x001000, +0x001000, +0x001000, +0x151000, +0x141000, +0x001000, +0x001000, +0x001000, +0x001000, +0x001000, +0x001001, +0x000000, +0x001011, +0x001011, +0x021031, +0x041051, +0x061071, +0x081091, +0x0a10b1, +0x0c10d1, +0x001001, +0x001001, +0x001000, +0x001000, +0x001001, +0x001001, +0x001000, +0x001000, +0x001000, +0x001000, +0x001000, +0x001001, +0x001000, +0x001000, +0x001000, +0x001000, +0x001041, +0x001000, +0x000000, +0x001000, +0x001000, +0x001000, +0x001001, +0x001001, +0x001000, +0x001000, +0x001000, +0x001000, +0x001001, +0x001001, +0x001001, +0x001001, +0x001000, +0x001001, +0x001001, +0x001000, +0x001000, +0x001001, +0x001001, +0x001001, +0x001001, +0x001001, +0x001001, +0x001000, +0x001000, +0x001000, +0x001000, +0x001000, +0x001001, +0x001000, +0x000000, +0x000000, +0x000000, +0x001000, +0x001000, +0x001000, +0x000000, +0x000000, +0x000000, +0x001000, +0x001001, +0x000001, +0x001000, +0x002794, +0x001000, +0x001001, +0x000001, +0x001000, +0x002794, +0x151000, +0x000000, +0x002794, +0x002794, +0x151000, +0x001000, +0x001001, +0x000001, +0x001000, +0x0027d4, +0x001000, +0x001001, +0x001000, +0x001000, +0x001001, +0x001001, +0x0010c1, +0x001000, +0x0010c1, +0x001001, +0x001000, +0x001000, +0x001061, +0x001061, +0x000000, +0x000000, +0x000000, +0x001071, +0x000000, +0x001071, +0x001000, +0x001000, +0x001031, +0x001061, +0x001000, +0x001061, +0x001061, +0x001000, +0x001000, +0x001031, +0x001061, +0x000000, +0x001000, +0x001041, +0x001001, +0x000000, +0x001000, +0x001011, +0x001001, +0x000000, +0x000000, +0x000000, +0x001000, +0x001011, +0x001001, +0x000000, +0x001000, +0x001001, +0x000001, +0x001000, +0x002794, +0x002794, +0x001041, +0x001041, +0x001000, +0x001000, +0x001000, +0x001011, +0x001001, +0x001000, +0x001011, +0x001001, +0x001000, +0x001011, +0x001001, +0x000000, +0x001000, +0x001011, +0x001001, +0x000000, +0x001000, +0x001001, +0x001001, +0x001031, +0x001061, +0x001061, +0x001061, +0x151000, +0x001000, +0x001000, +0x001081, +0x001001, +0x001001, +0x001001, +0x001001, +0x0000bd, +0x001041, +0x001000, +0x001041, +0x001001, +0x001001, +0x000000, +0x001001, +0x001000, +0x001051, +0x001000, +0x001001, +0x001051, +0x001001, +0x0000cb, +0x001000, +0x001001, +0x001001, +0x001001, +0x001001, +0x00fff9, +0x001000, +0x001000, +0x000000, +0x001000, +0x001071, +0x001000, +0x000000, +0x001071, +0x001071, +0x001071, +0x001071, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x001000, +0x001000, +0x0000fc, +0x000000, +0x000000, +0x001000, +0x001000, +0x001000, +0x001000, +0x001000, +0x004444, +0x001000, +0x001000, +0x001061, +0x001061, +0x001031, +0x001061, +0x001061, +0x001061, +0x001031, +0x001061, +0x001000, +0x001000, +0x001000, +0x001000, +0x001000, +0x001000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000008, +0x100001, +0x100001, +0x100001, +0x100001, +0x100001, +0x100001, +0x100001, +0x100001, +0x100001, +0x100001, +0x100001, +0x100001, +0x100001, +0x100001, +0x100001, +0x100001, +0x100001, +0x100001, +0x700001, +0x700001, +0x700001, +0x700001, +0x700001, +0x700001, +0x700001, +0x700001, +0x700001, +0x700001, +0x700001, +0x700001, +0x700001, +0x700001, +0x700001, +0x700001, +0x700001, +0x700001, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x040002, +0x000000, +0x000000, +0x000000, +0x000000, +0x023c94, +0x5ed280, +0x6a9a5d, +0xbf42f0, +0x056260, +0x0f02e8, +0xeb9d08, +0x13f0e8, +0xeed498, +0x0d8628, +0xf610e8, +0x06dac8, +0xfb8ca8, +0x02b6a8, +0x9d1d03, +0x3411d3, +0xe7110b, +0x0a8b43, +0xfc4793, +0x0208b8, +0x6d23e0, +0x66c791, +0xb09170, +0x142c90, +0x03c304, +0xf376f8, +0x0eb9d8, +0xf220d0, +0x0b9710, +0xf71850, +0x0661c0, +0xfbb618, +0x02b430, +0x99fe5b, +0x37ceab, +0xe408e3, +0x0c8ac3, +0xfb2e83, +0x0464a8, +0x782010, +0x61b101, +0xa7ab80, +0x1ef5c0, +0xfadbf0, +0xfa10a0, +0x0a1678, +0xf53c30, +0x09a2c0, +0xf83d98, +0x05c418, +0xfc0144, +0x0296d8, +0x9badf3, +0x386703, +0xe2e293, +0x0d8413, +0xfa9443, +0x05d8f0, +0x42ccf5, +0x5b6439, +0x9fa4a8, +0x2a0528, +0xf141c8, +0x5c184b, +0x04be58, +0xf8ea80, +0x073f50, +0xf9b218, +0x04f108, +0xfc6e8c, +0x0264f0, +0xa04a13, +0x3770b3, +0xe2819b, +0x0e2353, +0xfa1fab, +0x07d850, +0x498425, +0x53f3c9, +0x9a9170, +0x334af8, +0xe88c00, +0x0875d0, +0xdcf763, +0xfcaf74, +0x04b6b0, +0xfb4d68, +0x03fc0c, +0xfcf654, +0x022008, +0xa80de3, +0x348833, +0xe33ce3, +0x0e2e23, +0xf9f08b, +0x0aadb0, +0x4fdc61, +0x4b98d9, +0x989408, +0x3a6068, +0xe12888, +0x0ec210, +0xfa8240, +0x14e61b, +0x022f7c, +0xfcf624, +0x02f50c, +0xfd8f38, +0x7356ab, +0xb24bfb, +0x300053, +0xe4f083, +0x0db28b, +0xfa0193, +0x0e5198, +0x55cb8d, +0x427b21, +0x9968b8, +0x3f50c0, +0xdb27e8, +0x143b08, +0xf604a8, +0x03bf5c, +0xef1dc3, +0xa7922b, +0x7977cb, +0x8ca91b, +0x5c4373, +0xbe654b, +0x2a32fb, +0xe76cb3, +0x0cc843, +0xfa47fb, +0x12b270, +0x5b537d, +0x716ee8, +0x9cd140, +0x423000, +0xd68e40, +0x18d298, +0xf20c30, +0x06e2f8, +0xfd6ac0, +0x0eee5b, +0x3575db, +0xb6e5bb, +0x4398ab, +0xcbda13, +0x236a1b, +0xea894b, +0x0b83a3, +0xfaba2b, +0x17d078, +0x606a75, +0x5cd070, +0xa2a0d0, +0x4306e0, +0xd365f8, +0x1c7720, +0xeeab88, +0x09ae08, +0xfb4778, +0x7127a3, +0xf2fbcb, +0xe1581b, +0x2a1533, +0xda3733, +0x1be75b, +0xee2313, +0x09f65b, +0xfb4feb, +0x1db640, +0x64f695, +0x4768e0, +0xaaa7f0, +0x41db98, +0xd1bd70, +0x1f1310, +0xebf900, +0x0c0d48, +0xf961f0, +0x032d94, +0xb409ab, +0x0aabc3, +0x108f73, +0xe8fccb, +0x13f29b, +0xf2141b, +0x08330b, +0xfc00bb, +0x2477b8, +0x68d739, +0x318e40, +0xb4aec0, +0x3ebd10, +0xd19bf0, +0x2095b8, +0xea0778, +0x0def88, +0xf7c838, +0x046be0, +0xfdea24, +0x319613, +0xf7da9b, +0xf7ab83, +0x0bd423, +0xf635fb, +0x064ca3, +0xfcc40b, +0x2c29d8, +0x6be82d, +0x1ba3e0, +0xc06ee8, +0x39c7a8, +0xd2fe70, +0x20f5c0, +0xe8e4e8, +0x0f46d0, +0xf68680, +0x0575e0, +0xfd2110, +0x54da23, +0xe0c55b, +0x05c47b, +0x03d513, +0xfa6163, +0x0456bb, +0xfd9103, +0x34dcb8, +0x6e0619, +0x0617a0, +0xcd9208, +0x3327e0, +0xd5d488, +0x2033b8, +0xe89830, +0x1009d8, +0xf5a608, +0x064398, +0xfc7b10, +0x735b3b, +0xcc0f3b, +0x12cf0b, +0xfc3c73, +0xfe6f83, +0x0264b3, +0xfe5ef3, +0x3ea030, +0x6f129d, +0xf14c40, +0xdbbf58, +0x2b1358, +0xda0390, +0x1e5960, +0xe92088, +0x1034f8, +0xf52c00, +0x06cfe8, +0xfbfc98, +0x023104, +0xba501b, +0x1e683b, +0xf5460b, +0x023efb, +0x00878b, +0xff2633, +0x497dd8, +0x6ef2a5, +0xdda780, +0xea95d0, +0x21ca50, +0xdf6710, +0x1b7880, +0xea7720, +0x0fc900, +0xf51a98, +0x071778, +0xfba8d8, +0x027b84, +0xac06cb, +0x283a63, +0xef271b, +0x05b193, +0xfeceb3, +0xffdfeb, +0x5561e0, +0x6d93e5, +0xcbaf78, +0xf99118, +0x17aaa0, +0xe5c408, +0x17b2e0, +0xec89f0, +0x0ecde0, +0xf56fc8, +0x071978, +0xfb81d8, +0x02aad0, +0xa1a46b, +0x2ff333, +0xea151b, +0x08a803, +0xfd4a6b, +0x000003, +0x000020, +0x3fffe0, +0x000020, +0x3fffe0, +0x01b16b, +0xf855f3, +0x14740b, +0xd40cc3, +0x539323, +0xfdafb8, +0x03fef8, +0xf8cbc0, +0x107398, +0x7f26c5, +0xf19bc0, +0x06a660, +0xfc4508, +0x0228bc, +0xb2821b, +0x284343, +0xeda3d3, +0x069cf3, +0x03c6eb, +0xefdbfb, +0x2a4a93, +0xa5ff43, +0x02a8ac, +0xfb4da0, +0x081d20, +0xf146b8, +0x22b568, +0x7ca649, +0xe57730, +0x0c8b38, +0xf8ede8, +0x041728, +0xfdb6d0, +0x4b880b, +0xddec9b, +0x0c0373, +0x06309b, +0xe6e21b, +0x40ab93, +0xfdde98, +0x040178, +0xf8f1a0, +0x0c31f8, +0xe9b5b8, +0x367598, +0x788dfd, +0xdbb070, +0x1185c8, +0xf61488, +0x05bc08, +0xfcce9c, +0x68d11b, +0xd13c0b, +0x101e33, +0x08d62b, +0xddc993, +0x56a233, +0xfd2bf0, +0x054a20, +0xf6b500, +0x1012a8, +0xe26390, +0x4b56d0, +0x72f70d, +0xd45408, +0x157878, +0xf3cc50, +0x070c10, +0xfc1754, +0x7f746f, +0xc7c91b, +0x12ea3b, +0x0b96fb, +0xd501e3, +0x6b2573, +0xfc8844, +0x067398, +0xf4b188, +0x139340, +0xdb9f08, +0x60f058, +0x6c0395, +0xcf5d50, +0x185148, +0xf221f8, +0x07fff0, +0xfb9490, +0x023c70, +0xc1a1c3, +0x147503, +0x0e4b13, +0xcd04b3, +0x7d228f, +0xfbfbf8, +0x076f18, +0xf30060, +0x1688a8, +0xd5b880, +0x76d0d4, +0x63ddc5, +0xccb738, +0x1a0988, +0xf11b68, +0x089470, +0xfb4790, +0x025f04, +0xbeae3b, +0x14d9d3, +0x10c49b, +0xc650c3, +0x022e24, +0xfb8f00, +0x082ea8, +0xf1b920, +0x18ca30, +0xd0ff50, +0x4640a1, +0x5ab67d, +0xcc3da8, +0x1aa578, +0xf0b7e8, +0x08ca48, +0xfb2f48, +0x0266a0, +0xbeb5b3, +0x143ecb, +0x12d1ab, +0xc1642b, +0x02555c, +0xfb48b0, +0x08a5d0, +0xf0f0a0, +0x1a3350, +0xcdbf38, +0x50c415, +0x50c415, +0xcdbf38, +0x1a3350, +0xf0f0a0, +0x08a5d0, +0xfb48b0, +0x02555c, +0xc1642b, +0x12d1ab, +0x143ecb, +0xbeb5b3, +0x0266a0, +0xfb2f48, +0x08ca48, +0xf0b7e8, +0x1aa578, +0xcc3da8, +0x5ab67d, +0x4640a1, +0xd0ff50, +0x18ca30, +0xf1b920, +0x082ea8, +0xfb8f00, +0x022e24, +0xc650c3, +0x10c49b, +0x14d9d3, +0xbeae3b, +0x025f04, +0xfb4790, +0x089470, +0xf11b68, +0x1a0988, +0xccb738, +0x63ddc5, +0x76d0d4, +0xd5b880, +0x1688a8, +0xf30060, +0x076f18, +0xfbfbf8, +0x7d228f, +0xcd04b3, +0x0e4b13, +0x147503, +0xc1a1c3, +0x023c70, +0xfb9490, +0x07fff0, +0xf221f8, +0x185148, +0xcf5d50, +0x6c0395, +0x60f058, +0xdb9f08, +0x139340, +0xf4b188, +0x067398, +0xfc8844, +0x6b2573, +0xd501e3, +0x0b96fb, +0x12ea3b, +0xc7c91b, +0x7f746f, +0xfc1754, +0x070c10, +0xf3cc50, +0x157878, +0xd45408, +0x72f70d, +0x4b56d0, +0xe26390, +0x1012a8, +0xf6b500, +0x054a20, +0xfd2bf0, +0x56a233, +0xddc993, +0x08d62b, +0x101e33, +0xd13c0b, +0x68d11b, +0xfcce9c, +0x05bc08, +0xf61488, +0x1185c8, +0xdbb070, +0x788dfd, +0x367598, +0xe9b5b8, +0x0c31f8, +0xf8f1a0, +0x040178, +0xfdde98, +0x40ab93, +0xe6e21b, +0x06309b, +0x0c0373, +0xddec9b, +0x4b880b, +0xfdb6d0, +0x041728, +0xf8ede8, +0x0c8b38, +0xe57730, +0x7ca649, +0x22b568, +0xf146b8, +0x081d20, +0xfb4da0, +0x02a8ac, +0xa5ff43, +0x2a4a93, +0xefdbfb, +0x03c6eb, +0x069cf3, +0xeda3d3, +0x284343, +0xb2821b, +0x0228bc, +0xfc4508, +0x06a660, +0xf19bc0, +0x7f26c5, +0x107398, +0xf8cbc0, +0x03fef8, +0xfdafb8, +0x539323, +0xd40cc3, +0x14740b, +0xf855f3, +0x01b16b, +0x000003, +0x000003, +0x000003, +0x000003, +0x000003, +0x000003, +0x000003, +0x000003, +0x040002, +0x000003, +0x000003, +0x000003, +0x000003, +0x000003, +0x000003, +0x000003, +0x000003, +0x000003, +0x000020, +0x3fffe0, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x040002, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x040002, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x040002, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0xb29ef9, +0x06d0f0, +0x06f82a, +0x000003, +0xf907da, +0xf92f10, +0x4d6109, +0x5b69b8, +0x28bfdc, +0xfa6c52, +0x8de6c0, +0x074aaa, +0x7a7c54, +0x078e34, +0xe705e8, +0x2cd4fc, +0xcb8068, +0x2cd4fc, +0xe705e8, +0x078e34, +0xbcc9d9, +0x0d38aa, +0xdc89f2, +0x33e6a2, +0xd43b62, +0x143386, +0x4fad57, +0xfbc240, +0x07ba10, +0xf6e0d0, +0x07ba10, +0xfbc240, +0x4fad57, +0xb8ab0d, +0x0de5ae, +0xdb14ea, +0x358402, +0xd34f7e, +0x146b32, +0x882bbd, +0x0b38ba, +0xf4c74a, +0x77d445, +0x70255d, +0xf5085a, +0x0b75e6, +0x0b2ce8, +0xfc17ec, +0x14ffa0, +0x9543af, +0x14ffa0, +0xfc17ec, +0x0b2ce8, +0xb7e094, +0x0693b6, +0xee7e42, +0x1b0bae, +0xe6318e, +0x0e8672, +0x035ac0, +0xdae2df, +0x063e74, +0x1acf33, +0x063e74, +0xdae2df, +0x035ac0, +0xb1a5e4, +0x06f542, +0xedda66, +0x1b9aa6, +0xe5f54a, +0x0e8d72, +0x666669, +0x999999, +0x000003, +0x08c704, +0x000003, +0xf4b6f8, +0x000003, +0x0fcca4, +0x000003, +0xe5aaf0, +0x000003, +0x4eff30, +0x7c1680, +0x4eff30, +0x000003, +0xe5aaf0, +0x000003, +0x0fcca4, +0x000003, +0xf4b6f8, +0x000003, +0x08c704, +0x000003, +0x028e88, +0xb46d8b, +0x051de8, +0x183def, +0x04d91c, +0x183def, +0x051de8, +0xb46d8b, +0x028e88, +0xfd245c, +0x22e2b4, +0x9f3a1d, +0x09cf9e, +0xeb653a, +0x1cb806, +0xe5ac1e, +0x0ea2c6, +0x000003, +0x08c704, +0x000003, +0xf4b6f8, +0x000003, +0x0fcca4, +0x000003, +0xe5aaf0, +0x000003, +0x4eff30, +0x7c1680, +0x4eff30, +0x000003, +0xe5aaf0, +0x000003, +0x0fcca4, +0x000003, +0xf4b6f8, +0x000003, +0x08c704, +0x000003, +0x028e88, +0xb46d8b, +0x051de8, +0x183def, +0x04d91c, +0x183def, +0x051de8, +0xb46d8b, +0x028e88, +0xfd245c, +0x22e2b4, +0x9f3a1d, +0x09cf9e, +0xeb653a, +0x1cb806, +0xe5ac1e, +0x0ea2c6, +0x000003, +0x000003, +0x02c197, +0x05832b, +0x02c197, +0x000003, +0x000003, +0x84a705, +0x07da1a, +0x000003, +0x0430ab, +0x7ff7a1, +0x000003, +0x0430ab, +0x7ff7a1, +0x000003, +0x000003, +0x02c197, +0x05832b, +0x02c197, +0x000003, +0x000003, +0x84a705, +0x07da1a, +0x000003, +0x000003, +0x02c197, +0x05832b, +0x02c197, +0x000003, +0x000003, +0x84a705, +0x07da1a, +0x000003, +0x0430ab, +0x7ff7a1, +0x000003, +0x0430ab, +0x7ff7a1, +0x000003, +0x0430ab, +0x7ff7a1, +0x000003, +0x0430ab, +0x7ff7a1, +0x000020, +0x3fffe0, +0x000000, +0x000000, +0x000000, +0x000000, +0x040002, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x040002, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x040002, +0x000000, +0x000000, +0x000000, +0x000000, +0x269ec3, +0x0d0ff4, +0x051eba, +0x640001, +0x02f290, +0xfdd340, +0x02a810, +0x02a810, +0xfdd340, +0x02f290, +0x45a895, +0xf4a186, +0x18a312, +0xe445b2, +0x10419e, +0x090500, +0x16c7b0, +0x2cad48, +0x3a8790, +0x3a8790, +0x2cad48, +0x16c7b0, +0x090500, +0x1d3910, +0xafcb81, +0x07030e, +0xf2f61a, +0x10728a, +0xf06caa, +0x09186a, +0x048280, +0x0b63d8, +0x1656a8, +0x1d43c8, +0x1d43c8, +0x1656a8, +0x0b63d8, +0x048280, +0x1d3910, +0xafcb81, +0x07030e, +0xf2f61a, +0x10728a, +0xf06caa, +0x09186a, diff --git a/sound/soc/codecs/abe/C_ABE_FW.PM b/sound/soc/codecs/abe/C_ABE_FW.PM new file mode 100644 index 000000000000..45a86849da91 --- /dev/null +++ b/sound/soc/codecs/abe/C_ABE_FW.PM @@ -0,0 +1,2048 @@ +0x1600200f, +0x0a0011d0, +0x08200000, +0x08200000, +0x07800000, +0x160269ce, +0x014000e0, +0x014000e1, +0x014000e2, +0x014000e3, +0x014000e4, +0x014000e5, +0x014000e6, +0x014000e7, +0x014000e8, +0x014000e9, +0x014000ea, +0x014000eb, +0x014000ec, +0x014000ed, +0x014000ef, +0x014000ef, +0x144000e4, +0x9e000000, +0x0a2037a0, +0x9e000040, +0x0a2037a0, +0x9e000080, +0x0a2037a0, +0x9e0000c0, +0x0a2037a0, +0x9e080000, +0x0a2037a0, +0x9e080100, +0x0a2037a0, +0x9e080200, +0x0a2037a0, +0x9e080300, +0x0a2037a0, +0x9e080400, +0x0a2037a0, +0x9e080500, +0x0a2037a0, +0x9e080600, +0x0a2037a0, +0x9e080700, +0x0a2037a0, +0x9c050800, +0x0a2037a0, +0x16000010, +0x16000001, +0x17000102, +0x01400042, +0x17800103, +0x01400043, +0x98020000, +0x048004ff, +0x413ffcfe, +0x1600274d, +0x1601df4c, +0x0a200fe0, +0x1600274d, +0x16020b4c, +0x0a200fe0, +0x1600274d, +0x1601de4c, +0x0a200fe0, +0x403ffcfe, +0x048ffcff, +0x08200000, +0x048004ff, +0x413ffcfe, +0x1600274d, +0x1601e14c, +0x0a200fe0, +0x1600274d, +0x1601f34c, +0x0a200fe0, +0x1600274d, +0x1601e04c, +0x0a200fe0, +0x403ffcfe, +0x048ffcff, +0x08200000, +0x048004ff, +0x413ffcfe, +0x1600274d, +0x1601e34c, +0x0a200fe0, +0x1600274d, +0x1601f44c, +0x0a200fe0, +0x1600274d, +0x1601e24c, +0x0a200fe0, +0x403ffcfe, +0x048ffcff, +0x08200000, +0x048004ff, +0x413ffcfe, +0x1600274d, +0x1601fa4c, +0x0a200fe0, +0x1600274d, +0x16022c4c, +0x0a200fe0, +0x1600274d, +0x1601fb4c, +0x0a200fe0, +0x403ffcfe, +0x048ffcff, +0x08200000, +0x048004ff, +0x413ffcfe, +0x1600274d, +0x1601fc4c, +0x0a200fe0, +0x1600274d, +0x16022d4c, +0x0a200fe0, +0x1600274d, +0x1601fd4c, +0x0a200fe0, +0x403ffcfe, +0x048ffcff, +0x08200000, +0x048004ff, +0x413ffcfe, +0x1600274d, +0x1601fe4c, +0x0a200fe0, +0x1600274d, +0x1601ec4c, +0x0a200fe0, +0x1600274d, +0x1601ff4c, +0x0a200fe0, +0x403ffcfe, +0x048ffcff, +0x08200000, +0x048004ff, +0x413ffcfe, +0x1600274d, +0x1602004c, +0x0a200fe0, +0x1600274d, +0x1601ed4c, +0x0a200fe0, +0x1600274d, +0x1602014c, +0x0a200fe0, +0x403ffcfe, +0x048ffcff, +0x08200000, +0x048004ff, +0x413ffcfe, +0x1600274d, +0x1602024c, +0x0a200fe0, +0x1600274d, +0x16022e4c, +0x0a200fe0, +0x1600274d, +0x1602034c, +0x0a200fe0, +0x403ffcfe, +0x048ffcff, +0x08200000, +0x048004ff, +0x413ffcfe, +0x1600274d, +0x1602044c, +0x0a200fe0, +0x1600274d, +0x16022f4c, +0x0a200fe0, +0x1600274d, +0x1602054c, +0x0a200fe0, +0x403ffcfe, +0x048ffcff, +0x08200000, +0x048004ff, +0x413ffcfe, +0x1600274d, +0x1602064c, +0x0a200fe0, +0x1600274d, +0x1601ee4c, +0x0a200fe0, +0x1600274d, +0x1602074c, +0x0a200fe0, +0x403ffcfe, +0x048ffcff, +0x08200000, +0x048004ff, +0x413ffcfe, +0x1600274d, +0x1602084c, +0x0a200fe0, +0x1600274d, +0x1601ef4c, +0x0a200fe0, +0x1600274d, +0x1602094c, +0x0a200fe0, +0x403ffcfe, +0x048ffcff, +0x08200000, +0x048004ff, +0x413ffcfe, +0x1600274d, +0x16020c4c, +0x0a200fe0, +0x1600274d, +0x1601f04c, +0x0a200fe0, +0x1600274d, +0x16020d4c, +0x0a200fe0, +0x403ffcfe, +0x048ffcff, +0x08200000, +0x048004ff, +0x413ffcfe, +0x1600274d, +0x16020e4c, +0x0a200fe0, +0x1600274d, +0x1601f14c, +0x0a200fe0, +0x1600274d, +0x16020f4c, +0x0a200fe0, +0x403ffcfe, +0x048ffcff, +0x08200000, +0x9d0c8118, +0x07800000, +0x9f16001a, +0x9f12021a, +0x9f12031a, +0x9f12051a, +0x98800ee0, +0x9d0c8118, +0x08200000, +0x9d0c8118, +0x07800000, +0x9f15001a, +0x9f11041a, +0x98800f70, +0x9d0c8118, +0x08200000, +0x400002c0, +0x048002ff, +0x000000c5, +0x000004c6, +0x9c028000, +0x400006c7, +0x12000155, +0x013ffefe, +0xc00008c4, +0x1e080000, +0x020005de, +0x00000ac3, +0xdc02b160, +0x04c3ff2d, +0xdc01ba70, +0x128002dd, +0xdc02a440, +0x048fffdd, +0x9c061830, +0x0b200000, +0x003ffefe, +0x000002c4, +0x400004c5, +0x048ffeff, +0x000006c6, +0x000008c7, +0x9d02a040, +0x9d02a950, +0x9d01b260, +0x9d02bc70, +0x08200000, +0x16025f48, +0x00000089, +0x16025eea, +0x400000ac, +0x16025e86, +0x40000066, +0x0600000c, +0x0400069b, +0x4a801280, +0x1600274d, +0x0a200fe0, +0x4000009c, +0x16025ece, +0x410000ec, +0x0600000c, +0x1600274d, +0x0a8013f0, +0x16028003, +0x00000030, +0x00000231, +0x00000435, +0x04800211, +0x04400511, +0x16025fe4, +0x0000004e, +0x0300010e, +0x04800211, +0x04400511, +0x0300010c, +0x04800211, +0x04400511, +0x03000109, +0x01000231, +0x0a200fe0, +0x04800299, +0x41000089, +0x05c00b90, +0x4ac01280, +0x16025ea5, +0x40000055, +0x16025f84, +0x40000047, +0x16025fee, +0x04000599, +0x400000e1, +0x04800177, +0x01000089, +0x41000047, +0x04a00111, +0x410000e1, +0x06000001, +0x4aa01570, +0x16025fcd, +0x400000d6, +0x1601c549, +0x41000089, +0x04800166, +0x010000d6, +0x1600c005, +0x16026941, +0x16000002, +0x40000011, +0x16026900, +0x9e0e0550, +0xdd140530, +0x160ffff4, +0x41000002, +0x06000001, +0x08400000, +0x01000004, +0x9d140550, +0x0a801200, +0x0a001570, +0x9d0c8118, +0x9c080018, +0x9f03fc10, +0x07800000, +0x98801660, +0x9d0c8118, +0x08200000, +0x9d0c8118, +0x9c180028, +0x9c180068, +0x9f03fc10, +0x07800000, +0x988016d0, +0x9d0c8118, +0x08200000, +0x9d0c8108, +0x9c180028, +0x9f03fc10, +0x07800000, +0x98801750, +0x9d0c8108, +0x08200000, +0x9d188108, +0x9c0c0038, +0x9f020410, +0x07800000, +0x988017c0, +0x9d188108, +0x08200000, +0xdc0c0018, +0x04a001dd, +0x9f040010, +0x9c0c00b8, +0x9f0400b0, +0x9d188108, +0x9f065810, +0x98801860, +0x07800000, +0x07800000, +0x9d188108, +0x08200000, +0x9d188108, +0x9d188148, +0x9c0c0018, +0x9f020410, +0x07800000, +0x988018f0, +0x9d188108, +0x9d188148, +0x08200000, +0x16000474, +0x16000485, +0x16000496, +0x1600005d, +0x9c032340, +0x9c032c50, +0x9c033560, +0x9c180028, +0x9c180068, +0x9c1800a8, +0x9c1800e8, +0x07800000, +0x07800000, +0x9d0c8318, +0x9d0c84b8, +0x9c180028, +0x9c180068, +0x9c1800a8, +0x9c1800e8, +0x07800000, +0x07800000, +0x9d0c8518, +0x9d0c83b8, +0x9c180028, +0x9c180068, +0x9c1800a8, +0x9c1800e8, +0x07800000, +0x07800000, +0x9d0c8418, +0x9d0c85b8, +0x988019f0, +0x9d032340, +0x9d032c50, +0x9d033560, +0x08200000, +0x160004f4, +0x16000505, +0x16000516, +0x9c032340, +0x9c032c50, +0x9c033560, +0x1600005d, +0x9c0c0318, +0x9c0c04b8, +0x9f020410, +0x9f0204b0, +0x07800000, +0x9d188108, +0x9d188148, +0x9d188188, +0x9d1881c8, +0x9c0c03b8, +0x9c0c0518, +0x9f0204b0, +0x07800000, +0x9d188108, +0x9d188148, +0x9d188188, +0x9d1881c8, +0x9c0c0418, +0x9f020410, +0x9c0c05b8, +0x07800000, +0x9d188108, +0x9d188148, +0x9d188188, +0x9d1881c8, +0x98801c30, +0x9d032340, +0x9d032c50, +0x9d033560, +0x08200000, +0x1600000d, +0x9e0f00d0, +0x00800e0d, +0x07800000, +0x9c0c0038, +0x9f020430, +0x04a002dd, +0x07800000, +0x9d188108, +0x9c0c0038, +0x9f020430, +0x98801e90, +0x9d188108, +0x08200000, +0x08200000, +0x08200000, +0x08200000, +0x08200000, +0x9c0c00c0, +0x9c030f10, +0x9c009020, +0x9c0c0468, +0x9d0c8530, +0x1600007d, +0x9f130462, +0x9f13056a, +0x9c0c0428, +0x9f130422, +0x9d0c8570, +0x16000004, +0x9f1780ea, +0x9f13052a, +0x9c0c0468, +0x9f130462, +0x9d0c8530, +0x16000005, +0x9f1380ea, +0x9f13056a, +0x9c0c0428, +0x9f130422, +0x9d0c8570, +0x07800000, +0x9f1380ea, +0x9f13052a, +0x9c0c0468, +0x9f130462, +0x9d0c8530, +0x98802050, +0x9f1380ea, +0x9f13056a, +0x9c0c0428, +0x9f13042a, +0x9d0c8570, +0x16000006, +0x9f1380ea, +0x9f13052a, +0x16000007, +0x07800000, +0x9d0c8538, +0x9e048000, +0x9f1380ea, +0x9f1380ea, +0x9c031830, +0x07800000, +0x9d0c83c8, +0x07800000, +0x07800000, +0xa007026a, +0x9f0628b0, +0x07800000, +0x9d0c8248, +0x9d0c8190, +0x08200000, +0x9c180004, +0x9c180080, +0x16000004, +0x07800000, +0x9c043e60, +0x9c043f60, +0x9c0c02b0, +0x9c180628, +0xdc180668, +0x1f040030, +0x9f040070, +0x9e0f0040, +0x9d0c8138, +0x9d188708, +0x9d188748, +0x08200000, +0x1440000d, +0x40000004, +0x16000011, +0x40000205, +0x16000002, +0x40000406, +0x16000003, +0x400006d7, +0x16000000, +0x9c0c00b0, +0x9f03a0b0, +0x9e048000, +0xdc1803e0, +0x1f040020, +0x9e040040, +0x9f0400d0, +0x9c0c0090, +0x9e008000, +0x9d1883c0, +0x9c0c0240, +0xc10000d4, +0x1f040090, +0x010002d5, +0x010004d6, +0x010006d7, +0x9d0c8120, +0x08200000, +0x9c028c10, +0x1440000d, +0x00000004, +0x9c0c04b8, +0x9d06a40a, +0x9d06a40a, +0x9d06a40a, +0x9d06a40a, +0x9d06a40a, +0x40000205, +0x16000002, +0x40000406, +0x16000003, +0x400006d7, +0x16000000, +0x9d028c10, +0x16000011, +0x9f03a0b0, +0x9e048000, +0xdc1803e0, +0x1f040020, +0x9e040040, +0x9f0400d0, +0x9c0c0090, +0x9e008000, +0x9d1883c0, +0x9c0c0240, +0xc10000d4, +0x1f040090, +0x010002d5, +0x010004d6, +0x010006d7, +0x9d0c8120, +0x08200000, +0x9c038600, +0x07800000, +0x07800000, +0x9c180770, +0xdc100348, +0x160fff05, +0x9f000810, +0x9f118412, +0x9f001010, +0x9f002810, +0x9c0c00b8, +0x160ffd80, +0x9d0c8410, +0x9f1d8012, +0x9f001810, +0x9f0400d0, +0x9c0c0210, +0x16000204, +0xdd0e00b0, +0x16000005, +0x9f1d80b2, +0x9f0000b0, +0x9f0020b0, +0x9f0400d0, +0x05800560, +0x0a802930, +0x9c0c0510, +0x0a002940, +0x9c0c0618, +0x16000014, +0x9d0c81e8, +0x9d0c8148, +0x0a8029b0, +0x9c0c05b0, +0x9c0c0510, +0x0a0029d0, +0x9c0c06b8, +0x9c0c0618, +0x07800000, +0x9d0c81e8, +0x9d0c8148, +0x988027b0, +0x9d180750, +0x08200000, +0x9d019220, +0x048002ff, +0x14400004, +0x413ffefe, +0x16000040, +0x9c010910, +0x0a203de0, +0x14400040, +0x9c030810, +0x16000171, +0x9c009f30, +0x9c019220, +0x0a2038e0, +0x9c009830, +0x003ffefe, +0x048ffeff, +0x08200000, +0x40000024, +0x048002ff, +0x41000224, +0x16000005, +0x413ffefe, +0x04000400, +0x9e0f0150, +0x01000025, +0x0a202ce0, +0x403ffefe, +0x16000007, +0x9e0f0170, +0x048ffeff, +0x08200000, +0x048002ff, +0x413ffefe, +0x16000005, +0x01000025, +0x0a202ce0, +0x40000024, +0x16000005, +0x403ffefe, +0x04200454, +0x41000224, +0x048ffeff, +0x08200000, +0x048008ff, +0x413ff8f8, +0x1440000d, +0x9c038e10, +0x413ffaf9, +0x04a001dd, +0x413ffcfa, +0x16000001, +0x413ffefb, +0x160000f0, +0x9c100400, +0x9c100480, +0x9c1d06c8, +0x9f085030, +0x9c180678, +0x9c180650, +0x058001a0, +0x0aa030b0, +0x04800144, +0x04400044, +0x07800000, +0x05800040, +0x9d180658, +0x0a802ec0, +0x9d040008, +0x9e090000, +0x07800000, +0x07800000, +0x9e0d0500, +0x0a002f90, +0x05800160, +0x0ac02f40, +0x9e090000, +0x07800000, +0x07800000, +0x9e0d0500, +0x9d040508, +0x0a002f90, +0x9d040008, +0x9e090000, +0x07800000, +0x9d040008, +0x9e0d0500, +0x05800160, +0x0ac02ff0, +0x0480014b, +0x044000bb, +0x4a003020, +0x1440004a, +0x0420040a, +0x04a001ab, +0x044000bb, +0x120001aa, +0x42000a38, +0x120001bb, +0x42000b39, +0x12000288, +0x12000299, +0x9e0e8280, +0xca0031c0, +0x1e0e8390, +0xdd040608, +0x05800160, +0x0ac03160, +0x9d040008, +0x9e090000, +0x07800000, +0x05800040, +0x9e0d0500, +0x0aa031c0, +0x9d040508, +0x0a0031c0, +0x9e090000, +0x05800040, +0x9d040008, +0x9e0d0500, +0x0a8031c0, +0x9d040508, +0x9c1d06c8, +0xdc1d0648, +0x1f0400b0, +0x9c100700, +0xdc1d06c8, +0x1f040010, +0x9d108480, +0x9f0940b0, +0x9d108700, +0x00000cc9, +0x06000008, +0x0aa033b0, +0xdc1d0688, +0x14400005, +0x9c1d0608, +0x04a00255, +0xdd108480, +0x16000017, +0xdd108700, +0x160ffff8, +0x05800540, +0x0aa03370, +0x05800160, +0x0ac03360, +0x01000027, +0x0a003370, +0x01000028, +0x9e088000, +0xa0054dba, +0xa005c81a, +0x0a003450, +0xdd040608, +0x1e088000, +0xa0054dba, +0xa005c81a, +0x9f1f80b0, +0x9f1e0010, +0x9f040020, +0x9f040070, +0x9f020810, +0x9d040608, +0x9e0f0070, +0x9d0c8118, +0x98802d80, +0x003ffefb, +0x003ffcfa, +0x003ffaf9, +0x003ff8f8, +0x048ff8ff, +0x08200000, +0x9c0c0018, +0x9f0b0010, +0x04a001dd, +0x07800000, +0x9d0c8318, +0x07800000, +0xa00602ba, +0x9c0c0018, +0x9f0b0010, +0x9d0c82b8, +0x07800000, +0x9d0c8318, +0x98803540, +0x07800000, +0xa00602ba, +0x9c0c0118, +0x16000015, +0x9d0c81b8, +0x9d0c82b8, +0x9f092010, +0x9f0920b0, +0x9c1d05c0, +0x9f0930c0, +0x9c1d0548, +0x9f093860, +0x06000006, +0x0aa036c0, +0x06000017, +0x0aa036c0, +0x01800025, +0x9c0c0118, +0x9c0c01b0, +0x9f082010, +0x9f0820b0, +0x9c1d05c0, +0x9f0830c0, +0x9c1d0548, +0x9f083860, +0x06000006, +0x0aa03790, +0x06000017, +0x0aa03790, +0x01800125, +0x08200000, +0x07800000, +0x01400040, +0x01400041, +0x01400042, +0x01400043, +0x08200000, +0x16000474, +0x16000485, +0x16000496, +0x16000007, +0x9c032040, +0x9c032950, +0x9c033260, +0x9e0f0070, +0x9e0f0170, +0x9e0f0270, +0x9d032040, +0x9d032950, +0x9d033260, +0x08200000, +0x9c0c0018, +0x1440001d, +0x04a001dd, +0x9d0c8318, +0x07800000, +0x9c0c0018, +0xa00602ba, +0x07800000, +0x9d0c8318, +0x9d0c81b8, +0x9d0c02b8, +0x98803930, +0x07800000, +0xa00602ba, +0x07800000, +0x07800000, +0x9d0c81b8, +0x9d0c82b8, +0x08200000, +0x9c0c0018, +0x160000ad, +0x07800000, +0x9d0c8318, +0x07800000, +0x9c0c0018, +0xa00602ba, +0x07800000, +0x9d0c8318, +0x9d0c81b8, +0x9d0c02b8, +0x07800000, +0x9c0c0018, +0xa00602ba, +0x07800000, +0x9d0c8318, +0x9d0c02b8, +0x98803a60, +0x9c0c0018, +0xa00602ba, +0x07800000, +0x9d0c8318, +0x9d0c81b8, +0x9d0c02b8, +0x07800000, +0xa00602ba, +0x07800000, +0x07800000, +0x9d0c02b8, +0x08200000, +0x9c0c0038, +0x1440001d, +0x04a001dd, +0x9d0c8338, +0x07800000, +0xa00602ba, +0xa006821a, +0x9c0c0038, +0x07800000, +0x9d0c8298, +0x9d0c8338, +0x9d0c8198, +0x98803c40, +0x07800000, +0xa00602ba, +0xa006821a, +0x07800000, +0x07800000, +0x9d0c8298, +0x9d0c8198, +0x08200000, +0xdc0c0018, +0x04a00201, +0x04a001dd, +0xdd040008, +0x06000001, +0x04a00111, +0x0aa03d60, +0x9d0c8118, +0x98803d40, +0x08200000, +0x9c0c02b0, +0x9c0c0018, +0x04a00205, +0x07800000, +0x9d0c8118, +0xdd0c81b8, +0x06000005, +0x04a00155, +0x0aa03e30, +0x98803df0, +0x08200000, +0x9f160028, +0x9f168298, +0x04a001dd, +0x07800000, +0x9d0c8128, +0x07800000, +0x9f160028, +0x9f168298, +0x98803ed0, +0x9d0c8128, +0x08200000, +0x9f160020, +0x9f168098, +0x07800000, +0x9d0c8108, +0x9d0c8258, +0x98803f40, +0x08200000, +0x9f160010, +0x9f168068, +0x07800000, +0x07800000, +0x9d0c8128, +0x98803fb0, +0x08200000, +0x9d008810, +0x1280020d, +0x07800000, +0x9c038810, +0x9e0e0620, +0x04a001dd, +0x9f16801a, +0x9f12011a, +0x9f039810, +0x9f026810, +0x9f118610, +0x9f1680ba, +0x9f1201ba, +0x9f0398b0, +0x9f0268b0, +0x9f1186b0, +0x9d0c8718, +0x9d108248, +0x9d108208, +0x9d0c87b8, +0x9d1082c8, +0x9d108288, +0x98804080, +0x08200000, +0x00800003, +0x00800105, +0x144000d7, +0x1440001d, +0x9c039830, +0x9c03aa50, +0x07800000, +0x9c0c0018, +0x9c0c02b8, +0x07800000, +0x07800000, +0x9d0c8128, +0x98804210, +0x1440007d, +0x08200000, +0x010002fe, +0x00801605, +0x16002c23, +0x12000155, +0x0200035e, +0x0b200000, +0x00800405, +0x16002c23, +0x12000155, +0x0200035e, +0x0b200000, +0x00801705, +0x16002c23, +0x12000155, +0x0200035e, +0x0b200000, +0x000002fe, +0x07800000, +0x08200000, +0x16000181, +0x04000101, +0x00000215, +0x00800b03, +0x00000017, +0x9e0e0450, +0x06000003, +0x16000004, +0x0aa04510, +0x01800354, +0x9c01b970, +0x00800715, +0x16002c26, +0x9c180404, +0x9c180480, +0x410004fe, +0x12000155, +0x00800d0d, +0x0200056e, +0x9c051820, +0x0a0045c0, +0x01800054, +0x9c01b870, +0x00800715, +0x16002c26, +0x9c180404, +0x9c180480, +0x410004fe, +0x12000155, +0x00800d0d, +0x0200056e, +0x9c041920, +0x04a001dd, +0x0b200000, +0x0000021d, +0x000004fe, +0x00000806, +0x008007d7, +0x00800f02, +0x40000014, +0x04c07f77, +0x9e0e0560, +0x40800a02, +0x04500273, +0x418007d3, +0x16000003, +0x07800000, +0x07800000, +0x9d140530, +0x08200000, +0x16000181, +0x04000101, +0x00800b03, +0x00000212, +0x00000017, +0x9e0e0420, +0x00000416, +0xdc180404, +0x06000003, +0x9c180480, +0x0aa04a90, +0x9c052b20, +0x9c042820, +0x9c023970, +0x07800000, +0x07800000, +0x9d01b060, +0x16000005, +0x160ffff6, +0x00800e04, +0x00800503, +0x05800420, +0x17c00565, +0x0ae049a0, +0x04000344, +0x05800420, +0x17c00565, +0x0ae04a70, +0x04000344, +0x05800420, +0x17c00565, +0x0ae04a70, +0x04000344, +0x05800420, +0x0ae04a70, +0x16000016, +0x04000344, +0x05800420, +0x0ae04a70, +0x04000344, +0x05800420, +0x17c00565, +0x0ae04a70, +0x14400065, +0x12000134, +0x04000443, +0x00800e04, +0x04000433, +0x07800000, +0x07800000, +0x0b400003, +0x9c100308, +0x16000012, +0x9d019320, +0x07800000, +0x07800000, +0x9c019020, +0x01800c05, +0x0a004d70, +0x9c042b20, +0x9c052920, +0x9c023870, +0x07800000, +0x07800000, +0x9d00b360, +0x16000004, +0x16000005, +0x160ffff6, +0x00800503, +0x05800420, +0x17c00565, +0x0ae04cb0, +0x04000344, +0x05800420, +0x17c00565, +0x0ae04d60, +0x04000344, +0x05800420, +0x17c00565, +0x0ae04d60, +0x04000344, +0x05800420, +0x0ae04d60, +0x16000016, +0x04000344, +0x05800420, +0x17c00565, +0x0ae04d60, +0x04000344, +0x05800420, +0x17c00565, +0x0ae04d60, +0x14400065, +0x12000134, +0x04000443, +0x07800000, +0x07800000, +0x0b400003, +0x9c100308, +0x16000012, +0x9d019320, +0x07800000, +0x07800000, +0x9c019120, +0x01800c05, +0x00800715, +0x16002c26, +0x410004fe, +0x12000155, +0x00000202, +0x00800d04, +0x0200056e, +0x0400042d, +0x04a001dd, +0x0b200000, +0x00000806, +0x000004fe, +0x0000021d, +0x9e0e0560, +0x00800b05, +0x408007d7, +0x06000005, +0x40800f02, +0x04c07f77, +0x4a804f50, +0x04500273, +0x00800a02, +0x9e088100, +0x07800000, +0x418007d3, +0x16000003, +0x12800277, +0x018003d7, +0x9d140530, +0x08200000, +0x00800a02, +0x9e088000, +0x07800000, +0x418007d3, +0x16000003, +0x12800277, +0x018000d7, +0x9d140530, +0x08200000, +0x00001807, +0x00801e02, +0x07800000, +0x9c01b970, +0x12000c23, +0x07800000, +0x9e088100, +0x07800000, +0x07800000, +0x04c3ff66, +0x04500366, +0x07800000, +0x16000003, +0x9e0c8100, +0x16027406, +0x00800064, +0x1600003d, +0x04a00122, +0x9c03a040, +0x04800166, +0x9e0f0130, +0x04800433, +0x06000002, +0x9c0c0038, +0x9c0c0078, +0x9c0c00b8, +0x9d0c810c, +0x9d0c815c, +0x9d0c81ac, +0x98805150, +0x0aa050d0, +0x9e0f0120, +0x08200000, +0x40800605, +0x048004ff, +0x413ffcf8, +0x144000d3, +0x413ffef9, +0x144000e8, +0x16002c2e, +0x12000155, +0x420005ee, +0x04a001dd, +0x0b200000, +0x9e088000, +0x40000e05, +0x1440008e, +0x40800b09, +0x16000007, +0x9e0e8040, +0x9e0f0070, +0x04200355, +0x01000e05, +0x06000005, +0x0aa05510, +0x40000403, +0x12000f98, +0x40800a06, +0x12800f88, +0x06000008, +0x4a805420, +0x1600024d, +0x40001604, +0x04800199, +0x00001405, +0x01000e04, +0x01000c05, +0x0a005470, +0x40001204, +0x04800199, +0x00001005, +0x01000e04, +0x01000c05, +0x41800b09, +0x16000014, +0x05c00d30, +0x9e0e8050, +0x0a805500, +0x12000233, +0x9e0e0530, +0x9d140570, +0x0a005510, +0x01800014, +0x003ffef9, +0x003ffcf8, +0x048ffcff, +0x08200000, +0x0080070d, +0x00800203, +0x40800905, +0x048002ff, +0x413ffefe, +0x040003dd, +0x00000e04, +0x9c03a950, +0x06000004, +0x0a8056c0, +0x058004d0, +0x0ae056b0, +0x042004d2, +0x1440004d, +0x0a2051f0, +0x00000e04, +0x05800420, +0x0ae05680, +0x0a0056c0, +0x1440002d, +0x0a2051f0, +0x0a0056c0, +0x0a2051f0, +0x003ffefe, +0x40800905, +0x048ffeff, +0x9d03a950, +0x08200000, +0x048008ff, +0x9c039e30, +0x413ff8f8, +0x1440002d, +0x013ffaf9, +0x013ffcfa, +0x013ffefb, +0x9c018202, +0x9c028c12, +0x07800000, +0x9e088200, +0x9e090300, +0x07800000, +0x14400042, +0x14400083, +0x9e088400, +0x9e090500, +0x9d180634, +0x07800000, +0x14400085, +0x07800000, +0x07800000, +0x9d180654, +0x98805780, +0x16027fca, +0x16000842, +0x12000222, +0x408000a4, +0x160282cd, +0x408001a5, +0x16000007, +0x9e0e0220, +0x408002a8, +0x16000806, +0x408003a9, +0x12000155, +0x410000a7, +0x04500544, +0x9d140270, +0x408000d5, +0x12000288, +0x410002a7, +0x04500844, +0x408001d8, +0x12000399, +0x408002d6, +0x04500944, +0x410000d7, +0x1602830a, +0x408003d9, +0x12000455, +0x410002d7, +0x04500544, +0x408000a5, +0x12000588, +0x408001a2, +0x04500844, +0x408002a8, +0x12000666, +0x410000a7, +0x04500644, +0x408003a6, +0x12000799, +0x410002a7, +0x04500944, +0x12000855, +0x04500544, +0x1602738a, +0x160273cb, +0x12000922, +0x04500244, +0x12000a88, +0x04500844, +0x400000a8, +0x12000b66, +0x400000b9, +0x04500644, +0x04a00188, +0x04a00199, +0x16000005, +0x16000006, +0x06000008, +0x0aa05c60, +0x16000015, +0x000002a8, +0x06000009, +0x0aa05ca0, +0x16000016, +0x000002b9, +0x16026742, +0x410000a8, +0x12000166, +0x410000b9, +0x04500655, +0x40800021, +0x16025fcd, +0x41800027, +0x06000004, +0x0aa05d90, +0x06000005, +0x0aa05e10, +0x06000001, +0x0aa05ea0, +0x0a005fa0, +0x160000a8, +0x400000d6, +0x12000c88, +0x04500487, +0x07800000, +0x06000005, +0x9d180078, +0x0a805e80, +0x160000c8, +0x400000d6, +0x12000c88, +0x04500587, +0x07800000, +0x07800000, +0x9d180078, +0x06000001, +0x0a805f10, +0x160000d8, +0x400000d6, +0x12000c88, +0x04500187, +0x07800000, +0x07800000, +0x9d180078, +0x16000243, +0x12000233, +0x16000fb9, +0x16000016, +0x9e0e0530, +0x16000007, +0x9d03c890, +0x07800000, +0x9d140570, +0x16026001, +0x16000013, +0x00000014, +0x16025fe2, +0x00800041, +0x16000005, +0x160ffff6, +0x05800510, +0x01800045, +0x17000353, +0x17800363, +0x04800233, +0x01000023, +0x003ffefb, +0x003ffcfa, +0x003ffaf9, +0x003ff8f8, +0x048ff8ff, +0x08200000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x07800000, +0x07800000, +0x07800000, +0x08400000, +0x0a000000, diff --git a/sound/soc/codecs/abe/C_ABE_FW.SM32 b/sound/soc/codecs/abe/C_ABE_FW.SM32 new file mode 100644 index 000000000000..e575c586e3ae --- /dev/null +++ b/sound/soc/codecs/abe/C_ABE_FW.SM32 @@ -0,0 +1,4432 @@ +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00049603, +0x00000000, +0x00049902, +0x00000000, +0x0006C203, +0x00000000, +0x0004E305, +0x00000000, +0x0004E804, +0x00000000, +0x0006BD05, +0x00000000, +0x0001690C, +0x00000000, +0x0004EC28, +0x00000000, +0x00053C28, +0x00000000, +0x00075406, +0x00000000, +0x00026A18, +0x00000000, +0x00012012, +0x00000000, +0x00013212, +0x00011D00, +0x00014224, +0x00011E12, +0x00013012, +0x00120024, +0x00051000, +0x0001420E, +0x0001420E, +0x0001420E, +0x0001420E, +0x0001420E, +0x0001420E, +0x0001420E, +0x0001420E, +0x0001420E, +0x0001420E, +0x0001420E, +0x0001420E, +0x0001420E, +0x0001420E, +0x0001420E, +0x0001420E, +0x0001450C, +0x00015004, +0x0001450C, +0x00015404, +0x00000000, +0x00015802, +0x00000000, +0x00015A02, +0x0001510C, +0x00015C04, +0x0001510C, +0x00016004, +0x00000000, +0x0001750C, +0x00000000, +0x0001810C, +0x00000000, +0x00015D0C, +0x00000000, +0x0001510C, +0x00000000, +0x0001450C, +0x0001510C, +0x00015D0C, +0x00000000, +0x00018D0C, +0x00000000, +0x0001A50C, +0x00000000, +0x0001B10C, +0x00000000, +0x00023D0C, +0x00024909, +0x00024909, +0x00000000, +0x00016609, +0x000B0009, +0x00000000, +0x00000000, +0x0001990C, +0x00000000, +0x0006C50C, +0x00000000, +0x0002820C, +0x00026A18, +0x0002D60C, +0x00026A18, +0x0002E20C, +0x00000000, +0x00028E0C, +0x00026A00, +0x0002EE0C, +0x00026A00, +0x0002FA0C, +0x00000000, +0x00029A0C, +0x00026A18, +0x0003060C, +0x00026A18, +0x0003120C, +0x00026A18, +0x00031E0C, +0x00026A18, +0x00032A0C, +0x00000000, +0x0002A60C, +0x00026A18, +0x0003360C, +0x00026A18, +0x0003420C, +0x00000000, +0x0002B218, +0x00000000, +0x0002CA0C, +0x00026A18, +0x00034E0C, +0x00026A18, +0x00035A0C, +0x00026A18, +0x0003660C, +0x00026A18, +0x0003720C, +0x00026A18, +0x00037E0C, +0x00026A18, +0x00038A0C, +0x00000000, +0x0003967C, +0x00000000, +0x00041218, +0x00000000, +0x00042A18, +0x00000000, +0x00044218, +0x00000000, +0x00045A18, +0x00067801, +0x00000202, +0x00000000, +0x00048A0C, +0x000B0019, +0x00000000, +0x000B0009, +0x00000000, +0x00000006, +0x00000000, +0x00000000, +0x00049B18, +0x00000000, +0x0004B318, +0x00000000, +0x0004CB18, +0x000B274C, +0x00000000, +0x000B274A, +0x00000000, +0x000B2740, +0x00000000, +0x00000000, +0x0004EC28, +0x00018213, +0x00016F13, +0x0004EC28, +0x0002A100, +0x0002A200, +0x0009D508, +0x00580002, +0x001AF800, +0x00000000, +0x00051428, +0x00018213, +0x00016F13, +0x00051428, +0x00029F00, +0x0002A000, +0x0009DD08, +0x005D0002, +0x001AA800, +0x00000000, +0x00051428, +0x00000003, +0x00000000, +0x00580004, +0x001AF800, +0x005D0004, +0x001AA800, +0x00000000, +0x00051428, +0x00000000, +0x00053C28, +0x0002B512, +0x0002A312, +0x00053C28, +0x0003C300, +0x0003C400, +0x0009ED08, +0x0067000C, +0x0019E000, +0x00000000, +0x0005640C, +0x0001A50C, +0x0001450C, +0x00000000, +0x0005700C, +0x00000000, +0x00057C0C, +0x00026A18, +0x0005880C, +0x00026A18, +0x0005940C, +0x0005B919, +0x0005B919, +0x00000000, +0x0003F719, +0x0005A019, +0x0005A019, +0x0003DE19, +0x0003C519, +0x00000000, +0x00041D0D, +0x00000000, +0x0004100D, +0x0005D20D, +0x0005D20D, +0x0005DF0D, +0x0005DF0D, +0x0001000D, +0x00000000, +0x00030007, +0x00000000, +0x000B000D, +0x00000000, +0x0005EC0F, +0x0005EC0F, +0x000B000F, +0x00000000, +0x0005FB0F, +0x0005FB0F, +0x00000000, +0x00043707, +0x00000000, +0x00043E0D, +0x00060A07, +0x00060A07, +0x0006110D, +0x0006110D, +0x00000000, +0x00042A0D, +0x00061E0D, +0x00061E0D, +0x00062B0D, +0x00062B0D, +0x00000000, +0x00063802, +0x00000000, +0x00044B0D, +0x00063A07, +0x00063A07, +0x0006410D, +0x0006410D, +0x00030007, +0x00000000, +0x00000000, +0x00064E04, +0x00067A09, +0x00067A09, +0x0004A609, +0x0004A609, +0x000B0009, +0x00000000, +0x00000000, +0x00068902, +0x00068303, +0x00068303, +0x0009FD02, +0x0004AF03, +0x00000003, +0x0027FC00, +0x00000003, +0x00282C00, +0x00000003, +0x00283000, +0x00000000, +0x00068B02, +0x00068603, +0x00068603, +0x000A0D02, +0x0004B203, +0x00000003, +0x0027FE00, +0x00000000, +0x00069528, +0x00018213, +0x00016F13, +0x00069528, +0x0004D300, +0x0004D400, +0x000A0208, +0x009A0002, +0x001AA800, +0x009A0004, +0x001AA800, +0x0006D109, +0x0006D109, +0x0006DA09, +0x0006DA09, +0x00000000, +0x0004B509, +0x00000000, +0x0004BE09, +0x00000000, +0x00068D02, +0x0006E303, +0x0006E303, +0x000A0F02, +0x0004C703, +0x00000000, +0x00069102, +0x0006E603, +0x0006E603, +0x000A1302, +0x0004CA03, +0x00000000, +0x00068F02, +0x0006E903, +0x0006E903, +0x000A1102, +0x0004CD03, +0x00000003, +0x00282E00, +0x00000000, +0x00069302, +0x0006EC03, +0x0006EC03, +0x000A1502, +0x0004D003, +0x00000003, +0x00283200, +0x00000000, +0x0006EF0C, +0x00026A18, +0x0006FB0C, +0x00026A18, +0x0007070C, +0x00072D07, +0x00072D07, +0x0007340D, +0x0007340D, +0x0007130D, +0x0007130D, +0x0007200D, +0x0007200D, +0x00000000, +0x00069528, +0x00000000, +0x00067801, +0x00000000, +0x00067901, +0x00065211, +0x00065211, +0x00066315, +0x00066315, +0x00045802, +0x00045A15, +0x00067901, +0x00066315, +0x00046F11, +0x00067801, +0x00BB0011, +0x0000BC00, +0x00074109, +0x00074109, +0x00000000, +0x0004D509, +0x00074A09, +0x00074A09, +0x0004E709, +0x0004DE09, +0x0009CB00, +0x00075301, +0x00002730, +0x00000000, +0x00000000, +0x00078C06, +0x00026A00, +0x0007AA18, +0x0007C20B, +0x0007C20B, +0x00000000, +0x0004F40B, +0x00011D00, +0x00079218, +0x0007C20B, +0x0007C20B, +0x0007AA18, +0x00078C06, +0x00C9000B, +0x0000CA00, +0x00000000, +0x00075A06, +0x00026A18, +0x00076118, +0x0004F004, +0x00076000, +0x00011D00, +0x00077900, +0x000A0A00, +0x00077A12, +0x00EA00D1, +0x000026FF, +0x00000000, +0x00075406, +0x00000000, +0x00100020, +0x00742644, +0x00000026, +0x00000000, +0x0004FF0F, +0x0007E50F, +0x0007E50F, +0x00000000, +0x00050E0F, +0x0017000F, +0x00000000, +0x0007F40F, +0x0007F40F, +0x0008030F, +0x0008030F, +0x0008120F, +0x0008120F, +0x0008210F, +0x0008210F, +0x00ED2730, +0x00000000, +0x000019E0, +0x00000000, +0x00001A08, +0x00000000, +0x00001A30, +0x00000000, +0x00001A58, +0x00000000, +0x00001A80, +0x00000000, +0x00001AA8, +0x00000000, +0x00001AD0, +0x00000000, +0x00001AF8, +0x00000000, +0x00001B20, +0x00000000, +0x00001B48, +0x00000000, +0x00001B70, +0x00000000, +0x00001B98, +0x00000000, +0x00001BC0, +0x00000000, +0x00001BE8, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00098110, +0x00000000, +0x00070400, +0x00EE00ED, +0x00000600, +0x00000002, +0x00000000, +0x00000000, +0x00011D00, +0x00000000, +0x0001270C, +0x00000000, +0x00083008, +0x00000000, +0x00083810, +0x00000000, +0x00084818, +0x00000000, +0x00086048, +0x00221111, +0x00333322, +0x00000000, +0x0004720C, +0x00000000, +0x00047E0C, +0x0001E10D, +0x0001E10D, +0x0001EE0D, +0x0001EE0D, +0x0001FB07, +0x0001FB07, +0x0002020D, +0x0002020D, +0x00020F0D, +0x00020F0D, +0x00021C0D, +0x00021C0D, +0x00022907, +0x00022907, +0x0002300D, +0x0002300D, +0x00000000, +0x0001BD0C, +0x00000000, +0x0001C90C, +0x00000000, +0x0001D502, +0x00000000, +0x0001D704, +0x00000000, +0x0001DB02, +0x00000000, +0x0001DD04, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00040000, +0x00040000, +0x00000001, +0x00000010, +0x00000001, +0x00000010, +0x00000001, +0x00000010, +0x00000001, +0x00000010, +0x00000001, +0x00000010, +0x00000001, +0x00000010, +0x00000001, +0x00000010, +0x00000001, +0x00000010, +0x00000001, +0x00000010, +0x00000001, +0x00000010, +0x00000001, +0x00000010, +0x00000001, +0x00000010, +0x00000001, +0x00000010, +0x00000001, +0x00000010, +0x00000001, +0x00000010, +0x00000001, +0x00000010, +0x00000001, +0x00000010, +0x00000000, +0x00000000, +0x00400000, +0x00400000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x0000001B, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000003, +0x00000000, +0x00000003, +0x00000000, +0x00000003, +0x00000000, +0x00000006, +0x00000000, +0x00000006, +0x00000000, +0x00000006, +0x00000000, +0x00000009, +0x00000000, +0x00000009, +0x00000000, +0x00000009, +0x00000000, +0x00000005, +0x00000000, +0x00000005, +0x00000000, +0x00000005, +0x00000000, +0x00000007, +0x00000000, +0x00000007, +0x00000000, +0x00000007, +0x00000000, +0x00000008, +0x00000000, +0x00000008, +0x00000000, +0x00000008, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, diff --git a/sound/soc/codecs/abe/C_ABE_FW.lDM b/sound/soc/codecs/abe/C_ABE_FW.lDM new file mode 100644 index 000000000000..4baff629f6f6 --- /dev/null +++ b/sound/soc/codecs/abe/C_ABE_FW.lDM @@ -0,0 +1,16384 @@ +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000622, +0x03E9038E, +0x03D403F4, +0x00F903DE, +0x03FB00F0, +0x041A01F3, +0x02A30277, +0x02C2034E, +0x040202B4, +0x000203BF, +0x0255023A, +0x022A0555, +0x007E0062, +0x008C0070, +0x00B6009A, +0x00C400A8, +0x00E000D2, +0x05710429, +0x03A10380, +0x00460038, +0x00030054, +0x016E0167, +0x017D0176, +0x01910183, +0x01BC0198, +0x01EF01E1, +0x01F101F0, +0x04FE01F2, +0x046E043C, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00AF000C, +0x008E008D, +0x0090008F, +0x00000000, +0x002E000C, +0x00940093, +0x00960095, +0x00000000, +0x00B0000C, +0x00A200A1, +0x009100A3, +0x00000000, +0x00B0000C, +0x00A800A7, +0x00AA00A9, +0x00000000, +0x00B1000C, +0x00A500A4, +0x009200A6, +0x00000000, +0x00B1000C, +0x00AC00AB, +0x00AE00AD, +0x00000000, +0x0055000D, +0x00560003, +0x00590057, +0x00000013, +0x0055000D, +0x00560006, +0x00610057, +0x00000013, +0x0064000D, +0x00650008, +0x00680066, +0x00000012, +0x005A000E, +0x005B0002, +0x005E005C, +0x00000013, +0x005A000E, +0x005B0005, +0x0062005C, +0x00000013, +0x0097000E, +0x00980004, +0x009B0099, +0x00000013, +0x0097000E, +0x00980007, +0x009C0099, +0x00000013, +0x00010013, +0x00C300B7, +0x00DE0001, +0x00000000, +0x01060003, +0x00010084, +0x004E0001, +0x00000000, +0x01070003, +0x00010089, +0x00600001, +0x00000000, +0x01100003, +0x00010112, +0x004E0001, +0x00000000, +0x01100003, +0x00010113, +0x00600001, +0x00000000, +0x004B0003, +0x00010084, +0x004E0001, +0x00000000, +0x004B0003, +0x00010089, +0x00600001, +0x00000000, +0x00210010, +0x00710021, +0x004C0072, +0x00000000, +0x00B00000, +0x009D00B0, +0x008C009F, +0x00000000, +0x00B10000, +0x009E00B1, +0x008C00A0, +0x00000000, +0x00210010, +0x00C100B0, +0x008C00C2, +0x00000000, +0x0001001F, +0x00010001, +0x00000001, +0x00000000, +0x0001001E, +0x00010001, +0x00000001, +0x00000000, +0x000D000F, +0x000F000E, +0x00110010, +0x00000000, +0x00270000, +0x002A0029, +0x002C002B, +0x00000000, +0x00030000, +0x00750003, +0x00770074, +0x00000000, +0x00230000, +0x00760023, +0x00790073, +0x00000000, +0x00060000, +0x007F0006, +0x0078007D, +0x00000000, +0x00230000, +0x00800023, +0x0079007E, +0x00000000, +0x00280000, +0x00830106, +0x00790081, +0x00000000, +0x00840000, +0x00820002, +0x00770074, +0x00000000, +0x00280000, +0x00870107, +0x00790085, +0x00000000, +0x00890000, +0x00860005, +0x0078007D, +0x00000000, +0x01140000, +0x01080114, +0x00770074, +0x00000000, +0x01110000, +0x01090111, +0x00790073, +0x00000000, +0x01150000, +0x010A0115, +0x0078007D, +0x00000000, +0x01110000, +0x010B0111, +0x0079007E, +0x00000000, +0x002D0000, +0x010D0110, +0x00790081, +0x00000000, +0x01120000, +0x010C0112, +0x00770074, +0x00000000, +0x002D0000, +0x010F0110, +0x00790085, +0x00000000, +0x01130000, +0x010E0113, +0x0078007D, +0x00000000, +0x002D0000, +0x006F002E, +0x004C0070, +0x00000000, +0x002E0000, +0x008A00AF, +0x008C008B, +0x00000000, +0x00260000, +0x00B5004B, +0x00790081, +0x00000000, +0x00840000, +0x00B400B6, +0x00770074, +0x00000000, +0x00260000, +0x00B3004B, +0x00790085, +0x00000000, +0x00890000, +0x00B200B6, +0x0078007D, +0x00000000, +0x002E0000, +0x00BF00AF, +0x008C00C0, +0x00000000, +0x00500000, +0x007C0050, +0x007B00D6, +0x00000000, +0x004F0000, +0x007A004F, +0x007B00D6, +0x00000000, +0x00AF0007, +0x0001002E, +0x00000017, +0x00000000, +0x00B00007, +0x00010021, +0x00000018, +0x00000000, +0x00D40014, +0x00010001, +0x00D50001, +0x00000000, +0x00010020, +0x00010001, +0x00DF0001, +0x00000000, +0x00010020, +0x00010001, +0x00E00001, +0x00000000, +0x00010020, +0x00010001, +0x00E10001, +0x00000000, +0x00010020, +0x00010001, +0x00E20001, +0x00000000, +0x00010020, +0x00010001, +0x00E30001, +0x00000000, +0x00010020, +0x00010001, +0x00E40001, +0x00000000, +0x00010020, +0x00010001, +0x00E50001, +0x00000000, +0x00010020, +0x00010001, +0x00E60001, +0x00000000, +0x00010020, +0x00010001, +0x00E70001, +0x00000000, +0x00010020, +0x00010001, +0x00E80001, +0x00000000, +0x00010020, +0x00010001, +0x00E90001, +0x00000000, +0x00010020, +0x00010001, +0x00EA0001, +0x00000000, +0x00010020, +0x00010001, +0x00EB0001, +0x00000000, +0x00010020, +0x00010001, +0x00EB0001, +0x00000000, +0x00FB0021, +0x00010001, +0x00FD0001, +0x00000000, +0x00200005, +0x001C0026, +0x00000021, +0x00000000, +0x00290005, +0x001D002D, +0x00000020, +0x00000000, +0x00080006, +0x00250020, +0x0000001A, +0x00000000, +0x00080006, +0x00250021, +0x0000001B, +0x00000000, +0x00080006, +0x006A0069, +0x0000001E, +0x00000000, +0x00080006, +0x006A0028, +0x0000001F, +0x00000000, +0x00C60001, +0x00CE0051, +0x00000019, +0x00000000, +0x00030004, +0x000C0023, +0x004E0001, +0x00000000, +0x00060004, +0x000C0023, +0x00600001, +0x00000000, +0x01140004, +0x000C0111, +0x004E0001, +0x00000000, +0x01150004, +0x000C0111, +0x00600001, +0x00000000, +0x00210004, +0x00FF0050, +0x00FE0001, +0x00000000, +0x002D0004, +0x00FF004F, +0x00FE0001, +0x00000000, +0x003A0002, +0x003C003B, +0x00000016, +0x00000000, +0x002F0002, +0x00310030, +0x00000013, +0x00000000, +0x00320002, +0x00340033, +0x00000014, +0x00000000, +0x00350002, +0x00370036, +0x00000015, +0x00000000, +0x00690002, +0x006C006B, +0x00000019, +0x00000000, +0x01110002, +0x00390038, +0x00000019, +0x00000000, +0x00080002, +0x00440043, +0x00000019, +0x00000000, +0x00B00002, +0x00B100B0, +0x00000019, +0x00000000, +0x00D30002, +0x00CD00C5, +0x00000019, +0x00000000, +0x003E0002, +0x0040003F, +0x00000019, +0x00000000, +0x00010009, +0x00010027, +0x00520001, +0x00000000, +0x00010009, +0x00010022, +0x00530001, +0x00000000, +0x00C5000B, +0x00C700C6, +0x00CC00C8, +0x00000000, +0x00CD000A, +0x00CF00CE, +0x00D200D0, +0x00000000, +0x0001001C, +0x00010001, +0x00000001, +0x00000000, +0x0001001A, +0x00010001, +0x00000001, +0x00000000, +0x0001001D, +0x00010001, +0x00000001, +0x00000000, +0x0001001B, +0x00010001, +0x00000001, +0x00000000, +0x00010018, +0x00010001, +0x00000001, +0x00000000, +0x00010016, +0x00010001, +0x00000001, +0x00000000, +0x00010019, +0x00010001, +0x00000001, +0x00000000, +0x00010017, +0x00010001, +0x00000001, +0x00000000, +0x00010022, +0x00010001, +0x00000001, +0x00000000, +0x00010024, +0x00010001, +0x00000001, +0x00000000, +0x00010025, +0x00010001, +0x00000001, +0x00000000, +0x00010026, +0x00010001, +0x00000001, +0x00000000, +0x00460023, +0x00D7003A, +0x00D900D8, +0x00000000, +0x00470023, +0x00DA002F, +0x00D900D8, +0x00000000, +0x00480023, +0x00DB0032, +0x00D900D8, +0x00000000, +0x00490023, +0x00DC0035, +0x00D900D8, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000010, +0x00000000, +0x00000000, +0x00001C54, +0x00000000, +0x00180000, +0x00001C53, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x0000000A, +0x00000000, +0x00000000, +0x00000000, +0x7FFF7FFF, +0x7FFF7FFF, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000004, +0x00000001, +0x00000000, +0x00000000, +0x00000000, +0x003FFFF0, +0x00000000, +0x00400000, +0x00000004, +0x00000001, +0x00000000, +0x00000000, +0x00000000, +0x003FFFF0, +0x00000000, +0x00400000, +0x0182016F, +0x01A80195, +0x01CE01BB, +0x01F401E1, +0x021A0207, +0x0240022D, +0x02660253, +0x028C0279, +0x00000004, +0x00000001, +0x00000000, +0x00000000, +0x00000000, +0x003FFFF0, +0x00000000, +0x00400000, +0x02B502A3, +0x02D902C7, +0x02FD02EB, +0x0321030F, +0x03450333, +0x03690357, +0x038D037B, +0x03B1039F, +0x00008363, +0x00000428, +0x00000000, +0x00004000, +0x00001FFF, +0x00000004, +0x00000001, +0x00000000, +0x00000000, +0x00000000, +0x003FFFF0, +0x00000000, +0x00400000, +0x00000000, +0x00000000, +0x00000000, +0x00008363, +0x00000428, +0x00008363, +0x00000428, +0x00008363, +0x00000428, +0x00008363, +0x00000428, +0x00008363, +0x00000428, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, diff --git a/sound/soc/codecs/abe/C_ABE_FW_SIZE.h b/sound/soc/codecs/abe/C_ABE_FW_SIZE.h new file mode 100644 index 000000000000..3221b53e9068 --- /dev/null +++ b/sound/soc/codecs/abe/C_ABE_FW_SIZE.h @@ -0,0 +1,6 @@ +/* + FW 05.10 MEMORY SIZES +*/ +#define ABE_DMEM_SIZE_OPTIMIZED 16384 +#define ABE_SMEM_SIZE_OPTIMIZED 15360 +#define ABE_CMEM_SIZE_OPTIMIZED 6552
\ No newline at end of file diff --git a/sound/soc/codecs/abe/Makefile b/sound/soc/codecs/abe/Makefile new file mode 100644 index 000000000000..4dd762827518 --- /dev/null +++ b/sound/soc/codecs/abe/Makefile @@ -0,0 +1,10 @@ +snd-soc-abe-hal-objs += abe_api.o \ + abe_dbg.o \ + abe_ext.o \ + abe_ini.o \ + abe_irq.o \ + abe_lib.o \ + abe_seq.o \ + +obj-$(CONFIG_SND_SOC_ABE_TWL6040) += snd-soc-abe-hal.o + diff --git a/sound/soc/codecs/abe/abe_api.c b/sound/soc/codecs/abe/abe_api.c new file mode 100644 index 000000000000..4a9b1e71fa1f --- /dev/null +++ b/sound/soc/codecs/abe/abe_api.c @@ -0,0 +1,2131 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ + +#include "abe_main.h" +#include "abe_typedef.h" + +static abe_uint32 ABE_FW_PM[ABE_PMEM_SIZE / 4] = { +#include "C_ABE_FW.PM" +}; +static abe_uint32 ABE_FW_CM[ABE_CMEM_SIZE / 4] = { +#include "C_ABE_FW.CM" +}; +static abe_uint32 ABE_FW_DM[ABE_DMEM_SIZE / 4] = { +#include "C_ABE_FW.lDM" +}; +static abe_uint32 ABE_FW_SM[ABE_SMEM_SIZE / 4] = { +#include "C_ABE_FW.SM32" +}; + +/** +* @fn abe_reset_hal() +* +* Operations : reset the HAL by reloading the static variables and default AESS registers. +* Called after a PRCM cold-start reset of ABE +* +* @see ABE_API.h +*/ +void abe_reset_hal(void) +{ + abe_dbg_output = TERMINAL_OUTPUT; + abe_irq_dbg_read_ptr = 0; + + /* load firmware */ + abe_load_fw(); + + /* load default port values - gain = 0dB for all */ + abe_reset_all_ports(); + + /* load default sequence list */ + abe_reset_all_sequence(); + + /* build the scheduler tables */ + abe_build_scheduler_table(); + + /* init hardware components */ + abe_hw_configuration(); +} + +/** +* @fn abe_load_fwl() +* +* Operations : +* loads the Audio Engine firmware, generate a single pulse on the Event generator +* to let execution start, read the version number returned from this execution. +* +* @see ABE_API.h +*/ +void abe_load_fw_param(abe_uint32 *PMEM, abe_uint32 PMEM_SIZE, + abe_uint32 *CMEM, abe_uint32 CMEM_SIZE, + abe_uint32 *SMEM, abe_uint32 SMEM_SIZE, + abe_uint32 *DMEM, abe_uint32 DMEM_SIZE) +{ +#if PC_SIMULATION + /* the code is loaded from the Checkers */ +#else + abe_uint32 event_gen, event_gen_saved, i, pmem_instruction; + + /* Save the event Generator status */ + abe_block_copy(COPY_FROM_ABE_TO_HOST, ABE_ATC, + EVENT_GENERATOR_START, &event_gen_saved, 4); + + /* Stop the event Generator */ + event_gen = 0; + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_ATC, + EVENT_GENERATOR_START, &event_gen, 4); + + /* Load PMEM with Idle instructions + * B 7FF + * B 7FF + * ... + * IDLE + * B 000 + */ +#define AE_B_7FE 0x0a007fe0 +#define AE_IDLE 0x08400000 +#define AE_B_000 0x0a000000 + + for (i = (0x000<<2), pmem_instruction = AE_B_7FE; i < (0x7fe<<2); i+=4) + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_PMEM, i, + &pmem_instruction, 4); + + for (i = (0x7fe<<2), pmem_instruction = AE_IDLE; i < (0x7ff<<2); i+=4) + abe_block_copy (COPY_FROM_HOST_TO_ABE, ABE_PMEM, i, + &pmem_instruction, 4); + + for (i = (0x7ff<<2), pmem_instruction = AE_B_000; i < (0x800<<2); i+=4) + abe_block_copy (COPY_FROM_HOST_TO_ABE, ABE_PMEM, i, + &pmem_instruction, 4); + + /* Now we are sure the firmware is stalled */ + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_PMEM, 0, PMEM, PMEM_SIZE); + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_CMEM, 0, CMEM, CMEM_SIZE); + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_SMEM, 0, SMEM, SMEM_SIZE); + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, 0, DMEM, DMEM_SIZE); + + /* Restore the event Generator status */ + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_ATC, EVENT_GENERATOR_START, + &event_gen_saved, 4); +#endif +} + +void abe_load_fw(void) +{ + abe_load_fw_param(ABE_FW_PM, sizeof (ABE_FW_PM), + ABE_FW_CM, sizeof (ABE_FW_CM), ABE_FW_SM, sizeof (ABE_FW_SM), + ABE_FW_DM, sizeof (ABE_FW_DM)); +} + +/* + * S = power (2, 31) * 0.25; + * N = 4; B = 2; F=[1/N 1/N]; gen_and_save('dbg_8k_2.txt', B, F, N, S); + * N = 8; B = 2; F=[1/N 2/N]; gen_and_save('dbg_16k_2.txt', B, F, N, S); + * N = 12; B = 2; F=[1/N 2/N]; gen_and_save('dbg_48k_2.txt', B, F, N, S); + * N = 60; B = 2; F=[4/N 8/N]; gen_and_save('dbg_amic.txt', B, F, N, S); + * N = 10; B = 6; F=[1/N 2/N 3/N 1/N 2/N 3/N]; gen_and_save('dbg_dmic.txt', B, F, N, S); + */ +void abe_load_embeddded_patterns (void) +{ + abe_uint32 i; +#if 0 +/* To avoid warnings */ +#define patterns_dmic_len 60 + const long patterns_dmic[patterns_dmic_len] = { /* 9.6kHZ */ + 315564800, 510594560, 510594560, 315564800, 510594560, 510594560, + 510594560, 315564800, -315565056, 510594560, 315564800, -315565056, + 510594560, -315565056, -315565056, 510594560, -315565056, -315565056, + 315564800, -510594816, 510594560, 315564800, -510594816, 510594560, + 0, -256, 0, 0, -256,0, + -315565056, 510594560, -510594816, -315565056, 510594560, -510594816, + -510594816, 315564800, 315564800, -510594816, 315564800, 315564800, + -510594816, -315565056, 315564800, -510594816, -315565056, 315564800, + -315565056, -510594816,-510594816, -315565056, -510594816, -510594816, + -256, -256, -256, -256, -256, -256, + }; +#endif +#define patterns_mcpdm_len (6*12) + const long patterns_mcpdm[patterns_mcpdm_len] = { + 268435200, 464943616, 536870912, 536870912, 464943616, 268435200, + 464943616, 464943616, 0, 0, 464943616, 464943616, + 536870912, 0, -536870912, -536870912, 0, 536870912, + 464943616, -464943872, -256, -256, -464943872, 464943616, + 268435456, -464943872, 536870912, 536870912, -464943872, 268435456, + 0, -256, 0, 0, -256, 0, + -268435456, 464943616, -536870912, -536870912, 464943616, -268435456, + -464943872, 464943616, -256, -256, 464943616, -464943872, + -536870912, 0, 536870912, 536870912, 0, -536870912, + -464943872, -464943872, 0, 0, -464943872, -464943872, + -268435712, -464943872, -536870912, -536870912, -464943872, -268435712, + -256, -256, -256, -256, -256, -256, + }; +#if 0 +#define patterns_amic_len 120 + const long patterns_amic[patterns_amic_len] = { /* 6 / 12kHz */ + 218364928, 398972672, 398972672, 533929728, 510594560, 315564800, + 533929728, -111621888, 464943616, -464943872, 315564800, -510594816, + 111621632, -218365184, -111621888, 218364928, -315565056, 510594560, + -464943872, 464943616, -533929984, 111621632, -510594816, -315565056, + -398972928, -533929984, -218365184, -398972928, -256, -256, 218364928, + 398972672, 398972672, 533929728, 510594560, 315564800, 533929728, + -111621888, 464943616, -464943872, 315564800, -510594816, 111621632, + -218365184, -111621888, 218364928, -315565056, 510594560, -464943872, + 464943616, -533929984, 111621632, -510594816, -315565056, -398972928, + -533929984, -218365184, -398972928, -256, -256, 218364928, 398972672, + 398972672, 533929728, 510594560, 315564800, 533929728, -111621888, + 464943616, -464943872, 315564800, -510594816, 111621632, -218365184, + -111621888, 218364928, -315565056, 510594560, -464943872, 464943616, + -533929984, 111621632, -510594816, -315565056, -398972928, -533929984, + -218365184, -398972928, -256, -256, 218364928, 398972672, 398972672, + 533929728, 510594560, 315564800, 533929728, -111621888, 464943616, + -464943872, 315564800, -510594816, 111621632, -218365184, -111621888, + 218364928, -315565056, 510594560, -464943872, 464943616, -533929984, + 111621632, -510594816, -315565056, -398972928, -533929984, -218365184, + -398972928, -256, -256, + }; +#endif +#define patterns_48k_len 24 + const long patterns_48k[patterns_48k_len] = { /* 4kHz 8kHZ */ + 268435200, 464943616, 464943616, 464943616, 536870912, 0, + 464943616, -464943872, 268435456, -464943872, 0, -256, + -268435456, 464943616, -464943872, 464943616, -536870912, + 0, -464943872, -464943872, -268435712, -464943872, -256, -256, + }; +#define patterns_16k_len 16 + const long patterns_16k[patterns_16k_len] = { /* 2kHz / 4kHz */ + 379624960, 536870912, 536870912, 0, 379624960, -536870912, 0, -256, + -379625216, 536870912, -536870912, 0, -379625216, -536870912, -256, -256, + }; +#define patterns_8k_len 8 + const long patterns_8k[patterns_8k_len] = { /* 2kHz */ + 536870912, 536870912, 0, 0, -536870912, -536870912, -256, -256, + }; + + for (i = 0; i < patterns_mcpdm_len; i++) + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_SMEM, + S_DBG_MCPDM_PATTERN_ADDR *8, + (abe_uint32 *)(&(patterns_mcpdm[i])), 4); + for (i = 0; i < patterns_16k_len; i++) + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_SMEM, + S_DBG_16K_PATTERN_ADDR *8, + (abe_uint32 *)(&(patterns_16k[i])), 4); + for (i = 0; i < patterns_8k_len; i++) + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_SMEM, + S_DBG_8K_PATTERN_ADDR *8, + (abe_uint32 *)(&(patterns_8k[i])), 4); + for (i = 0; i < patterns_48k_len; i++) + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_SMEM, + S_DBG_48K_PATTERN_ADDR *8, + (abe_uint32 *)(&(patterns_48k[i])), 4); +} + +/* + * ABE_HARDWARE_CONFIGURATION + * + * Parameter : + * U : use-case description list (pointer) + * H : pointer to the output structure + * + * Operations : + * return a structure with the HW thresholds compatible with the HAL/FW/AESS_ATC + * will be upgraded in FW06 + * + * Return value : + * None. + */ +void abe_read_hardware_configuration(abe_use_case_id *u, abe_opp_t *o, abe_hw_config_init_t *hw) +{ + abe_read_use_case_opp(u, o); + + /* @@@ keep OPP 100 for now */ + (*o) = ABE_OPP100; + + hw->MCPDM_CTRL__DIV_SEL = 0; /* 0: 96kHz 1:192kHz */ + hw->MCPDM_CTRL__CMD_INT = 1; /* 0: no command in the FIFO, 1: 6 data on each lines (with commands) */ + hw->MCPDM_CTRL__PDMOUTFORMAT = 0; /* 0:MSB aligned 1:LSB aligned */ + hw->MCPDM_CTRL__PDM_DN5_EN = 1; + hw->MCPDM_CTRL__PDM_DN4_EN = 1; + hw->MCPDM_CTRL__PDM_DN3_EN = 1; + hw->MCPDM_CTRL__PDM_DN2_EN = 1; + hw->MCPDM_CTRL__PDM_DN1_EN = 1; + hw->MCPDM_CTRL__PDM_UP3_EN = 0; + hw->MCPDM_CTRL__PDM_UP2_EN = 1; + hw->MCPDM_CTRL__PDM_UP1_EN = 1; + hw->MCPDM_FIFO_CTRL_DN__DN_TRESH = MCPDM_DL_ITER/6; /* All the McPDM_DL FIFOs are enabled simultaneously */ + hw->MCPDM_FIFO_CTRL_UP__UP_TRESH = MCPDM_UL_ITER/2; /* number of ATC access upon AMIC DMArequests, 2 the FIFOs channels are enabled */ + + hw->DMIC_CTRL__DMIC_CLK_DIV = 0; /* 0:2.4MHz 1:3.84MHz */ + hw->DMIC_CTRL__DMICOUTFORMAT = 0; /* 0:MSB aligned 1:LSB aligned */ + hw->DMIC_CTRL__DMIC_UP3_EN = 1; + hw->DMIC_CTRL__DMIC_UP2_EN = 1; + hw->DMIC_CTRL__DMIC_UP1_EN = 1; + hw->DMIC_FIFO_CTRL__DMIC_TRESH = DMIC_ITER/6; /* 1*(DMIC_UP1_EN+ 2+ 3)*2 OCP read access every 96/88.1 KHz. */ + + hw->MCBSP_SPCR1_REG__RJUST = 1; /* 1:MSB 2:LSB aligned */ + hw->MCBSP_THRSH2_REG_REG__XTHRESHOLD = 1; + hw->MCBSP_THRSH1_REG_REG__RTHRESHOLD = 1; + + hw->AESS_EVENT_GENERATOR_COUNTER__COUNTER_VALUE = EVENT_GENERATOR_COUNTER_DEFAULT; /* 2050 gives about 96kHz */ + hw->AESS_EVENT_SOURCE_SELECTION__SELECTION = 1; /* 0: DMAreq, 1:Counter */ + hw->AESS_AUDIO_ENGINE_SCHEDULER__DMA_REQ_SELECTION = ABE_ATC_MCPDMDL_DMA_REQ; /* 5bits DMAreq selection */ + + hw->HAL_EVENT_SELECTION = EVENT_TIMER; +} + +/* + * ABE_DEFAULT_CONFIGURATION + * + * Parameter : + * use-case-ID : "LP player", "voice-call" use-cases as defined in the paragraph + * "programming use-case sequences" + * Param 1, 2, 3, 4 used for non regression tests + * + * Operations : + * private API used during development. Loads all the necessary parameters and data + * patterns to allow a stand-alone functional test without the need of. + * + * Return value : + * None. + */ +void abe_default_configuration(abe_uint32 use_case) +{ + abe_data_format_t format; + abe_dma_t dma_sink; + abe_uint32 data_sink; + abe_use_case_id UC2[] = {ABE_AUDIO_PLAYER_ON_HEADSET_OR_EARPHONE, ABE_RINGER_TONES, (abe_use_case_id)0}; + abe_use_case_id UC5[] = {ABE_AUDIO_PLAYER_ON_HEADSET_OR_EARPHONE, (abe_use_case_id)0}; + abe_opp_t OPP; + abe_hw_config_init_t CONFIG; + + switch (use_case) { + /* voice ul/dl on earpiece + MM_DL on IHF */ + case UC2_VOICE_CALL_AND_IHF_MMDL: + /* enable one of the preloaded and programmable routing + * configuration for the uplink paths + * Here enable the VX_UL path with Digital microphones: + * abe_enable_router_configuration(UPROUTE, UPROUTE_CONFIG_DMIC1); + * To be added here: + * - Device driver initialization following + * abe_read_hardware_configuration() returned data + * McPDM_DL : 6 slots activated (5 + Commands) + * DMIC : 6 microphones activated + * McPDM_UL : 2 microphones activated (No status) + */ + abe_read_hardware_configuration(UC2, &OPP, &CONFIG); /* check hw config and opp config */ + abe_set_opp_processing(OPP); /* sets the OPP100 on FW05.xx */ + abe_write_event_generator(CONFIG.HAL_EVENT_SELECTION); /* "tick" of the audio engine */ + /* mixers' configuration = voice on earphone + music on hands-free path */ + abe_write_mixer(MIXDL1, GAIN_0dB, RAMP_1MS, MIX_DL1_INPUT_VX_DL); + abe_write_mixer(MIXDL2, GAIN_0dB, RAMP_50MS, MIX_DL2_INPUT_MM_DL); + + abe_enable_data_transfer(MM_UL2_PORT); + abe_enable_data_transfer(MM_UL_PORT); + abe_enable_data_transfer(MM_DL_PORT); /* enable all the data paths */ + abe_enable_data_transfer(VX_DL_PORT); + abe_enable_data_transfer(VX_UL_PORT); + abe_enable_data_transfer(PDM_UL_PORT); + abe_enable_data_transfer(DMIC_PORT); + abe_enable_data_transfer(PDM_DL_PORT); + abe_enable_data_transfer(TONES_DL_PORT); + break; + case UC5_PINGPONG_MMDL: + /* Ping-Pong access through MM_DL using Left/Right + * 16bits/16bits data format + * To be added here: + * - Device driver initialization following abe_read_hardware_configuration() returned data + * McPDM_DL : 6 slots activated (5 + Commands) + * DMIC : 6 microphones activated + * McPDM_UL : 2 microphones activated (No status) + */ + abe_read_hardware_configuration(UC5, &OPP, &CONFIG); /* check hw config and opp config */ + abe_set_opp_processing(OPP); /* sets the OPP100 on FW05.xx */ + abe_write_event_generator(CONFIG.HAL_EVENT_SELECTION); /* "tick" of the audio engine */ + + /* MM_DL init: overwrite the previous default initialization made above */ + format.f = 48000; + format.samp_format = MONO_MSB; + + /* connect a Ping-Pong SDMA protocol to MM_DL port + * with Ping-Pong 576 mono samples + * (12x4 bytes for each ping & pong size) + */ + abe_connect_dmareq_ping_pong_port(MM_DL_PORT, &format, ABE_CBPR0_IDX, (12 * 4), &dma_sink); + + /* mixers' configuration = voice on earphone + music on hands-free path */ + abe_write_mixer(MIXDL1, GAIN_0dB, RAMP_2MS, MIX_DL1_INPUT_MM_DL); + abe_write_mixer(MIXDL2, GAIN_0dB, RAMP_50MS, MIX_DL2_INPUT_MM_DL); + + /* Here: connect the sDMA to "dma_sink" content */ + abe_enable_data_transfer(MM_DL_PORT); /* enable all the data paths */ + abe_enable_data_transfer(PDM_DL1_PORT); + break; + case UC6_PINGPONG_MMDL_WITH_IRQ: + /* Ping-Pong using the IRQ instead of the sDMA */ + abe_read_hardware_configuration(UC5, &OPP, &CONFIG); /* check hw config and opp config */ + abe_set_opp_processing(OPP); /* sets the OPP100 on FW05.xx */ + abe_write_event_generator(CONFIG.HAL_EVENT_SELECTION); /* "tick" of the audio engine */ + + /* MM_DL init: overwrite the previous default initialization made above */ + format.f = 48000; + format.samp_format = STEREO_16_16; + + /* connect a Ping-Pong cache-flush protocol to MM_DL port + * with 50Hz (20ms) rate + */ + abe_add_subroutine(&abe_irq_pingpong_player_id, + (abe_subroutine2) abe_default_irq_pingpong_player, + SUB_0_PARAM, (abe_uint32*)0); + #define N_SAMPLES_BYTES (120 *4) + abe_connect_irq_ping_pong_port(MM_DL_PORT, &format, + abe_irq_pingpong_player_id, N_SAMPLES_BYTES, &data_sink, + PING_PONG_WITH_MCU_IRQ); + + /* mixers' configuration = voice on earphone + music on hands-free path */ + abe_write_mixer(MIXDL1, GAIN_0dB, RAMP_2MS, MIX_DL1_INPUT_MM_DL); + abe_write_mixer(MIXDL2, GAIN_0dB, RAMP_50MS, MIX_DL2_INPUT_MM_DL); + + abe_enable_data_transfer(MM_DL_PORT); /* enable all the data paths */ + abe_enable_data_transfer(PDM_DL1_PORT); + break; + case UC71_STOP_ALL: + abe_disable_data_transfer(MM_UL2_PORT); + abe_disable_data_transfer(MM_DL_PORT); + abe_disable_data_transfer(VX_DL_PORT); + abe_disable_data_transfer(VX_UL_PORT); + abe_disable_data_transfer(PDM_UL_PORT); + abe_disable_data_transfer(DMIC_PORT); + abe_disable_data_transfer(PDM_DL_PORT); + break; + case UC72_ENABLE_ALL: + abe_enable_data_transfer(MM_UL2_PORT); + abe_enable_data_transfer(MM_DL_PORT); + abe_enable_data_transfer(VX_DL_PORT); + abe_enable_data_transfer(VX_UL_PORT); + abe_enable_data_transfer(PDM_UL_PORT); + abe_enable_data_transfer(DMIC_PORT); + abe_enable_data_transfer(PDM_DL_PORT); + break; + default: + break; + } +} + +/* + * ABE_IRQ_PROCESSING + * + * Parameter : + * No parameter + * + * Operations : + * This subroutine will check the IRQ_FIFO from the AE and act accordingly. + * Some IRQ source are originated for the delivery of "end of time sequenced tasks" + * notifications, some are originated from the Ping-Pong protocols, some are generated from + * the embedded debugger when the firmware stops on programmable break-points, etc … + * + * Return value : + * None. + */ +void abe_irq_processing(void) +{ + abe_uint32 clear_abe_irq; + abe_uint32 abe_irq_dbg_write_ptr, i, cmem_src; + abe_irq_data_t IRQ_data; + + /* extract the write pointer index from CMEM memory (INITPTR format) */ + /* CMEM address of the write pointer in bytes */ + cmem_src = MCU_IRQ_FIFO_ptr_labelID * 4; + abe_block_copy(COPY_FROM_ABE_TO_HOST, ABE_CMEM, cmem_src, + (abe_uint32*)&abe_irq_dbg_write_ptr, + sizeof (abe_irq_dbg_write_ptr)); + abe_irq_dbg_write_ptr = ((abe_irq_dbg_write_ptr >> 16) & 0x255); + + /* loop on the IRQ FIFO content */ + for (i = 0; i < D_McuIrqFifo_sizeof; i += 4) { + /* stop when the FIFO is empty */ + if (abe_irq_dbg_write_ptr == abe_irq_dbg_read_ptr) + break; + /* read the IRQ/DBG FIFO */ + abe_block_copy(COPY_FROM_ABE_TO_HOST, ABE_DMEM, + D_McuIrqFifo_ADDR + i, (abe_uint32*)&IRQ_data, + sizeof (IRQ_data)); + abe_irq_dbg_read_ptr += 4; + + /* select the source of the interrupt */ + switch (IRQ_data.tag) { + case IRQtag_APS: + abe_irq_aps(IRQ_data.data); + break; + case IRQtag_PP: + abe_irq_ping_pong(); + break; + case IRQtag_COUNT: + abe_irq_check_for_sequences(IRQ_data.data); + break; + default: + break; + } + } + + abe_monitoring(); + + clear_abe_irq = 1; + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_ATC, ABE_MCU_IRQSTATUS, + &clear_abe_irq, 4); +} + +/* + * ABE_WRITE_EVENT_GENERATOR + * + * Parameter : + * e: Event Generation Counter, McPDM, DMIC or default. + * + * Operations : + * load the AESS event generator hardware source. Loads the firmware parameters + * accordingly. Indicates to the FW which data stream is the most important to preserve + * in case all the streams are asynchronous. If the parameter is "default", let the HAL + * decide which Event source is the best appropriate based on the opened ports. + * + * When neither the DMIC and the McPDM are activated the AE will have its EVENT generator programmed + * with the EVENT_COUNTER. The event counter will be tuned in order to deliver a pulse frequency higher + * than 96 kHz. The DPLL output at 100% OPP is MCLK = (32768kHz x6000) = 196.608kHz + * The ratio is (MCLK/96000)+(1<<1) = 2050 + * (1<<1) in order to have the same speed at 50% and 100% OPP (only 15 MSB bits are used at OPP50%) + * + * Return value : + * None. + */ +void abe_write_event_generator(abe_event_id e) +{ + abe_uint32 event, selection, counter, start; + + counter = EVENT_GENERATOR_COUNTER_DEFAULT; + start = EVENT_GENERATOR_ON; + abe_current_event_id = e; + + switch (e) { + case EVENT_MCPDM: + selection = EVENT_SOURCE_DMA; + event = ABE_ATC_MCPDMDL_DMA_REQ; + break; + case EVENT_DMIC: + selection = EVENT_SOURCE_DMA; + event = ABE_ATC_DMIC_DMA_REQ; + break; + case EVENT_TIMER: + selection = EVENT_SOURCE_COUNTER; + event = 0; + break; + case EVENT_McBSP: + selection = EVENT_SOURCE_COUNTER; + event = 0; + break; + case EVENT_McASP: + selection = EVENT_SOURCE_COUNTER; + event = 0; + break; + case EVENT_SLIMBUS: + selection = EVENT_SOURCE_COUNTER; + event = 0; + break; + case EVENT_44100: + selection = EVENT_SOURCE_COUNTER; + event = 0; + counter = EVENT_GENERATOR_COUNTER_44100; + break; + case EVENT_DEFAULT: + selection = EVENT_SOURCE_COUNTER; + event = 0; + break; + default: + abe_dbg_param |= ERR_API; + abe_dbg_error_log(ABE_BLOCK_COPY_ERR); + } + + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_ATC, EVENT_GENERATOR_COUNTER, &counter, 4); + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_ATC, EVENT_SOURCE_SELECTION, &selection, 4); + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_ATC, EVENT_GENERATOR_START, &start, 4); + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_ATC, AUDIO_ENGINE_SCHEDULER, &event, 4); + + /* flow control on Phoenix path */ + selection = D_IOdescr_ADDR+PDM_DL_PORT*sizeof(ABE_SIODescriptor) + flow_counter_; + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, D_Slot23_ctrl_ADDR, &selection, 4); +} + +/** +* abe_read_use_case_opp() description for void abe_read_use_case_opp(). +* +* Operations : returns the expected min OPP for a given use_case list +* +* Parameter : No parameter +* @param +* +* @pre no pre-condition +* +* @post +* +* @return error code +* +* @see +*/ +void abe_read_use_case_opp(abe_use_case_id *u, abe_opp_t *o) +{ + abe_uint32 opp, i; + abe_use_case_id *ptr = u; + + #define MAX_READ_USE_CASE_OPP 10 /* there is no reason to have more use_cases */ + #define OPP_25 1 + #define OPP_50 2 + #define OPP_100 4 + + opp = i = 0; + do { + /* check for pointer errors */ + if (i > MAX_READ_USE_CASE_OPP) { + abe_dbg_param |= ERR_API; + abe_dbg_error_log(ABE_READ_USE_CASE_OPP_ERR); + break; + } + + /* check for end_of_list */ + if (*ptr <= 0) + break; + + /* check for end_of_list */ + if (*ptr > ABE_LAST_USE_CASE) + break; + + /* OPP selection based on current firmware implementation */ + switch (*ptr) { + case ABE_AUDIO_PLAYER_ON_HEADSET_OR_EARPHONE: + opp |= OPP_25; + break; + case ABE_DRIFT_MANAGEMENT_FOR_AUDIO_PLAYER: + opp |= OPP_100; + break; + case ABE_VOICE_CALL_ON_HEADSET_OR_EARPHONE_OR_BT: + opp |= OPP_50; + break; + case ABE_MULTIMEDIA_AUDIO_RECORDER: + opp |= OPP_50; + break; + case ABE_VIBRATOR_OR_HAPTICS: + opp |= OPP_100; + break; + case ABE_VOICE_CALL_ON_HANDS_FREE_SPEAKER: + opp |= OPP_100; + break; + case ABE_RINGER_TONES: + opp |= OPP_100; + break; + case ABE_VOICE_CALL_WITH_EARPHONE_ACTIVE_NOISE_CANCELLER: + opp |= OPP_100; + break; + default: + break; + } + + i++; + ptr++; + } while (*ptr <= 0 || *ptr > ABE_LAST_USE_CASE); + + if (opp & OPP_100) + *o = ABE_OPP100; + else if (opp & OPP_50) + *o = ABE_OPP50; + else + *o = ABE_OPP25; +} + +/* + * ABE_READ_LOWEST_OPP + * + * Parameter : + * Data pointer : returned data + * + * Operations : + * Returns the lowest possible OPP based on the current active ports + * + * Return value : + * None. + */ +void abe_read_lowest_opp(abe_opp_t *o) +{ + *o = ABE_OPP100; +} + +/* + * ABE_SET_OPP_PROCESSING + * + * Parameter : + * New processing network and OPP: + * 0: Ultra Lowest power consumption audio player (no post-processing, no mixer) + * 1: OPP 25% (simple multimedia features, including low-power player) + * 2: OPP 50% (multimedia and voice calls) + * 3: OPP100% (EANC, multimedia complex use-cases) + * + * Operations : + * Rearranges the FW task network to the corresponding OPP list of features. + * The corresponding AE ports are supposed to be set/reset accordingly before this switch. + * + * Return value : + * error code when the new OPP do not corresponds the list of activated features + */ +void abe_set_opp_processing(abe_opp_t opp) +{ + abe_uint32 dOppMode32; + + switch(opp){ + case ABE_OPP25: + /* OPP25% */ + dOppMode32 = DOPPMODE32_OPP25; + break; + case ABE_OPP50: + /* OPP50% */ + dOppMode32 = DOPPMODE32_OPP50; + break; + default: + abe_dbg_param |= ERR_API; + abe_dbg_error_log(ABE_BLOCK_COPY_ERR); + case ABE_OPP100: + /* OPP100% */ + dOppMode32 = DOPPMODE32_OPP100; + break; + } + + /* Write Multiframe inside DMEM */ + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, + D_maxTaskBytesInSlot_ADDR, &dOppMode32, sizeof(abe_uint32)); +} + +/* + * ABE_SET_PING_PONG_BUFFER + * + * Parameter : + * Port_ID : + * New data + * + * Operations : + * Updates the next ping-pong buffer with "size" samples copied from the + * host processor. This API notifies the FW that the data transfer is done. + * The size is added on top of the previous size. + */ +void abe_set_ping_pong_buffer(abe_port_id port, abe_uint32 n) +{ + abe_uint32 sio_pp_desc_address, struct_offset, *src, dst; + ABE_SPingPongDescriptor desc_pp; + + /* ping_pong is only supported on MM_DL */ + if (port != MM_DL_PORT) { + abe_dbg_param |= ERR_API; + abe_dbg_error_log(ABE_PARAMETER_ERROR); + } + + /* read the port SIO descriptor and extract the current pointer address after reading the counter */ + sio_pp_desc_address = D_PingPongDesc_ADDR; + abe_block_copy(COPY_FROM_ABE_TO_HOST, ABE_DMEM, sio_pp_desc_address, (abe_uint32*)&desc_pp, sizeof(ABE_SPingPongDescriptor)); + + if ((desc_pp.counter & 0x1) == 0) + desc_pp.nextbuff0_Samples = (abe_uint16) (n >> 2); /* FW uses words numbers instead of bytes */ + else + desc_pp.nextbuff1_Samples = (abe_uint16) (n >> 2); + + struct_offset = (abe_uint32)&(desc_pp.nextbuff0_BaseAddr) - (abe_uint32)&(desc_pp); + src = (abe_uint32 *) &(desc_pp.nextbuff0_BaseAddr); + dst = sio_pp_desc_address + struct_offset; + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, dst, src, + sizeof(desc_pp) - struct_offset); +} + +/* + * ABE_READ_NEXT_PING_PONG_BUFFER + * + * Parameter : + * Port_ID : + * Returned address to the next buffer (byte offset from DMEM start) + * + * Operations : + * Tell the next base address of the next ping_pong Buffer and reset its size + * + * + */ +void abe_read_next_ping_pong_buffer(abe_port_id port, abe_uint32 *p, abe_uint32 *n) +{ + abe_uint32 sio_pp_desc_address, datasize; + ABE_SPingPongDescriptor desc_pp; + + /* ping_pong is only supported on MM_DL */ + if (port != MM_DL_PORT) { + abe_dbg_param |= ERR_API; + abe_dbg_error_log(ABE_PARAMETER_ERROR); + } + + /* read the port SIO descriptor and extract the current pointer address after reading the counter */ + sio_pp_desc_address = D_PingPongDesc_ADDR; + abe_block_copy(COPY_FROM_ABE_TO_HOST, ABE_DMEM, sio_pp_desc_address, (abe_uint32*)&desc_pp, sizeof(ABE_SPingPongDescriptor)); + + if ((desc_pp.counter & 0x1) == 0) { + (*p) = desc_pp.nextbuff0_BaseAddr; + (*n) = desc_pp.nextbuff0_Samples; + } else { + (*p) = desc_pp.nextbuff1_BaseAddr; + (*n) = desc_pp.nextbuff1_Samples; + } + + /* translates the number of samples in bytes */ + datasize = abe_dma_port_iter_factor(&((abe_port[port]).format)); + (*n) = (*n) * datasize; + +} + +/* + * ABE_INIT_PING_PONG_BUFFER + * + * Parameter : + * size of the ping pong + * number of buffers (2 = ping/pong) + * returned address of the ping-pong list of base address (byte offset from DMEM start) + * + * Operations : + * Computes the base address of the ping_pong buffers + * + */ +void abe_init_ping_pong_buffer(abe_port_id id, abe_uint32 s, abe_uint32 n, abe_uint32 *p) +{ + abe_uint32 i, dmem_addr; + + abe_size_pingpong = s; + abe_nb_pingpong = n; + + /* ping_pong is supported in 2 buffers configuration right now but FW is ready for ping/pong/pung/pang... */ + if (id != MM_DL_PORT || n > MAX_PINGPONG_BUFFERS) { + abe_dbg_param |= ERR_API; + abe_dbg_error_log(ABE_PARAMETER_ERROR); + } + + for (i = 0; i < abe_nb_pingpong; i++) { + dmem_addr = dmem_ping_pong_buffer + (i * abe_size_pingpong); + abe_base_address_pingpong [i] = dmem_addr; /* base addresses of the ping pong buffers in U8 unit */ + } + + *p = (abe_uint32)dmem_ping_pong_buffer; +} + +/* + * ABE_PLUG_SUBROUTINE + * + * Parameter : + * id: returned sequence index after plugging a new subroutine + * f : subroutine address to be inserted + * n : number of parameters of this subroutine + * + * Returned value : error code + * + * Operations : register a list of subroutines for call-back purpose + * + */ +void abe_plug_subroutine(abe_uint32 *id, abe_subroutine2 f, abe_uint32 n, abe_uint32* params) +{ + /* debug trace */ + abe_add_subroutine (id, f, n, params); +} + +/* + * ABE_PLUG_SEQUENCE + * + * Parameter : + * Id: returned sequence index after pluging a new sequence (index in the tables) + * s : sequence to be inserted + * + * Operations : + * Load a time-sequenced operations. + * + * Return value : + * None. + */ +void abe_plug_sequence(abe_uint32 *id, abe_sequence_t *s) +{ + just_to_avoid_the_many_warnings = *id; + just_to_avoid_the_many_warnings_abe_sequence_t = *s; +} + +/* + * ABE_SET_SEQUENCE_TIME_ACCURACY + * + * Parameter : + * patch bit field used to guarantee the code compatibility without conditionnal compilation + * Sequence index + * + * Operations : two counters are implemented in the firmware: + * - one "fast" counter, generating an IRQ to the HAL for sequences scheduling, the rate is in the range 1ms .. 100ms + * - one "slow" counter, generating an IRQ to the HAL for the management of ASRC drift, the rate is in the range 1s .. 100s + * + * Return value : + * None. + */ +void abe_set_sequence_time_accuracy(abe_micros_t fast, abe_micros_t slow) +{ + just_to_avoid_the_many_warnings_abe_micros_t = fast; + just_to_avoid_the_many_warnings_abe_micros_t = slow; +} + +/* + * ABE_LAUNCH_SEQUENCE + * + * Parameter : + * patch bit field used to guarantee the code compatibility without conditionnal compilation + * Sequence index + * + * Operations : + * Launch a list a time-sequenced operations. + * + * Return value : + * None. + */ +void abe_launch_sequence(abe_patch_rev patch, abe_uint32 n) +{ + just_to_avoid_the_many_warnings_abe_patch_rev = patch; + just_to_avoid_the_many_warnings = n; +} + +/* + * ABE_LAUNCH_SEQUENCE_PARAM + * + * Parameter : + * patch bit field used to guarantee the code compatibility without conditionnal compilation + * Sequence index + * Parameters to the programmable sequence + * + * Operations : + * Launch a list a time-sequenced operations. + * + * Return value : + * None. + */ +void abe_launch_sequence_param(abe_patch_rev patch, abe_uint32 n, abe_int32 *param1, abe_int32 *param2, abe_int32 *param3, abe_int32 *param4) +{ + just_to_avoid_the_many_warnings_abe_patch_rev = patch; + just_to_avoid_the_many_warnings = *param1; + just_to_avoid_the_many_warnings = *param2; + just_to_avoid_the_many_warnings = *param3; + just_to_avoid_the_many_warnings = *param4; + just_to_avoid_the_many_warnings = n; +} + +/* + * ABE_READ_ANALOG_GAIN_DL + * + * Parameter : + * gain value pointer + * + * Operations : + * returns to the data pointer the gain value of the phoenix headset in case the + * dynamic extension is activated. + * + * Return value : + * None. + */ +void abe_read_analog_gain_dl(abe_gain_t *a) +{ + just_to_avoid_the_many_warnings_abe_gain_t = *a; +} + +/* + * ABE_READ_ANALOG_GAIN_UL + * + * Parameter : + * gain value pointer + * + * Operations : + * returns to the data pointer the gain value of the phoenix headset in case the + * dynamic extension is activated. + * + * Return value : + * None. + */ +void abe_read_analog_gain_ul(abe_gain_t *a) +{ + just_to_avoid_the_many_warnings_abe_gain_t = *a; +} + +/* + * ABE_ENABLE_DYN_UL_GAIN + * + * Parameter : + * None. + * + * Operations : + * enables the audio engine capability to change dynamically the analog microphone + * amplitude based on the information of analog gain changes. + * + * Return value : + * None. + */ +void abe_enable_dyn_ul_gain(void) +{ +} + +/* + * ABE_DISABLE_DYN_UL_GAIN + * + * Parameter : + * + * + * Operations : + * disables the audio engine capability to change dynamically the analog microphone + * amplitude based on the information of analog gain changes. + * + * Return value : + * None. + */ +void abe_disable_dyn_ul_gain(void) +{ +} + +/* + * ABE_ENABLE_DYN_EXTENSION + * + * Parameter : + * None + * + * Operations : + * enables the audio engine capability to change the analog gain of Phoenix headset port. + * This feature enables dynamic range extension by increasing the digital gains and lowering + * the analog gains. This API is preferably called at reset time. + * + * Return value : + * None. + */ +void abe_enable_dyn_extension(void) +{ +} + +/* + * ABE_DISABLE_DYN_EXTENSION + * + * Parameter : + * None + * + * Operations : + * disables the audio engine capability to change the analog gain of Phoenix headset port. + * + * Return value : + * None. + */ +void abe_disable_dyn_extension(void) +{ +} + +/* + * ABE_NOTIFY_ANALOG_GAIN_CHANGED + * + * Parameter : + * Id: name of the Phoenix (or other device) port for which a gain was changed + * G: pointer to the notified gain value + * + * Operations : + * The upper layer tells the HAL a new gain was programmed in the analog renderer. + * This will help the tuning of the APS parameters. + * + * Return value : + * None. + */ +void abe_notify_analog_gain_changed(abe_ana_port_id Id, abe_gain_t *G) +{ + just_to_avoid_the_many_warnings_abe_gain_t = *G; + just_to_avoid_the_many_warnings_abe_ana_port_id = Id; +} + +/* + * ABE_RESET_PORT + * + * Parameters : + * id: port name + * + * Returned value : error code + * + * Operations : stop the port activity and reload default parameters on the associated processing features. + * Clears the internal AE buffers. + * + */ +void abe_reset_port(abe_port_id id) +{ + abe_port [id] = ((abe_port_t *) abe_port_init) [id]; +} + +/* + * ABE_READ_REMAINING_DATA + * + * Parameter : + * Port_ID : + * size : pointer to the remaining number of 32bits words + * + * Operations : + * computes the remaining amount of data in the buffer. + * + * Return value : + * error code + */ +void abe_read_remaining_data(abe_port_id port, abe_uint32 *n) +{ + just_to_avoid_the_many_warnings = *n; + just_to_avoid_the_many_warnings_abe_port_id = port; +} + +/* + * ABE_DISABLE_DATA_TRANSFER + * + * Parameter : + * p: port indentifier + * + * Operations : + * disables the ATC descriptor and stop IO/port activities + * disable the IO task (@f = 0) + * clear ATC DMEM buffer, ATC enabled + * + * Return value : + * None. + */ +void abe_disable_data_transfer(abe_port_id id) +{ + /* local host variable status= "port is running" */ + abe_port[id].status = IDLE_P; + /* disable DMA requests */ + abe_disable_dma_request(id); + /* disable ATC transfers */ + abe_disable_atc(id); + abe_clean_temporary_buffers(id); +} + +/* + * ABE_ENABLE_DATA_TRANSFER + * + * Parameter : + * p: port indentifier + * + * Operations : + * enables the ATC descriptor + * reset ATC pointers + * enable the IO task (@f <> 0) + * + * Return value : + * None. + */ +void abe_enable_data_transfer(abe_port_id id) +{ + abe_port_protocol_t *protocol; + abe_data_format_t format; + + abe_clean_temporary_buffers(id); + + if (id == PDM_UL_PORT) { + /* initializes the ABE ATC descriptors in DMEM - MCPDM_UL */ + protocol = &(abe_port[PDM_UL_PORT].protocol); + format = abe_port[PDM_UL_PORT].format; + abe_init_atc(PDM_UL_PORT); + abe_init_io_tasks(PDM_UL_PORT, &format, protocol); + } + if (id == PDM_DL_PORT) { + /* initializes the ABE ATC descriptors in DMEM - MCPDM_DL */ + protocol = &(abe_port[PDM_DL_PORT].protocol); + format = abe_port[PDM_DL_PORT].format; + abe_init_atc(PDM_DL_PORT); + abe_init_io_tasks(PDM_DL_PORT, &format, protocol); + } + if (id == DMIC_PORT) { + /* one DMIC port enabled = all DMICs enabled, + * since there is a single DMIC path for all DMICs */ + protocol = &(abe_port[DMIC_PORT].protocol); + format = abe_port[DMIC_PORT].format; + abe_init_atc(DMIC_PORT); + abe_init_io_tasks(DMIC_PORT, &format, protocol); + } + + /* local host variable status= "port is running" */ + abe_port[id].status = RUN_P; + /* enable DMA requests */ + abe_enable_dma_request(id); +} + +/* + * ABE_WRITE_CLOCK_MODE + * + * Parameter : + * + * Operations : + * information from the upper layers of the clock configuration in Phoenix in + * order to correctly translate the global counter values in time. + * + * Return value : + * None. + */ +void abe_write_clock_mode(abe_uint32 mode) +{ + just_to_avoid_the_many_warnings = mode; +} + +/* + * ABE_READ_GLOBAL_COUNTER + * + * Parameter : + * data pointer to the counter value + * data pointer to the translated milliseconds + * + * Operations : + * returns the value of the 32bits counter incremented on each firmware scheduling task + * loops (250us / 272us with respectively 48kHz / 44.1kHz on Phoenix). Translates this data + * in milli seconds format. + * + * Return value : + * None. + */ +void abe_read_global_counter(abe_time_stamp_t *t, abe_millis_t *m) +{ + just_to_avoid_the_many_warnings_abe_time_stamp_t = *t; + just_to_avoid_the_many_warnings_abe_millis_t = *m; +} + +/* + * ABE_SET_DMIC_FILTER + * + * Parameter : + * DMIC decimation ratio : 16/25/32/40 + * + * Operations : + * Loads in CMEM a specific list of coefficients depending on the DMIC sampling + * frequency (2.4MHz or 3.84MHz). This table compensates the DMIC decimator roll-off at 20kHz. + * The default table is loaded with the DMIC 2.4MHz recommended configuration. + * + * Return value : + * None. + */ +void abe_set_dmic_filter(abe_dmic_ratio_t d) +{ + just_to_avoid_the_many_warnings = (abe_uint32)d; +} + +/** +* @fn abe_connect_cbpr_dmareq_port() +* +* Operations : enables the data echange between a DMA and the ABE through the +* CBPr registers of AESS. +* +* Parameters : +* id: port name +* f : desired data format +* d : desired dma_request line (0..7) +* a : returned pointer to the base address of the CBPr register and number of +* samples to exchange during a DMA_request. +* +* @see ABE_API.h +*/ +void abe_connect_cbpr_dmareq_port(abe_port_id id, abe_data_format_t *f, abe_uint32 d, abe_dma_t *returned_dma_t) +{ + if (f->f == 44100) + /* waiting for a true SRC_44_48 in ABE */ + abe_write_event_generator(EVENT_44100); + abe_port[id] = ((abe_port_t *)abe_port_init)[id]; + + abe_port[id].format = *f; + abe_port[id].protocol.protocol_switch = DMAREQ_PORT_PROT; + abe_port[id].protocol.p.prot_dmareq.iter = abe_dma_port_iteration(f); + abe_port[id].protocol.p.prot_dmareq.dma_addr = ABE_DMASTATUS_RAW; + abe_port[id].protocol.p.prot_dmareq.dma_data = (1 << d); + + abe_port[id].status = RUN_P; + + /* load the micro-task parameters */ + abe_init_io_tasks(id, &((abe_port [id]).format), &((abe_port [id]).protocol)); + + /* load the dma_t with physical information from AE memory mapping */ + abe_init_dma_t(id, &((abe_port [id]).protocol)); + + /* load the ATC descriptors - disabled */ + abe_init_atc(id); + + /* return the dma pointer address */ + abe_read_port_address(id, returned_dma_t); +} + +/** +* @fn abe_connect_dmareq_port() +* +* Operations : enables the data echanges between a DMA and a direct access to +* the DMEM memory of ABE. On each dma_request activation the DMA will exchange +* "iter" bytes and rewind its pointer to the base address "l3" waiting for the +* next activation. The scheme is used for the MM_UL and debug port +* +* Parameters : +* id: port name +* f : desired data format +* d : desired dma_request line (0..7) +* a : returned pointer to the base address of the ping-pong buffer and number +* of samples to exchange during a DMA_request.. +* +* @see ABE_API.h +*/ +void abe_connect_dmareq_port(abe_port_id id, abe_data_format_t *f, abe_uint32 d, abe_dma_t *a) +{ +} + +/** +* @fn abe_connect_dmareq_ping_pong_port() +* +* Operations : enables the data echanges between a DMA and a direct access to +* the DMEM memory of ABE. On each dma_request activation the DMA will exchange +* "s" bytes and switch to the "pong" buffer for a new buffer exchange. +* +* Parameters : +* id: port name +* f : desired data format +* d : desired dma_request line (0..7) +* s : half-buffer (ping) size +* +* a : returned pointer to the base address of the ping-pong buffer and number of samples to exchange during a DMA_request. +* +* @see ABE_API.h +*/ +void abe_connect_dmareq_ping_pong_port(abe_port_id id, abe_data_format_t *f, abe_uint32 d, abe_uint32 s, abe_dma_t *returned_dma_t) +{ + abe_dma_t dma1; + + /* ping_pong is only supported on MM_DL */ + if (id != MM_DL_PORT) + { + abe_dbg_param |= ERR_API; + abe_dbg_error_log(ABE_PARAMETER_ERROR); + } + + /* declare PP buffer and prepare the returned dma_t */ + abe_init_ping_pong_buffer(MM_DL_PORT, s, 2, (abe_uint32 *)&(returned_dma_t->data)); + + abe_port [id] = ((abe_port_t *) abe_port_init) [id]; + + (abe_port [id]).format = (*f); + (abe_port [id]).protocol.protocol_switch = PINGPONG_PORT_PROT; + (abe_port [id]).protocol.p.prot_pingpong.buf_addr = dmem_ping_pong_buffer; + (abe_port [id]).protocol.p.prot_pingpong.buf_size = s; + (abe_port [id]).protocol.p.prot_pingpong.irq_addr = ABE_DMASTATUS_RAW; + (abe_port [id]).protocol.p.prot_pingpong.irq_data = (1 << d); + + abe_port [id].status = RUN_P; + + /* load the micro-task parameters DESC_IO_PP */ + abe_init_io_tasks(id, &((abe_port [id]).format), &((abe_port [id]).protocol)); + + /* load the dma_t with physical information from AE memory mapping */ + abe_init_dma_t(id, &((abe_port [id]).protocol)); + + dma1.data = (abe_uint32 *)(abe_port [id].dma.data + ABE_DMEM_BASE_ADDRESS_L3); + dma1.iter = abe_port [id].dma.iter; + (*returned_dma_t) = dma1; +} + +/** +* @fn abe_connect_irq_ping_pong_port() +* +* Operations : enables the data echanges between a direct access to the DMEM +* memory of ABE using cache flush. On each IRQ activation a subroutine +* registered with "abe_plug_subroutine" will be called. This subroutine +* will generate an amount of samples, send them to DMEM memory and call +* "abe_set_ping_pong_buffer" to notify the new amount of samples in the +* pong buffer. +* +* Parameters : +* id: port name +* f : desired data format +* I : index of the call-back subroutine to call +* s : half-buffer (ping) size +* +* p: returned base address of the first (ping) buffer) +* +* @see ABE_API.h +*/ +void abe_connect_irq_ping_pong_port(abe_port_id id, abe_data_format_t *f, + abe_uint32 d, abe_uint32 s, abe_uint32 *p, abe_uint32 dsp_mcu_flag) +{ + /* ping_pong is only supported on MM_DL */ + if (id != MM_DL_PORT) { + abe_dbg_param |= ERR_API; + abe_dbg_error_log(ABE_PARAMETER_ERROR); + } + + /* declare PP buffer for mono 20ms = 960 samples */ + abe_init_ping_pong_buffer(MM_DL_PORT, s, 2, p); + + abe_port [id] = ((abe_port_t *) abe_port_init) [id]; + (abe_port [id]).format = (*f); + (abe_port [id]).protocol.protocol_switch = PINGPONG_PORT_PROT; + (abe_port [id]).protocol.p.prot_pingpong.buf_addr = dmem_ping_pong_buffer; + (abe_port [id]).protocol.p.prot_pingpong.buf_size = s; + (abe_port [id]).protocol.p.prot_pingpong.irq_data = (1); + + if (dsp_mcu_flag == PING_PONG_WITH_MCU_IRQ) + (abe_port [id]).protocol.p.prot_pingpong.irq_addr = ABE_MCU_IRQSTATUS_RAW; + + if (dsp_mcu_flag == PING_PONG_WITH_DSP_IRQ) + (abe_port [id]).protocol.p.prot_pingpong.irq_addr = ABE_DSP_IRQSTATUS_RAW; + + abe_port [id].status = RUN_P; + + /* load the micro-task parameters */ + abe_init_io_tasks(id, &((abe_port [id]).format), &((abe_port [id]).protocol)); + + /* load the ATC descriptors - disabled */ + abe_init_atc(id); + + (*p)= (abe_port [id]).protocol.p.prot_pingpong.buf_addr; +} + +/** +* @fn abe_connect_serial_port() +* +* Operations : enables the data echanges between a McBSP and an ATC buffer in +* DMEM. This API is used connect 48kHz McBSP streams to MM_DL and 8/16kHz +* voice streams to VX_UL, VX_DL, BT_VX_UL, BT_VX_DL. It abstracts the +* abe_write_port API. +* +* Parameters : +* id: port name +* f : data format +* i : peripheral ID (McBSP #1, #2, #3) +* +* @see ABE_API.h +*/ +void abe_connect_serial_port(abe_port_id id, abe_data_format_t *f, abe_mcbsp_id mcbsp_id) +{ + abe_port [id] = ((abe_port_t *) abe_port_init) [id]; + (abe_port [id]).format = (*f); + (abe_port [id]).protocol.protocol_switch = SERIAL_PORT_PROT; + /* McBSP peripheral connected to ATC */ + (abe_port [id]).protocol.p.prot_serial.desc_addr = mcbsp_id*ATC_SIZE; + /* ITERation on each DMAreq signals */ + (abe_port [id]).protocol.p.prot_serial.iter = abe_dma_port_iteration(f); + + //(abe_port [id]).protocol.p.prot_serial.buf_addr; /* Address of ATC McBSP/McASP descriptor's in bytes */ + //(abe_port [id]).protocol.p.prot_serial.buf_size; /* DMEM address in bytes */ + //(abe_port [id]).protocol.p.prot_serial.thr_flow; /* Data threshold for flow management */ + + abe_port [id].status = RUN_P; + /* load the micro-task parameters */ + abe_init_io_tasks(id, &((abe_port [id]).format), &((abe_port [id]).protocol)); + /* load the ATC descriptors - disabled */ + abe_init_atc(id); +} + +/* + * ABE_WRITE_PORT_DESCRIPTOR + * + * Parameter : + * id: port name + * f : input pointer to the data format + * p : input pointer to the protocol description + * dma : output pointer to the DMA iteration and data destination pointer : + * + * Operations : + * writes the corresponding port descriptor in the AE memory spaces. The ATC DMEM descriptors + * are initialized. + * - translates the data format to AE I/O task format + * - copy to DMEM + * - load ATC descriptor - disabled + * + * Return value : + * None. + */ +void abe_write_port_descriptor(abe_port_id id, abe_data_format_t *format, abe_port_protocol_t *prot, abe_dma_t *dma) +{ +#if 0 + abe_dbg_log(ID_WRITE_PORT_DESCRIPTOR); + + if (abe_port [id].status) + abe_dbg_log(ABE_PORT_REPROGRAMMING); + + + // load internal HAL data + + abe_port [id].status = RUN_P; // running status + abe_port [id].format = (*format); // format = input parameter + abe_port [id].drift = 0; // no drift yet + abe_port [id].callback = NOCALLBACK; + abe_port [id].protocol = (*prot); // protocol = input parameter + + + // load AE memory space + + abe_init_io_tasks(id, format, prot); // load the micro-task parameters + abe_init_dma_t(id, prot); // load the dma_t with physical information from AE memory mapping + abe_init_atc(id); // load the ATC descriptors - disabled + abe_read_port_address(id, dma); // return the dma pointer address + +#endif +} + +/* + * ABE_READ_PORT_DESCRIPTOR + * + * Parameter : + * id: port name + * f : input pointer to the data format + * p : input pointer to the protocol description + * dma : output pointer to the DMA iteration and data destination pointer : + * + * Operations : + * returns the port parameters from the HAL internal buffer. + * + * Return value : + * error code in case the Port_id is not compatible with the current OPP value + */ +void abe_read_port_descriptor(abe_port_id port, abe_data_format_t *f, abe_port_protocol_t *p) +{ + (*f) = (abe_port[port]).format; + (*p) = (abe_port[port]).protocol; +} + +/* + * ABE_READ_APS_ENERGY + * + * Parameter : + * Port_ID : port ID supporting APS + * APS data struct pointer + * + * Operations : + * Returns the estimated amount of energy + * + * Return value : + * error code when the Port is not activated. + */ +void abe_read_aps_energy(abe_port_id *p, abe_gain_t *a) +{ + just_to_avoid_the_many_warnings_abe_port_id = *p; + just_to_avoid_the_many_warnings_abe_gain_t = *a; +} + +/* + * ABE_READ_PORT_ADDRESS + * + * Parameter : + * dma : output pointer to the DMA iteration and data destination pointer + * + * Operations : + * This API returns the address of the DMA register used on this audio port. + * Depending on the protocol being used, adds the base address offset L3 (DMA) or MPU (ARM) + * + * Return value : + */ +void abe_read_port_address(abe_port_id port, abe_dma_t *dma2) +{ + abe_dma_t_offset dma1; + abe_uint32 protocol_switch; + + dma1 = (abe_port[port]).dma; + protocol_switch = abe_port[port].protocol.protocol_switch; + + switch (protocol_switch) { + case PINGPONG_PORT_PROT: + /* return the base address of the ping buffer in L3 and L4 spaces */ + (*dma2).data = (void *)(dma1.data + ABE_DMEM_BASE_ADDRESS_L3); + (*dma2).l3_dmem = (void *)(dma1.data + ABE_DMEM_BASE_ADDRESS_L3); + (*dma2).l4_dmem = (void *)(dma1.data + ABE_DMEM_BASE_ADDRESS_L4); + break; + case DMAREQ_PORT_PROT: + /* return the CBPr(L3), DMEM(L3), DMEM(L4) address */ + (*dma2).data = (void *)(dma1.data + ABE_ATC_BASE_ADDRESS_L3); + (*dma2).l3_dmem = + (void *)((abe_port[port]).protocol.p.prot_dmareq.buf_addr + + ABE_DMEM_BASE_ADDRESS_L3); + (*dma2).l4_dmem = (void *)((abe_port[port]).protocol.p.prot_dmareq.buf_addr + ABE_DMEM_BASE_ADDRESS_L4); + break; + default: + break; + } + + (*dma2).iter = (dma1.iter); +} + +/* + * ABE_WRITE_PORT_GAIN + * + * Parameter : + * port : name of the port (VX_DL_PORT, MM_DL_PORT, MM_EXT_DL_PORT, TONES_DL_PORT, …) + * dig_gain_port pointer to returned port gain and time constant + * + * Operations : + * saves the gain data in the local HAL-L0 table of gains in native format. + * Translate the gain to the AE-FW format and load it in CMEM + * + * Return value : + * error code in case the gain_id is not compatible with the current OPP value. + */ +void abe_write_port_gain(abe_port_id port, abe_gain_t g, abe_ramp_t ramp) +{ +#if 0 + abe_uint32 port_coef, lin_g, iir_ramp1, iir_ramp1MA; + abe_float f_g, f_lin_g, f_ramp, f_iir_ramp1; + + switch (id) { + case PDM_UL_PORT: + port_coef = cmem_port_pdmul; + break; + case BT_VX_UL_PORT: + port_coef = cmem_port_btul; + break; + case MM_UL_PORT: + port_coef = cmem_port_mmul; + break; + case MM_UL2_PORT: + port_coef = cmem_port_mmul2; + break; + case VX_UL_PORT: + port_coef = cmem_port_vxul; + break; + case MM_DL_PORT: + port_coef = cmem_port_pdmdl; + break; + case VX_DL_PORT: + port_coef = cmem_port_vxdl; + break; + case TONES_DL_PORT: + port_coef = cmem_port_tones; + break; + case VIB_DL_PORT: + port_coef = cmem_port_vibdl; + break; + case BT_VX_DL_PORT: + port_coef = cmem_port_btdl; + break; + case PDM_DL1_PORT: + port_coef = cmem_port_pdmdl1; + break; + case MM_EXT_OUT_PORT: + port_coef = cmem_port_mmext; + break; + case PDM_DL2_PORT: + port_coef = cmem_port_pdmdl2; + break; + case PDM_VIB_PORT: + port_coef = cmem_port_pdmvib; + break; + case DMIC_PORT2: + port_coef = cmem_port_dmic2; + break; + case DMIC_PORT3: + port_coef = cmem_port_dmic3; + break; + case DMIC_PORT1: + default: + port_coef = cmem_port_dmic1; + break; + } + + f_g = (abe_float)g; + f_ramp = (abe_float)ramp; + + abe_translate_gain_format(MILLIBELS_TO_LINABE, f_g, &f_lin_g); + abe_translate_to_xmem_format(ABE_CMEM, f_lin_g, &lin_g); + + abe_translate_ramp_format(f_ramp, &f_iir_ramp1); + abe_translate_to_xmem_format(ABE_CMEM, f_iir_ramp1, &iir_ramp1); + abe_translate_to_xmem_format(ABE_CMEM, (1 - f_iir_ramp1), &iir_ramp1MA); + + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_CMEM, 4*port_coef, (abe_uint32*)&lin_g, sizeof(lin_g)); + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_CMEM, 4*cmem_ramp_alpha, (abe_uint32*)&iir_ramp1, sizeof(iir_ramp1)); + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_CMEM, 4*cmem_ramp_1_M_alpha, (abe_uint32*)&iir_ramp1MA, sizeof(iir_ramp1MA)); +#endif +} + +/* + * ABE_READ_GAIN + * + * Parameter : + * port : name of the port (VX_DL_PORT, MM_DL_PORT, MM_EXT_DL_PORT, TONES_DL_PORT, …) + * dig_gain_port pointer to returned port gain and time constant + * + * Operations : + * returns the real-time value of the gain from CMEM. + * + * Return value : + * error code in case the gain_id is not compatible with the current OPP value. + */ +void abe_read_port_gain(abe_port_id port, abe_gain_t *gain, abe_ramp_t *ramp) +{ + just_to_avoid_the_many_warnings_abe_port_id = port; + just_to_avoid_the_many_warnings_abe_gain_t = *gain; + just_to_avoid_the_many_warnings_abe_ramp_t = *ramp; +} + +/* + * ABE_READ_GAIN_RANGES + * + * Parameter : + * Id : name of the AE port + * Gain data pointer to the minimum, maximum gain, + * gain steps for the overall digital and/or analog hardware. + * + * Operations : + * returns the gain steps accuracy and range. If the API abe_enable_dyn_extension + * was called, the ports connected to Phoenix McPDM will also incorporate the gains + * of the analog part, else only the digital part is taken into account. + * + * Return value : + * None. + */ +void abe_read_gain_range(abe_port_id id, abe_gain_t *min, abe_gain_t *max, abe_gain_t *step) +{ + just_to_avoid_the_many_warnings_abe_port_id = id; + just_to_avoid_the_many_warnings_abe_gain_t = *min; + just_to_avoid_the_many_warnings_abe_gain_t = *max; + just_to_avoid_the_many_warnings_abe_gain_t = *step; +} + +/* + * ABE_WRITE_EQUALIZER + * + * Parameter : + * Id : name of the equalizer + * Param : equalizer coefficients + * + * Operations : + * Load the coefficients in CMEM. This API can be called when the corresponding equalizer + * is not activated. After reloading the firmware the default coefficients corresponds to + * "no equalizer feature". Loading all coefficients with zeroes disables the feature. + * + * Return value : + * None. + */ +void abe_write_equalizer(abe_equ_id id, abe_equ_t *param) +{ +#if 0 + setCM(C_DMIC1_EQ_Coefs_ADDR, C_DMIC1_EQ_Coefs_ADDR+16, pGain, Sth); + setCM(C_DMIC2_EQ_Coefs_ADDR, C_DMIC2_EQ_Coefs_ADDR+16, pGain, Sth); + setCM(C_DMIC3_EQ_Coefs_ADDR, C_DMIC3_EQ_Coefs_ADDR+16, pGain, Sth); + setCM(C_SDT_Coefs_ADDR, C_SDT_Coefs_ADDR+16, pGain, Sth); + setCM(C_DL1_Coefs_ADDR, C_DL1_Coefs_ADDR+16, pGain, Sth); + + setCM(C_DL2_R_Coefs_ADDR, C_DL2_R_Coefs_ADDR+16, pGain, Sth); + setCM(C_DL2_L_Coefs_ADDR, C_DL2_L_Coefs_ADDR+16, pGain, Sth) +#endif +} + +/* + * ABE_SET_ASRC_DRIFT_CONTROL + * + * Parameter : + * Id : name of the asrc + * f: flag which enables (1) the automatic computation of drift parameters + * + * Operations : + * When an audio port is connected to an hardware peripheral (MM_DL connected to a McBSP for + * example), the drift compensation can be managed in "forced mode" (f=0) or "adaptive mode" + * (f=1). In the first case the drift is managed with the usage of the API "abe_write_asrc". + * In the second case the firmware will generate on periodic basis an information about the + * observed drift, the HAL will reload the drift parameter based on those observations. + * + * Return value : + * None. + */ +void abe_set_asrc_drift_control(abe_asrc_id id, abe_uint32 f) +{ +} + +/* + * ABE_WRITE_ASRC + * + * Parameter : + * Id : name of the asrc + * param : drift value t compensate + * + * Operations : + * Load the drift coefficients in FW memory. This API can be called when the corresponding + * ASRC is not activated. After reloading the firmware the default coefficients corresponds + * to "no ASRC activated". Loading the drift value with zero disables the feature. + * + * Return value : + * None. + */ +void abe_write_asrc(abe_asrc_id id, abe_drift_t dppm) +{ +#if 0 + abe_int32 dtempvalue, adppm, alpha_current, beta_current, asrc_params; + abe_int32 atempvalue32[8]; + /* + * x = ppm + * - 1000000/x must be multiple of 16 + * - deltaalpha = round(2^20*x*16/1000000)=round(2^18/5^6*x) on 22 bits. then shifted by 2bits + * - minusdeltaalpha + * - oneminusepsilon = 1-deltaalpha/2. + * ppm = 250 + * - 1000000/250=4000 + * - deltaalpha = 4194.3 ~ 4195 => 0x00418c + */ + /* examples for -6250 ppm */ + // atempvalue32[0] = 4; /* d_constalmost0 */ + // atempvalue32[1] = -1; /* d_driftsign */ + // atempvalue32[2] = 15; /* d_subblock */ + // atempvalue32[3] = 0x00066668; /* d_deltaalpha */ + // atempvalue32[4] = 0xfff99998; /* d_minusdeltaalpha */ + // atempvalue32[5] = 0x003ccccc; /* d_oneminusepsilon */ + // atempvalue32[6] = 0x00000000; /* d_alphazero */ + // atempvalue32[7] = 0x00400000; /* d_betaone */ + + /* compute new value for the ppm */ + if (dppm > 0){ + atempvalue32[1] = 1; /* d_driftsign */ + adppm = dppm; + } else { + atempvalue32[1] = -1; /* d_driftsign */ + adppm = (-1*dppm); + } + + dtempvalue = (adppm << 4) + adppm - ((adppm * 3481L)/15625L); + atempvalue32[3] = dtempvalue<<2; + atempvalue32[4] = (-dtempvalue)<<2; + atempvalue32[5] = (0x00100000-(dtempvalue/2))<<2; + + switch (id) { + case ASRC2: /* asynchronous sample-rate-converter for the uplink voice path */ + alpha_current = C_AlphaCurrent_UL_VX_ADDR; + beta_current = C_BetaCurrent_UL_VX_ADDR; + asrc_params = D_AsrcVars_UL_VX_ADDR; + break; + case ASRC1: /* asynchronous sample-rate-converter for the downlink voice path */ + alpha_current = C_AlphaCurrent_DL_VX_ADDR; + beta_current = C_BetaCurrent_DL_VX_ADDR; + asrc_params = D_AsrcVars_DL_VX_ADDR; + break; + default: + case ASRC3: /* asynchronous sample-rate-converter for the multimedia player */ + alpha_current = C_AlphaCurrent_DL_MM_ADDR; + beta_current = C_BetaCurrent_DL_MM_ADDR; + asrc_params = D_AsrcVars_DL_MM_ADDR; + break; + } + + dtempvalue = 0x00000000; + abe_block_copy (COPY_FROM_HOST_TO_ABE, ABE_CMEM, alpha_current,(abe_uint32 *)&dtempvalue, 4); + dtempvalue = 0x00400000; + abe_block_copy (COPY_FROM_HOST_TO_ABE, ABE_CMEM, beta_current, (abe_uint32 *)&dtempvalue, 4); + abe_block_copy (COPY_FROM_HOST_TO_ABE, ABE_CMEM, asrc_params , (abe_uint32 *)&atempvalue32, sizeof(atempvalue32)); +#endif +} + +/* + * ABE_WRITE_APS + * + * Parameter : + * Id : name of the aps filter + * param : table of filter coefficients + * + * Operations : + * Load the filters and thresholds coefficients in FW memory. This API can be called when + * the corresponding APS is not activated. After reloading the firmware the default coefficients + * corresponds to "no APS activated". Loading all the coefficients value with zero disables + * the feature. + * + * Return value : + * None. + */ +void abe_write_aps(abe_aps_id id, abe_aps_t *param) +{ +} + +/* + * ABE_WRITE_MIXER + * + * Parameter : + * Id : name of the mixer + * param : list of input gains of the mixer + * p : list of port corresponding to the above gains + * + * Operations : + * Load the gain coefficients in FW memory. This API can be called when the corresponding + * MIXER is not activated. After reloading the firmware the default coefficients corresponds + * to "all input and output mixer's gain in mute state". A mixer is disabled with a network + * reconfiguration corresponding to an OPP value. + * + * Return value : + * None. + */ +void abe_write_gain(abe_gain_id id, abe_gain_t f_g, abe_ramp_t f_ramp, abe_port_id p) +{ + abe_uint32 lin_g, mixer_target, mixer_offset; + abe_int32 gain_index; + + gain_index = ((f_g - min_mdb) / 100); + gain_index = maximum(gain_index, 0); + gain_index = minimum(gain_index, sizeof_db2lin_table); + + lin_g = abe_db2lin_table [gain_index]; + + switch(id) { + default: + case GAINS_DMIC1: + mixer_offset = dmic1_gains_offset; + break; + case GAINS_DMIC2: + mixer_offset = dmic2_gains_offset; + break; + case GAINS_DMIC3: + mixer_offset = dmic3_gains_offset; + break; + case GAINS_AMIC: + mixer_offset = amic_gains_offset; + break; + case GAINS_DL1: + mixer_offset = dl1_gains_offset; + break; + case GAINS_DL2: + mixer_offset = dl2_gains_offset; + break; + case GAINS_SPLIT: + mixer_offset = splitters_gains_offset; + break; + case MIXDL1: + mixer_offset = mixer_dl1_offset; + break; + case MIXDL2: + mixer_offset = mixer_dl2_offset; + break; + case MIXECHO: + mixer_offset = mixer_echo_offset; + break; + case MIXSDT: + mixer_offset = mixer_sdt_offset; + break; + case MIXVXREC: + mixer_offset = mixer_vxrec_offset; + break; + case MIXAUDUL: + mixer_offset = mixer_audul_offset; + break; + } + + mixer_target = (smem_target_gain_base << 1);/* SMEM word32 address */ + mixer_target += mixer_offset; + mixer_target += p; + mixer_target <<= 2; /* translate coef address in Bytes */ + + /* load the S_G_Target SMEM table */ + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_SMEM, mixer_target, + (abe_uint32*)&lin_g, sizeof(lin_g)); +} + +void abe_write_mixer(abe_mixer_id id, abe_gain_t f_g, abe_ramp_t f_ramp, abe_port_id p) +{ + abe_write_gain((abe_gain_id)id, f_g, f_ramp, p); +} + +/* + * ABE_WRITE_EANC + * + * Parameter : + * param : table of coefficients + * + * Operations : + * Load the EANC coefficients in FW memory. This API can be called when EANC is not + * activated. After reloading the firmware the default coefficients corresponds to + * "no EANC activated". Loading the coefficients value with zero disables the feature. + * + * Return value : + * None. + */ +void abe_write_eanc(abe_eanc_t *param) +{ +} + +/* + * ABE_SET_ROUTER_CONFIGURATION + * + * Parameter : + * Id : name of the router + * Conf : id of the configuration + * param : list of output index of the route + * + * Operations : + * The uplink router takes its input from DMIC (6 samples), AMIC (2 samples) and + * PORT1/2 (2 stereo ports). Each sample will be individually stored in an intermediate + * table of 10 elements. The intermediate table is used to route the samples to + * three directions : REC1 mixer, 2 EANC DMIC source of filtering and MM recording audio path. + * For example, a use case consisting in AMIC used for uplink voice communication, DMIC 0,1,2,3 + * used for multimedia recording, , DMIC 5 used for EANC filter, DMIC 4 used for the feedback channel, + * will be implemented with the following routing table index list : + * [3, 2 , 1, 0, 0, 0 (two dummy indexes to data that will not be on MM_UL), 4, 5, 7, 6] + * example + * abe_set_router_configuration (UPROUTE, UPROUTE_CONFIG_AMIC, abe_router_ul_table_preset[UPROUTE_CONFIG_AMIC]); + * Return value : + * None. + */ +void abe_set_router_configuration(abe_router_id id, abe_uint32 configuration, abe_router_t *param) +{ + abe_uint8 aUplinkMuxing[16], n, i; + + n = D_aUplinkRouting_ADDR_END - D_aUplinkRouting_ADDR + 1; + + for(i=0; i < n; i++) + aUplinkMuxing[i] = (abe_uint8) (param [i]); + + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, D_aUplinkRouting_ADDR, (abe_uint32 *)aUplinkMuxing, sizeof (aUplinkMuxing)); +} + +/* + * ABE_READ_ASRC + * + * Parameter : + * Id : name of the asrc + * param : drift value to compensate + * + * + * Operations : + * read drift ppm value + * + * Return value : + * None. + */ +void abe_read_asrc(abe_asrc_id id, abe_drift_t *param) +{ +} + +/* + * ABE_READ_APS + * + * Parameter : + * Id : name of the aps filter + * param : table of filter coefficients + * + * Operations : + * Read APS coefficients + * + * Return value : + * None. + */ +void abe_read_aps(abe_aps_id id, abe_aps_t *param) +{ +} + +/* + * ABE_READ_MIXER + * + * Parameter : + * Id : name of the mixer + * param : gain + * port corresponding to the above gains + * + * + * Return value : + * None. + */ +void abe_read_mixer(abe_mixer_id id, abe_gain_t *gain, abe_ramp_t *f_ramp, abe_port_id p) +{ +} + +/* + * ABE_READ_EANC + * + * Parameter : + * param : table of coefficients + * + * Operations : + * read eanc coefficients + * + * Return value : + * None. + */ +void abe_read_eanc(abe_eanc_t *param) +{ +} + +/* + * ABE_READ_ROUTER + * + * Parameter : + * Id : name of the router + * param : list of output index of the route + * + * Operations : + * + * + * Return value : + * None. + */ +void abe_read_router(abe_router_id id, abe_router_t *param) +{ + just_to_avoid_the_many_warnings_abe_router_t = *param; + just_to_avoid_the_many_warnings_abe_router_id = id; +} + +/* + * ABE_READ_DEBUG_TRACE + * + * Parameter : + * data destination pointer + * max number of data read + * + * Operations : + * reads the AE circular data pointer holding pairs of debug data+timestamps, and store + * the pairs in linear addressing to the parameter pointer. Stops the copy when the max + * parameter is reached or when the FIFO is empty. + * + * Return value : + * None. + */ +void abe_read_debug_trace(abe_uint32 *data, abe_uint32 *n) +{ + just_to_avoid_the_many_warnings = (*data); + just_to_avoid_the_many_warnings = (*n); +} + +/* + * ABE_SET_DEBUG_TRACE + * + * Parameter : + * debug ID from a list to be defined + * + * Operations : + * load a mask which filters the debug trace to dedicated types of data + * + * Return value : + * None. + */ +void abe_set_debug_trace(abe_dbg_t debug) +{ +} + +/* + * ABE_SET_DEBUG_PINS + * + * Parameter : + * debugger commands to the AESS register in charge of the debug pins + * + * Operations : + * interpret the debugger commands: activate the AESS debug pins and + * allocate those pins to the AE outputs. + * + * Return value : + * None. + */ +void abe_set_debug_pins(abe_uint32 debug_pins) +{ + just_to_avoid_the_many_warnings = debug_pins; +} + +/* + * ABE_REMOTE_DEBUGGER_INTERFACE + * + * Parameter : + * + * Operations : + * interpretation of the UART stream from the remote debugger commands. + * The commands consist in setting break points, loading parameter + * + * Return value : + * None. + */ +void abe_remote_debugger_interface(abe_uint32 n, abe_uint8 *p) +{ + just_to_avoid_the_many_warnings = n; + just_to_avoid_the_many_warnings = (abe_uint32) (*p); +} diff --git a/sound/soc/codecs/abe/abe_api.h b/sound/soc/codecs/abe/abe_api.h new file mode 100644 index 000000000000..b224d7001baf --- /dev/null +++ b/sound/soc/codecs/abe/abe_api.h @@ -0,0 +1,1090 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ + +#ifndef _ABE_API_H_ +#define _ABE_API_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * External API + */ +#if PC_SIMULATION +extern void target_server_read_pmem(abe_uint32 address, abe_uint32 *data, abe_uint32 nb_words_32bits); +extern void target_server_write_pmem(abe_uint32 address, abe_uint32 *data, abe_uint32 nb_words_32bits); +extern void target_server_read_cmem(abe_uint32 address, abe_uint32 *data, abe_uint32 nb_words_32bits); +extern void target_server_write_cmem(abe_uint32 address, abe_uint32 *data, abe_uint32 nb_words_32bits); +extern void target_server_read_atc(abe_uint32 address, abe_uint32 *data, abe_uint32 nb_words_32bits); +extern void target_server_write_atc(abe_uint32 address, abe_uint32 *data, abe_uint32 nb_words_32bits); +extern void target_server_read_smem(abe_uint32 address_48bits, abe_uint32 *data, abe_uint32 nb_words_48bits); +extern void target_server_write_smem(abe_uint32 address_48bits, abe_uint32 *data, abe_uint32 nb_words_48bits); +extern void target_server_read_dmem(abe_uint32 address_byte, abe_uint32 *data, abe_uint32 nb_byte); +extern void target_server_write_dmem(abe_uint32 address_byte, abe_uint32 *data, abe_uint32 nb_byte); + +extern void target_server_activate_mcpdm_ul(void); +extern void target_server_activate_mcpdm_dl(void); +extern void target_server_activate_dmic(void); +extern void target_server_set_voice_sampling(int dVirtAudioVoiceMode, int dVirtAudioVoiceSampleFrequency); +extern void target_server_set_dVirtAudioMultimediaMode(int dVirtAudioMultimediaMode); +#endif + +/* + * Internal API + */ + +/** +* abe_read_sys_clock() description for void abe_read_sys_clock(). +* +* Operations : returns the current time indication for the LOG +* +* Parameter : No parameter +* @param +* +* @pre no pre-condition +* +* @post +* +* @return error code +* +* @see +*/ +void abe_read_sys_clock(abe_micros_t *time); + +/** +* abe_fprintf() description for void abe_fprintf(). +* +* Operations : returns the current time indication for the LOG +* +* Parameter : No parameter +* @param +* +* @pre no pre-condition +* +* @post +* +* @return error code +* +* @see +*/ +//void abe_fprintf(char *line); + +/* + * API as part of the HAL paper documentation + */ + +/** +* abe_reset_hal() description for void abe_reset_hal(). +* +* Operations : reset the HAL by reloading the static variables and default AESS registers. +* Called after a PRCM cold-start reset of ABE +* +* Parameter : No parameter +* @param +* +* @pre no pre-condition +* +* @post +* +* @return error code +* +* @see +*/ +void abe_reset_hal(void); + +/** +* abe_read_use_case_opp() description for void abe_read_use_case_opp(). +* +* Operations : returns the expected min OPP for a given use_case list +* +* Parameter : No parameter +* @param +* +* @pre no pre-condition +* +* @post +* +* @return error code +* +* @see +*/ +void abe_read_use_case_opp(abe_use_case_id *u, abe_opp_t *o); + +/** +* abe_load_fw() description for void abe_load_fw(). +* +* Operations : +* loads the Audio Engine firmware, generate a single pulse on the Event generator +* to let execution start, read the version number returned from this execution. +* +* Parameter : No parameter +* @param +* +* @pre no pre-condition +* +* @post +* +* @return error code in case the firmware does not start. +* +* @see +*/ +void abe_load_fw(void); + +/** +* abe_read_port_address() description for void abe_read_port_address(). +* +* Operations : +* This API returns the address of the DMA register used on this audio port. +* +* Parameter : No parameter +* @param dma : output pointer to the DMA iteration and data destination pointer +* +* @pre no pre-condition +* +* @post +* +* @return error code +* +* @see +*/ +void abe_read_port_address(abe_port_id port, abe_dma_t *dma); + +/** +* abe_default_configuration() description for void abe_default_configuration(). +* +* Parameter : +* use-case-ID : "LP player", "voice-call" use-cases as defined in the paragraph +* "programming use-case sequences" +* param1, 2, 3, 4 : two parameters to be used later during FW06 integration +* +* Operations : +* private API used during development. Loads all the necessary parameters and data +* patterns to allow a stand-alone functional test without the need of. +* +* Parameter : No parameter +* @param dma : output pointer to the DMA iteration and data destination pointer +* +* @pre no pre-condition +* +* @post +* +* @return error code +* +* @see +*/ +void abe_default_configuration(abe_uint32 use_case); + +/** +* abe_irq_processing() description for void abe_irq_processing(). +* +* Parameter : +* No parameter +* +* Operations : +* This subroutine will check the IRQ_FIFO from the AE and act accordingly. +* Some IRQ source are originated for the delivery of "end of time sequenced tasks" +* notifications, some are originated from the Ping-Pong protocols, some are generated from +* the embedded debugger when the firmware stops on programmable break-points, etc … +* +* @param dma : output pointer to the DMA iteration and data destination pointer +* +* @pre no pre-condition +* +* @post +* +* @return error code +* +* @see +*/ +void abe_irq_processing(void); + +/** +* abe_write_event_generator () description for void abe_event_generator_switch(). +* +* Operations : +* load the AESS event generator hardware source. Loads the firmware parameters +* accordingly. Indicates to the FW which data stream is the most important to preserve +* in case all the streams are asynchronous. If the parameter is "default", let the HAL +* decide which Event source is the best appropriate based on the opened ports. +* +* @param e: Event Generation Counter, McPDM, DMIC or default. +* +* @pre no pre-condition +* +* @post +* +* @return error code +* +* @see +*/ +void abe_write_event_generator(abe_event_id e); + +/** +* abe_read_lowest_opp() description for void abe_read_lowest_opp(). +* +* Operations : +* Returns the lowest possible OPP based on the current active ports. +* +* @param o: returned data +* +* @pre no pre-condition +* +* @post +* +* @return error code +* +* @see +*/ +void abe_read_lowest_opp(abe_opp_t *o); + +/** +* abe_set_opp_processing() description for void abe_set_opp_processing(). +* +* Parameter : +* New processing network and OPP: +* 0: Ultra Lowest power consumption audio player (no post-processing, no mixer); +* 1: OPP 25% (simple multimedia features, including low-power player); +* 2: OPP 50% (multimedia and voice calls); +* 3: OPP100% (EANC, multimedia complex use-cases); +* +* Operations : +* Rearranges the FW task network to the corresponding OPP list of features. +* The corresponding AE ports are supposed to be set/reset accordingly before this switch. +* +* @param o: desired opp +* +* @pre no pre-condition +* +* @post +* +* @return error code +* +* @see +*/ +void abe_set_opp_processing(abe_opp_t opp); + +/** +* abe_set_ping_pong_bufferg() description for void abe_set_ping_pong_buffer(). +* +* Parameter : +* Port_ID : +* Pointer name : Read or Write pointer +* New data +* +* Operations : +* Updates the ping-pong read/write pointer with the input data. +* +* @param +* +* @pre no pre-condition +* +* @post +* +* @return error code +* +* @see +*/ +void abe_set_ping_pong_buffer(abe_port_id port, abe_uint32 n); + +/** +* @fn abe_connect_irq_ping_pong_port() +* +* Operations : enables the data echanges between a direct access to the DMEM +* memory of ABE using cache flush. On each IRQ activation a subroutine +* registered with "abe_plug_subroutine" will be called. This subroutine +* will generate an amount of samples, send them to DMEM memory and call +* "abe_set_ping_pong_buffer" to notify the new amount of samples in the +* pong buffer. +* +* Parameters : +* id: port name +* f : desired data format +* I : index of the call-back subroutine to call +* s : half-buffer (ping) size +* +* p: returned base address of the first (ping) buffer) +* +* @see ABE_API.h +*/ +void abe_connect_irq_ping_pong_port(abe_port_id id, abe_data_format_t *f, abe_uint32 d, + abe_uint32 s, abe_uint32 *p, abe_uint32 dsp_mcu_flag); + +/** +* abe_plug_subroutine() description for void abe_plug_subroutine(). +* +* Parameter : +* id: returned sequence index after plugging a new subroutine +* f : subroutine address to be inserted +* +* Operations : +* register a list of subroutines for call-back purpose. +* +* @param +* +* @pre no pre-condition +* +* @post +* +* @return error code +* +* @see +*/ +void abe_plug_subroutine(abe_uint32 *id, abe_subroutine2 f, abe_uint32 n, abe_uint32 *params); + +/** +* abe_plug_sequence() description for void abe_plug_sequence(). +* + * Parameter : + * Id: returned sequence index after pluging a new sequence (index in the tables); + * s : sequence to be inserted + * + * Operations : + * Load a list a time-sequenced operations. +* +* @param +* +* @pre no pre-condition +* +* @post +* +* @return error code +* +* @see +*/ +void abe_plug_sequence(abe_uint32 *id, abe_sequence_t *s); + +/** +* abe_launch_sequence() description for void abe_launch_sequence(). +* +* Parameter : +* Sequence index +* +* Operations : +* Launch a list a time-sequenced operations. +* +* @param +* +* @pre no pre-condition +* +* @post +* +* @return error code +* +* @see +*/ +void abe_launch_sequence(abe_patch_rev patch, abe_uint32 n); + +/** +* abe_launch_sequence_param() description for void abe_launch_sequence_param(). +* +* Parameter : +* Sequence index +* Parameters to the programmable sequence +* +* Operations : +* Launch a list a time-sequenced operations. +* +* @param +* +* @pre no pre-condition +* +* @post +* +* @return error code +* +* @see +*/ +void abe_launch_sequence_param(abe_patch_rev patch, abe_uint32 n, abe_int32 *param1, abe_int32 *param2, abe_int32 *param3, abe_int32 *param4);; + +/** +* abe_read_analog_gain_dl() description for void abe_read_analog_gain_dl(). +* +* Parameter : +* gain value pointer +* +* Operations : +* returns to the data pointer the gain value of the phoenix headset in case the +* dynamic extension is activated. +* +* @param +* +* @pre no pre-condition +* +* @post +* +* @return error code +* +* @see +*/ +void abe_read_analog_gain_dl(abe_gain_t *a); + +/** +* abe_read_analog_gain_ul() description for void abe_read_analog_gain_ul(). +* + * Parameter : + * gain value pointer + * + * Operations : + * returns to the data pointer the gain value of the phoenix headset in case the + * dynamic extension is activated. +* +* @param +* +* @pre no pre-condition +* +* @post +* +* @return error code +* +* @see +*/ +void abe_read_analog_gain_ul(abe_gain_t *a); + +/** +* abe_enable_dyn_ul_gain() description for void abe_enable_dyn_ul_gain(). +* +* Parameter : +* None. +* +* Operations : +* enables the audio engine capability to change dynamically the analog microphone +* amplitude based on the information of analog gain changes.. +* +* @param +* +* @pre no pre-condition +* +* @post +* +* @return error code +* +* @see +*/ +void abe_enable_dyn_ul_gain(void); + +/** +* abe_disable_dyn_ul_gain() description for void abe_disable_dyn_ul_gain(). +* +* Parameter : +* None. +* +* Operations : +* disables the audio engine capability to change dynamically the analog microphone +* amplitude based on the information of analog gain changes. +* +* @param +* +* @pre no pre-condition +* +* @post +* +* @return error code +* +* @see +*/ +void abe_disable_dyn_ul_gain(void); + +/** +* abe_enable_dyn_extension() description for void abe_enable_dyn_extension(). +* +* Parameter : +* None +* +* Operations : +* enables the audio engine capability to change the analog gain of Phoenix headset port. +* This feature enables dynamic range extension by increasing the digital gains and lowering +* the analog gains. This API is preferably called at reset time. +* +* @param +* +* @pre no pre-condition +* +* @post +* +* @return error code +* +* @see +*/ +void abe_enable_dyn_extension(void); + +/** +* abe_disable_dyn_extension() description for void abe_disable_dyn_extension(). +* +* Parameter : +* None +* +* Operations : +* disables the audio engine capability to change the analog gain of Phoenix heads +* +* @param +* +* @pre no pre-condition +* +* @post +* +* @return error code +* +* @see +*/ +void abe_disable_dyn_extension(void); + +/* + * ABE_NOTIFY_ANALOG_GAIN_CHANGED + * + * Parameter : + * Id: name of the Phoenix (or other device); port for which a gain was changed + * G: pointer to the notified gain value + * + * Operations : + * The upper layer tells the HAL a new gain was programmed in the analog renderer. + * This will help the tuning of the APS parameters. + * + * Return value : + * None. + */ +void abe_notify_analog_gain_changed(abe_ana_port_id Id, abe_gain_t *G); + +/* + * ABE_RESET_PORT + * + * Parameters : + * id: port name + * + * Returned value : error code + * + * Operations : stop the port activity and reload default parameters on the associated processing features. + * + */ +void abe_reset_port(abe_port_id id); + +/* + * ABE_READ_REMAINING_DATA + * + * Parameter : + * Port_ID : + * size : pointer to the remaining number of 32bits words + * + * Operations : + * computes the remaining amount of data in the buffer. + * + * Return value : + * error code + */ +void abe_read_remaining_data(abe_port_id port, abe_uint32 *n); + +/* + * ABE_DISABLE_DATA_TRANSFER + * + * Parameter : + * p: port indentifier + * + * Operations : + * disables the ATC descriptor + * + * Return value : + * None. + */ +void abe_disable_data_transfer (abe_port_id p); + +/* + * ABE_ENABLE_DATA_TRANSFER + * + * Parameter : + * p: port indentifier + * + * Operations : + * enables the ATC descriptor + * + * Return value : + * None. + */ +void abe_enable_data_transfer(abe_port_id p); + +/* + * ABE_READ_GLOBAL_COUNTER + * + * Parameter : + * data pointer to the counter value + * data pointer to the translated milliseconds + * + * Operations : + * returns the value of the 32bits counter incremented on each firmware scheduling task + * loops (250us / 272us with respectively 48kHz / 44.1kHz on Phoenix);. Translates this data + * in milli seconds format. + * + * Return value : + * None. + */ +void abe_read_global_counter(abe_time_stamp_t *t, abe_millis_t *m); + +/* + * ABE_SET_DMIC_FILTER + * + * Parameter : + * DMIC decimation ratio : 16/25/32/40 + * + * Operations : + * Loads in CMEM a specific list of coefficients depending on the DMIC sampling + * frequency (2.4MHz or 3.84MHz);. This table compensates the DMIC decimator roll-off at 20kHz. + * The default table is loaded with the DMIC 2.4MHz recommended configuration. + * + * Return value : + * None. + */ +void abe_set_dmic_filter(abe_dmic_ratio_t d); + +/** +* @fn abe_connect_cbpr_dmareq_port() +* +* Operations : enables the data echange between a DMA and the ABE through the +* CBPr registers of AESS. +* +* Parameters : +* id: port name +* f : desired data format +* d : desired dma_request line (0..7) +* a : returned pointer to the base address of the CBPr register and number of +* samples to exchange during a DMA_request. +* +* @see ABE_API.h +*/ +void abe_connect_cbpr_dmareq_port(abe_port_id id, abe_data_format_t *f, abe_uint32 d, abe_dma_t *a); + +/** +* @fn abe_connect_dmareq_port() +* +* Operations : enables the data echange between a DMA and the ABE through the +* CBPr registers of AESS. +* +* Parameters : +* id: port name +* f : desired data format +* d : desired dma_request line (0..7) +* a : returned pointer to the base address of the ping-pong buffer and number +* of samples to exchange during a DMA_request.. +* +* @see ABE_API.h +*/ +void abe_connect_dmareq_port(abe_port_id id, abe_data_format_t *f, abe_uint32 d, abe_dma_t *a); + +/** +* @fn abe_connect_dmareq_ping_pong_port() +* +* Operations : enables the data echanges between a DMA and a direct access to the +* DMEM memory of ABE. On each dma_request activation the DMA will exchange "s" +* bytes and switch to the "pong" buffer for a new buffer exchange.ABE +* +* Parameters : +* id: port name +* f : desired data format +* d : desired dma_request line (0..7) +* s : half-buffer (ping) size +* +* a : returned pointer to the base address of the ping-pong buffer and number of samples to exchange during a DMA_request. +* +* @see ABE_API.h +*/ +void abe_connect_dmareq_ping_pong_port(abe_port_id id, abe_data_format_t *f, abe_uint32 d, abe_uint32 s, abe_dma_t *a); + +/** +* @fn abe_connect_serial_port() +* +* Operations : enables the data echanges between a McBSP and an ATC buffer in +* DMEM. This API is used connect 48kHz McBSP streams to MM_DL and 8/16kHz +* voice streams to VX_UL, VX_DL, BT_VX_UL, BT_VX_DL. It abstracts the +* abe_write_port API. +* +* Parameters : +* id: port name +* f : data format +* i : peripheral ID (McBSP #1, #2, #3) +* +* @see ABE_API.h +*/ +void abe_connect_serial_port(abe_port_id id, abe_data_format_t *f, abe_mcbsp_id i); + +/* + * ABE_WRITE_PORT_DESCRIPTOR + * + * Parameter : + * id: port name + * f : input pointer to the data format + * p : input pointer to the protocol description + * dma : output pointer to the DMA iteration and data destination pointer + * + * Operations : + * writes the corresponding port descriptor in the AE memory spaces. The ATC DMEM descriptors + * are initialized. + * - translates the data format to AE I/O task format + * - copy to DMEM + * - load ATC descriptor - disabled + * + * Return value : + * None. + */ +void abe_write_port_descriptor(abe_port_id id, abe_data_format_t *f, abe_port_protocol_t *p, abe_dma_t *dma); + +/* + * ABE_READ_PORT_DESCRIPTOR + * + * Parameter : + * id: port name + * f : input pointer to the data format + * p : input pointer to the protocol description + * + * Operations : + * returns the port parameters from the HAL internal buffer. + * + * Return value : + * error code in case the Port_id is not compatible with the current OPP value + */ +void abe_read_port_descriptor(abe_port_id id, abe_data_format_t *f, abe_port_protocol_t *p); + +/* + * ABE_READ_APS_ENERGY + * + * Parameter : + * Port_ID : port ID supporting APS + * APS data struct pointer + * + * Operations : + * Returns the estimated amount of energy + * + * Return value : + * error code when the Port is not activated. + */ +void abe_read_aps_energy(abe_port_id *p, abe_gain_t *a); + +/* + * ABE_WRITE_PORT_GAIN + * + * Parameter : + * port : name of the port (VX_DL_PORT, MM_DL_PORT, MM_EXT_DL_PORT, TONES_DL_PORT, …); + * dig_gain_port pointer to returned port gain and time constant + * + * Operations : + * saves the gain data in the local HAL-L0 table of gains in native format. + * Translate the gain to the AE-FW format and load it in CMEM + * + * Return value : + * error code in case the gain_id is not compatible with the current OPP value. + */ + +void abe_write_port_gain(abe_port_id port, abe_gain_t g, abe_ramp_t ramp); +void abe_write_gain(abe_gain_id id, abe_gain_t f_g, abe_ramp_t f_ramp, abe_port_id p); + +/* + * ABE_READ_GAIN + * + * Parameter : + * port : name of the port (VX_DL_PORT, MM_DL_PORT, MM_EXT_DL_PORT, TONES_DL_PORT, …); + * dig_gain_port pointer to returned port gain and time constant + * + * Operations : + * returns the real-time value of the gain from CMEM. + * + * Return value : + * error code in case the gain_id is not compatible with the current OPP value. + */ +void abe_read_port_gain(abe_port_id port, abe_gain_t *gain, abe_ramp_t *ramp); + +/* + * ABE_READ_GAIN_RANGES + * + * Parameter : + * Id : name of the AE port + * Gain data pointer to the minimum, maximum gain, + * gain steps for the overall digital and/or analog hardware. + * + * Operations : + * returns the gain steps accuracy and range. If the API abe_enable_dyn_extension + * was called, the ports connected to Phoenix McPDM will also incorporate the gains + * of the analog part, else only the digital part is taken into account. + * + * Return value : + * None. + */ +void abe_read_gain_range(abe_port_id id, abe_gain_t *min, abe_gain_t *max, abe_gain_t *step); + +/* + * ABE_WRITE_EQUALIZER + * + * Parameter : + * Id : name of the equalizer + * Param : equalizer coefficients + * + * Operations : + * Load the coefficients in CMEM. This API can be called when the corresponding equalizer + * is not activated. After reloading the firmware the default coefficients corresponds to + * "no equalizer feature". Loading all coefficients with zeroes disables the feature. + * + * Return value : + * None. + */ +void abe_write_equalizer(abe_equ_id id, abe_equ_t *param); + +/* + * ABE_WRITE_ASRC + * + * Parameter : + * Id : name of the asrc + * param : drift value t compensate + * + * Operations : + * Load the drift coefficients in FW memory. This API can be called when the corresponding + * ASRC is not activated. After reloading the firmware the default coefficients corresponds + * to "no ASRC activated". Loading the drift value with zero disables the feature. + * + * Return value : + * None. + */ +void abe_write_asrc(abe_asrc_id id, abe_drift_t param); +void abe_set_asrc_drift_control(abe_asrc_id id, abe_uint32 f); + +/* + * ABE_WRITE_APS + * + * Parameter : + * Id : name of the aps filter + * param : table of filter coefficients + * + * Operations : + * Load the filters and thresholds coefficients in FW memory. This API can be called when + * the corresponding APS is not activated. After reloading the firmware the default coefficients + * corresponds to "no APS activated". Loading all the coefficients value with zero disables + * the feature. + * + * Return value : + * None. + */ +void abe_write_aps(abe_aps_id id, abe_aps_t *param); + +/* + * ABE_WRITE_MIXER + * + * Parameter : + * Id : name of the mixer + * param : list of input gains of the mixer + * p : list of ports corresponding to the above gains + * + * Operations : + * Load the gain coefficients in FW memory. This API can be called when the corresponding + * MIXER is not activated. After reloading the firmware the default coefficients corresponds + * to "all input and output mixer's gain in mute state". A mixer is disabled with a network + * reconfiguration corresponding to an OPP value. + * + * Return value : + * None. + */ +void abe_write_mixer(abe_mixer_id id, abe_gain_t g, abe_ramp_t ramp, abe_port_id p); + +/* + * ABE_WRITE_EANC + * + * Parameter : + * param : table of coefficients + * + * Operations : + * Load the EANC coefficients in FW memory. This API can be called when EANC is not + * activated. After reloading the firmware the default coefficients corresponds to + * "no EANC activated". Loading the coefficients value with zero disables the feature. + * + * Return value : + * None. + */ +void abe_write_eanc(abe_eanc_t *param); + +/* + * ABE_ENABLE_ROUTER_CONFIGURATION + * + * Parameter : + * Id : name of the router + * param : list of output index of the route + * + * Operations : load a pre-computed router configuration + * + * Return value : + * None. + */ +void abe_enable_router_configuration(abe_router_id id, abe_uint32 configuration); + +/* + * ABE_SET_ROUTER_CONFIGURATION + * + * Parameter : + * Id : name of the router + * Conf : id of the configuration + * param : list of output index of the route + * + * Operations : + * The uplink router takes its input from DMIC (6 samples), AMIC (2 samples) and + * PORT1/2 (2 stereo ports). Each sample will be individually stored in an intermediate + * table of 10 elements. The intermediate table is used to route the samples to + * three directions : REC1 mixer, 2 EANC DMIC source of filtering and MM recording audio path. + * For example, a use case consisting in AMIC used for uplink voice communication, DMIC 0,1,2,3 + * used for multimedia recording, , DMIC 5 used for EANC filter, DMIC 4 used for the feedback channel, + * will be implemented with the following routing table index list : + * [3, 2 , 1, 0, 0, 0 (two dummy indexes to data that will not be on MM_UL), 4, 5, 7, 6] + * + * Return value : + * None. + */ +void abe_set_router_configuration(abe_router_id id, abe_uint32 configuration, abe_router_t *param); + +/* + * ABE_WRITE_ROUTER + * + * Parameter : + * Id : name of the router + * param : list of output index of the route + * + * Operations : + * The uplink router takes its input from DMIC (6 samples);, AMIC (2 samples); and + * PORT1/2 (2 stereo ports);. Each sample will be individually stored in an intermediate + * table of 10 elements. The intermediate table is used to route the samples to + * three directions : REC1 mixer, 2 EANC DMIC source of filtering and MM recording audio path. + * For example, a use case consisting in AMIC used for uplink voice communication, DMIC 0,1,2,3 + * used for multimedia recording, , DMIC 5 used for EANC filter, DMIC 4 used for the feedback channel, + * will be implemented with the following routing table index list : + * [3, 2 , 1, 0, 0, 0 (two dummy indexes to data that will not be on MM_UL);, 4, 5, 7, 6] + * + * Return value : + * None. + */ +void abe_write_router(abe_router_id id, abe_router_t *param); + +/* + * ABE_READ_ASRC + * + * Parameter : + * Id : name of the asrc + * param : drift value to compensate + * + * + * Operations : + * read drift ppm value + * + * Return value : + * None. + */ +void abe_read_asrc(abe_asrc_id id, abe_drift_t *param); + +/* + * ABE_READ_APS + * + * Parameter : + * Id : name of the aps filter + * param : table of filter coefficients + * + * Operations : + * Read APS coefficients + * + * Return value : + * None. + */ +void abe_read_aps(abe_aps_id id, abe_aps_t *param); + +/* + * ABE_READ_MIXER + * + * Parameter : + * Id : name of the aps filter + * param : table of filter coefficients + * + * Operations : + * Id : name of the mixer + * param : list of input and output gains of the mixer + * + * Return value : + * None. + */ +void abe_read_mixer(abe_mixer_id id, abe_gain_t *f_gain, abe_ramp_t *f_ramp, abe_port_id p); + +/* + * ABE_READ_EANC + * + * Parameter : + * param : table of coefficients + * + * Operations : + * read eanc coefficients + * + * Return value : + * None. + */ +void abe_read_eanc(abe_eanc_t *param); + +/* + * ABE_READ_ROUTER + * + * Parameter : + * Id : name of the router + * param : list of output index of the route + * + * Operations : + * + * + * Return value : + * None. + */ +void abe_read_router(abe_router_id id, abe_router_t *param); + +/* + * ABE_READ_DEBUG_TRACE + * + * Parameter : + * data destination pointer + * max number of data read + * + * Operations : + * reads the AE circular data pointer holding pairs of debug data+timestamps, and store + * the pairs in linear addressing to the parameter pointer. Stops the copy when the max + * parameter is reached or when the FIFO is empty. + * + * Return value : + * None. + */ +void abe_read_debug_trace(abe_uint32 *data, abe_uint32 *n); + +/* + * ABE_SET_DEBUG_TRACE + * + * Parameter : + * debug ID from a list to be defined + * + * Operations : + * load a mask which filters the debug trace to dedicated types of data + * + * Return value : + * None. + */ +void abe_set_debug_trace(abe_dbg_t debug); + +/* + * ABE_SET_DEBUG_PINS + * + * Parameter : + * debugger commands to the AESS register in charge of the debug pins + * + * Operations : + * interpret the debugger commands: activate the AESS debug pins and + * allocate those pins to the AE outputs. + * + * Return value : + * None. + */ +void abe_set_debug_pins(abe_uint32 debug_pins); + +#ifdef __cplusplus +} +#endif + +#endif /* _ABE_API_H_ */ diff --git a/sound/soc/codecs/abe/abe_cm_addr.h b/sound/soc/codecs/abe/abe_cm_addr.h new file mode 100644 index 000000000000..8b30376016a6 --- /dev/null +++ b/sound/soc/codecs/abe/abe_cm_addr.h @@ -0,0 +1,346 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ + +#ifndef _ABE_CM_ADDR_H_ +#define _ABE_CM_ADDR_H_ + +#define init_CM_ADDR 0 +#define init_CM_ADDR_END 284 +#define init_CM_sizeof 285 + +#define C_Data_LSB_2_ADDR 285 +#define C_Data_LSB_2_ADDR_END 285 +#define C_Data_LSB_2_sizeof 1 + +#define C_1_Alpha_ADDR 286 +#define C_1_Alpha_ADDR_END 303 +#define C_1_Alpha_sizeof 18 + +#define C_Alpha_ADDR 304 +#define C_Alpha_ADDR_END 321 +#define C_Alpha_sizeof 18 + +#define C_GainsWRamp_ADDR 322 +#define C_GainsWRamp_ADDR_END 335 +#define C_GainsWRamp_sizeof 14 + +#define C_Gains_DL1M_ADDR 336 +#define C_Gains_DL1M_ADDR_END 339 +#define C_Gains_DL1M_sizeof 4 + +#define C_Gains_DL2M_ADDR 340 +#define C_Gains_DL2M_ADDR_END 343 +#define C_Gains_DL2M_sizeof 4 + +#define C_Gains_EchoM_ADDR 344 +#define C_Gains_EchoM_ADDR_END 345 +#define C_Gains_EchoM_sizeof 2 + +#define C_Gains_SDTM_ADDR 346 +#define C_Gains_SDTM_ADDR_END 347 +#define C_Gains_SDTM_sizeof 2 + +#define C_Gains_VxRecM_ADDR 348 +#define C_Gains_VxRecM_ADDR_END 351 +#define C_Gains_VxRecM_sizeof 4 + +#define C_Gains_ULM_ADDR 352 +#define C_Gains_ULM_ADDR_END 355 +#define C_Gains_ULM_sizeof 4 + +#define C_Gains_unused_ADDR 356 +#define C_Gains_unused_ADDR_END 357 +#define C_Gains_unused_sizeof 2 + +#define C_SDT_Coefs_ADDR 358 +#define C_SDT_Coefs_ADDR_END 366 +#define C_SDT_Coefs_sizeof 9 + +#define C_CoefASRC1_VX_ADDR 367 +#define C_CoefASRC1_VX_ADDR_END 385 +#define C_CoefASRC1_VX_sizeof 19 + +#define C_CoefASRC2_VX_ADDR 386 +#define C_CoefASRC2_VX_ADDR_END 404 +#define C_CoefASRC2_VX_sizeof 19 + +#define C_CoefASRC3_VX_ADDR 405 +#define C_CoefASRC3_VX_ADDR_END 423 +#define C_CoefASRC3_VX_sizeof 19 + +#define C_CoefASRC4_VX_ADDR 424 +#define C_CoefASRC4_VX_ADDR_END 442 +#define C_CoefASRC4_VX_sizeof 19 + +#define C_CoefASRC5_VX_ADDR 443 +#define C_CoefASRC5_VX_ADDR_END 461 +#define C_CoefASRC5_VX_sizeof 19 + +#define C_CoefASRC6_VX_ADDR 462 +#define C_CoefASRC6_VX_ADDR_END 480 +#define C_CoefASRC6_VX_sizeof 19 + +#define C_CoefASRC7_VX_ADDR 481 +#define C_CoefASRC7_VX_ADDR_END 499 +#define C_CoefASRC7_VX_sizeof 19 + +#define C_CoefASRC8_VX_ADDR 500 +#define C_CoefASRC8_VX_ADDR_END 518 +#define C_CoefASRC8_VX_sizeof 19 + +#define C_CoefASRC9_VX_ADDR 519 +#define C_CoefASRC9_VX_ADDR_END 537 +#define C_CoefASRC9_VX_sizeof 19 + +#define C_CoefASRC10_VX_ADDR 538 +#define C_CoefASRC10_VX_ADDR_END 556 +#define C_CoefASRC10_VX_sizeof 19 + +#define C_CoefASRC11_VX_ADDR 557 +#define C_CoefASRC11_VX_ADDR_END 575 +#define C_CoefASRC11_VX_sizeof 19 + +#define C_CoefASRC12_VX_ADDR 576 +#define C_CoefASRC12_VX_ADDR_END 594 +#define C_CoefASRC12_VX_sizeof 19 + +#define C_CoefASRC13_VX_ADDR 595 +#define C_CoefASRC13_VX_ADDR_END 613 +#define C_CoefASRC13_VX_sizeof 19 + +#define C_CoefASRC14_VX_ADDR 614 +#define C_CoefASRC14_VX_ADDR_END 632 +#define C_CoefASRC14_VX_sizeof 19 + +#define C_CoefASRC15_VX_ADDR 633 +#define C_CoefASRC15_VX_ADDR_END 651 +#define C_CoefASRC15_VX_sizeof 19 + +#define C_CoefASRC16_VX_ADDR 652 +#define C_CoefASRC16_VX_ADDR_END 670 +#define C_CoefASRC16_VX_sizeof 19 + +#define C_AlphaCurrent_UL_VX_ADDR 671 +#define C_AlphaCurrent_UL_VX_ADDR_END 671 +#define C_AlphaCurrent_UL_VX_sizeof 1 + +#define C_BetaCurrent_UL_VX_ADDR 672 +#define C_BetaCurrent_UL_VX_ADDR_END 672 +#define C_BetaCurrent_UL_VX_sizeof 1 + +#define C_AlphaCurrent_DL_VX_ADDR 673 +#define C_AlphaCurrent_DL_VX_ADDR_END 673 +#define C_AlphaCurrent_DL_VX_sizeof 1 + +#define C_BetaCurrent_DL_VX_ADDR 674 +#define C_BetaCurrent_DL_VX_ADDR_END 674 +#define C_BetaCurrent_DL_VX_sizeof 1 + +#define C_CoefASRC1_DL_MM_ADDR 675 +#define C_CoefASRC1_DL_MM_ADDR_END 692 +#define C_CoefASRC1_DL_MM_sizeof 18 + +#define C_CoefASRC2_DL_MM_ADDR 693 +#define C_CoefASRC2_DL_MM_ADDR_END 710 +#define C_CoefASRC2_DL_MM_sizeof 18 + +#define C_CoefASRC3_DL_MM_ADDR 711 +#define C_CoefASRC3_DL_MM_ADDR_END 728 +#define C_CoefASRC3_DL_MM_sizeof 18 + +#define C_CoefASRC4_DL_MM_ADDR 729 +#define C_CoefASRC4_DL_MM_ADDR_END 746 +#define C_CoefASRC4_DL_MM_sizeof 18 + +#define C_CoefASRC5_DL_MM_ADDR 747 +#define C_CoefASRC5_DL_MM_ADDR_END 764 +#define C_CoefASRC5_DL_MM_sizeof 18 + +#define C_CoefASRC6_DL_MM_ADDR 765 +#define C_CoefASRC6_DL_MM_ADDR_END 782 +#define C_CoefASRC6_DL_MM_sizeof 18 + +#define C_CoefASRC7_DL_MM_ADDR 783 +#define C_CoefASRC7_DL_MM_ADDR_END 800 +#define C_CoefASRC7_DL_MM_sizeof 18 + +#define C_CoefASRC8_DL_MM_ADDR 801 +#define C_CoefASRC8_DL_MM_ADDR_END 818 +#define C_CoefASRC8_DL_MM_sizeof 18 + +#define C_CoefASRC9_DL_MM_ADDR 819 +#define C_CoefASRC9_DL_MM_ADDR_END 836 +#define C_CoefASRC9_DL_MM_sizeof 18 + +#define C_CoefASRC10_DL_MM_ADDR 837 +#define C_CoefASRC10_DL_MM_ADDR_END 854 +#define C_CoefASRC10_DL_MM_sizeof 18 + +#define C_CoefASRC11_DL_MM_ADDR 855 +#define C_CoefASRC11_DL_MM_ADDR_END 872 +#define C_CoefASRC11_DL_MM_sizeof 18 + +#define C_CoefASRC12_DL_MM_ADDR 873 +#define C_CoefASRC12_DL_MM_ADDR_END 890 +#define C_CoefASRC12_DL_MM_sizeof 18 + +#define C_CoefASRC13_DL_MM_ADDR 891 +#define C_CoefASRC13_DL_MM_ADDR_END 908 +#define C_CoefASRC13_DL_MM_sizeof 18 + +#define C_CoefASRC14_DL_MM_ADDR 909 +#define C_CoefASRC14_DL_MM_ADDR_END 926 +#define C_CoefASRC14_DL_MM_sizeof 18 + +#define C_CoefASRC15_DL_MM_ADDR 927 +#define C_CoefASRC15_DL_MM_ADDR_END 944 +#define C_CoefASRC15_DL_MM_sizeof 18 + +#define C_CoefASRC16_DL_MM_ADDR 945 +#define C_CoefASRC16_DL_MM_ADDR_END 962 +#define C_CoefASRC16_DL_MM_sizeof 18 + +#define C_AlphaCurrent_DL_MM_ADDR 963 +#define C_AlphaCurrent_DL_MM_ADDR_END 963 +#define C_AlphaCurrent_DL_MM_sizeof 1 + +#define C_BetaCurrent_DL_MM_ADDR 964 +#define C_BetaCurrent_DL_MM_ADDR_END 964 +#define C_BetaCurrent_DL_MM_sizeof 1 + +#define C_DL2_L_Coefs_ADDR 965 +#define C_DL2_L_Coefs_ADDR_END 989 +#define C_DL2_L_Coefs_sizeof 25 + +#define C_DL2_R_Coefs_ADDR 990 +#define C_DL2_R_Coefs_ADDR_END 1014 +#define C_DL2_R_Coefs_sizeof 25 + +#define C_DL1_Coefs_ADDR 1015 +#define C_DL1_Coefs_ADDR_END 1039 +#define C_DL1_Coefs_sizeof 25 + +#define C_VX_8_48_BP_Coefs_ADDR 1040 +#define C_VX_8_48_BP_Coefs_ADDR_END 1052 +#define C_VX_8_48_BP_Coefs_sizeof 13 + +#define C_VX_8_48_LP_Coefs_ADDR 1053 +#define C_VX_8_48_LP_Coefs_ADDR_END 1065 +#define C_VX_8_48_LP_Coefs_sizeof 13 + +#define C_VX_48_8_LP_Coefs_ADDR 1066 +#define C_VX_48_8_LP_Coefs_ADDR_END 1078 +#define C_VX_48_8_LP_Coefs_sizeof 13 + +#define C_VX_16_48_HP_Coefs_ADDR 1079 +#define C_VX_16_48_HP_Coefs_ADDR_END 1085 +#define C_VX_16_48_HP_Coefs_sizeof 7 + +#define C_VX_16_48_LP_Coefs_ADDR 1086 +#define C_VX_16_48_LP_Coefs_ADDR_END 1098 +#define C_VX_16_48_LP_Coefs_sizeof 13 + +#define C_VX_48_16_LP_Coefs_ADDR 1099 +#define C_VX_48_16_LP_Coefs_ADDR_END 1111 +#define C_VX_48_16_LP_Coefs_sizeof 13 + +#define C_EANC_WarpCoeffs_ADDR 1112 +#define C_EANC_WarpCoeffs_ADDR_END 1113 +#define C_EANC_WarpCoeffs_sizeof 2 + +#define C_EANC_FIRcoeffs_ADDR 1114 +#define C_EANC_FIRcoeffs_ADDR_END 1134 +#define C_EANC_FIRcoeffs_sizeof 21 + +#define C_EANC_IIRcoeffs_ADDR 1135 +#define C_EANC_IIRcoeffs_ADDR_END 1151 +#define C_EANC_IIRcoeffs_sizeof 17 + +#define C_EANC_FIRcoeffs_2nd_ADDR 1152 +#define C_EANC_FIRcoeffs_2nd_ADDR_END 1172 +#define C_EANC_FIRcoeffs_2nd_sizeof 21 + +#define C_EANC_IIRcoeffs_2nd_ADDR 1173 +#define C_EANC_IIRcoeffs_2nd_ADDR_END 1189 +#define C_EANC_IIRcoeffs_2nd_sizeof 17 + +#define C_APS_DL1_coeffs1_ADDR 1190 +#define C_APS_DL1_coeffs1_ADDR_END 1198 +#define C_APS_DL1_coeffs1_sizeof 9 + +#define C_APS_DL1_M_coeffs2_ADDR 1199 +#define C_APS_DL1_M_coeffs2_ADDR_END 1201 +#define C_APS_DL1_M_coeffs2_sizeof 3 + +#define C_APS_DL1_C_coeffs2_ADDR 1202 +#define C_APS_DL1_C_coeffs2_ADDR_END 1204 +#define C_APS_DL1_C_coeffs2_sizeof 3 + +#define C_APS_DL2_L_coeffs1_ADDR 1205 +#define C_APS_DL2_L_coeffs1_ADDR_END 1213 +#define C_APS_DL2_L_coeffs1_sizeof 9 + +#define C_APS_DL2_R_coeffs1_ADDR 1214 +#define C_APS_DL2_R_coeffs1_ADDR_END 1222 +#define C_APS_DL2_R_coeffs1_sizeof 9 + +#define C_APS_DL2_L_M_coeffs2_ADDR 1223 +#define C_APS_DL2_L_M_coeffs2_ADDR_END 1225 +#define C_APS_DL2_L_M_coeffs2_sizeof 3 + +#define C_APS_DL2_R_M_coeffs2_ADDR 1226 +#define C_APS_DL2_R_M_coeffs2_ADDR_END 1228 +#define C_APS_DL2_R_M_coeffs2_sizeof 3 + +#define C_APS_DL2_L_C_coeffs2_ADDR 1229 +#define C_APS_DL2_L_C_coeffs2_ADDR_END 1231 +#define C_APS_DL2_L_C_coeffs2_sizeof 3 + +#define C_APS_DL2_R_C_coeffs2_ADDR 1232 +#define C_APS_DL2_R_C_coeffs2_ADDR_END 1234 +#define C_APS_DL2_R_C_coeffs2_sizeof 3 + +#define C_AlphaCurrent_ECHO_REF_ADDR 1235 +#define C_AlphaCurrent_ECHO_REF_ADDR_END 1235 +#define C_AlphaCurrent_ECHO_REF_sizeof 1 + +#define C_BetaCurrent_ECHO_REF_ADDR 1236 +#define C_BetaCurrent_ECHO_REF_ADDR_END 1236 +#define C_BetaCurrent_ECHO_REF_sizeof 1 + +#define C_APS_DL1_EQ_ADDR 1237 +#define C_APS_DL1_EQ_ADDR_END 1245 +#define C_APS_DL1_EQ_sizeof 9 + +#define C_APS_DL2_L_EQ_ADDR 1246 +#define C_APS_DL2_L_EQ_ADDR_END 1254 +#define C_APS_DL2_L_EQ_sizeof 9 + +#define C_APS_DL2_R_EQ_ADDR 1255 +#define C_APS_DL2_R_EQ_ADDR_END 1263 +#define C_APS_DL2_R_EQ_sizeof 9 + +#define C_Vibra2_consts_ADDR 1264 +#define C_Vibra2_consts_ADDR_END 1267 +#define C_Vibra2_consts_sizeof 4 + +#define C_Vibra1_coeffs_ADDR 1268 +#define C_Vibra1_coeffs_ADDR_END 1278 +#define C_Vibra1_coeffs_sizeof 11 + +#define C_48_96_LP_Coefs_ADDR 1279 +#define C_48_96_LP_Coefs_ADDR_END 1293 +#define C_48_96_LP_Coefs_sizeof 15 + +#define C_98_48_LP_Coefs_ADDR 1294 +#define C_98_48_LP_Coefs_ADDR_END 1308 +#define C_98_48_LP_Coefs_sizeof 15 + +#endif /* _ABECM_ADDR_H_ */ diff --git a/sound/soc/codecs/abe/abe_cof.h b/sound/soc/codecs/abe/abe_cof.h new file mode 100644 index 000000000000..f4d50d2132ff --- /dev/null +++ b/sound/soc/codecs/abe/abe_cof.h @@ -0,0 +1,9 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ diff --git a/sound/soc/codecs/abe/abe_dat.h b/sound/soc/codecs/abe/abe_dat.h new file mode 100644 index 000000000000..61cf11a356ce --- /dev/null +++ b/sound/soc/codecs/abe/abe_dat.h @@ -0,0 +1,1300 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ + +#ifndef _ABE_DAT_H_ +#define _ABE_DAT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Callbacks + */ +abe_subroutine2 callbacks[MAXCALLBACK]; /* 2 parameters subroutine pointers */ + +abe_port_t abe_port[MAXNBABEPORTS]; /* list of ABE ports */ + +const abe_port_t abe_port_init[MAXNBABEPORTS] = { +/* status, data format, drift, callback, io-task buffer 1, io-task buffer 2, + * protocol, dma offset, features, name + * - Features reseted at start + */ + + /* DMIC1 */ + { + IDLE_P, + {96000, SIX_MSB}, + NODRIFT, + NOCALLBACK, + 0, + 0, + { + SNK_P, + DMIC_PORT_PROT, + {{ + dmem_dmic, + dmem_dmic_size, + DMIC_ITER + }}, + }, + {0, 0}, + {EQDMIC1, EQDMIC3, EQDMIC3, 0}, + "DMIC", + }, + /* PDM_UL */ + { + IDLE_P, + {96000, STEREO_MSB}, + NODRIFT, + NOCALLBACK, + smem_amic, + 0, + { + SNK_P, + MCPDMUL_PORT_PROT, + {{ + dmem_amic, + dmem_amic_size, + MCPDM_UL_ITER, + }}, + }, + {0, 0}, + {EQAMIC, 0}, + "PDM_UL", + }, + /* BT_VX_UL */ + { + IDLE_P, + {8000, STEREO_MSB}, + NODRIFT, + NOCALLBACK, + smem_bt_vx_ul, + 0, + { + SNK_P, + SERIAL_PORT_PROT, + {{ + MCBSP1_DMA_TX * ATC_SIZE, + dmem_bt_vx_ul, + dmem_bt_vx_ul_size, + 1 * SCHED_LOOP_8kHz, + }}, + }, + {0, 0}, + {0}, + "BT_VX_UL", + }, + /* MM_UL */ + { + IDLE_P, + {48000, STEREO_MSB}, + NODRIFT, + NOCALLBACK, + smem_mm_ul, + 0, + { + SRC_P, + DMAREQ_PORT_PROT, + {{ + CBPr_DMA_RTX3 * ATC_SIZE, + dmem_mm_ul, + dmem_mm_ul_size, + 10 * SCHED_LOOP_48kHz, + ABE_DMASTATUS_RAW, + 1 << 3, + }}, + }, + {CIRCULAR_BUFFER_PERIPHERAL_R__3, 120}, + {UPROUTE, 0}, + "MM_UL", + }, + /* MM_UL2 */ + { + IDLE_P, + {48000, STEREO_MSB}, + NODRIFT, + NOCALLBACK, + smem_mm_ul2, + 0, + { + SRC_P, + DMAREQ_PORT_PROT, + {{ + CBPr_DMA_RTX4 * ATC_SIZE, + dmem_mm_ul2, + dmem_mm_ul2_size, + 2 * SCHED_LOOP_48kHz, + ABE_DMASTATUS_RAW, + 1 << 4, + }}, + }, + {CIRCULAR_BUFFER_PERIPHERAL_R__4, 24}, + {UPROUTE, 0}, + "MM_UL2", + }, + /* VX_UL */ + { + IDLE_P, + {8000, MONO_MSB}, + NODRIFT, + NOCALLBACK, + smem_vx_ul, + 0, + { + SRC_P, + DMAREQ_PORT_PROT, + {{ + CBPr_DMA_RTX2*ATC_SIZE, + dmem_vx_ul, + dmem_vx_ul_size / 2, + 1 * SCHED_LOOP_8kHz, + ABE_DMASTATUS_RAW, + 1 << 2, + }}, + }, + {CIRCULAR_BUFFER_PERIPHERAL_R__2, 2}, + {ASRC2, 0}, + "VX_UL", + }, + /* MM_DL */ + { + IDLE_P, + {48000, STEREO_MSB}, + NODRIFT, + NOCALLBACK, + smem_mm_dl_opp100, + 0, + { + SNK_P, + PINGPONG_PORT_PROT, + {{ + CBPr_DMA_RTX0 * ATC_SIZE, + dmem_mm_dl, + dmem_mm_dl_size, + 2 * SCHED_LOOP_48kHz, + ABE_DMASTATUS_RAW, + 1 << 0, + }}, + }, + {CIRCULAR_BUFFER_PERIPHERAL_R__0, 24}, + {ASRC3, 0}, + "MM_DL", + }, + /* VX_DL */ + { + IDLE_P, + {8000, MONO_MSB}, + NODRIFT, + NOCALLBACK, + smem_vx_dl, + 0, + { + SNK_P, + DMAREQ_PORT_PROT, + {{ + CBPr_DMA_RTX1 * ATC_SIZE, + dmem_vx_dl, + dmem_vx_dl_size, + 1 * SCHED_LOOP_8kHz, + ABE_DMASTATUS_RAW, + 1 << 1, + }}, + }, + {CIRCULAR_BUFFER_PERIPHERAL_R__1, 2}, + {ASRC1, 0}, + "VX_DL", + }, + /* TONES_DL */ + { + IDLE_P, + {48000, STEREO_MSB}, + NODRIFT, + NOCALLBACK, + smem_tones_dl, + 0, + { + SNK_P, + DMAREQ_PORT_PROT, + {{ + CBPr_DMA_RTX5 * ATC_SIZE, + dmem_tones_dl, + dmem_tones_dl_size, + 2 * SCHED_LOOP_48kHz, + ABE_DMASTATUS_RAW, + 1 << 5, + }}, + }, + {CIRCULAR_BUFFER_PERIPHERAL_R__5, 24}, + {0}, + "TONES_DL", + }, + /* VIB_DL */ + { + IDLE_P, + {24000, STEREO_MSB}, + NODRIFT, + NOCALLBACK, + smem_vib, + 0, + { + SNK_P, + DMAREQ_PORT_PROT, + {{ + CBPr_DMA_RTX6 * ATC_SIZE, + dmem_vib_dl, + dmem_vib_dl_size, + 2 * SCHED_LOOP_24kHz, + ABE_DMASTATUS_RAW, + 1 << 6, + }}, + }, + {CIRCULAR_BUFFER_PERIPHERAL_R__6, 12}, + {0}, + "VIB_DL", + }, + /* BT_VX_DL */ + { + IDLE_P, + {8000, MONO_MSB}, + NODRIFT, + NOCALLBACK, + smem_bt_vx_dl, + 0, + { + SRC_P, + SERIAL_PORT_PROT, + {{ + MCBSP1_DMA_RX * ATC_SIZE, + dmem_bt_vx_dl, + dmem_bt_vx_dl_size, + 1 * SCHED_LOOP_8kHz, + }}, + }, + {0, 0}, + {0}, + "BT_VX_DL", + }, + /* PDM_DL1 */ + { + IDLE_P, + {96000, SIX_MSB}, + NODRIFT, + NOCALLBACK, + 0, + 0, + { + SRC_P, + MCPDMDL_PORT_PROT, + {{ + dmem_mcpdm, + dmem_mcpdm_size, + }}, + }, + {0, 0}, + {MIXDL1, EQ1, APS1, MIXDL2, EQ2L, EQ2R, APS2L, APS2R, 0}, + "PDM_DL", + }, + /* MM_EXT_OUT */ + { + IDLE_P, + {48000, STEREO_MSB}, + NODRIFT, + NOCALLBACK, + smem_mm_ext_out, + 0, + { + SRC_P, + SERIAL_PORT_PROT, + {{ + MCBSP1_DMA_TX * ATC_SIZE, + dmem_mm_ext_out, + dmem_mm_ext_out_size, + 2 * SCHED_LOOP_48kHz, + }}, + }, + {0, 0}, + {0}, + "MM_EXT_OUT", + }, + /* MM_EXT_IN */ + { + IDLE_P, + {48000, STEREO_MSB}, + NODRIFT, + NOCALLBACK, + smem_mm_ext_in, + 0, + { + SRC_P, + SERIAL_PORT_PROT, + {{ + MCBSP1_DMA_RX * ATC_SIZE, + dmem_mm_ext_in, + dmem_mm_ext_in_size, + 2 * SCHED_LOOP_48kHz, + }}, + }, + {0, 0}, + {0}, + "MM_EXT_IN", + }, +#if 0 + /* SCHD_DBG_PORT */ + { + IDLE_P, + {48000, STEREO_MSB}, + NODRIFT, + NOCALLBACK, + smem_mm_trace, + 0, + { + SRC_P, + DMAREQ_PORT_PROT, + {{ + CBPr_DMA_RTX7 * ATC_SIZE, + dmem_mm_trace, + dmem_mm_trace_size, + 2 * SCHED_LOOP_48kHz, + DEFAULT_THR_WRITE, + ABE_DMASTATUS_RAW, + 1 << 4, + }}, + }, + {CIRCULAR_BUFFER_PERIPHERAL_R__7, 24}, + {SEQUENCE, CONTROL, GAINS, 0}, + "SCHD_DBG", + }, +#endif +}; + +const abe_port_info_t abe_port_info[MAXNBABEPORTS] = { + /* DMIC */ + { + ABE_OPP50, + {SUB_WRITE_PORT_GAIN, {DMIC_PORT, MUTE_GAIN, 0, 0}}, + {0, {0, 0, 0, 0}} + }, + /* PDM_UL */ + { + ABE_OPP50, + {SUB_WRITE_PORT_GAIN, {DMIC_PORT, MUTE_GAIN, 0, 0}}, + {0, {0, 0, 0, 0}} + }, + /* BT_VX_UL */ + { + ABE_OPP50, + {SUB_WRITE_PORT_GAIN, {DMIC_PORT, MUTE_GAIN, 0, 0}}, + {0, {0, 0, 0, 0}} + }, + /* MM_UL */ + { + ABE_OPP50, + {SUB_WRITE_PORT_GAIN, {DMIC_PORT, MUTE_GAIN, 0, 0}}, + {0, {0, 0, 0, 0}} + }, + /* MM_UL2 */ + { + ABE_OPP50, + {SUB_WRITE_PORT_GAIN, {DMIC_PORT, MUTE_GAIN, 0, 0}}, + {0, {0, 0, 0, 0}} + }, + /* VX_UL */ + { + ABE_OPP50, + {SUB_WRITE_PORT_GAIN, {DMIC_PORT, MUTE_GAIN, 0, 0}}, + {0, {0, 0, 0, 0}} + }, + /* MM_DL */ + { + ABE_OPP50, + {SUB_WRITE_MIXER, {MM_DL_PORT, MUTE_GAIN, 0, 0}}, + {0, {0, 0, 0, 0}} + }, + /* VX_DL */ + { + ABE_OPP50, + {SUB_WRITE_PORT_GAIN, {DMIC_PORT, MUTE_GAIN, 0, 0}}, + {0, {0, 0, 0, 0}} + }, + /* TONES_DL */ + { + ABE_OPP50, + {SUB_WRITE_PORT_GAIN, {DMIC_PORT, MUTE_GAIN, 0, 0}}, + {0, {0, 0, 0, 0}} + }, + /* VIB_DL */ + { + ABE_OPP50, + {SUB_WRITE_PORT_GAIN, {DMIC_PORT, MUTE_GAIN, 0, 0}}, + {0, {0, 0, 0, 0}} + }, + /* BT_VX_DL */ + { + ABE_OPP50, + {SUB_WRITE_PORT_GAIN, {DMIC_PORT, MUTE_GAIN, 0, 0}}, + {0, {0, 0, 0, 0}} + }, + /* PDM_DL */ + { + ABE_OPP50, + {SUB_WRITE_PORT_GAIN, {DMIC_PORT, MUTE_GAIN, 0, 0}}, + {0, {0, 0, 0, 0}} + }, + /* MM_EXT_OUT */ + { + ABE_OPP50, + {SUB_WRITE_PORT_GAIN, {DMIC_PORT, MUTE_GAIN, 0, 0}}, + {0, {0, 0, 0, 0}} + }, + /* MM_EXT_IN */ + { + ABE_OPP50, + {SUB_WRITE_PORT_GAIN, {DMIC_PORT, MUTE_GAIN, 0, 0}}, + {0, {0, 0, 0, 0}} + }, + /* + SCHD_DBG_PORT + { + ABE_OPP25, + {SUB_WRITE_PORT_GAIN, {DMIC_PORT, MUTE_GAIN, 0, 0}}, + {0, {0, 0, 0, 0}} + }, + */ +}; + +/* + * Firmware features + */ +abe_feature_t all_feature[MAXNBFEATURE]; + +const abe_feature_t all_feature_init[] = { +/* on_reset, off, read, write, status, input, output, slots, opp, name */ + /* EQ1: equalizer downlink path headset + earphone */ + { + c_feat_init_eq, + c_feat_init_eq, + c_feat_read_eq1, + c_write_eq1, + 0, + 0x1000, + 0x1010, + 2, + 0, + ABE_OPP25, + " DLEQ1", + }, + /* EQ2L: equalizer downlink path integrated handsfree left */ + { + c_feat_init_eq, + c_feat_init_eq, + c_feat_read_eq2, + c_write_eq2, + 0, + 0x1000, + 0x1010, + 2, + 0, + ABE_OPP100, + " DLEQ2L", + }, + /* EQ2R: equalizer downlink path integrated handsfree right */ + { + c_feat_init_eq, + c_feat_init_eq, + c_feat_read_eq3, + c_write_eq3, + 0, + 0x1000, + 0x1010, + 2, + 0, + ABE_OPP100, + " DLEQ2R", + }, + /* EQSDT: equalizer downlink path side-tone */ + { + c_feat_init_eq, + c_feat_init_eq, + c_feat_read_eq3, + c_write_eq3, + 0, + 0x1000, + 0x1010, + 2, + 0, + ABE_OPP50, + " EQSDT", + }, + /* EQDMIC1: SRC+equalizer uplink DMIC 1st pair */ + { + c_feat_init_eq, + c_feat_init_eq, + c_feat_read_eq3, + c_write_eq3, + 0, + 0x1000, + 0x1010, + 2, + 0, + ABE_OPP50, + " EQDMIC1", + }, + /* EQDMIC2: SRC+equalizer uplink DMIC 2nd pair */ + { + c_feat_init_eq, + c_feat_init_eq, + c_feat_read_eq3, + c_write_eq3, + 0, + 0x1000, + 0x1010, + 2, + 0, + ABE_OPP50, + " EQDMIC2", + }, + /* EQDMIC3: SRC+equalizer uplink DMIC 3rd pair */ + { + c_feat_init_eq, + c_feat_init_eq, + c_feat_read_eq3, + c_write_eq3, + 0, + 0x1000, + 0x1010, + 2, + 0, + ABE_OPP50, + " EQDMIC3", + }, + /* EQAMIC: SRC+equalizer uplink AMIC */ + { + c_feat_init_eq, + c_feat_init_eq, + c_feat_read_eq3, + c_write_eq3, + 0, + 0x1000, + 0x1010, + 2, + 0, + ABE_OPP50, + " EQAMIC", + }, + /* APS1: Acoustic protection for headset */ + { + c_feat_init_eq, + c_feat_init_eq, + c_feat_read_eq3, + c_write_eq3, + 0, + 0x1000, + 0x1010, + 2, + 0, + ABE_OPP25, + " APS1", + }, + /* APS2: acoustic protection high-pass filter for handsfree left */ + { + c_feat_init_eq, + c_feat_init_eq, + c_feat_read_eq3, + c_write_eq3, + 0, + 0x1000, + 0x1010, + 2, + 0, + ABE_OPP100, + " APS2", + }, + /* APS3: acoustic protection high-pass filter for handsfree right */ + { + c_feat_init_eq, + c_feat_init_eq, + c_feat_read_eq3, + c_write_eq3, + 0, + 0x1000, + 0x1010, + 2, + 0, + ABE_OPP100, + " APS3", + }, + /* ASRC1: asynchronous sample-rate-converter for the downlink voice path */ + { + c_feat_init_eq, + c_feat_init_eq, + c_feat_read_eq3, + c_write_eq3, + 0, + 0x1000, + 0x1010, + 2, + 0, + ABE_OPP50, + " ASRC_VXDL" + }, + /* ASRC2: asynchronous sample-rate-converter for the uplink voice path */ + { + c_feat_init_eq, + c_feat_init_eq, + c_feat_read_eq3, + c_write_eq3, + 0, + 0x1000, + 0x1010, + 2, + 0, + ABE_OPP50, + " ASRC_VXUL", + }, + /* ASRC3: asynchronous sample-rate-converter for the multimedia player */ + { + c_feat_init_eq, + c_feat_init_eq, + c_feat_read_eq3, + c_write_eq3, + 0, + 0x1000, + 0x1010, + 2, + 0, + ABE_OPP100, + " ASRC_MMDL", + }, + /* ASRC4: asynchronous sample-rate-converter for the echo reference */ + { + c_feat_init_eq, + c_feat_init_eq, + c_feat_read_eq3, + c_write_eq3, + 0, + 0x1000, + 0x1010, + 2, + 0, + ABE_OPP50, + " ASRC_ECHO", + }, + /* MXDL1: mixer of the headset and earphone path */ + { + c_feat_init_eq, + c_feat_init_eq, + c_feat_read_eq3, + c_write_eq3, + 0, + 0x1000, + 0x1010, + 2, + 0, + ABE_OPP25, + " MIX_DL1", + }, + /* MXDL2: mixer of the hands-free path */ + { + c_feat_init_eq, + c_feat_init_eq, + c_feat_read_eq3, + c_write_eq3, + 0, + 0x1000, + 0x1010, + 2, + 0, + ABE_OPP100, + " MIX_DL2", + }, + /* MXAUDUL: mixer for uplink tone mixer */ + { + c_feat_init_eq, + c_feat_init_eq, + c_feat_read_eq3, + c_write_eq3, + 0, + 0x1000, + 0x1010, + 2, + 0, + ABE_OPP50, + " MXSAUDUL", + }, + /* MXVXREC: mixer for voice recording */ + { + c_feat_init_eq, + c_feat_init_eq, + c_feat_read_eq3, + c_write_eq3, + 0, + 0x1000, + 0x1010, + 2, + 0, + ABE_OPP50, + " MXVXREC", + }, + /* MXSDT: mixer for side-tone */ + { + c_feat_init_eq, + c_feat_init_eq, + c_feat_read_eq3, + c_write_eq3, + 0, + 0x1000, + 0x1010, + 2, + 0, + ABE_OPP50, + " MIX_SDT", + }, + /* MXECHO: mixer for echo reference */ + { + c_feat_init_eq, + c_feat_init_eq, + c_feat_read_eq3, + c_write_eq3, + 0, + 0x1000, + 0x1010, + 2, + 0, + ABE_OPP50, + " MIX_ECHO", + }, + /* UPROUTE: router of the uplink path */ + { + c_feat_init_eq, + c_feat_init_eq, + c_feat_read_eq3, + c_write_eq3, + 0, + 0x1000, + 0x1010, + 2, + 0, + ABE_OPP50, + " DLEQ3", + }, + /* GAINS: all gains */ + { + c_feat_init_eq, + c_feat_init_eq, + c_feat_read_eq3, + c_write_eq3, + 0, + 0x1000, + 0x1010, + 2, + 0, + ABE_OPP25, + " DLEQ3", + }, + /* EANC: active noise canceller */ + { + c_feat_init_eq, + c_feat_init_eq, + c_feat_read_eq3, + c_write_eq3, + 0, + 0x1000, + 0x1010, + 2, + 0, + ABE_OPP100, + " DLEQ3", + }, + /* SEQ: sequencing queue of micro tasks */ + { + c_feat_init_eq, + c_feat_init_eq, + c_feat_read_eq3, + c_write_eq3, + 0, + 0x1000, + 0x1010, + 2, + 0, + ABE_OPP25, + " DLEQ3", + }, + /* CTL: Phoenix control queue through McPDM */ + { + c_feat_init_eq, + c_feat_init_eq, + c_feat_read_eq3, + c_write_eq3, + 0, + 0x1000, + 0x1010, + 2, + 0, + ABE_OPP25, + " DLEQ3", + }, +}; + +/* + * Memory mapping of DMEM FIFOs + */ +abe_uint32 abe_map_dmem[LAST_PORT_ID]; /* DMEM port map */ +abe_uint32 abe_map_dmem_secondary[LAST_PORT_ID]; +abe_uint32 abe_map_dmem_size[LAST_PORT_ID]; /* DMEM port buffer sizes */ + +/* + * AESS/ATC destination and source address translation + * (except McASPs) from the original 64bits words address + */ +const abe_uint32 abe_atc_dstid[ABE_ATC_DESC_SIZE >> 3] = { + /* DMA_0 DMIC PDM_DL PDM_UL McB1TX McB1RX McB2TX McB2RX 0-7 */ + 0, 0, 12, 0, 1, 0, 2, 0, + /* McB3TX McB3RX SLIMT0 SLIMT1 SLIMT2 SLIMT3 SLIMT4 SLIMT5 8-15 */ + 3, 0, 4, 5, 6, 7, 8, 9, + /* SLIMT6 SLIMT7 SLIMR0 SLIMR1 SLIMR2 SLIMR3 SLIMR4 SLIMR5 16-23 */ + 10, 11, 0, 0, 0, 0, 0, 0, + /* SLIMR6 SLIMR7 McASP1X ------ ------ McASP1R ----- ------ 24-31 */ + 0, 0, 14, 0, 0, 0, 0, 0, + /* CBPrT0 CBPrT1 CBPrT2 CBPrT3 CBPrT4 CBPrT5 CBPrT6 CBPrT7 32-39 */ + 63, 63, 63, 63, 63, 63, 63, 63, + /* CBP_T0 CBP_T1 CBP_T2 CBP_T3 CBP_T4 CBP_T5 CBP_T6 CBP_T7 40-47 */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* CBP_T8 CBP_T9 CBP_T10 CBP_T11 CBP_T12 CBP_T13 CBP_T14 CBP_T15 48-63 */ + 0, 0, 0, 0, 0, 0, 0, 0, +}; + +const abe_uint32 abe_atc_srcid[ABE_ATC_DESC_SIZE >> 3] = { + /* DMA_0 DMIC PDM_DL PDM_UL McB1TX McB1RX McB2TX McB2RX 0-7 */ + 0, 12, 0, 13, 0, 1, 0, 2, + /* McB3TX McB3RX SLIMT0 SLIMT1 SLIMT2 SLIMT3 SLIMT4 SLIMT5 8-15 */ + 0, 3, 0, 0, 0, 0, 0, 0, + /* SLIMT6 SLIMT7 SLIMR0 SLIMR1 SLIMR2 SLIMR3 SLIMR4 SLIMR5 16-23 */ + 0, 0, 4, 5, 6, 7, 8, 9, + /* SLIMR6 SLIMR7 McASP1X ------ ------ McASP1R ------ ------ 24-31 */ + 10, 11, 0, 0, 0, 14, 0, 0, + /* CBPrT0 CBPrT1 CBPrT2 CBPrT3 CBPrT4 CBPrT5 CBPrT6 CBPrT7 32-39 */ + 63, 63, 63, 63, 63, 63, 63, 63, + /* CBP_T0 CBP_T1 CBP_T2 CBP_T3 CBP_T4 CBP_T5 CBP_T6 CBP_T7 40-47 */ + 0, 0, 0, 0, 0, 0, 0, 0, + /* CBP_T8 CBP_T9 CBP_T10 CBP_T11 CBP_T12 CBP_T13 CBP_T14 CBP_T15 48-63 */ + 0, 0, 0, 0, 0, 0, 0, 0, +}; + +/* + * Router tables + */ +const abe_router_t abe_router_ul_table_preset[NBROUTE_CONFIG][NBROUTE_UL] = { + /* Voice uplink with Phoenix microphones - Uproute config_dmic1 */ + { + /* 0 .. 9 = MM_UL */ + DMIC1_L_labelID, + DMIC1_R_labelID, + DMIC2_L_labelID, + DMIC2_R_labelID, + DMIC3_L_labelID, + DMIC3_R_labelID, + ZERO_labelID, + ZERO_labelID, + ZERO_labelID, + ZERO_labelID, + /* 10 .. 11 = MM_UL2 */ + AMIC_L_labelID, + AMIC_R_labelID, + /* 12 .. 13 = VX_UL */ + AMIC_L_labelID, + AMIC_R_labelID, + /* 14 .. 15 = RESERVED */ + ZERO_labelID, + ZERO_labelID, + }, + /* Voice uplink with the first DMIC pair - Uproute config_dmic2 */ + { + /* 0 .. 9 = MM_UL */ + DMIC2_L_labelID, + DMIC2_R_labelID, + DMIC3_L_labelID, + DMIC3_R_labelID, + DMIC1_L_labelID, + DMIC1_R_labelID, + ZERO_labelID, + ZERO_labelID, + ZERO_labelID, + ZERO_labelID, + /* 10 .. 11 = MM_UL2 */ + DMIC1_L_labelID, + DMIC1_R_labelID, + /* 12 .. 13 = VX_UL */ + DMIC1_L_labelID, + DMIC1_R_labelID, + /* 14 .. 15 = RESERVED */ + ZERO_labelID, + ZERO_labelID, + }, + /* Voice uplink with the second DMIC pair - Uproute config_dmic3 */ + { + /* 0 .. 9 = MM_UL */ + DMIC3_L_labelID, + DMIC3_R_labelID, + DMIC1_L_labelID, + DMIC1_R_labelID, + DMIC2_L_labelID, + DMIC2_R_labelID, + ZERO_labelID, + ZERO_labelID, + ZERO_labelID, + ZERO_labelID, + /* 10 .. 11 = MM_UL2 */ + DMIC2_L_labelID, + DMIC2_R_labelID, + /* 12 .. 13 = VX_UL */ + DMIC2_L_labelID, + DMIC2_R_labelID, + /* 14 .. 15 = RESERVED */ + ZERO_labelID, + ZERO_labelID, + }, + /* VOICE UPLINK WITH THE LAST DMIC PAIR - UPROUTE_CONFIG_DMIC3 */ + { + AMIC_L_labelID, /* 0 .. 9 = MM_UL */ + AMIC_R_labelID, + DMIC2_L_labelID, + DMIC2_R_labelID, + DMIC3_L_labelID, + DMIC3_R_labelID, + ZERO_labelID, + ZERO_labelID, + ZERO_labelID, + ZERO_labelID, + DMIC3_L_labelID, + DMIC3_R_labelID, /* 10 .. 11 = MM_UL2 */ + DMIC3_L_labelID, + DMIC3_R_labelID, /* 12 .. 13 = VX_UL */ + ZERO_labelID, + ZERO_labelID, /* 14 .. 15 = RESERVED */ + }, + /* VOICE UPLINK WITH THE BT - UPROUTE_CONFIG_BT */ + { + BT_UL_L_labelID, + BT_UL_R_labelID, + DMIC2_L_labelID, + DMIC2_R_labelID, /* 0 .. 9 = MM_UL */ + DMIC3_L_labelID, + DMIC3_R_labelID, + DMIC1_L_labelID, + DMIC1_R_labelID, + ZERO_labelID, + ZERO_labelID, + AMIC_L_labelID, + AMIC_R_labelID, /* 10 .. 11 = MM_UL2 */ + BT_UL_L_labelID, + BT_UL_R_labelID, /* 12 .. 13 = VX_UL */ + ZERO_labelID, + ZERO_labelID, /* 14 .. 15 = RESERVED */ + }, +}; + +/* all default routing configurations */ +abe_router_t abe_router_ul_table[NBROUTE_CONFIG_MAX][NBROUTE_UL]; + +/* + * ABE_GLOBAL DATA + */ +/* flag, indicates the allowed control of Phoenix through McPDM slot 6 */ +abe_uint32 abe_global_mcpdm_control; +abe_event_id abe_current_event_id; + +/* + * ABE SUBROUTINES AND SEQUENCES + */ + +/* +const abe_seq_t abe_seq_array [MAXNBSEQUENCE] [MAXSEQUENCESTEPS] = + {{0, 0, 0, 0}, {-1, 0, 0, 0}}, + {{0, 0, 0, 0}, {-1, 0, 0, 0}}, +const seq_t setup_hw_sequence2 [ ] = { 0, C_AE_FUNC1, 0, 0, 0, 0, + -1, C_CALLBACK1, 0, 0, 0, 0 }; + +const abe_subroutine2 abe_sub_array [MAXNBSUBROUTINE] = + abe_init_atc, 0, 0, + abe_init_atc, 0, 0, + + typedef double (*PtrFun) (double); +PtrFun pFun; +pFun = sin; +y = (* pFun) (x); +*/ + +const abe_sequence_t seq_null = { + NOMASK, + { + CL_M1, + 0, + {0, 0, 0, 0}, + 0, + }, + { + CL_M1, + 0, + {0, 0, 0, 0}, + 0, + }, +}; + +/* table of new subroutines called in the sequence */ +abe_subroutine2 abe_all_subsubroutine[MAXNBSUBROUTINE]; +/* number of parameters per calls */ +abe_uint32 abe_all_subsubroutine_nparam[MAXNBSUBROUTINE]; +/* index of the subroutine */ +abe_uint32 abe_subroutine_id[MAXNBSUBROUTINE]; +abe_uint32* abe_all_subroutine_params[MAXNBSUBROUTINE]; +abe_uint32 abe_subroutine_write_pointer; + +/* table of all sequences */ +abe_sequence_t abe_all_sequence[MAXNBSEQUENCE]; + +abe_uint32 abe_sequence_write_pointer; + +/* current number of pending sequences (avoids to look in the table) */ +abe_uint32 abe_nb_pending_sequences; + +/* pending sequences due to ressource collision */ +abe_uint32 abe_pending_sequences[MAXNBSEQUENCE]; + +/* mask of unsharable ressources among other sequences */ +abe_uint32 abe_global_sequence_mask; + +/* table of active sequences */ +abe_seq_t abe_active_sequence[MAXACTIVESEQUENCE][MAXSEQUENCESTEPS]; + +/* index of the plugged subroutine doing ping-pong cache-flush DMEM accesses */ +abe_uint32 abe_irq_pingpong_player_id; +/* index of the plugged subroutine doing acoustics protection adaptation */ +abe_uint32 abe_irq_aps_adaptation_id; + +/* base addresses of the ping pong buffers in bytes addresses */ +abe_uint32 abe_base_address_pingpong[MAX_PINGPONG_BUFFERS]; + +/* size of each ping/pong buffers */ +abe_uint32 abe_size_pingpong; + +/* number of ping/pong buffer being used */ +abe_uint32 abe_nb_pingpong; + +/* + * ABE CONST AREA FOR PARAMETERS TRANSLATION + */ +const abe_uint32 abe_db2lin_table [sizeof_db2lin_table] = { + 0x00000000, /* SMEM coding of -120 dB */ + 0x00000000, /* SMEM coding of -119 dB */ + 0x00000000, /* SMEM coding of -118 dB */ + 0x00000000, /* SMEM coding of -117 dB */ + 0x00000000, /* SMEM coding of -116 dB */ + 0x00000000, /* SMEM coding of -115 dB */ + 0x00000000, /* SMEM coding of -114 dB */ + 0x00000000, /* SMEM coding of -113 dB */ + 0x00000000, /* SMEM coding of -112 dB */ + 0x00000000, /* SMEM coding of -111 dB */ + 0x00000000, /* SMEM coding of -110 dB */ + 0x00000000, /* SMEM coding of -109 dB */ + 0x00000001, /* SMEM coding of -108 dB */ + 0x00000001, /* SMEM coding of -107 dB */ + 0x00000001, /* SMEM coding of -106 dB */ + 0x00000001, /* SMEM coding of -105 dB */ + 0x00000001, /* SMEM coding of -104 dB */ + 0x00000001, /* SMEM coding of -103 dB */ + 0x00000002, /* SMEM coding of -102 dB */ + 0x00000002, /* SMEM coding of -101 dB */ + 0x00000002, /* SMEM coding of -100 dB */ + 0x00000002, /* SMEM coding of -99 dB */ + 0x00000003, /* SMEM coding of -98 dB */ + 0x00000003, /* SMEM coding of -97 dB */ + 0x00000004, /* SMEM coding of -96 dB */ + 0x00000004, /* SMEM coding of -95 dB */ + 0x00000005, /* SMEM coding of -94 dB */ + 0x00000005, /* SMEM coding of -93 dB */ + 0x00000006, /* SMEM coding of -92 dB */ + 0x00000007, /* SMEM coding of -91 dB */ + 0x00000008, /* SMEM coding of -90 dB */ + 0x00000009, /* SMEM coding of -89 dB */ + 0x0000000A, /* SMEM coding of -88 dB */ + 0x0000000B, /* SMEM coding of -87 dB */ + 0x0000000D, /* SMEM coding of -86 dB */ + 0x0000000E, /* SMEM coding of -85 dB */ + 0x00000010, /* SMEM coding of -84 dB */ + 0x00000012, /* SMEM coding of -83 dB */ + 0x00000014, /* SMEM coding of -82 dB */ + 0x00000017, /* SMEM coding of -81 dB */ + 0x0000001A, /* SMEM coding of -80 dB */ + 0x0000001D, /* SMEM coding of -79 dB */ + 0x00000021, /* SMEM coding of -78 dB */ + 0x00000025, /* SMEM coding of -77 dB */ + 0x00000029, /* SMEM coding of -76 dB */ + 0x0000002E, /* SMEM coding of -75 dB */ + 0x00000034, /* SMEM coding of -74 dB */ + 0x0000003A, /* SMEM coding of -73 dB */ + 0x00000041, /* SMEM coding of -72 dB */ + 0x00000049, /* SMEM coding of -71 dB */ + 0x00000052, /* SMEM coding of -70 dB */ + 0x0000005D, /* SMEM coding of -69 dB */ + 0x00000068, /* SMEM coding of -68 dB */ + 0x00000075, /* SMEM coding of -67 dB */ + 0x00000083, /* SMEM coding of -66 dB */ + 0x00000093, /* SMEM coding of -65 dB */ + 0x000000A5, /* SMEM coding of -64 dB */ + 0x000000B9, /* SMEM coding of -63 dB */ + 0x000000D0, /* SMEM coding of -62 dB */ + 0x000000E9, /* SMEM coding of -61 dB */ + 0x00000106, /* SMEM coding of -60 dB */ + 0x00000126, /* SMEM coding of -59 dB */ + 0x0000014A, /* SMEM coding of -58 dB */ + 0x00000172, /* SMEM coding of -57 dB */ + 0x0000019F, /* SMEM coding of -56 dB */ + 0x000001D2, /* SMEM coding of -55 dB */ + 0x0000020B, /* SMEM coding of -54 dB */ + 0x0000024A, /* SMEM coding of -53 dB */ + 0x00000292, /* SMEM coding of -52 dB */ + 0x000002E2, /* SMEM coding of -51 dB */ + 0x0000033C, /* SMEM coding of -50 dB */ + 0x000003A2, /* SMEM coding of -49 dB */ + 0x00000413, /* SMEM coding of -48 dB */ + 0x00000492, /* SMEM coding of -47 dB */ + 0x00000521, /* SMEM coding of -46 dB */ + 0x000005C2, /* SMEM coding of -45 dB */ + 0x00000676, /* SMEM coding of -44 dB */ + 0x0000073F, /* SMEM coding of -43 dB */ + 0x00000822, /* SMEM coding of -42 dB */ + 0x00000920, /* SMEM coding of -41 dB */ + 0x00000A3D, /* SMEM coding of -40 dB */ + 0x00000B7D, /* SMEM coding of -39 dB */ + 0x00000CE4, /* SMEM coding of -38 dB */ + 0x00000E76, /* SMEM coding of -37 dB */ + 0x0000103A, /* SMEM coding of -36 dB */ + 0x00001235, /* SMEM coding of -35 dB */ + 0x0000146E, /* SMEM coding of -34 dB */ + 0x000016EC, /* SMEM coding of -33 dB */ + 0x000019B8, /* SMEM coding of -32 dB */ + 0x00001CDC, /* SMEM coding of -31 dB */ + 0x00002061, /* SMEM coding of -30 dB */ + 0x00002455, /* SMEM coding of -29 dB */ + 0x000028C4, /* SMEM coding of -28 dB */ + 0x00002DBD, /* SMEM coding of -27 dB */ + 0x00003352, /* SMEM coding of -26 dB */ + 0x00003995, /* SMEM coding of -25 dB */ + 0x0000409C, /* SMEM coding of -24 dB */ + 0x0000487E, /* SMEM coding of -23 dB */ + 0x00005156, /* SMEM coding of -22 dB */ + 0x00005B43, /* SMEM coding of -21 dB */ + 0x00006666, /* SMEM coding of -20 dB */ + 0x000072E5, /* SMEM coding of -19 dB */ + 0x000080E9, /* SMEM coding of -18 dB */ + 0x000090A4, /* SMEM coding of -17 dB */ + 0x0000A24B, /* SMEM coding of -16 dB */ + 0x0000B618, /* SMEM coding of -15 dB */ + 0x0000CC50, /* SMEM coding of -14 dB */ + 0x0000E53E, /* SMEM coding of -13 dB */ + 0x00010137, /* SMEM coding of -12 dB */ + 0x0001209A, /* SMEM coding of -11 dB */ + 0x000143D1, /* SMEM coding of -10 dB */ + 0x00016B54, /* SMEM coding of -9 dB */ + 0x000197A9, /* SMEM coding of -8 dB */ + 0x0001C967, /* SMEM coding of -7 dB */ + 0x00020137, /* SMEM coding of -6 dB */ + 0x00023FD6, /* SMEM coding of -5 dB */ + 0x00028619, /* SMEM coding of -4 dB */ + 0x0002D4EF, /* SMEM coding of -3 dB */ + 0x00032D64, /* SMEM coding of -2 dB */ + 0x000390A4, /* SMEM coding of -1 dB */ + 0x00040000, /* SMEM coding of 0 dB */ + 0x00047CF2, /* SMEM coding of 1 dB */ + 0x00050923, /* SMEM coding of 2 dB */ + 0x0005A670, /* SMEM coding of 3 dB */ + 0x000656EE, /* SMEM coding of 4 dB */ + 0x00071CF5, /* SMEM coding of 5 dB */ + 0x0007FB26, /* SMEM coding of 6 dB */ + 0x0008F473, /* SMEM coding of 7 dB */ + 0x000A0C2B, /* SMEM coding of 8 dB */ + 0x000B4606, /* SMEM coding of 9 dB */ + 0x000CA62C, /* SMEM coding of 10 dB */ + 0x000E314A, /* SMEM coding of 11 dB */ + 0x000FEC9E, /* SMEM coding of 12 dB */ + 0x0011DE0A, /* SMEM coding of 13 dB */ + 0x00140C28, /* SMEM coding of 14 dB */ + 0x00167E60, /* SMEM coding of 15 dB */ + 0x00193D00, /* SMEM coding of 16 dB */ + 0x001C515D, /* SMEM coding of 17 dB */ + 0x001FC5EB, /* SMEM coding of 18 dB */ + 0x0023A668, /* SMEM coding of 19 dB */ + 0x00280000, /* SMEM coding of 20 dB */ + 0x002CE178, /* SMEM coding of 21 dB */ + 0x00325B65, /* SMEM coding of 22 dB */ + 0x00388062, /* SMEM coding of 23 dB */ + 0x003F654E, /* SMEM coding of 24 dB */ + 0x00472194, /* SMEM coding of 25 dB */ + 0x004FCF7C, /* SMEM coding of 26 dB */ + 0x00598C81, /* SMEM coding of 27 dB */ + 0x006479B7, /* SMEM coding of 28 dB */ + 0x0070BC3D, /* SMEM coding of 29 dB */ + 0x007E7DB9, /* SMEM coding of 30 dB */ +}; + + +const abe_uint32 abe_sin_table [] = { 0 }; +/* + * ABE_DEBUG DATA + */ + +/* + * IRQ and trace pointer in DMEM: + * FW updates a write pointer at "MCU_IRQ_FIFO_ptr_labelID", the read pointer is in HAL + */ +abe_uint32 abe_irq_dbg_read_ptr; + +/* General circular buffer used to trace APIs calls and AE activity */ +abe_uint32 abe_dbg_activity_log[DBG_LOG_SIZE]; +abe_uint32 abe_dbg_activity_log_write_pointer; +abe_uint32 abe_dbg_mask; + +/* Global variable holding parameter errors */ +abe_uint32 abe_dbg_param; + +/* Output of messages selector */ +abe_uint32 abe_dbg_output; + +/* Last parameters */ +#define SIZE_PARAM 10 + +abe_uint32 param1[SIZE_PARAM]; +abe_uint32 param2[SIZE_PARAM]; +abe_uint32 param3[SIZE_PARAM]; +abe_uint32 param4[SIZE_PARAM]; +abe_uint32 param5[SIZE_PARAM]; + +volatile abe_uint32 just_to_avoid_the_many_warnings; +volatile abe_gain_t just_to_avoid_the_many_warnings_abe_gain_t; +volatile abe_ramp_t just_to_avoid_the_many_warnings_abe_ramp_t; +volatile abe_dma_t just_to_avoid_the_many_warnings_abe_dma_t; +volatile abe_port_id just_to_avoid_the_many_warnings_abe_port_id; +volatile abe_millis_t just_to_avoid_the_many_warnings_abe_millis_t; +volatile abe_micros_t just_to_avoid_the_many_warnings_abe_micros_t; +volatile abe_patch_rev just_to_avoid_the_many_warnings_abe_patch_rev; +volatile abe_sequence_t just_to_avoid_the_many_warnings_abe_sequence_t; +volatile abe_ana_port_id just_to_avoid_the_many_warnings_abe_ana_port_id; +volatile abe_time_stamp_t just_to_avoid_the_many_warnings_abe_time_stamp_t; +volatile abe_data_format_t just_to_avoid_the_many_warnings_abe_data_format_t; +volatile abe_port_protocol_t just_to_avoid_the_many_warnings_abe_port_protocol_t; +volatile abe_router_t just_to_avoid_the_many_warnings_abe_router_t; +volatile abe_router_id just_to_avoid_the_many_warnings_abe_router_id; + +#ifdef __cplusplus +} +#endif + +#endif /* _ABE_DAT_H_ */ diff --git a/sound/soc/codecs/abe/abe_dbg.c b/sound/soc/codecs/abe/abe_dbg.c new file mode 100644 index 000000000000..6ec44640edb1 --- /dev/null +++ b/sound/soc/codecs/abe/abe_dbg.c @@ -0,0 +1,103 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ + +#include "abe_main.h" + +/* + * ABE_DBG_LOG + * + * Parameter : + * x : data to be logged + * + * abe_dbg_activity_log : global circular buffer holding the data + * abe_dbg_activity_log_write_pointer : circular write pointer + * + * Operations : + * saves data in the log file + * + * Return value : + * none + */ +void abe_dbg_log_copy(abe_uint32 x) +{ + abe_dbg_activity_log[abe_dbg_activity_log_write_pointer] = x; + + if (abe_dbg_activity_log_write_pointer == (DBG_LOG_SIZE - 1)) + abe_dbg_activity_log_write_pointer = 0; + else + abe_dbg_activity_log_write_pointer ++; +} + +void abe_dbg_log(abe_uint32 x) +{ + abe_time_stamp_t t; + abe_millis_t m; + abe_micros_t time; + + abe_read_global_counter(&t, &m);/* extract AE timer */ + abe_read_sys_clock(&time); /* extract system timer */ + + abe_dbg_log_copy(x); /* dump data */ + abe_dbg_log_copy(time); + abe_dbg_log_copy(t); + abe_dbg_log_copy(m); +} + +/* + * ABE_DEBUG_OUTPUT_PINS + * + * Parameter : + * x : d + * + * Operations : + * set the debug output pins of AESS + * + * Return value : + * + */ +void abe_debug_output_pins(abe_uint32 x) +{ + just_to_avoid_the_many_warnings = x; +} + + +/* + * ABE_DBG_ERROR_LOG + * + * Parameter : + * x : d + * + * Operations : + * log the error codes + * + * Return value : + * + */ +void abe_dbg_error_log(abe_uint32 x) +{ + just_to_avoid_the_many_warnings = x; +} + +/* + * ABE_DEBUGGER + * + * Parameter : + * x : d + * + * Operations : + * + * + * Return value : + * + */ +void abe_debugger(abe_uint32 x) +{ + just_to_avoid_the_many_warnings = x; +} diff --git a/sound/soc/codecs/abe/abe_dbg.h b/sound/soc/codecs/abe/abe_dbg.h new file mode 100644 index 000000000000..daecd9a7c374 --- /dev/null +++ b/sound/soc/codecs/abe/abe_dbg.h @@ -0,0 +1,167 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ + +#include "abe_main.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * DEFINE + */ +#define NO_OUTPUT 0 +#define TERMINAL_OUTPUT 1 +#define LINE_OUTPUT 2 +#define DEBUG_TRACE_OUTPUT 3 + +#define DBG_LOG_SIZE 1000 + +#define DBG_BITFIELD_OFFSET 8 + +#define DBG_API_CALLS 0 +#define DBG_MAPI (1L << (DBG_API_CALLS + DBG_BITFIELD_OFFSET)) + +#define DBG_EXT_DATA_ACCESS 1 +#define DBG_MDATA (1L << (DBG_EXT_DATA_ACCESS + DBG_BITFIELD_OFFSET)) + +#define DBG_ERR_CODES 2 +#define DBG_MERR (1L << (DBG_API_CALLS + DBG_BITFIELD_OFFSET)) + +/* + * IDs used for traces + */ +#define ID_RESET_HAL (1 + DBG_MAPI) +#define ID_LOAD_FW (2 + DBG_MAPI) +#define ID_DEFAULT_CONFIGURATION (3 + DBG_MAPI) +#define ID_IRQ_PROCESSING (4 + DBG_MAPI) +#define ID_EVENT_GENERATOR_SWITCH (5 + DBG_MAPI) +#define ID_SET_MEMORY_CONFIG (6 + DBG_MAPI) +#define ID_READ_LOWEST_OPP (7 + DBG_MAPI) +#define ID_SET_OPP_PROCESSING (8 + DBG_MAPI) +#define ID_SET_PING_PONG_BUFFER (9 + DBG_MAPI) +#define ID_PLUG_SUBROUTINE (10 + DBG_MAPI) +#define ID_UNPLUG_SUBROUTINE (11 + DBG_MAPI) +#define ID_PLUG_SEQUENCE (12 + DBG_MAPI) +#define ID_LAUNCH_SEQUENCE (13 + DBG_MAPI) +#define ID_LAUNCH_SEQUENCE_PARAM (14 + DBG_MAPI) +#define ID_SET_ANALOG_CONTROL (15 + DBG_MAPI) +#define ID_READ_ANALOG_GAIN_DL (16 + DBG_MAPI) +#define ID_READ_ANALOG_GAIN_UL (17 + DBG_MAPI) +#define ID_ENABLE_DYN_UL_GAIN (18 + DBG_MAPI) +#define ID_DISABLE_DYN_UL_GAIN (19 + DBG_MAPI) +#define ID_ENABLE_DYN_EXTENSION (20 + DBG_MAPI) +#define ID_DISABLE_DYN_EXTENSION (21 + DBG_MAPI) +#define ID_NOTIFY_ANALOG_GAIN_CHANGED (22 + DBG_MAPI) +#define ID_RESET_PORT (23 + DBG_MAPI) +#define ID_READ_REMAINING_DATA (24 + DBG_MAPI) +#define ID_DISABLE_DATA_TRANSFER (25 + DBG_MAPI) +#define ID_ENABLE_DATA_TRANSFER (26 + DBG_MAPI) +#define ID_READ_GLOBAL_COUNTER (27 + DBG_MAPI) +#define ID_SET_DMIC_FILTER (28 + DBG_MAPI) +#define ID_WRITE_PORT_DESCRIPTOR (29 + DBG_MAPI) +#define ID_READ_PORT_DESCRIPTOR (30 + DBG_MAPI) +#define ID_READ_PORT_ADDRESS (31 + DBG_MAPI) +#define ID_WRITE_PORT_GAIN (32 + DBG_MAPI) +#define ID_WRITE_HEADSET_OFFSET (33 + DBG_MAPI) +#define ID_READ_GAIN_RANGES (34 + DBG_MAPI) +#define ID_WRITE_EQUALIZER (35 + DBG_MAPI) +#define ID_WRITE_ASRC (36 + DBG_MAPI) +#define ID_WRITE_APS (37 + DBG_MAPI) +#define ID_WRITE_MIXER (38 + DBG_MAPI) +#define ID_WRITE_EANC (39 + DBG_MAPI) +#define ID_WRITE_ROUTER (40 + DBG_MAPI) +#define ID_READ_PORT_GAIN (41 + DBG_MAPI) +#define ID_READ_ASRC (42 + DBG_MAPI) +#define ID_READ_APS (43 + DBG_MAPI) +#define ID_READ_APS_ENERGY (44 + DBG_MAPI) +#define ID_READ_MIXER (45 + DBG_MAPI) +#define ID_READ_EANC (46 + DBG_MAPI) +#define ID_READ_ROUTER (47 + DBG_MAPI) +#define ID_READ_DEBUG_TRACE (48 + DBG_MAPI) +#define ID_SET_DEBUG_TRACE (49 + DBG_MAPI) +#define ID_SET_DEBUG_PINS (50 + DBG_MAPI) +#define ID_CALL_SUBROUTINE (51 + DBG_MAPI) + +/* + * IDs used for error codes + */ +#define NOERR 0 +#define ABE_SET_MEMORY_CONFIG_ERR (1 + DBG_MERR) +#define ABE_BLOCK_COPY_ERR (2 + DBG_MERR) +#define ABE_SEQTOOLONG (3 + DBG_MERR) +#define ABE_BADSAMPFORMAT (4 + DBG_MERR) +#define ABE_SET_ATC_MEMORY_CONFIG_ERR (5 + DBG_MERR) +#define ABE_PROTOCOL_ERROR (6 + DBG_MERR) +#define ABE_PARAMETER_ERROR (7 + DBG_MERR) +#define ABE_PORT_REPROGRAMMING (8 + DBG_MERR) /* port programmed while still running */ +#define ABE_READ_USE_CASE_OPP_ERR (9 + DBG_MERR) +#define ABE_PARAMETER_OVERFLOW (10 + DBG_MERR) + +/* + * IDs used for error codes + */ +#define ERR_LIB (1 << 1) /* error in the LIB.C file */ +#define ERR_API (1 << 2) /* error in the API.C file */ +#define ERR_INI (1 << 3) /* error in the INI.C file */ +#define ERR_SEQ (1 << 4) /* error in the SEQ.C file */ +#define ERR_DBG (1 << 5) /* error in the DBG.C file */ +#define ERR_EXT (1 << 6) /* error in the EXT.C file */ + +/* + * MACROS + */ +#ifdef HAL_TIME_STAMP +#define _log(x) ((x&abe_dbg_mask)?abe_dbg_log(x); \ + abe_dbg_time_stamp(x); \ + abe_dbg_printf(x); \ + ) +#else +#define _log(x) {if(x&abe_dbg_mask)abe_dbg_log(x);} +#endif + +/* + * PROTOTYPES + */ + +/* + * ABE_DBG_LOG + * + * Parameter : + * x : data to be logged + * + * abe_dbg_activity_log : global circular buffer holding the data + * abe_dbg_activity_log_write_pointer : circular write pointer + * + * Operations : + * saves data in the log file + * + * Return value : + * none + */ +void abe_dbg_log(abe_uint32 x); + +/* + * ABE_DBG_ERROR_LOG + * + * Parameter : + * x : d + * + * Operations : + * log the error codes + * + * Return value : + * + */ +void abe_dbg_error_log(abe_uint32 x); + +#ifdef __cplusplus +} +#endif diff --git a/sound/soc/codecs/abe/abe_def.h b/sound/soc/codecs/abe/abe_def.h new file mode 100644 index 000000000000..a8a6e5b5b12c --- /dev/null +++ b/sound/soc/codecs/abe/abe_def.h @@ -0,0 +1,364 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ + +#ifndef _ABE_DEF_H_ +#define _ABE_DEF_H_ + +/* + * HARDWARE AND PERIPHERAL DEFINITIONS + */ + +#define ABE_DMAREQ_REGISTER(desc) (abe_uint32 *)((desc/8) + CIRCULAR_BUFFER_PERIPHERAL_R__0) + +//#define ABE_SEND_DMAREQ(dma) (*((abe_uint32 *)(ABE_ATC_BASE_ADDRESS_MPU+ABE_DMASTATUS_RAW)) = (dma)) + +#define ABE_CBPR0_IDX 0 /* MM_DL */ +#define ABE_CBPR1_IDX 1 /* VX_DL */ +#define ABE_CBPR2_IDX 2 /* VX_UL */ +#define ABE_CBPR3_IDX 3 /* MM_UL */ +#define ABE_CBPR4_IDX 4 /* MM_UL2 */ +#define ABE_CBPR5_IDX 5 /* TONES */ +#define ABE_CBPR6_IDX 6 /* VIB */ +#define ABE_CBPR7_IDX 7 /* DEBUG/CTL */ + +#define CIRCULAR_BUFFER_PERIPHERAL_R__0 (0x100 + ABE_CBPR0_IDX * 4) +#define CIRCULAR_BUFFER_PERIPHERAL_R__1 (CIRCULAR_BUFFER_PERIPHERAL_R__0 + ABE_CBPR1_IDX * 4) +#define CIRCULAR_BUFFER_PERIPHERAL_R__2 (CIRCULAR_BUFFER_PERIPHERAL_R__0 + ABE_CBPR2_IDX * 4) +#define CIRCULAR_BUFFER_PERIPHERAL_R__3 (CIRCULAR_BUFFER_PERIPHERAL_R__0 + ABE_CBPR3_IDX * 4) +#define CIRCULAR_BUFFER_PERIPHERAL_R__4 (CIRCULAR_BUFFER_PERIPHERAL_R__0 + ABE_CBPR4_IDX * 4) +#define CIRCULAR_BUFFER_PERIPHERAL_R__5 (CIRCULAR_BUFFER_PERIPHERAL_R__0 + ABE_CBPR5_IDX * 4) +#define CIRCULAR_BUFFER_PERIPHERAL_R__6 (CIRCULAR_BUFFER_PERIPHERAL_R__0 + ABE_CBPR6_IDX * 4) +#define CIRCULAR_BUFFER_PERIPHERAL_R__7 (CIRCULAR_BUFFER_PERIPHERAL_R__0 + ABE_CBPR7_IDX * 4) + +/* + * cache-flush mechanism + */ +#define NB_BYTES_CACHELINE_SHFT 4 +#define NB_BYTES_IN_CACHE_LINE (1<<NB_BYTES_CACHELINE_SHFT) /* there are 16 bytes in each cache lines */ + +/* + * DEFINITIONS SHARED WITH VIRTAUDIO + */ + +#define UC1_LP 1 /* MP3 low-power player use-case */ +#define UC2_VOICE_CALL_AND_IHF_MMDL 2 /* enables voice ul/dl on earpiece + MM_DL on IHF */ +#define UC5_PINGPONG_MMDL 5 /* Test MM_DL with Ping-Pong */ +#define UC6_PINGPONG_MMDL_WITH_IRQ 6 /* ping-pong with IRQ instead of sDMA */ + +#define UC31_VOICE_CALL_8KMONO 31 +#define UC32_VOICE_CALL_8KSTEREO 32 +#define UC33_VOICE_CALL_16KMONO 33 +#define UC34_VOICE_CALL_16KSTEREO 34 +#define UC35_MMDL_MONO 35 +#define UC36_MMDL_STEREO 36 +#define UC37_MMUL2_MONO 37 +#define UC38_MMUL2_STEREO 38 + +#define UC41_____ 40 +#define UC71_STOP_ALL 71 /* stop all activities */ +#define UC72_ENABLE_ALL 72 /* stop all activities */ +#define UC81_ROUTE_AMIC 81 +#define UC82_ROUTE_DMIC01 82 +#define UC83_ROUTE_DMIC23 83 +#define UC84_ROUTE_DMIC45 84 + +#define UC91_ASRC_DRIFT1 91 +#define UC92_ASRC_DRIFT2 92 +#define UC93_EANC 93 + +#define PING_PONG_WITH_MCU_IRQ 1 +#define PING_PONG_WITH_DSP_IRQ 2 + +#define HAL_RESET_HAL 10 /* abe_reset_hal () */ +#define HAL_WRITE_MIXER 11 /* abe_write_mixer () */ + +#if 0 +#define HAL_WRITE_MIXER 12 /* void abe_irq_processing (void) */ +#define HAL_WRITE_MIXER 13 /* void abe_event_generator_switch (abe_event_id e) */ +#define HAL_WRITE_MIXER 14 /* abe_read_use_case_opp (abe_use_case_id *u, abe_opp_t *o) */ +#define HAL_WRITE_MIXER 15 /* abe_write_mixer () */ +#define HAL_WRITE_MIXER 17 /* abe_read_sys_clock (abe_micros_t *time); */ +#define HAL_WRITE_MIXER 18 /* abe_fprintf (char *line); */ +#define HAL_WRITE_MIXER 11 /* abe_reset_hal (void); */ +#define HAL_WRITE_MIXER 11 /* abe_read_use_case_opp (abe_use_case_id *u, abe_opp_t *o); */ +#define HAL_WRITE_MIXER 11 /* abe_load_fw (void); */ +#define HAL_WRITE_MIXER 11 /* abe_read_port_address (abe_port_id port, abe_dma_t *dma); */ +#define HAL_WRITE_MIXER 11 /* abe_default_configuration (abe_uint32 use_case, abe_uint32 param1, abe_uint32 param2, abe_uint32 param3, abe_uint32 param4); */ +#define HAL_WRITE_MIXER 11 /* abe_irq_processing (void); */ +#define HAL_WRITE_MIXER 11 /* abe_event_generator_switch (abe_event_id e); */ +#define HAL_WRITE_MIXER 11 /* abe_read_lowest_opp (abe_opp_t *o); */ +#define HAL_WRITE_MIXER 11 /* abe_set_opp_processing (abe_opp_t opp); */ +#define HAL_WRITE_MIXER 11 /* abe_set_ping_pong_buffer (abe_port_id port, abe_uint32 n); */ +#define HAL_WRITE_MIXER 11 /* abe_connect_irq_ping_pong_port (MM_DL, abe_data_format_t *f, abe_uint32 d, abe_uint32 s, abe_uint32 *p); */ +#define HAL_WRITE_MIXER 11 /* abe_plug_subroutine (abe_uint32 *id, abe_subroutine2 f, abe_uint32 n); */ +#define HAL_WRITE_MIXER 11 /* abe_plug_sequence (abe_uint32 *id, abe_sequence_t *s); */ +#define HAL_WRITE_MIXER 11 /* abe_launch_sequence (abe_patch_rev patch, abe_uint32 n); */ +#define HAL_WRITE_MIXER 11 /* abe_launch_sequence_param (abe_patch_rev patch, abe_uint32 n, abe_int32 *param1, abe_int32 *param2, abe_int32 *param3, abe_int32 *param4); */; */ +#define HAL_WRITE_MIXER 11 /* abe_read_analog_gain_dl (abe_gain_t *a); */ +#define HAL_WRITE_MIXER 11 /* abe_read_analog_gain_ul (abe_gain_t *a); */ +#define HAL_WRITE_MIXER 11 /* abe_enable_dyn_ul_gain (void); */ +#define HAL_WRITE_MIXER 11 /* abe_disable_dyn_ul_gain (void); */ +#define HAL_WRITE_MIXER 11 /* abe_enable_dyn_extension (void); */ +#define HAL_WRITE_MIXER 11 /* abe_disable_dyn_extension (void); */ +#define HAL_WRITE_MIXER 11 /* abe_notify_analog_gain_changed (abe_ana_port_id Id, abe_gain_t *G); */ +#define HAL_WRITE_MIXER 11 /* abe_reset_port (abe_port_id id); */ +#define HAL_WRITE_MIXER 11 /* abe_read_remaining_data (abe_port_id port, abe_uint32 *n); */ +#define HAL_WRITE_MIXER 11 /* abe_disable_data_transfer (abe_port_id *p); */ +#define HAL_WRITE_MIXER 11 /* abe_enable_data_transfer (abe_port_id p); */ +#define HAL_WRITE_MIXER 11 /* abe_read_global_counter (abe_time_stamp_t *t, abe_millis_t *m); */ +#define HAL_WRITE_MIXER 11 /* abe_set_dmic_filter (abe_dmic_ratio_t d); */ +#define HAL_WRITE_MIXER 11 /* abe_connect_cbpr_dmareq_port (abe_port_id id, abe_data_format_t *f, abe_uint32 d, abe_dma_t *a); */ +#define HAL_WRITE_MIXER 11 /* abe_connect_dmareq_port (abe_port_id id, abe_data_format_t *f, abe_uint32 d, abe_dma_t *a); */ +#define HAL_WRITE_MIXER 11 /* abe_connect_dmareq_ping_pong_port (abe_port_id id, abe_data_format_t *f, abe_uint32 d, abe_uint32 s, abe_dma_t *a); */ +#define HAL_WRITE_MIXER 11 /* abe_connect_serial_port (abe_port_id id, abe_data_format_t *f, abe_uint32 i); */ +#define HAL_WRITE_MIXER 11 /* abe_write_port_descriptor (abe_port_id id, abe_data_format_t *f, abe_port_protocol_t *p, abe_dma_t *dma); */ +#define HAL_WRITE_MIXER 11 /* abe_read_port_descriptor (abe_port_id id, abe_data_format_t *f, abe_port_protocol_t *p); */ +#define HAL_WRITE_MIXER 11 /* abe_read_aps_energy (abe_port_id *p, abe_gain_t *a); */ +#define HAL_WRITE_MIXER 11 /* abe_write_port_gain (abe_port_id port, abe_gain_t gain, abe_micros_t ramp); */ +#define HAL_WRITE_MIXER 11 /* abe_read_port_gain (abe_port_id port, abe_gain_t *gain, abe_micros_t *ramp); */ +#define HAL_WRITE_MIXER 11 /* abe_read_gain_range (abe_port_id id, abe_gain_t *min, abe_gain_t *max, abe_gain_t *step); */ +#define HAL_WRITE_MIXER 11 /* abe_write_equalizer (abe_equ_id id, abe_equ_t *param); */ +#define HAL_WRITE_MIXER 11 /* abe_write_asrc (abe_asrc_id id, abe_drift_t *param); */ +#define HAL_WRITE_MIXER 11 /* abe_write_aps (abe_aps_id id, abe_aps_t *param); */ +#define HAL_WRITE_MIXER 11 /* abe_write_mixer (abe_mixer_id id, abe_gain_t g, abe_micros_t ramp, abe_port_id p); */ +#define HAL_WRITE_MIXER 11 /* abe_write_eanc (abe_eanc_t *param); */ +#define HAL_WRITE_MIXER 11 /* abe_write_router (abe_router_id id, abe_router_t *param); */ +#define HAL_WRITE_MIXER 11 /* abe_read_asrc (abe_asrc_id id, abe_drift_t *param); */ +#define HAL_WRITE_MIXER 11 /* abe_read_aps (abe_aps_id id, abe_aps_t *param); */ +#define HAL_WRITE_MIXER 11 /* abe_read_mixer (abe_mixer_id id, abe_gain_t *gain, abe_micros_t *ramp, abe_port_id p); */ +#define HAL_WRITE_MIXER 11 /* abe_read_eanc (abe_eanc_t *param); */ +#define HAL_WRITE_MIXER 11 /* abe_read_router (abe_router_id id, abe_router_t *param); */ +#define HAL_WRITE_MIXER 11 /* abe_read_debug_trace (abe_uint32 *data, abe_uint32 *n); */ +#define HAL_WRITE_MIXER 11 /* abe_set_debug_trace (abe_dbg_t debug); */ +#define HAL_WRITE_MIXER 11 /* abe_set_debug_pins (abe_uint32 debug_pins); */ +#endif + +#define COPY_FROM_ABE_TO_HOST 1 /* ID used for LIB memory copy subroutines */ +#define COPY_FROM_HOST_TO_ABE 2 + +/* + * INTERNAL DEFINITIONS + */ + +#define CC_M1 0xFF /* unsigned version of (-1) */ +#define CS_M1 0xFFFF /* unsigned version of (-1) */ +#define CL_M1 0xFFFFFFFFL /* unsigned version of (-1) */ + +#define NBEANC1 20 /* 20 Q6.26 coef for the FIR */ +#define NBEANC2 16 /* 16 Q6.26 coef for the IIR */ + +#define NBEQ1 25 /* 24 Q6.26 coefficients */ +#define NBEQ2 13 /* 2x12 Q6.26 coefficients */ + +#define NBAPS1 10 /* TBD APS first set of parameters */ +#define NBAPS2 10 /* TBD APS second set of parameters */ + +#define NBMIX_AUDIO_UL 2 /* Mixer used for sending tones to the uplink voice path */ +#define NBMIX_DL1 4 /* Main downlink mixer */ +#define NBMIX_DL2 4 /* Handsfree downlink mixer */ +#define NBMIX_SDT 2 /* Side-tone mixer */ +#define NBMIX_ECHO 2 /* Echo reference mixer */ +#define NBMIX_VXREC 4 /* Voice record mixer */ + /* + Mixer ID Input port ID Comments + DL1_MIXER 0 MMDL path + 1 MMUL2 path + 2 VXDL path + 3 TONES path + + SDT_MIXER 0 Uplink path + 1 Downlink path + + ECHO_MIXER 0 DL1_MIXER path + 1 DL2_MIXER path + + AUDUL_MIXER 0 TONES_DL path + 1 Uplink path + 2 MM_DL path + + VXREC_MIXER 0 TONES_DL path + 1 VX_DL path + 2 MM_DL path + 3 VX_UL path + */ +#define MIX_VXUL_INPUT_MM_DL (abe_port_id)0 +#define MIX_VXUL_INPUT_TONES (abe_port_id)1 +#define MIX_VXUL_INPUT_VX_UL (abe_port_id)2 +#define MIX_VXUL_INPUT_VX_DL (abe_port_id)3 + +#define MIX_DL1_INPUT_MM_DL (abe_port_id)0 +#define MIX_DL1_INPUT_MM_UL2 (abe_port_id)1 +#define MIX_DL1_INPUT_VX_DL (abe_port_id)2 +#define MIX_DL1_INPUT_TONES (abe_port_id)3 + +#define MIX_DL2_INPUT_MM_DL (abe_port_id)0 +#define MIX_DL2_INPUT_MM_UL2 (abe_port_id)1 +#define MIX_DL2_INPUT_VX_DL (abe_port_id)2 +#define MIX_DL2_INPUT_TONES (abe_port_id)3 + +#define MIX_SDT_INPUT_UP_MIXER (abe_port_id)0 +#define MIX_SDT_INPUT_DL1_MIXER (abe_port_id)1 + +#define MIX_AUDUL_INPUT_MM_DL (abe_port_id)0 +#define MIX_AUDUL_INPUT_TONES (abe_port_id)1 +#define MIX_AUDUL_INPUT_UPLINK (abe_port_id)2 +#define MIX_AUDUL_INPUT_VX_DL (abe_port_id)3 + +#define MIX_VXREC_INPUT_MM_DL (abe_port_id)0 +#define MIX_VXREC_INPUT_TONES (abe_port_id)1 +#define MIX_VXREC_INPUT_VX_UL (abe_port_id)2 +#define MIX_VXREC_INPUT_VX_DL (abe_port_id)3 + +#define NBROUTE_UL 16 /* nb of samples to route */ +#define NBROUTE_CONFIG_MAX 10 /* 10 routing tables max */ + +#define NBROUTE_CONFIG 5 /* 5 pre-computed routing tables */ +#define UPROUTE_CONFIG_AMIC 0 /* AMIC on VX_UL */ +#define UPROUTE_CONFIG_DMIC1 1 /* DMIC first pair on VX_UL */ +#define UPROUTE_CONFIG_DMIC2 2 /* DMIC second pair on VX_UL */ +#define UPROUTE_CONFIG_DMIC3 3 /* DMIC last pair on VX_UL */ +#define UPROUTE_CONFIG_BT 4 /* BT_UL on VX_UL */ + +#define ABE_PMEM 1 +#define ABE_CMEM 2 +#define ABE_SMEM 3 +#define ABE_DMEM 4 +#define ABE_ATC 5 + +#define MAXCALLBACK 100 /* call-back indexes */ +#define MAXNBSUBROUTINE 100 /* subroutines */ + +#define MAXNBSEQUENCE 20 /* time controlled sequenced */ +#define MAXACTIVESEQUENCE 20 /* maximum simultaneous active sequences */ +#define MAXSEQUENCESTEPS 2 /* max number of steps in the sequences */ +#define MAXFEATUREPORT 12 /* max number of feature associated to a port */ +#define SUB_0_PARAM 0 +#define SUB_1_PARAM 1 /* number of parameters per sequence calls */ +#define SUB_2_PARAM 2 +#define SUB_3_PARAM 3 +#define SUB_4_PARAM 4 + +#define FREE_LINE 0 /* active sequence mask = 0 means the line is free */ +#define NOMASK (1 << 0) /* no ask for collision protection */ +#define MASK_PDM_OFF (1 << 1) /* do not allow a PDM OFF during the execution of this sequence */ +#define MASK_PDM_ON (1 << 2) /* do not allow a PDM ON during the execution of this sequence */ + +#define NBCHARFEATURENAME 16 /* explicit name of the feature */ +#define NBCHARPORTNAME 16 /* explicit name of the port */ +#define MAXNBABEPORTS LAST_PORT_ID /* number of sink+source ports of the ABE */ +#define MAX_MAP_DMEM LAST_PORT_ID + +#define SNK_P ABE_ATC_DIRECTION_IN /* sink / input port from Host point of view (or AESS for DMIC/McPDM/.. */ +#define SRC_P ABE_ATC_DIRECTION_OUT /* source / ouptut port */ + +#define NODRIFT 0 /* no ASRC applied */ +#define FORCED_DRIFT_CONTROL 1 /* for abe_set_asrc_drift_control */ +#define ADPATIVE_DRIFT_CONTROL 2 /* for abe_set_asrc_drift_control */ + +#define DOPPMODE32_OPP100 (0x00000010 | (0x00000000<<16)) +#define DOPPMODE32_OPP50 (0x0000000C | (0x0000004<<16)) +#define DOPPMODE32_OPP25 (0x0000008 | (0x0000000C<<16)) + +/* + * ABE CONST AREA FOR PARAMETERS TRANSLATION + */ +#define min_mdb (-12000) +#define max_mdb ( 3000) +#define sizeof_db2lin_table (1+ ((max_mdb - min_mdb)/100)) + +#define GAIN_MAXIMUM (abe_gain_t)3000L +#define GAIN_24dB (abe_gain_t)2400L +#define GAIN_18dB (abe_gain_t)1800L +#define GAIN_12dB (abe_gain_t)1200L +#define GAIN_6dB (abe_gain_t)600L +#define GAIN_0dB (abe_gain_t) 0L /* default gain = 1 */ +#define GAIN_M6dB (abe_gain_t)-600L +#define GAIN_M12dB (abe_gain_t)-1200L +#define GAIN_M18dB (abe_gain_t)-1800L +#define GAIN_M24dB (abe_gain_t)-2400L +#define GAIN_M30dB (abe_gain_t)-3000L +#define GAIN_M40dB (abe_gain_t)-4000L +#define GAIN_M50dB (abe_gain_t)-5000L +#define MUTE_GAIN (abe_gain_t)-12000L + +#define RAMP_0MS (abe_ramp_t)0L /* ramp_t is in milli- seconds */ +#define RAMP_1MS (abe_ramp_t)1L +#define RAMP_2MS (abe_ramp_t)2L +#define RAMP_5MS (abe_ramp_t)5L +#define RAMP_10MS (abe_ramp_t)10L +#define RAMP_20MS (abe_ramp_t)20L +#define RAMP_50MS (abe_ramp_t)50L +#define RAMP_100MS (abe_ramp_t)100L +#define RAMP_200MS (abe_ramp_t) 200L +#define RAMP_500MS (abe_ramp_t) 500L +#define RAMP_1000MS (abe_ramp_t) 1000L +#define RAMP_MAXLENGTH (abe_ramp_t) 10000L + +#define LINABE_TO_DECIBELS 1 /* for abe_translate_gain_format */ +#define DECIBELS_TO_LINABE 2 +#define IIRABE_TO_MICROS 1 /* for abe_translate_ramp_format */ +#define MICROS_TO_IIABE 2 + +#define IDLE_P 1 /* port idled */ +#define RUN_P 2 /* port running */ +#define NOCALLBACK 0 +#define NOPARAMETER 0 + /* HAL 06: those numbers may be x4 */ +#define MCPDM_UL_ITER 2 /* number of ATC access upon AMIC DMArequests, all the FIFOs are enabled */ +#define MCPDM_DL_ITER 6 /* All the McPDM FIFOs are enabled simultaneously */ +#define DMIC_ITER 6 /* All the DMIC FIFOs are enabled simultaneously */ + +#define DEFAULT_THR_READ 1 /* port / flow management */ +#define DEFAULT_THR_WRITE 1 /* port / flow management */ + +#define DEFAULT_CONTROL_MCPDMDL 1 /* allows control on the PDM line */ + +#define MAX_PINGPONG_BUFFERS 2 /* TBD later if needed */ + +/* + * Indexes to the subroutines + */ +#define SUB_WRITE_MIXER 1 +#define SUB_WRITE_PORT_GAIN 2 + +/* OLD WAY */ +#define c_feat_init_eq 1 +#define c_feat_read_eq1 2 +#define c_write_eq1 3 +#define c_feat_read_eq2 4 +#define c_write_eq2 5 +#define c_feat_read_eq3 6 +#define c_write_eq3 7 + +/* + * MACROS + */ + +#define LOAD_ABEREG(reg,data) {abe_uint32 *ocp_addr = (abe_uint32 *)((reg)+ABE_ATC_BASE_ADDRESS_MPU); *ocp_addr= (data);} + +#define maximum(a,b) (((a)<(b))?(b):(a)) +#define minimum(a,b) (((a)>(b))?(b):(a)) +#define absolute(a) ( ((a)>0) ? (a):((-1)*(a)) ) + +// Gives 1% errors +//#define abe_power_of_two(x) (abe_float)(1 + x*(0.69315 + x*(0.24022 + x*(0.056614 + x*(0.00975 ))))) /* for x = [-1..+1] */ +//#define abe_log_of_two(i) (abe_float)(-2.4983 + i*(4.0321 + i*(-2.0843 + i*(0.63 + i*(-0.0793))))) /* for i = [+1..+2[ */ +// Gives 0.1% errors +//#define abe_power_of_two(xx) (abe_float)(1 + xx*(0.69314718055995 + xx*(0.24022650695909 + xx*(0.05661419083812 + xx*(0.0096258236109 ))))) /* for x = [-1..+1] */ +//#define abe_log_of_two(i) (abe_float)(-3.02985297173966 + i*(6.07170945221999 + i*(-5.27332161514862 + i*(3.22638187067771 + i*(-1.23767101624897 + i*(0.26766043958616 + i*(-0.02490211314987))))))) /* for i = [+1..+2[ */ + +#if 0 +#define abe_power_of_two(xx) (abe_float)(0.9999999924494 + xx*(0.69314847688495 + xx*(0.24022677604481 + xx*(0.05549256818679 + xx*(0.00961666477618 + xx*(0.0013584351075 + xx*(0.00015654359307))))))) /* for x = [-1..+1] */ +#define abe_log_of_two(xx) (abe_float)(-3.02985297175803 + xx*(6.07170945229365 + xx*(-5.27332161527062 + xx*(3.22638187078450 + xx*(-1.23767101630110 + xx*(0.26766043959961 + xx*(-0.02490211315130))))))) /* for x = [+1..+2] */ +#define abe_sine(xx) (abe_float)(-0.000000389441 + xx*(6.283360925789 + xx*(-0.011140658372 + xx*(-41.073653348384 + xx*(-3.121196875959 + xx*(100.619954580736 + xx*( -59.133359355846))))))) /* for x = [0 .. pi/2] */ +#define abe_sqrt(xx) (abe_float)(0.32298238417665 + xx*(0.93621865220393 + xx*(-0.36276443369703 + xx*(0.13008602653101+ xx*(-0.03017833169073 + xx*(0.00393731964847 + xx*-0.00021858629159 )))))) /* for x = [1 .. 4] */ +#endif + +#endif /* _ABE_DEF_H_ */ diff --git a/sound/soc/codecs/abe/abe_define.h b/sound/soc/codecs/abe/abe_define.h new file mode 100644 index 000000000000..95889f84ee7b --- /dev/null +++ b/sound/soc/codecs/abe/abe_define.h @@ -0,0 +1,47 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ + +#ifndef _ABE_DEFINE_H_ +#define _ABE_DEFINE_H_ + +#define ATC_DESCRIPTOR_NUMBER 64 +#define PROCESSING_SLOTS 25 +#define TASK_POOL_LENGTH 128 +#define MCU_IRQ 0x24 +#define DMA_REQ 0x84 +#define DSP_IRQ 0x4c +#define IRQtag_APS 0x000a +#define IRQtag_COUNT 0x000c +#define IRQtag_PP 0x000d +#define DMAreq_7 0x0080 +#define IRQ_FIFO_LENGTH 16 +#define SDT_EQ_ORDER 4 +#define DL_EQ_ORDER 12 +#define MIC_FILTER_ORDER 4 +#define GAINS_WITH_RAMP1 14 +#define GAINS_WITH_RAMP2 22 +#define GAINS_WITH_RAMP_TOTAL 36 +#define EANC_FIR_TAPS 21 +#define EANC_IIR_ORDER 8 +#define ASRC_MEMLENGTH 40 +#define ASRC_UL_VX_FIR_L 19 +#define ASRC_DL_VX_FIR_L 19 +#define ASRC_DL_MM_FIR_L 18 +#define ASRC_N_8k 2 +#define ASRC_N_16k 4 +#define ASRC_N_48k 12 +#define VIBRA_N 5 +#define VIBRA1_IIR_MEMSIZE 11 +#define SAMP_LOOP_96K 24 +#define SAMP_LOOP_48K 12 +#define SAMP_LOOP_16K 4 +#define SAMP_LOOP_8K 2 + +#endif /* _ABE_DEFINE_H_ */ diff --git a/sound/soc/codecs/abe/abe_dm_addr.h b/sound/soc/codecs/abe/abe_dm_addr.h new file mode 100644 index 000000000000..2f880d36ba43 --- /dev/null +++ b/sound/soc/codecs/abe/abe_dm_addr.h @@ -0,0 +1,322 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ + +#ifndef _ABE_DM_ADDR_H_ +#define _ABE_DM_ADDR_H_ + +#define D_atcDescriptors_ADDR 0 +#define D_atcDescriptors_ADDR_END 511 +#define D_atcDescriptors_sizeof 512 + +#define stack_ADDR 512 +#define stack_ADDR_END 623 +#define stack_sizeof 112 + +#define D_version_ADDR 624 +#define D_version_ADDR_END 627 +#define D_version_sizeof 4 + +#define D_BT_DL_FIFO_ADDR 768 +#define D_BT_DL_FIFO_ADDR_END 1087 +#define D_BT_DL_FIFO_sizeof 320 + +#define D_BT_UL_FIFO_ADDR 1280 +#define D_BT_UL_FIFO_ADDR_END 1599 +#define D_BT_UL_FIFO_sizeof 320 + +#define D_MM_EXT_OUT_FIFO_ADDR 1792 +#define D_MM_EXT_OUT_FIFO_ADDR_END 2111 +#define D_MM_EXT_OUT_FIFO_sizeof 320 + +#define D_MM_EXT_IN_FIFO_ADDR 2304 +#define D_MM_EXT_IN_FIFO_ADDR_END 2623 +#define D_MM_EXT_IN_FIFO_sizeof 320 + +#define D_MM_UL2_FIFO_ADDR 2816 +#define D_MM_UL2_FIFO_ADDR_END 2975 +#define D_MM_UL2_FIFO_sizeof 160 + +#define D_VX_UL_FIFO_ADDR 3072 +#define D_VX_UL_FIFO_ADDR_END 3391 +#define D_VX_UL_FIFO_sizeof 320 + +#define D_VX_DL_FIFO_ADDR 3584 +#define D_VX_DL_FIFO_ADDR_END 3743 +#define D_VX_DL_FIFO_sizeof 160 + +#define D_DMIC_UL_FIFO_ADDR 3840 +#define D_DMIC_UL_FIFO_ADDR_END 4319 +#define D_DMIC_UL_FIFO_sizeof 480 + +#define D_MM_UL_FIFO_ADDR 4352 +#define D_MM_UL_FIFO_ADDR_END 4847 +#define D_MM_UL_FIFO_sizeof 496 + +#define D_MM_DL_FIFO_ADDR 4864 +#define D_MM_DL_FIFO_ADDR_END 5023 +#define D_MM_DL_FIFO_sizeof 160 + +#define D_TONES_DL_FIFO_ADDR 5120 +#define D_TONES_DL_FIFO_ADDR_END 5279 +#define D_TONES_DL_FIFO_sizeof 160 + +#define D_VIB_DL_FIFO_ADDR 5376 +#define D_VIB_DL_FIFO_ADDR_END 5535 +#define D_VIB_DL_FIFO_sizeof 160 + +#define D_McPDM_DL_FIFO_ADDR 5632 +#define D_McPDM_DL_FIFO_ADDR_END 6111 +#define D_McPDM_DL_FIFO_sizeof 480 + +#define D_McPDM_UL_FIFO_ADDR 6144 +#define D_McPDM_UL_FIFO_ADDR_END 6623 +#define D_McPDM_UL_FIFO_sizeof 480 + +#define D_IOdescr_ADDR 6624 +#define D_IOdescr_ADDR_END 7183 +#define D_IOdescr_sizeof 560 + +#define D_debugATCptrs_ADDR 7184 +#define D_debugATCptrs_ADDR_END 7247 +#define D_debugATCptrs_sizeof 64 + +#define d_zero_ADDR 7248 +#define d_zero_ADDR_END 7248 +#define d_zero_sizeof 1 + +#define dbg_trace1_ADDR 7249 +#define dbg_trace1_ADDR_END 7249 +#define dbg_trace1_sizeof 1 + +#define dbg_trace2_ADDR 7250 +#define dbg_trace2_ADDR_END 7250 +#define dbg_trace2_sizeof 1 + +#define dbg_trace3_ADDR 7251 +#define dbg_trace3_ADDR_END 7251 +#define dbg_trace3_sizeof 1 + +#define D_multiFrame_ADDR 7252 +#define D_multiFrame_ADDR_END 7651 +#define D_multiFrame_sizeof 400 + +#define D_tasksList_ADDR 7652 +#define D_tasksList_ADDR_END 9699 +#define D_tasksList_sizeof 2048 + +#define D_idleTask_ADDR 9700 +#define D_idleTask_ADDR_END 9701 +#define D_idleTask_sizeof 2 + +#define D_typeLengthCheck_ADDR 9702 +#define D_typeLengthCheck_ADDR_END 9703 +#define D_typeLengthCheck_sizeof 2 + +#define D_maxTaskBytesInSlot_ADDR 9704 +#define D_maxTaskBytesInSlot_ADDR_END 9705 +#define D_maxTaskBytesInSlot_sizeof 2 + +#define D_rewindTaskBytes_ADDR 9706 +#define D_rewindTaskBytes_ADDR_END 9707 +#define D_rewindTaskBytes_sizeof 2 + +#define D_pCurrentTask_ADDR 9708 +#define D_pCurrentTask_ADDR_END 9709 +#define D_pCurrentTask_sizeof 2 + +#define D_pFastLoopBack_ADDR 9710 +#define D_pFastLoopBack_ADDR_END 9711 +#define D_pFastLoopBack_sizeof 2 + +#define D_pNextFastLoopBack_ADDR 9712 +#define D_pNextFastLoopBack_ADDR_END 9715 +#define D_pNextFastLoopBack_sizeof 4 + +#define D_ppCurrentTask_ADDR 9716 +#define D_ppCurrentTask_ADDR_END 9717 +#define D_ppCurrentTask_sizeof 2 + +#define D_slotCounter_ADDR 9720 +#define D_slotCounter_ADDR_END 9721 +#define D_slotCounter_sizeof 2 + +#define D_loopCounter_ADDR 9724 +#define D_loopCounter_ADDR_END 9725 +#define D_loopCounter_sizeof 2 + +#define D_RewindFlag_ADDR 9726 +#define D_RewindFlag_ADDR_END 9727 +#define D_RewindFlag_sizeof 2 + +#define D_Slot23_ctrl_ADDR 9728 +#define D_Slot23_ctrl_ADDR_END 9731 +#define D_Slot23_ctrl_sizeof 4 + +#define D_McuIrqFifo_ADDR 9732 +#define D_McuIrqFifo_ADDR_END 9795 +#define D_McuIrqFifo_sizeof 64 + +#define D_PingPongDesc_ADDR 9796 +#define D_PingPongDesc_ADDR_END 9843 +#define D_PingPongDesc_sizeof 48 + +#define D_PP_MCU_IRQ_ADDR 9844 +#define D_PP_MCU_IRQ_ADDR_END 9845 +#define D_PP_MCU_IRQ_sizeof 2 + +#define D_ctrlPortFifo_ADDR 9856 +#define D_ctrlPortFifo_ADDR_END 9871 +#define D_ctrlPortFifo_sizeof 16 + +#define D_Idle_State_ADDR 9872 +#define D_Idle_State_ADDR_END 9875 +#define D_Idle_State_sizeof 4 + +#define D_Stop_Request_ADDR 9876 +#define D_Stop_Request_ADDR_END 9879 +#define D_Stop_Request_sizeof 4 + +#define D_Ref0_ADDR 9880 +#define D_Ref0_ADDR_END 9881 +#define D_Ref0_sizeof 2 + +#define D_DebugRegister_ADDR 9884 +#define D_DebugRegister_ADDR_END 10023 +#define D_DebugRegister_sizeof 140 + +#define D_Gcount_ADDR 10024 +#define D_Gcount_ADDR_END 10025 +#define D_Gcount_sizeof 2 + +#define D_DCcounter_ADDR 10028 +#define D_DCcounter_ADDR_END 10031 +#define D_DCcounter_sizeof 4 + +#define D_DCsum_ADDR 10032 +#define D_DCsum_ADDR_END 10039 +#define D_DCsum_sizeof 8 + +#define D_fastCounter_ADDR 10040 +#define D_fastCounter_ADDR_END 10043 +#define D_fastCounter_sizeof 4 + +#define D_slowCounter_ADDR 10044 +#define D_slowCounter_ADDR_END 10047 +#define D_slowCounter_sizeof 4 + +#define D_aUplinkRouting_ADDR 10048 +#define D_aUplinkRouting_ADDR_END 10063 +#define D_aUplinkRouting_sizeof 16 + +#define D_VirtAudioLoop_ADDR 10064 +#define D_VirtAudioLoop_ADDR_END 10067 +#define D_VirtAudioLoop_sizeof 4 + +#define D_AsrcVars_DL_VX_ADDR 10068 +#define D_AsrcVars_DL_VX_ADDR_END 10099 +#define D_AsrcVars_DL_VX_sizeof 32 + +#define D_AsrcVars_UL_VX_ADDR 10100 +#define D_AsrcVars_UL_VX_ADDR_END 10131 +#define D_AsrcVars_UL_VX_sizeof 32 + +#define D_CoefAddresses_VX_ADDR 10132 +#define D_CoefAddresses_VX_ADDR_END 10163 +#define D_CoefAddresses_VX_sizeof 32 + +#define D_AsrcVars_DL_MM_ADDR 10164 +#define D_AsrcVars_DL_MM_ADDR_END 10195 +#define D_AsrcVars_DL_MM_sizeof 32 + +#define D_CoefAddresses_DL_MM_ADDR 10196 +#define D_CoefAddresses_DL_MM_ADDR_END 10227 +#define D_CoefAddresses_DL_MM_sizeof 32 + +#define D_APS_DL1_M_thresholds_ADDR 10228 +#define D_APS_DL1_M_thresholds_ADDR_END 10235 +#define D_APS_DL1_M_thresholds_sizeof 8 + +#define D_APS_DL1_M_IRQ_ADDR 10236 +#define D_APS_DL1_M_IRQ_ADDR_END 10237 +#define D_APS_DL1_M_IRQ_sizeof 2 + +#define D_APS_DL1_C_IRQ_ADDR 10238 +#define D_APS_DL1_C_IRQ_ADDR_END 10239 +#define D_APS_DL1_C_IRQ_sizeof 2 + +#define D_TraceBufAdr_ADDR 10240 +#define D_TraceBufAdr_ADDR_END 10241 +#define D_TraceBufAdr_sizeof 2 + +#define D_TraceBufOffset_ADDR 10242 +#define D_TraceBufOffset_ADDR_END 10243 +#define D_TraceBufOffset_sizeof 2 + +#define D_TraceBufLength_ADDR 10244 +#define D_TraceBufLength_ADDR_END 10245 +#define D_TraceBufLength_sizeof 2 + +#define D_AsrcVars_ECHO_REF_ADDR 10248 +#define D_AsrcVars_ECHO_REF_ADDR_END 10279 +#define D_AsrcVars_ECHO_REF_sizeof 32 + +#define D_Pempty_ADDR 10280 +#define D_Pempty_ADDR_END 10283 +#define D_Pempty_sizeof 4 + +#define D_APS_DL2_L_M_IRQ_ADDR 10284 +#define D_APS_DL2_L_M_IRQ_ADDR_END 10285 +#define D_APS_DL2_L_M_IRQ_sizeof 2 + +#define D_APS_DL2_L_C_IRQ_ADDR 10286 +#define D_APS_DL2_L_C_IRQ_ADDR_END 10287 +#define D_APS_DL2_L_C_IRQ_sizeof 2 + +#define D_APS_DL2_R_M_IRQ_ADDR 10288 +#define D_APS_DL2_R_M_IRQ_ADDR_END 10289 +#define D_APS_DL2_R_M_IRQ_sizeof 2 + +#define D_APS_DL2_R_C_IRQ_ADDR 10290 +#define D_APS_DL2_R_C_IRQ_ADDR_END 10291 +#define D_APS_DL2_R_C_IRQ_sizeof 2 + +#define D_APS_DL1_C_thresholds_ADDR 10292 +#define D_APS_DL1_C_thresholds_ADDR_END 10299 +#define D_APS_DL1_C_thresholds_sizeof 8 + +#define D_APS_DL2_L_M_thresholds_ADDR 10300 +#define D_APS_DL2_L_M_thresholds_ADDR_END 10307 +#define D_APS_DL2_L_M_thresholds_sizeof 8 + +#define D_APS_DL2_L_C_thresholds_ADDR 10308 +#define D_APS_DL2_L_C_thresholds_ADDR_END 10315 +#define D_APS_DL2_L_C_thresholds_sizeof 8 + +#define D_APS_DL2_R_M_thresholds_ADDR 10316 +#define D_APS_DL2_R_M_thresholds_ADDR_END 10323 +#define D_APS_DL2_R_M_thresholds_sizeof 8 + +#define D_APS_DL2_R_C_thresholds_ADDR 10324 +#define D_APS_DL2_R_C_thresholds_ADDR_END 10331 +#define D_APS_DL2_R_C_thresholds_sizeof 8 + +#define D_nextMultiFrame_ADDR 10332 +#define D_nextMultiFrame_ADDR_END 10339 +#define D_nextMultiFrame_sizeof 8 + +#define D_PING_ADDR 16384 +#define D_PING_ADDR_END 40959 +#define D_PING_sizeof 24576 + +#define D_PONG_ADDR 40960 +#define D_PONG_ADDR_END 65535 +#define D_PONG_sizeof 24576 + +#endif /* _ABE_DM_ADDR_H_ */ diff --git a/sound/soc/codecs/abe/abe_ext.c b/sound/soc/codecs/abe/abe_ext.c new file mode 100644 index 000000000000..8142d8542ef5 --- /dev/null +++ b/sound/soc/codecs/abe/abe_ext.c @@ -0,0 +1,162 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ + +#include "abe_main.h" + +/* + * ABE_DEFAULT_IRQ_PINGPONG_PLAYER + * + * + * Operations : + * generates data for the cache-flush buffer MODE 16+16 + * + * Return value : + * None. + */ +void abe_default_irq_pingpong_player(void) +{ + /* ping-pong access to MM_DL at 48kHz Mono with 20ms packet sizes */ + #define N_SAMPLES_MAX ((int)(1024)) + + static abe_int32 idx; + abe_uint32 i, dst, n_samples; + abe_int32 temp [N_SAMPLES_MAX], audio_sample; + const abe_int32 audio_pattern [8] = {0, 11585, 16384, 11585, 0, -11586, -16384, -11586 }; + //const abe_int32 audio_pattern [8] = {16383,16383,16383,16383,-16384,-16384,-16384,-16384}; + + /* read the address of the Pong buffer */ + abe_read_next_ping_pong_buffer (MM_DL_PORT, &dst, &n_samples); + + /* generate a test pattern */ + for (i = 0; i < n_samples; i++) { + idx = (idx +1) & 7; /* circular addressing */ + audio_sample = audio_pattern [idx]; + temp [i] = ((audio_sample << 16) + audio_sample); + } + + /* copy the pattern (flush it) to DMEM pointer update + * not necessary here because the buffer size do not + * change from one ping to the other pong + */ + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, dst, (abe_uint32 *)&(temp[0]), n_samples * 4); + abe_set_ping_pong_buffer(MM_DL_PORT, n_samples * 4); +} + +/* + * ABE_DEFAULT_IRQ_PINGPONG_PLAYER_32BITS + * + * Operations: + * generates data for the cache-flush buffer MODE 32 BITS + * Return value: + * None. + */ +void abe_default_irq_pingpong_player_32bits(void) +{ +/* ping-pong access to MM_DL at 48kHz Mono with 20ms packet sizes */ +#define N_SAMPLES_MAX ((int)(1024)) + static abe_int32 idx; + abe_uint32 i, dst, n_samples; + abe_int32 temp[N_SAMPLES_MAX], audio_sample; + const abe_int32 audio_pattern[8] = {0, 11585, 16384, 11585, 0, -11586, -16384, -11586 }; + //const abe_int32 audio_pattern[8] = {16383,16383,16383,16383,-16384,-16384,-16384,-16384}; + + /* read the address of the Pong buffer */ + abe_read_next_ping_pong_buffer(MM_DL_PORT, &dst, &n_samples); + + /* generate a test pattern */ + for (i = 0; i < n_samples; i++) { + /* circular addressing */ + idx = (idx +1) & 7; + audio_sample = audio_pattern[idx]; + temp[i*2 +0] = (audio_sample << 16); + temp[i*2 +1] = (audio_sample << 16); + } + + /* copy the pattern (flush it) to DMEM pointer update + * not necessary here because the buffer size do not + * change from one ping to the other pong + */ + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, dst, + (abe_uint32 *)&(temp[0]), n_samples * 4 *2); + + abe_set_ping_pong_buffer(MM_DL_PORT, n_samples * 4 *2); +} +/* + * ABE_DEFAULT_IRQ_APS_ADAPTATION + * + * Operations : + * updates the APS filter and gain + * + * Return value : + * None. + */ +void abe_default_irq_aps_adaptation(void) +{ +} + +/* + * ABE_READ_SYS_CLOCK + * + * Parameter : + * pointer to the system clock + * + * Operations : + * returns the current time indication for the LOG + * + * Return value : + * None. + */ +void abe_read_sys_clock(abe_micros_t *time) +{ + static abe_micros_t clock; + + *time = clock; + clock ++; +} + +/* + * ABE_APS_TUNING + * + * Parameter : + * + * + * Operations : + * + * + * Return value : + * + */ +void abe_aps_tuning(void) +{ +} + +/** +* @fn abe_lock_executione() +* +* Operations : set a spin-lock and wait in case of collision +* +* +* @see ABE_API.h +*/ +void abe_lock_execution(void) +{ +} + +/** +* @fn abe_unlock_executione() +* +* Operations : reset a spin-lock (end of subroutine) +* +* +* @see ABE_API.h +*/ +void abe_unlock_execution(void) +{ +} diff --git a/sound/soc/codecs/abe/abe_ext.h b/sound/soc/codecs/abe/abe_ext.h new file mode 100644 index 000000000000..510e707d43f6 --- /dev/null +++ b/sound/soc/codecs/abe/abe_ext.h @@ -0,0 +1,165 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ + +#ifndef _ABE_EXT_H_ +#define _ABE_EXT_H_ + +#include <linux/io.h> +#define PC_SIMULATION 0 /* Tuning is done on PC ? */ + +/* + * OS DEPENDENT MMU CONFIGURATION + */ +#define ABE_ATC_BASE_ADDRESS_L3 0x490F1000L /* base address used for L3/DMA access */ +#define ABE_ATC_BASE_ADDRESS_L4 0x401F1000L /* base address used for L4/MCU access */ +#define ABE_DMEM_BASE_ADDRESS_L3 0x49080000L /* 64kB as seen from DMA access */ +#define ABE_DMEM_BASE_ADDRESS_L4 0x40180000L /* 64kB as seen from MCU access */ + + +#if 0 +#define ABE_PMEM_BASE_ADDRESS_MPU 0x401E0000L /* 8kB as seen from MPU access */ +#define ABE_CMEM_BASE_ADDRESS_MPU 0x401A0000L /* 8kB +++++++++++++++++++++++ */ +#define ABE_SMEM_BASE_ADDRESS_MPU 0x401C0000L /* 24kB */ +#define ABE_DMEM_BASE_ADDRESS_MPU 0x40180000L /* 64kB */ +#define ABE_ATC_BASE_ADDRESS_MPU 0x401F1000L +#else +#define ABE_PMEM_BASE_ADDRESS_MPU 0x490E0000L /* 8kB as seen from MPU access */ +#define ABE_CMEM_BASE_ADDRESS_MPU 0x490A0000L /* 8kB +++++++++++++++++++++++ */ +#define ABE_SMEM_BASE_ADDRESS_MPU 0x490C0000L /* 24kB */ +#define ABE_DMEM_BASE_ADDRESS_MPU 0x49080000L /* 64kB */ +#define ABE_ATC_BASE_ADDRESS_MPU 0x490F1000L +#endif + +/* + * HARDWARE AND PERIPHERAL DEFINITIONS + */ + +#define ABE_PMEM_SIZE 8192 /* PMEM SIZE in bytes (1024 words of 64 bits: : #32bits words x 4)*/ +#define ABE_CMEM_SIZE 8192 /* CMEM SIZE in bytes (2048 coeff : #32bits words x 4)*/ +#define ABE_SMEM_SIZE 24576 /* SMEM SIZE in bytes (3072 stereo samples : #32bits words x 4)*/ +#define ABE_DMEM_SIZE 65536L /* DMEM SIZE in bytes */ +#define ABE_ATC_DESC_SIZE 512 /* ATC REGISTERS SIZE in bytes */ + + +#define ABE_MCU_IRQSTATUS_RAW 0x24 /* holds the MCU Irq signal */ +#define ABE_MCU_IRQSTATUS 0x28 /* status : clear the IRQ */ +#define ABE_DSP_IRQSTATUS_RAW 0x4C /* holds the DSP Irq signal */ +#define ABE_DMASTATUS_RAW 0x84 /* holds the DMA req lines to the sDMA */ + + +#define EVENT_GENERATOR_COUNTER 0x68 +#define EVENT_GENERATOR_COUNTER_DEFAULT 2048 /* PLL output/desired sampling rate = (32768 * 6000)/96000 */ +#define EVENT_GENERATOR_COUNTER_44100 2229 /* PLL output/desired sampling rate = (32768 * 6000)/88400 */ + +#define EVENT_GENERATOR_START 0x6C /* start / stop the EVENT generator */ +#define EVENT_GENERATOR_ON 1 +#define EVENT_GENERATOR_OFF 0 + +#define EVENT_SOURCE_SELECTION 0x70 /* selection of the EVENT generator source */ +#define EVENT_SOURCE_DMA 0 +#define EVENT_SOURCE_COUNTER 1 + +#define AUDIO_ENGINE_SCHEDULER 0x74 /* selection of the ABE DMA req line from ATC */ +#define ABE_ATC_DMIC_DMA_REQ 1 +#define ABE_ATC_MCPDMDL_DMA_REQ 2 +#define ABE_ATC_MCPDMUL_DMA_REQ 3 +#define ABE_ATC_DIRECTION_IN 0 /* Direction=0 means input from ABE point of view */ +#define ABE_ATC_DIRECTION_OUT 1 /* Direction=1 means output from ABE point of view */ + +/* + * * DMA requests + * */ +#define External_DMA_0 0 //Internal connection doesn't connect at ABE boundary +#define DMIC_DMA_REQ 1 //Transmit request digital microphone +#define McPDM_DMA_DL 2 //Multichannel PDM downlink +#define McPDM_DMA_UP 3 //Multichannel PDM uplink +#define MCBSP1_DMA_TX 4 //MCBSP module 1 - transmit request +#define MCBSP1_DMA_RX 5 //MCBSP module 1 - receive request +#define MCBSP2_DMA_TX 6 //MCBSP module 2 - transmit request +#define MCBSP2_DMA_RX 7 //MCBSP module 2 - receive request +#define MCBSP3_DMA_TX 8 //MCBSP module 3 - transmit request +#define MCBSP3_DMA_RX 9 //MCBSP module 3 - receive request +#define SLIMBUS1_DMA_TX0 10 //SLIMBUS module 1 - transmit request channel 0 +#define SLIMBUS1_DMA_TX1 11 //SLIMBUS module 1 - transmit request channel 1 +#define SLIMBUS1_DMA_TX2 12 //SLIMBUS module 1 - transmit request channel 2 +#define SLIMBUS1_DMA_TX3 13 //SLIMBUS module 1 - transmit request channel 3 +#define SLIMBUS1_DMA_TX4 14 //SLIMBUS module 1 - transmit request channel 4 +#define SLIMBUS1_DMA_TX5 15 //SLIMBUS module 1 - transmit request channel 5 +#define SLIMBUS1_DMA_TX6 16 //SLIMBUS module 1 - transmit request channel 6 +#define SLIMBUS1_DMA_TX7 17 //SLIMBUS module 1 - transmit request channel 7 +#define SLIMBUS1_DMA_RX0 18 //SLIMBUS module 1 - receive request channel 0 +#define SLIMBUS1_DMA_RX1 19 //SLIMBUS module 1 - receive request channel 1 +#define SLIMBUS1_DMA_RX2 20 //SLIMBUS module 1 - receive request channel 2 +#define SLIMBUS1_DMA_RX3 21 //SLIMBUS module 1 - receive request channel 3 +#define SLIMBUS1_DMA_RX4 22 //SLIMBUS module 1 - receive request channel 4 +#define SLIMBUS1_DMA_RX5 23 //SLIMBUS module 1 - receive request channel 5 +#define SLIMBUS1_DMA_RX6 24 //SLIMBUS module 1 - receive request channel 6 +#define SLIMBUS1_DMA_RX7 25 //SLIMBUS module 1 - receive request channel 7 +#define McASP1_AXEVT 26 //McASP - Data transmit DMA request line +#define McASP1_AREVT 29 //McASP - Data receive DMA request line +#define CBPr_DMA_RTX0 32 //DMA of the Circular buffer peripheral 0 +#define CBPr_DMA_RTX1 33 //DMA of the Circular buffer peripheral 1 +#define CBPr_DMA_RTX2 34 //DMA of the Circular buffer peripheral 2 +#define CBPr_DMA_RTX3 35 //DMA of the Circular buffer peripheral 3 +#define CBPr_DMA_RTX4 36 //DMA of the Circular buffer peripheral 4 +#define CBPr_DMA_RTX5 37 //DMA of the Circular buffer peripheral 5 +#define CBPr_DMA_RTX6 38 //DMA of the Circular buffer peripheral 6 +#define CBPr_DMA_RTX7 39 //DMA of the Circular buffer peripheral 7 + +/* + * * ATC DESCRIPTORS - DESTINATIONS + * */ +#define DEST_DMEM_access 0x00 +#define DEST_MCBSP1_TX 0x01 +#define DEST_MCBSP2_TX 0x02 +#define DEST_MCBSP3_TX 0x03 +#define DEST_SLIMBUS1_TX0 0x04 +#define DEST_SLIMBUS1_TX1 0x05 +#define DEST_SLIMBUS1_TX2 0x06 +#define DEST_SLIMBUS1_TX3 0x07 +#define DEST_SLIMBUS1_TX4 0x08 +#define DEST_SLIMBUS1_TX5 0x09 +#define DEST_SLIMBUS1_TX6 0x0A +#define DEST_SLIMBUS1_TX7 0x0B +#define DEST_MCPDM_DL 0x0C +#define DEST_MCASP_TX0 0x0D +#define DEST_MCASP_TX1 0x0E +#define DEST_MCASP_TX2 0x0F +#define DEST_MCASP_TX3 0x10 +#define DEST_EXTPORT0 0x11 +#define DEST_EXTPORT1 0x12 +#define DEST_EXTPORT2 0x13 +#define DEST_EXTPORT3 0x14 +#define DEST_MCPDM_ON 0x15 +#define DEST_CBP_CBPr 0x3F + +/* + * * ATC DESCRIPTORS - SOURCES + * */ +#define SRC_DMEM_access 0x0 +#define SRC_MCBSP1_RX 0x01 +#define SRC_MCBSP2_RX 0x02 +#define SRC_MCBSP3_RX 0x03 +#define SRC_SLIMBUS1_RX0 0x04 +#define SRC_SLIMBUS1_RX1 0x05 +#define SRC_SLIMBUS1_RX2 0x06 +#define SRC_SLIMBUS1_RX3 0x07 +#define SRC_SLIMBUS1_RX4 0x08 +#define SRC_SLIMBUS1_RX5 0x09 +#define SRC_SLIMBUS1_RX6 0x0A +#define SRC_SLIMBUS1_RX7 0x0B +#define SRC_DMIC_UP 0x0C +#define SRC_MCPDM_UP 0x0D +#define SRC_MCASP_RX0 0x0E +#define SRC_MCASP_RX1 0x0F +#define SRC_MCASP_RX2 0x10 +#define SRC_MCASP_RX3 0x11 +#define SRC_CBP_CBPr 0x3F +#endif /* _ABE_EXT_H_ */ diff --git a/sound/soc/codecs/abe/abe_functionsId.h b/sound/soc/codecs/abe/abe_functionsId.h new file mode 100644 index 000000000000..265bb033196b --- /dev/null +++ b/sound/soc/codecs/abe/abe_functionsId.h @@ -0,0 +1,78 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ + +#ifndef _ABE_FUNCTIONSID_H_ +#define _ABE_FUNCTIONSID_H_ + +/* + * TASK function ID definitions + */ +#define C_ABE_FW_FUNCTION_IIR 0 +#define C_ABE_FW_FUNCTION_monoToStereoPack 1 +#define C_ABE_FW_FUNCTION_stereoToMonoSplit 2 +#define C_ABE_FW_FUNCTION_decimator 3 +#define C_ABE_FW_FUNCTION_OS0Fill 4 +#define C_ABE_FW_FUNCTION_mixer2 5 +#define C_ABE_FW_FUNCTION_mixer4 6 +#define C_ABE_FW_FUNCTION_inplaceGain 7 +#define C_ABE_FW_FUNCTION_EANC 8 +#define C_ABE_FW_FUNCTION_StreamRouting 9 +#define C_ABE_FW_FUNCTION_VIBRA2 10 +#define C_ABE_FW_FUNCTION_VIBRA1 11 +#define C_ABE_FW_FUNCTION_APS_core 12 +#define C_ABE_FW_FUNCTION_ASRC_DL_wrapper 13 +#define C_ABE_FW_FUNCTION_ASRC_UL_wrapper 14 +#define C_ABE_FW_FUNCTION_gainConverge 15 +#define C_ABE_FW_FUNCTION_dualIir 16 +#define C_ABE_FW_FUNCTION_EANC_wrapper 17 +#define C_ABE_FW_FUNCTION_DCoffset 18 +#define C_ABE_FW_FUNCTION_DCoffset2 19 +#define C_ABE_FW_FUNCTION_IO_DL_pp 20 +#define C_ABE_FW_FUNCTION_EANCUpdateOutSample 21 +#define C_ABE_FW_FUNCTION_VX_DL_8_48_wrapper 22 +#define C_ABE_FW_FUNCTION_VX_UL_48_8_wrapper 23 +#define C_ABE_FW_FUNCTION_VX_DL_16_48_wrapper 24 +#define C_ABE_FW_FUNCTION_VX_UL_48_16_wrapper 25 +#define C_ABE_FW_FUNCTION_BT_UL_8_48_wrapper 26 +#define C_ABE_FW_FUNCTION_BT_DL_48_8_wrapper 27 +#define C_ABE_FW_FUNCTION_BT_UL_16_48_wrapper 28 +#define C_ABE_FW_FUNCTION_BT_DL_48_16_wrapper 29 +#define C_ABE_FW_FUNCTION_ECHO_REF_48_8_wrapper 30 +#define C_ABE_FW_FUNCTION_ECHO_REF_48_16_wrapper 31 +#define C_ABE_FW_FUNCTION_IO_generic2 32 +#define C_ABE_FW_FUNCTION_irq_fifo_debug 33 +#define C_ABE_FW_FUNCTION_synchronize_pointers 34 +#define C_ABE_FW_FUNCTION_IIR_SRC_MIC 35 +#define C_ABE_FW_FUNCTION_APS_FEEDBACK_DL1_wrapper 36 +#define C_ABE_FW_FUNCTION_APS_FEEDBACK_DL2_L_wrapper 37 +#define C_ABE_FW_FUNCTION_APS_FEEDBACK_DL2_R_wrapper 38 + +/* + * COPY function ID definitions + */ +#define NULL_COPY_CFPID 0 +#define COPY_D2S_LR_CFPID 1 +#define COPY_D2S_2_CFPID 2 +#define COPY_D2S_MONO_CFPID 3 +#define COPY_S1D_MONO_CFPID 4 +#define COPY_S2D_MONO_CFPID 5 +#define COPY_S2D_2_CFPID 6 +#define COPY_DMIC_CFPID 7 +#define COPY_MCPDM_DL_CFPID 8 +#define COPY_MM_UL_CFPID 9 +#define SPLIT_SMEM_CFPID 10 +#define MERGE_SMEM_CFPID 11 +#define SPLIT_TDM_12_CFPID 12 +#define MERGE_TDM_12_CFPID 13 +#define ROUTE_MM_UL_CFPID 14 +#define IO_DMAREQ_CFPID 15 +#define IO_IP_CFPID 16 + +#endif /* _ABE_FUNCTIONSID_H_ */ diff --git a/sound/soc/codecs/abe/abe_fw.h b/sound/soc/codecs/abe/abe_fw.h new file mode 100644 index 000000000000..33e29d4fe77d --- /dev/null +++ b/sound/soc/codecs/abe/abe_fw.h @@ -0,0 +1,468 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ + +#include "abe_cm_addr.h" +#include "abe_sm_addr.h" +#include "abe_dm_addr.h" +#include "abe_typedef.h" + +/* + * GLOBAL DEFINITION + */ +#define FW_SCHED_LOOP_FREQ 4000 /* one scheduler loop = 4kHz = 12 samples at 48kHz */ +#define EVENT_FREQUENCY 96000 +#define SLOTS_IN_SCHED_LOOP (96000/FW_SCHED_LOOP_FREQ) + +#define SCHED_LOOP_8kHz ( 8000/FW_SCHED_LOOP_FREQ) +#define SCHED_LOOP_16kHz (16000/FW_SCHED_LOOP_FREQ) +#define SCHED_LOOP_24kHz (24000/FW_SCHED_LOOP_FREQ) +#define SCHED_LOOP_48kHz (48000/FW_SCHED_LOOP_FREQ) + +#define TASKS_IN_SLOT 8 +/* + * DMEM AREA - SCHEDULER + */ +#define smem_mm_trace 0 +#define dmem_mm_trace D_debugATCptrs_ADDR +#define dmem_mm_trace_size ((D_debugATCptrs_ADDR_END-D_debugATCptrs_ADDR+1)/4) + + +#define ATC_SIZE 8 /* 8 bytes per descriptors */ + +typedef struct { + unsigned rdpt:7; /* first 32bits word of the descriptor */ + unsigned reserved0:1; + unsigned cbsize:7; + unsigned irqdest:1; + unsigned cberr:1; + unsigned reserved1:5; + unsigned cbdir:1; + unsigned nw:1; + unsigned wrpt:7; + unsigned reserved2:1; + unsigned badd:12; /* second 32bits word of the descriptor */ + unsigned iter:7; /* iteration field overlaps the 16 bits boundary */ + unsigned srcid:6; + unsigned destid:6; + unsigned desen:1; +} abe_satcdescriptor_aess; + +/* + * table of scheduler tasks : + * char scheduler_table[24 x 4] : four bytes used at OPP100% + */ +#define dmem_scheduler_table D_multiFrame_ADDR + +#define dmem_eanc_task_pointer D_pFastLoopBack_ADDR + +/* + * OPP value : + * pointer increment steps in the scheduler table + */ +#define dmem_scheduler_table_step D_taskStep_ADDR + +/* + * table of scheduler tasks (max 64) : + * char task_descriptors[64 x 8] : eight bytes per task + * TASK INDEX, INITPTR 1,2,3, INITREG, Loop Counter, Reserved 1,2 + */ +#define dmem_task_descriptor D_tasksList_ADDR + +/* + * table of task function addresses: + * short task_function_descriptors[32 x 1] : 16bits addresses to PMEM using TASK_INDEX above + */ + +/* + * IDs of the micro tasks + */ + +// from ABE_FunctionsId.h +/*#define id_ copyMultiFrame_TFID +#define id_ inplaceGain_TFID +#define id_ mixer_TFID +#define id_ IIR_TFID +#define id_ gainConverge_TFID +#define id_ sinGen_TFID +#define id_ OSR0Fill_TFID +#define id_ IOtask_TFID + +#define id_mixer +#define id_eq +#define id_upsample_src +#define id_downsample_src +#define id_asrc +#define id_gain_update +#define id_aps_hs +#define id_aps_ihf +#define id_dither +#define id_eanc +#define id_io +#define id_router +#define id_dynamic_dl +#define id_dynamic_ul +#define id_sequence_reader +#define id_ .. +*/ + +/* + * I/O DESCRIPTORS + */ +#define dmem_port_descriptors D_IOdescr_ADDR + +/* ping_pong_t descriptors table + * structure of 8 bytes: + * uint16 base_address1 + * uint16 size1 (16bits address format) + * uint16 base_address2 + * uint16 size2 + * } ping_pong_t + * ping_pong_t dmem_ping_pong_t [8] + */ +#define dmem_ping_pong_buffer D_PING_ADDR /* U8 address */ + +/* + * IRQ mask used with ports with IRQ (DMA or host) + * uint32 dmem_irq_masks [8] + */ +#define dmem_irq_masks D_IRQMask_ADDR + +/* + * tables of to the 8 FIFO sequences (delayed commands) holding 12bytes tasks in the format + * structure { + * 1) Down counter delay on 16bits, decremented on each scheduler period + * 2) Code on 8 bits for the type of operation to execute : call or data move. + * 3) Three 16bits parameters (for data move example example : source/destination/counter) + * 4) Three bytes reserved + * } seq_fw_task_t + * + * structure { + * uint32 : base address(MSB) + read pointer(LSB) + * uint32 : max address (MSB) + write pointer (LSB) + * } FIFO_generic; + * seq_fw_task_t FIFO_CONTENT [8]; 96 bytes + * + * FIFO_SEQ dmem_fifo_sequences [8]; all FIFO sequences + */ +#define dmem_fifo_sequences D_DCFifo_ADDR +#define dmem_fifo_sequences_descriptors D_DCFifoDesc_ADDR + +/* + * IRQ FIFOs + * + * structure { + * uint32 : base address(MSB) + read pointer(LSB) + * uint32 : max address (MSB) + write pointer (LSB) + * uint32 IRQ_CODES [6]; + * } dmem_fifo_irq_mcu; 32 bytes + * } dmem_fifo_irq_dsp; 32 bytes + */ +#define dmem_fifo_irq_mcu_descriptor D_McuIrqFifoDesc_ADDR +#define dmem_fifo_irq_dsp_descriptor D_DspIrqFifoDesc_ADDR +#define dmem_fifo_irq_mcu D_McuIrqFifo_ADDR +#define dmem_fifo_irq_dsp D_DspIrqFifo_ADDR + +/* + * remote debugger exchange buffer + * uint32 dmem_debug_ae2hal [32] + * uint32 dmem_debug_hal2ae [32] + */ +#define dmem_debug_ae2hal D_DebugAbe2hal_ADDR +#define dmem_debug_hal2ae D_Debug_hal2abe_ADDR + +/* + * DMEM address of the ASRC ppm drift parameter for ASRCs (voice and multimedia paths) + * uint32 smem_asrc(x)_drift + */ +#define dmem_asrc1_drift D_ASRC1drift_ADDR +#define dmem_asrc2_drift D_ASRC2drift_ADDR + +/* + * DMEM indexes of the router uplink paths + * uint8 dmem_router_index [8] + */ +// OC: TBD ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +//#define dmem_router_index + +/* + * analog control circular buffer commands to Phoenix + * structure { + * uint32 : base address(MSB) + read pointer(LSB) + * uint32 : max address (MSB) + write pointer (LSB) + * uint32 FIFO_CONTENT [6]; + * } dmem_commands_to_phoenix; 32 bytes + */ +#define dmem_commands_to_phoenix D_Cmd2PhenixFifo_ADDR +#define dmem_commands_to_phoenix_descriptor D_Cmd2PhenixFifoDesc_ADDR + +/* + * analog control circular buffer commands from Phoenix (status line) + * structure { + * uint32 : base address(MSB) + read pointer(LSB) + * uint32 : max address (MSB) + write pointer (LSB) + * uint32 FIFO_CONTENT [6]; + * } dmem_commands_to_phoenix; 32 bytes + */ +#define dmem_commands_from_phoenix D_StatusFromPhenixFifo_ADDR +#define dmem_commands_from_phoenix_descriptor D_StatusFromPhenixFifoDesc_ADDR + +/* + * DEBUG mask + * uint16 dmem_debug_trace_mask + * each bit of this word enables a type a trace in the debug circular buffer + */ + +// OC: TBD ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +//#define dmem_debug_trace_mask + +/* + * DEBUG circular buffer + * structure { + * uint32 : base address(MSB) + read pointer(LSB) + * uint32 : max address (MSB) + write pointer (LSB) + * uint32 FIFO_CONTENT [14]; = TIMESTAMP + CODE + * } dmem_debug_trace_buffer; 64 bytes + * should be much larger (depends on the DMEM mapping...) + */ +#define dmem_debug_trace_buffer +#define dmem_debug_trace_fifo D_debugFifo_ADDR +#define dmem_debug_trace_descriptor D_debugFifoDesc_ADDR + +/* + * Infinite counter incremented on each sheduler periods (~250 us) + * uint16 dmem_debug_time_stamp + */ +#define dmem_debug_time_stamp D_loopCounter_ADDR + +/* + * ATC BUFFERS + IO TASKS SMEM buffers + */ +#define dmem_dmic D_DMIC_UL_FIFO_ADDR +#define dmem_dmic_size ((D_DMIC_UL_FIFO_ADDR_END-D_DMIC_UL_FIFO_ADDR+1)/4) +#define smem_dmic1 DMIC0_96_labelID +#define smem_dmic2 DMIC1_96_labelID +#define smem_dmic3 DMIC2_96_labelID + +#define dmem_amic D_McPDM_UL_FIFO_ADDR +#define dmem_amic_size ((D_McPDM_UL_FIFO_ADDR_END-D_McPDM_UL_FIFO_ADDR+1)/4) +#define smem_amic AMIC_96_labelID + +#define dmem_mcpdm D_McPDM_DL_FIFO_ADDR +#define dmem_mcpdm_size ((D_McPDM_DL_FIFO_ADDR_END-D_McPDM_DL_FIFO_ADDR+1)/4) + +#define dmem_mm_ul D_MM_UL_FIFO_ADDR +#define dmem_mm_ul_size ((D_MM_UL_FIFO_ADDR_END-D_MM_UL_FIFO_ADDR+1)/4) +#define smem_mm_ul MM_UL_labelID /* managed directly by the router */ + +#define dmem_mm_ul2 D_MM_UL2_FIFO_ADDR +#define dmem_mm_ul2_size ((D_MM_UL2_FIFO_ADDR_END-D_MM_UL2_FIFO_ADDR+1)/4) +#define smem_mm_ul2 MM_UL2_labelID /* managed directly by the router */ + +#define dmem_mm_dl D_MM_DL_FIFO_ADDR +#define dmem_mm_dl_size ((D_MM_DL_FIFO_ADDR_END-D_MM_DL_FIFO_ADDR+1)/4) +#define smem_mm_dl_opp100 MM_DL_labelID +#define smem_mm_dl_opp25 MM_DL_labelID /* @@@ at OPP 25/50 or without ASRC */ + +#define dmem_vx_dl D_VX_DL_FIFO_ADDR +#define dmem_vx_dl_size ((D_VX_DL_FIFO_ADDR_END-D_VX_DL_FIFO_ADDR+1)/4) +#define smem_vx_dl Voice_16k_DL_labelID /* ASRC input buffer, size 40 */ + +#define dmem_vx_ul D_VX_UL_FIFO_ADDR +#define dmem_vx_ul_size ((D_VX_UL_FIFO_ADDR_END-D_VX_UL_FIFO_ADDR+1)/4) +#define smem_vx_ul Voice_16k_UL_labelID + +#define dmem_tones_dl D_TONES_DL_FIFO_ADDR +#define dmem_tones_dl_size ((D_TONES_DL_FIFO_ADDR_END-D_TONES_DL_FIFO_ADDR+1)/4) +#define smem_tones_dl Tones_labelID + +#define dmem_vib_dl D_VIB_DL_FIFO_ADDR +#define dmem_vib_dl_size ((D_VIB_DL_FIFO_ADDR_END-D_VIB_DL_FIFO_ADDR+1)/4) +#define smem_vib IO_VIBRA_DL_labelID + +#define dmem_mm_ext_out D_MM_EXT_OUT_FIFO_ADDR +#define dmem_mm_ext_out_size ((D_MM_EXT_OUT_FIFO_ADDR_END-D_MM_EXT_OUT_FIFO_ADDR+1)/4) +#define smem_mm_ext_out DL1_M_labelID + +#define dmem_mm_ext_in D_MM_EXT_IN_FIFO_ADDR +#define dmem_mm_ext_in_size ((D_MM_EXT_IN_FIFO_ADDR_END-D_MM_EXT_IN_FIFO_ADDR+1)/4) +#define smem_mm_ext_in AMIC_labelID + +#define dmem_bt_vx_dl D_BT_DL_FIFO_ADDR +#define dmem_bt_vx_dl_size ((D_BT_DL_FIFO_ADDR_END-D_BT_DL_FIFO_ADDR+1)/4) +#define smem_bt_vx_dl AMIC_labelID + +#define dmem_bt_vx_ul D_BT_UL_FIFO_ADDR +#define dmem_bt_vx_ul_size ((D_BT_UL_FIFO_ADDR_END-D_BT_UL_FIFO_ADDR+1)/4) +#define smem_bt_vx_ul DL1_M_labelID + +/* + * INITPTR / INITREG AREA + */ + +/* + * POINTER - used for the port descriptor programming + * corresponds to 8bits addresses to the INITPTR area + * + * List from ABE_INITxxx_labels.h + */ +#define ptr_ul_rec +#define ptr_vx_dl +#define ptr_mm_dl +#define ptr_mm_ext +#define ptr_tones +#define ptr_vibra2 + +/* + * SMEM AREA + */ + +/* + * PHOENIX OFFSET in SMEM + * used to subtract a DC offset on the headset path (power consumption optimization) + */ + +/* OC: exact usage to be detailled */ +#define smem_phoenix_offset S_PhoenixOffset_ADDR + +/* + * EQUALIZERS Z AREA + * used to reset the filter memory - IIR-8 (max) + * int24 stereo smem_equ(x) [8x2 + 1] + */ +#define smem_equ1 S_EQU1_data_ADDR +#define smem_equ2 S_EQU2_data_ADDR +#define smem_equ3 S_EQU3_data_ADDR +#define smem_equ4 S_EQU4_data_ADDR +#define smem_sdt S_SDT_data_ADDR + +/* + * GAIN SMEM on PORT + * int32 smem_G0 [18] : desired gain on the ports + * format of G0 = 6 bits left shifted desired gain in linear 24bits format + * int24 stereo G0 [18] = G0 + * int24 stereo GI [18] current value of the gain in the same format of G0 + * List of smoothed gains : + * 6 DMIC 0 1 2 3 4 5 + * 2 AMIC L R + * 4 PORT1/2_RX L R + * 2 MM_EXT L R + * 2 MM_VX_DL L R + * 2 IHF L R + * --------------- + * 18 = TOTAL + */ +//#define smem_g0 S_GTarget_ADDR /* [9] 2 gains in 1 SM address */ +//#define smem_g1 S_GCurrent_ADDR /* [9] 2 gains in 1 SM address */ + +/* + * COEFFICIENTS AREA + */ + +/* + * delay coefficients used in the IIR-1 filters + * int24 cmem_gain_delay_iir1[9 x 2] (a, (1-a)) + * + * 3 for 6 DMIC 0 1 2 3 4 5 + * 1 for 2 AMIC L R + * 2 for 4 PORT1/2_RX L R + * 1 for 2 MM_EXT L R + * 1 for 2 MM_VX_DL L R + * 1 for 2 IHF L R + */ + +#define cmem_gain_alpha C_Alpha_ADDR /* [9] */ +#define cmem_gain_1_alpha C_1_Alpha_ADDR + +/* + * gain controls + */ +#define GAIN_LEFT_OFFSET (abe_port_id)0 +#define GAIN_RIGHT_OFFSET (abe_port_id)1 + +#define cmem_gains_base C_GainsWRamp_ADDR +#define smem_target_gain_base S_GTarget1_ADDR +#define cmem_1_Alpha_base C_1_Alpha_ADDR +#define cmem_Alpha_base C_Alpha_ADDR + +#define dmic1_gains_offset 0 /* stereo gains */ +#define dmic2_gains_offset 2 /* stereo gains */ +#define dmic3_gains_offset 4 /* stereo gains */ +#define amic_gains_offset 6 /* stereo gains */ +#define dl1_gains_offset 8 /* stereo gains */ +#define dl2_gains_offset 10 /* stereo gains */ +#define splitters_gains_offset 12 /* stereo gains */ + +#define mixer_dl1_offset 14 +#define mixer_dl2_offset 18 +#define mixer_echo_offset 22 +#define mixer_sdt_offset 24 +#define mixer_vxrec_offset 26 +#define mixer_audul_offset 30 +#define gain_unused_offset 34 + +/* + * DMIC SRC 96->48 + * the filter is changed depending on the decimatio ratio used (16/25/32/40) + * int32 cmem_src2_dmic [6] IIR with 2 coefs in the recursive part and 4 coefs in the direct part + */ +#define cmem_src2_dmic + +/* + * EANC coefficients + * structure of : + * 20 Q6.26 coef for the FIR + * 16 Q6.26 coef for the IIR + * 1 Q6.26 coef for Lambda + */ +#define cmem_eanc_coef_fir +#define cmem_eanc_coef_iir +#define cmem_eanc_coef_lambda + +/* + * EQUALIZERS - SDT - COEF AREA + * int24 cmem_equ(x) [8x2+1] + */ +#define cmem_equ1 C_EQU1_data_ADDR +#define cmem_equ2 C_EQU2_data_ADDR +#define cmem_equ3 C_EQU3_data_ADDR +#define cmem_equ4 C_EQU4_data_ADDR +#define cmem_sdt C_SDT_data_ADDR + +/* + * APS - COEF AREA + * int24 cmem_aps(x) [16] + */ +#define cmem_aps1 +#define cmem_aps2 +#define cmem_aps3 + +/* + * DITHER - COEF AREA + * int24 cmem_dither(x) [4] + */ +#define cmem_dither + +/* + * PMEM AREA + */ +#define sub_null_copy NULL_COPY_CFPID +#define sub_copy_dmic COPY_DMIC_CFPID +#define sub_copy_mm_ul COPY_MM_UL_CFPID +#define sub_copy_mcpdm_dl COPY_MCPDM_DL_CFPID +#define sub_copy_d2s_1616 COPY_D2S_LR_CFPID /* data move in IO tasks */ +#define sub_copy_d2s COPY_D2S_2_CFPID +#define sub_copy_d2s_mono COPY_D2S_MONO_CFPID +#define sub_copy_s2d_left COPY_S1D_MONO_CFPID +#define sub_copy_s2d_mono COPY_S2D_MONO_CFPID +#define sub_copy_s2d COPY_S2D_2_CFPID + +//#ifdef __cplusplus +//} +//#endif diff --git a/sound/soc/codecs/abe/abe_ini.c b/sound/soc/codecs/abe/abe_ini.c new file mode 100644 index 000000000000..aaa3972503b5 --- /dev/null +++ b/sound/soc/codecs/abe/abe_ini.c @@ -0,0 +1,1162 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ + +#include "abe_main.h" +#include "abe_dat.h" /* data declaration */ + +/* + * initialize the default values for call-backs to subroutines + * - FIFO IRQ call-backs for sequenced tasks + * - FIFO IRQ call-backs for audio player/recorders (ping-pong protocols) + * - Remote debugger interface + * - Error monitoring + * - Activity Tracing + */ + +/* + * ABE_HW_CONFIGURATION + * + * Parameter : + * + * Operations : + * + * + * Return value : + * + */ +void abe_hw_configuration() +{ + abe_uint32 atc_reg; + abe_port_protocol_t *protocol; + abe_data_format_t format; + + /* initializes the ABE ATC descriptors in DMEM - MCPDM_UL */ + protocol = &(abe_port[PDM_UL_PORT].protocol); + format = abe_port[PDM_UL_PORT].format; + abe_init_atc(PDM_UL_PORT); + abe_init_io_tasks(PDM_UL_PORT, &format, protocol); + + /* initializes the ABE ATC descriptors in DMEM - MCPDM_DL */ + protocol = &(abe_port[PDM_DL_PORT].protocol); + format = abe_port[PDM_DL_PORT].format; + abe_init_atc(PDM_DL_PORT); + abe_init_io_tasks(PDM_DL_PORT, &format, protocol); + + /* one DMIC port enabled = all DMICs enabled, since there is a single DMIC path for all DMICs */ + protocol = &(abe_port[DMIC_PORT].protocol); + format = abe_port[DMIC_PORT].format; + abe_init_atc(DMIC_PORT); + abe_init_io_tasks(DMIC_PORT, &format, protocol); + + /* enables the DMAreq from AESS AESS_DMAENABLE_SET = 255 */ + atc_reg = 0xFF; + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_ATC, 0x60, &atc_reg, 4); +} + +/* + * ABE_BUILD_SCHEDULER_TABLE + * + * Parameter : + * + * Operations : + * + * + * Return value : + * + */ +void abe_build_scheduler_table() +{ + short VirtAudio_aMultiFrame[PROCESSING_SLOTS][TASKS_IN_SLOT]; + abe_uint16 i, n; + abe_uint8 *ptr; + char aUplinkMuxing[16]; + + /* LOAD OF THE TASKS' MULTIFRAME */ + /* WARNING ON THE LOCATION OF IO_MM_DL WHICH IS PATCHED IN "abe_init_io_tasks" */ + + for (ptr = (abe_uint8 *)&(VirtAudio_aMultiFrame[0][0]), i=0; i < sizeof (VirtAudio_aMultiFrame); i++) + *ptr++ = 0; + + //VirtAudio_aMultiFrame[0][0] = 0; + //VirtAudio_aMultiFrame[0][1] = 0; + VirtAudio_aMultiFrame[0][2] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_VX_DL; + //VirtAudio_aMultiFrame[0][3] = 0; + //VirtAudio_aMultiFrame[0][4] = 0; + //VirtAudio_aMultiFrame[0][5] = 0; + //@@@ VirtAudio_aMultiFrame[0][6] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_ASRC_MM_DL; No ASRC + //VirtAudio_aMultiFrame[0][7] = 0; + //VirtAudio_aMultiFrame[1][0] = 0; + //VirtAudio_aMultiFrame[1][1] = 0; +#define TASK_ASRC_VX_DL_SLT 1 +#define TASK_ASRC_VX_DL_IDX 2 + //VirtAudio_aMultiFrame[1][2] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_ASRC_VX_DL_16; +#define TASK_VX_DL_SLT 1 +#define TASK_VX_DL_IDX 3 + VirtAudio_aMultiFrame[1][3] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_VX_DL_16_48; + //VirtAudio_aMultiFrame[1][4] = 0; + //VirtAudio_aMultiFrame[1][5] = 0; + VirtAudio_aMultiFrame[1][6] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2Mixer; + VirtAudio_aMultiFrame[1][7] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_VIB_DL; + VirtAudio_aMultiFrame[2][0] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DL1Mixer; + //VirtAudio_aMultiFrame[2][1] = 0; + VirtAudio_aMultiFrame[2][2] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_SideTone; + //VirtAudio_aMultiFrame[2][3] = 0; + VirtAudio_aMultiFrame[2][4] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_SDTMixer; + VirtAudio_aMultiFrame[2][5] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_DMIC; + //VirtAudio_aMultiFrame[2][6] = 0; + //VirtAudio_aMultiFrame[2][7] = 0; + + VirtAudio_aMultiFrame[3][0] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DL1_EQ; + //VirtAudio_aMultiFrame[3][1] = 0; + VirtAudio_aMultiFrame[3][2] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_EchoMixer; + //VirtAudio_aMultiFrame[3][3] = 0; + //VirtAudio_aMultiFrame[3][4] = 0; + //VirtAudio_aMultiFrame[3][5] = 0; + VirtAudio_aMultiFrame[3][6] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2_EQ; + VirtAudio_aMultiFrame[3][7] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_VIBRA_SPLIT; + VirtAudio_aMultiFrame[4][0] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DL1_APS_EQ; + VirtAudio_aMultiFrame[4][1] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DL1_GAIN; + VirtAudio_aMultiFrame[4][2] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_VXRECMixer; + VirtAudio_aMultiFrame[4][3] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_VXREC_SPLIT; + //VirtAudio_aMultiFrame[4][4] = 0; + //VirtAudio_aMultiFrame[4][5] = 0; + VirtAudio_aMultiFrame[4][6] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_VIBRA1; + VirtAudio_aMultiFrame[4][7] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_VIBRA2; + + VirtAudio_aMultiFrame[5][0] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_EARP_48_96_0SR; + VirtAudio_aMultiFrame[5][1] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_EARP_48_96_LP; + VirtAudio_aMultiFrame[5][2] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_PDM_UL; + //VirtAudio_aMultiFrame[5][3] = 0; + //VirtAudio_aMultiFrame[5][4] = 0; + //VirtAudio_aMultiFrame[5][5] = 0; + VirtAudio_aMultiFrame[5][6] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2_APS_EQ; + VirtAudio_aMultiFrame[5][7] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2_GAIN; + + VirtAudio_aMultiFrame[6][0] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_EARP_48_96_LP; + VirtAudio_aMultiFrame[6][1] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_PDM_DL; + //VirtAudio_aMultiFrame[6][2] = 0; + //VirtAudio_aMultiFrame[6][3] = 0; + //VirtAudio_aMultiFrame[6][4] = 0; + //VirtAudio_aMultiFrame[6][5] = 0; + VirtAudio_aMultiFrame[6][6] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2_APS_SPLIT; + //VirtAudio_aMultiFrame[6][7] = 0; + + //VirtAudio_aMultiFrame[7][0] = 0; + //VirtAudio_aMultiFrame[7][1] = 0; + VirtAudio_aMultiFrame[7][2] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_BT_UL_SPLIT; + VirtAudio_aMultiFrame[7][3] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DBG_SYNC; + //VirtAudio_aMultiFrame[7][4] = 0; + //VirtAudio_aMultiFrame[7][5] = 0; + VirtAudio_aMultiFrame[7][6] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2_R_APS_CORE; + VirtAudio_aMultiFrame[7][7] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2_L_APS_CORE; + + //VirtAudio_aMultiFrame[8][0] = 0; + //VirtAudio_aMultiFrame[8][1] = 0; + VirtAudio_aMultiFrame[8][2] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DMIC1_96_48_LP; + //VirtAudio_aMultiFrame[8][3] = 0; + VirtAudio_aMultiFrame[8][4] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DMIC1_SPLIT; + //VirtAudio_aMultiFrame[8][5] = 0; + //VirtAudio_aMultiFrame[8][6] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_EANC_FBK_96_48; + //VirtAudio_aMultiFrame[8][7] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_EANC_FBK_SPLIT; + + //VirtAudio_aMultiFrame[9][0] = 0; + //VirtAudio_aMultiFrame[9][1] = 0; + VirtAudio_aMultiFrame[9][2] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DMIC2_96_48_LP; + //VirtAudio_aMultiFrame[9][3] = 0; + VirtAudio_aMultiFrame[9][4] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DMIC2_SPLIT; + //VirtAudio_aMultiFrame[9][5] = 0; + VirtAudio_aMultiFrame[9][6] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IHF_48_96_0SR; + VirtAudio_aMultiFrame[9][7] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IHF_48_96_LP; + + //VirtAudio_aMultiFrame[10][0] = 0; + //VirtAudio_aMultiFrame[10][1] = 0; + VirtAudio_aMultiFrame[10][2] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DMIC3_96_48_LP; + //VirtAudio_aMultiFrame[10][3] = 0; + VirtAudio_aMultiFrame[10][4] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DMIC3_SPLIT; + //VirtAudio_aMultiFrame[10][5] = 0; + //VirtAudio_aMultiFrame[10][6] = 0; // D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_EANC_COPY; // NEW: copy EANC coefs to working CMEM areas + VirtAudio_aMultiFrame[10][7] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IHF_48_96_LP; + + //VirtAudio_aMultiFrame[11][0] = 0; + //VirtAudio_aMultiFrame[11][1] = 0; + VirtAudio_aMultiFrame[11][2] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_AMIC_96_48_LP; + //VirtAudio_aMultiFrame[11][3] = 0; + VirtAudio_aMultiFrame[11][4] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_AMIC_SPLIT; + //VirtAudio_aMultiFrame[11][5] = 0; + //VirtAudio_aMultiFrame[11][6] = 0; + VirtAudio_aMultiFrame[11][7] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_VIBRA_PACK; + + //VirtAudio_aMultiFrame[12][0] = 0; + //VirtAudio_aMultiFrame[12][1] = 0; + VirtAudio_aMultiFrame[12][2] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_BT_VX_DL; + VirtAudio_aMultiFrame[12][3] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_VX_UL_ROUTING; + VirtAudio_aMultiFrame[12][4] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_ULMixer; +#define TASK_VX_UL_SLT 12 +#define TASK_VX_UL_IDX 5 + VirtAudio_aMultiFrame[12][5] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_VX_UL_48_16; + //VirtAudio_aMultiFrame[12][6] = 0; + //VirtAudio_aMultiFrame[12][7] = 0; + //VirtAudio_aMultiFrame[13][0] = 0; + //VirtAudio_aMultiFrame[13][1] = 0; + VirtAudio_aMultiFrame[13][2] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_MM_UL2_ROUTING; + //VirtAudio_aMultiFrame[13][3] = 0; + VirtAudio_aMultiFrame[13][4] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_MM_UL; + //VirtAudio_aMultiFrame[13][5] = 0; + //VirtAudio_aMultiFrame[13][6] = 0; + //VirtAudio_aMultiFrame[13][7] = 0; + + //VirtAudio_aMultiFrame[14][0] = 0; + //VirtAudio_aMultiFrame[14][1] = 0; + //VirtAudio_aMultiFrame[14][2] = 0; + VirtAudio_aMultiFrame[14][3] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_DMIC; +#define TASK_BT_DL_48_8_SLT 14 +#define TASK_BT_DL_48_8_IDX 4 + VirtAudio_aMultiFrame[14][4] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_BT_DL_48_8; + //VirtAudio_aMultiFrame[14][5] = 0; +#define TASK_ECHO_SLT 14 +#define TASK_ECHO_IDX 6 + VirtAudio_aMultiFrame[14][6] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_ECHO_REF_48_16; + //VirtAudio_aMultiFrame[14][7] = 0; + + VirtAudio_aMultiFrame[15][0] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DL1_APS_IIR; + VirtAudio_aMultiFrame[15][1] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DL1_APS_CORE; + //VirtAudio_aMultiFrame[15][2] = 0; + VirtAudio_aMultiFrame[15][3] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_BT_VX_UL; + //VirtAudio_aMultiFrame[15][4] = 0; + //VirtAudio_aMultiFrame[15][5] = 0; + //VirtAudio_aMultiFrame[15][6] = 0; +#define TASK_ASRC_ECHO_SLT 15 +#define TASK_ASRC_ECHO_IDX 7 + //@@@ VirtAudio_aMultiFrame[15][7] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_ASRC_ECHO_REF_16; + + //VirtAudio_aMultiFrame[16][0] = 0; + //VirtAudio_aMultiFrame[16][1] = 0; +#define TASK_ASRC_VX_UL_SLT 16 +#define TASK_ASRC_VX_UL_IDX 2 + //@@@ VirtAudio_aMultiFrame[16][2] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_ASRC_VX_UL_16; + VirtAudio_aMultiFrame[16][3] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_VX_UL; // USING ECHO REF MERGED + //VirtAudio_aMultiFrame[16][4] = 0; + //VirtAudio_aMultiFrame[16][5] = 0; + //VirtAudio_aMultiFrame[16][6] = 0; + //VirtAudio_aMultiFrame[16][7] = 0; + + //VirtAudio_aMultiFrame[17][0] = 0; + //VirtAudio_aMultiFrame[17][1] = 0; +#define TASK_BT_UL_8_48_SLT 17 +#define TASK_BT_UL_8_48_IDX 2 + VirtAudio_aMultiFrame[17][2] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_BT_UL_8_48; + VirtAudio_aMultiFrame[17][3] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_MM_UL2; + //VirtAudio_aMultiFrame[17][4] = 0; + //VirtAudio_aMultiFrame[17][5] = 0; + //VirtAudio_aMultiFrame[17][6] = 0; + //VirtAudio_aMultiFrame[17][7] = 0; + + VirtAudio_aMultiFrame[18][0] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_PDM_DL; + //VirtAudio_aMultiFrame[18][1] = 0; + //VirtAudio_aMultiFrame[18][2] = 0; + //VirtAudio_aMultiFrame[18][3] = 0; + //VirtAudio_aMultiFrame[18][4] = 0; + //VirtAudio_aMultiFrame[18][5] = 0; + //VirtAudio_aMultiFrame[18][6] = 0; + //VirtAudio_aMultiFrame[18][7] = 0; + +#define TASK_IO_MM_DL_SLT 19 +#define TASK_IO_MM_DL_IDX 0 + VirtAudio_aMultiFrame[19][0] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_MM_DL; + //VirtAudio_aMultiFrame[19][1] = 0 + //VirtAudio_aMultiFrame[19][2] = 0; + //VirtAudio_aMultiFrame[19][3] = 0; + //VirtAudio_aMultiFrame[19][4] = 0; + //VirtAudio_aMultiFrame[19][5] = 0; + //VirtAudio_aMultiFrame[19][6] = 0; + //VirtAudio_aMultiFrame[19][7] = 0; + + VirtAudio_aMultiFrame[20][0] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_TONES_DL; + VirtAudio_aMultiFrame[20][1] = 0; + VirtAudio_aMultiFrame[20][2] = 0; + //VirtAudio_aMultiFrame[20][3] = 0; + //VirtAudio_aMultiFrame[20][4] = 0; + //VirtAudio_aMultiFrame[20][5] = 0; + //VirtAudio_aMultiFrame[20][6] = 0; + //VirtAudio_aMultiFrame[20][7] = 0; + + //VirtAudio_aMultiFrame[21][0] = 0; + //VirtAudio_aMultiFrame[21][1] = 0; + //VirtAudio_aMultiFrame[21][2] = 0; + //VirtAudio_aMultiFrame[21][3] = 0; + //VirtAudio_aMultiFrame[21][4] = 0; + //VirtAudio_aMultiFrame[21][5] = 0; + //VirtAudio_aMultiFrame[21][6] = 0; + //VirtAudio_aMultiFrame[21][7] = 0; + + VirtAudio_aMultiFrame[22][0] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_DEBUG_IRQFIFO; // MUST STAY ON SLOT 22 + //VirtAudio_aMultiFrame[22][1] = 0; + VirtAudio_aMultiFrame[22][2] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_MM_EXT_OUT; + VirtAudio_aMultiFrame[22][3] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_MM_EXT_IN; + //VirtAudio_aMultiFrame[22][4] = 0; + //VirtAudio_aMultiFrame[22][5] = 0; + //VirtAudio_aMultiFrame[22][6] = 0; + //VirtAudio_aMultiFrame[22][7] = 0; + + VirtAudio_aMultiFrame[23][0] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_GAIN_UPDATE; + //VirtAudio_aMultiFrame[23][1] = 0; + //VirtAudio_aMultiFrame[23][2] = 0; + //VirtAudio_aMultiFrame[23][3] = 0; + //VirtAudio_aMultiFrame[23][4] = 0; + //VirtAudio_aMultiFrame[23][5] = 0; + //VirtAudio_aMultiFrame[23][6] = 0; + //VirtAudio_aMultiFrame[23][7] = 0; + + //VirtAudio_aMultiFrame[24][0] = 0; + //VirtAudio_aMultiFrame[24][1] = 0; + //VirtAudio_aMultiFrame[24][2] = 0; + //VirtAudio_aMultiFrame[24][3] = 0; + //VirtAudio_aMultiFrame[24][4] = 0; + //VirtAudio_aMultiFrame[24][5] = 0; + //VirtAudio_aMultiFrame[24][6] = 0; + //VirtAudio_aMultiFrame[24][7] = 0; + + abe_block_copy (COPY_FROM_HOST_TO_ABE, ABE_DMEM, D_multiFrame_ADDR, (abe_uint32*)VirtAudio_aMultiFrame, sizeof (VirtAudio_aMultiFrame)); + + // EANC Fast Loopback + // dFastLoopback = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_EANC_WRAP2; + // abe_block_copy (COPY_FROM_HOST_TO_ABE, ABE_DMEM, D_pFastLoopBack_ADDR, (abe_uint32*)&dFastLoopback, sizeof (dFastLoopback)); + + /* reset the uplink router */ + n = D_aUplinkRouting_ADDR_END - D_aUplinkRouting_ADDR + 1; + for(i = 0; i < n; i++) + aUplinkMuxing[i] = ZERO_labelID; + + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, D_aUplinkRouting_ADDR, (abe_uint32 *)aUplinkMuxing, sizeof(aUplinkMuxing)); +} + +/* + * ABE_INIT_ATC + * + * Parameter : + * prot : protocol being used + * + * Operations : + * load the DMEM ATC/AESS descriptors + * + * Return value : + * + */ +void abe_init_atc(abe_port_id id) +{ + abe_satcdescriptor_aess desc; + abe_uint8 iter; + abe_int32 datasize; + + // load default values of the descriptor + desc.rdpt = desc.wrpt = desc.irqdest = desc.cberr = desc.desen = desc.nw =0; + desc.reserved0 = desc.reserved1 = desc.reserved2 = 0; + desc.srcid = desc.destid = desc.badd = desc.iter = desc.cbsize = 0; + + datasize = abe_dma_port_iter_factor (&((abe_port[id]).format)); + iter = (abe_uint8) abe_dma_port_iteration (&((abe_port[id]).format)); + + if (abe_port[id].protocol.direction == ABE_ATC_DIRECTION_IN) // IN from AESS point of view + if (iter + 2*datasize > 126) + desc.wrpt = (iter >>1) + (2*datasize); + else + desc.wrpt = iter + 2*datasize; + else + desc.wrpt = 0 + 2*datasize; + + switch ((abe_port[id]).protocol.protocol_switch) { + case SLIMBUS_PORT_PROT: + desc.cbdir = (abe_port[id]).protocol.direction; + desc.cbsize = (abe_port[id]).protocol.p.prot_slimbus.buf_size; + desc.badd = ((abe_port[id]).protocol.p.prot_slimbus.buf_addr1) >> 4; + desc.iter = (abe_port[id]).protocol.p.prot_slimbus.iter; + desc.srcid = abe_atc_srcid [(abe_port[id]).protocol.p.prot_slimbus.desc_addr1 >> 3]; + + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, + (abe_port[id]).protocol.p.prot_slimbus.desc_addr1, + (abe_uint32*)&desc, sizeof(desc)); + + desc.badd = (abe_port[id]).protocol.p.prot_slimbus.buf_addr2; + desc.srcid = abe_atc_srcid [(abe_port[id]).protocol.p.prot_slimbus.desc_addr2 >> 3]; + + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, + (abe_port[id]).protocol.p.prot_slimbus.desc_addr2, + (abe_uint32*)&desc, sizeof(desc)); + break; + case SERIAL_PORT_PROT: + desc.cbdir = (abe_port[id]).protocol.direction; + desc.cbsize = (abe_port[id]).protocol.p.prot_serial.buf_size; + desc.badd = ((abe_port[id]).protocol.p.prot_serial.buf_addr) >> 4; + desc.iter = (abe_port[id]).protocol.p.prot_serial.iter; + desc.srcid = abe_atc_srcid[(abe_port[id]).protocol.p.prot_serial.desc_addr >> 3]; + desc.destid = abe_atc_dstid[(abe_port[id]).protocol.p.prot_serial.desc_addr >> 3]; + + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, + (abe_port[id]).protocol.p.prot_serial.desc_addr, + (abe_uint32*)&desc, sizeof(desc)); + break; + case DMIC_PORT_PROT: + desc.cbdir = ABE_ATC_DIRECTION_IN; + desc.cbsize = (abe_port[id]).protocol.p.prot_dmic.buf_size; + desc.badd = ((abe_port[id]).protocol.p.prot_dmic.buf_addr) >> 4; + desc.iter = DMIC_ITER; + desc.srcid = abe_atc_srcid[ABE_ATC_DMIC_DMA_REQ]; + + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, + ABE_ATC_DMIC_DMA_REQ * ATC_SIZE, (abe_uint32*)&desc, sizeof(desc)); + break; + case MCPDMDL_PORT_PROT: + abe_global_mcpdm_control = abe_port[id].protocol.p.prot_mcpdmdl.control; /* Control allowed on McPDM DL */ + desc.cbdir = ABE_ATC_DIRECTION_OUT; + desc.cbsize = (abe_port[id]).protocol.p.prot_mcpdmdl.buf_size; + desc.badd = ((abe_port[id]).protocol.p.prot_mcpdmdl.buf_addr) >> 4; + desc.iter = MCPDM_DL_ITER; + desc.destid = abe_atc_dstid[ABE_ATC_MCPDMDL_DMA_REQ]; + + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, + ABE_ATC_MCPDMDL_DMA_REQ * ATC_SIZE, (abe_uint32*)&desc, sizeof(desc)); + break; + case MCPDMUL_PORT_PROT: + desc.cbdir = ABE_ATC_DIRECTION_IN; + desc.cbsize = (abe_port[id]).protocol.p.prot_mcpdmul.buf_size; + desc.badd = ((abe_port[id]).protocol.p.prot_mcpdmul.buf_addr) >> 4; + desc.iter = MCPDM_UL_ITER; + desc.srcid = abe_atc_srcid[ABE_ATC_MCPDMUL_DMA_REQ]; + + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, + ABE_ATC_MCPDMUL_DMA_REQ * ATC_SIZE, (abe_uint32*)&desc, sizeof(desc)); + break; + case PINGPONG_PORT_PROT: + /* software protocol, nothing to do on ATC */ + break; + case DMAREQ_PORT_PROT: + desc.cbdir = (abe_port[id]).protocol.direction; + desc.cbsize = (abe_port[id]).protocol.p.prot_dmareq.buf_size; + desc.badd = ((abe_port[id]).protocol.p.prot_dmareq.buf_addr) >> 4; + desc.iter = 1; /* CBPr needs ITER=1. this is the eDMA job to do the iterations */ + /* input from ABE point of view */ + if (abe_port[id].protocol.direction == ABE_ATC_DIRECTION_IN) { + desc.rdpt = 127; + desc.wrpt = 0; + desc.srcid = abe_atc_srcid[(abe_port[id]).protocol.p.prot_dmareq.desc_addr >> 3]; + } else { + desc.rdpt = 0; + desc.wrpt = 127; + desc.destid = abe_atc_dstid[(abe_port[id]).protocol.p.prot_dmareq.desc_addr >> 3]; + } + + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, + (abe_port[id]).protocol.p.prot_dmareq.desc_addr, (abe_uint32*)&desc, sizeof (desc)); + break; + default: + break; + } +} + +/* + * + * ABE_INIT_DMA_T + * Parameter : + * prot : protocol being used + * + * Operations : + * load the dma_t with physical information from AE memory mapping + * + * Return value : + * + */ +void abe_init_dma_t(abe_port_id id, abe_port_protocol_t *prot) +{ + abe_dma_t_offset dma; + abe_uint32 idx; + + dma.data = 0; /* default dma_t points to address 0000... */ + dma.iter = 0; + + switch (prot->protocol_switch) { + case PINGPONG_PORT_PROT: + for (idx = 0; idx < 32; idx++) { + if (((prot->p).prot_pingpong.irq_data) == (abe_uint32)(1 << idx)) + break; + } + (prot->p).prot_dmareq.desc_addr = (CBPr_DMA_RTX0+idx)*ATC_SIZE; + dma.data = (prot->p).prot_pingpong.buf_addr; + dma.iter = (prot->p).prot_pingpong.buf_size; + break; + case DMAREQ_PORT_PROT: + for (idx = 0; idx < 32; idx++) { + if (((prot->p).prot_dmareq.dma_data) == (abe_uint32)(1 << idx)) + break; + } + dma.data = (CIRCULAR_BUFFER_PERIPHERAL_R__0 + idx*4); + dma.iter = (prot->p).prot_dmareq.iter; + (prot->p).prot_dmareq.desc_addr = (CBPr_DMA_RTX0+idx)*ATC_SIZE; + break; + case SLIMBUS_PORT_PROT: + case SERIAL_PORT_PROT: + case DMIC_PORT_PROT: + case MCPDMDL_PORT_PROT: + case MCPDMUL_PORT_PROT: + default: + break; + } + + /* upload the dma type */ + abe_port [id].dma = dma; +} + +/* + * ABE_DISENABLE_DMA_REQUEST + * Parameter: + * Operations: + * Return value: + */ +void abe_disable_enable_dma_request(abe_port_id id, abe_uint32 on_off) +{ + ABE_SIODescriptor desc; + abe_uint8 desc_second_word[4], irq_dmareq_field; + abe_uint32 sio_desc_address; + + if (abe_port[id].protocol.protocol_switch == DMAREQ_PORT_PROT) { + sio_desc_address = dmem_port_descriptors + (id * sizeof(ABE_SIODescriptor)); + abe_block_copy(COPY_FROM_ABE_TO_HOST, ABE_DMEM, sio_desc_address, (abe_uint32*)&desc, sizeof (desc)); + if (on_off) { + desc.atc_irq_data = (abe_uint8) abe_port[id].protocol.p.prot_dmareq.dma_data; + desc.on_off = 0x80; + } else { + desc.atc_irq_data = 0; + desc.on_off = 0; + } + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, sio_desc_address, (abe_uint32*)&desc, sizeof (desc)); + } + + if (abe_port[id].protocol.protocol_switch == PINGPONG_PORT_PROT) { + irq_dmareq_field = (abe_uint8)(on_off * abe_port[id].protocol.p.prot_pingpong.irq_data); + sio_desc_address = D_PingPongDesc_ADDR; + + abe_block_copy(COPY_FROM_ABE_TO_HOST, ABE_DMEM, sio_desc_address + 4, (abe_uint32 *)desc_second_word, 4); + desc_second_word[2] = irq_dmareq_field; + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, sio_desc_address + 4, (abe_uint32 *)desc_second_word, 4); + } +} + +void abe_enable_dma_request(abe_port_id id) +{ + abe_disable_enable_dma_request(id, 1); +} + +/* + * ABE_DISABLE_DMA_REQUEST + * + * Parameter: + * Operations: + * Return value: + * + */ +void abe_disable_dma_request(abe_port_id id) +{ + abe_disable_enable_dma_request(id, 0); +} + + +/* + * ABE_ENABLE_ATC + * Parameter: + * Operations: + * Return value: + */ +void abe_enable_atc(abe_port_id id) +{ + just_to_avoid_the_many_warnings = (abe_port_id)id; +#if 0 + abe_satcdescriptor_aess desc; + abe_block_copy(COPY_FROM_ABE_TO_HOST, ABE_DMEM, + (abe_port[id]).protocol.p.prot_dmareq.desc_addr, + (abe_uint32*)&desc, sizeof (desc)); + desc.desen = 1; + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, + (abe_port[id]).protocol.p.prot_dmareq.desc_addr, + (abe_uint32*)&desc, sizeof (desc)); +#endif +} + + +/* + * ABE_DISABLE_ATC + * Parameter: + * Operations: + * Return value: + */ +void abe_disable_atc(abe_port_id id) +{ + abe_satcdescriptor_aess desc; + + abe_block_copy(COPY_FROM_ABE_TO_HOST, ABE_DMEM, + (abe_port[id]).protocol.p.prot_dmareq.desc_addr, + (abe_uint32*)&desc, sizeof (desc)); + desc.desen = 0; + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, + (abe_port[id]).protocol.p.prot_dmareq.desc_addr, + (abe_uint32*)&desc, sizeof (desc)); +} + +/* + * ABE_INIT_IO_TASKS + * + * Parameter : + * prot : protocol being used + * + * Operations : + * load the micro-task parameters doing to DMEM <==> SMEM data moves + * + * I/O descriptors input parameters : + * For Read from DMEM usually THR1/THR2 = X+1/X-1 + * For Write to DMEM usually THR1/THR2 = 2/0 + * UP_1/2 =X+1/X-1 + * + * Return value : + * + */ +void abe_init_io_tasks(abe_port_id id, abe_data_format_t *format, abe_port_protocol_t *prot) +{ + ABE_SIODescriptor desc; + ABE_SPingPongDescriptor desc_pp; + abe_uint32 x_io, direction, iter_samples, smem1, smem2, smem3, io_sub_id; + abe_uint32 copy_func_index, before_func_index, after_func_index; + abe_uint32 dmareq_addr, dmareq_field; + abe_uint32 sio_desc_address, datasize, iter, nsamp, datasize2, dOppMode32; + abe_uint32 atc_ptr_saved, atc_ptr_saved2, copy_func_index1; + abe_uint32 copy_func_index2, atc_desc_address1, atc_desc_address2; + short VirtAudio_aMultiFrame[PROCESSING_SLOTS][TASKS_IN_SLOT]; + + if (prot->protocol_switch == PINGPONG_PORT_PROT) { + if (MM_DL_PORT == id) { + // @@@@ reset local memory + abe_block_copy(COPY_FROM_ABE_TO_HOST, ABE_DMEM, + D_multiFrame_ADDR, + (abe_uint32*)VirtAudio_aMultiFrame, + sizeof (VirtAudio_aMultiFrame)); + VirtAudio_aMultiFrame[TASK_IO_MM_DL_SLT][TASK_IO_MM_DL_IDX] = + D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_PING_PONG; + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, + D_multiFrame_ADDR, (abe_uint32*)VirtAudio_aMultiFrame, + sizeof (VirtAudio_aMultiFrame)); + } else { + abe_dbg_param |= ERR_API; + abe_dbg_error_log (ABE_PARAMETER_ERROR); + } + + smem1 = (abe_uint8) abe_port[id].smem_buffer1; + copy_func_index = (abe_uint8) abe_dma_port_copy_subroutine_id (id); + dmareq_addr = abe_port[id].protocol.p.prot_pingpong.irq_addr; + dmareq_field = abe_port[id].protocol.p.prot_pingpong.irq_data; + datasize = abe_dma_port_iter_factor (format); + iter = abe_dma_port_iteration (format); + iter_samples = (iter / datasize); /* number of "samples" either mono or stereo */ + + /* load the IO descriptor */ + desc_pp.drift_ASRC = 0; /* no drift */ + desc_pp.drift_io = 0; /* no drift */ + desc_pp.hw_ctrl_addr = (abe_uint16) dmareq_addr; + desc_pp.copy_func_index = (abe_uint8) copy_func_index; + desc_pp.smem_addr = (abe_uint8) smem1; + desc_pp.atc_irq_data = (abe_uint8) dmareq_field; /* DMA req 0 is used for CBPr0 */ + desc_pp.x_io = (abe_uint8) iter_samples; /* size of block transfer */ + desc_pp.data_size = (abe_uint8) datasize; + desc_pp.workbuff_BaseAddr = (abe_uint16) (abe_base_address_pingpong [0]); /* address comunicated in Bytes */ + desc_pp.workbuff_Samples = (abe_uint16) ((abe_size_pingpong/datasize) >> 2); /* size comunicated in XIO sample */ + desc_pp.nextbuff0_BaseAddr = (abe_uint16) (abe_base_address_pingpong [0]); + desc_pp.nextbuff0_Samples = (abe_uint16) ((abe_size_pingpong/datasize) >> 2); + desc_pp.nextbuff1_BaseAddr = (abe_uint16) (abe_base_address_pingpong [1]); + desc_pp.nextbuff1_Samples = (abe_uint16) ((abe_size_pingpong/datasize) >> 2); + desc_pp.counter = 1; + + /* send a DMA req to fill B0 with N samples + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_ATC, ABE_DMASTATUS_RAW, &(abe_port[id].protocol.p.prot_pingpong.irq_data), 4); */ + + sio_desc_address = D_PingPongDesc_ADDR; + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, sio_desc_address, + (abe_uint32*)&desc_pp, sizeof (desc_pp)); + } else { + io_sub_id = dmareq_addr = ABE_DMASTATUS_RAW; + dmareq_field = 0; + atc_desc_address1 = atc_desc_address2 = 0; + + datasize2=datasize = abe_dma_port_iter_factor(format); + x_io = (abe_uint8) abe_dma_port_iteration(format); + nsamp = (x_io / datasize); + + atc_ptr_saved2=atc_ptr_saved = DMIC_ATC_PTR_labelID + id; + + smem1 = abe_port[id].smem_buffer1; + smem3 = smem2 = abe_port[id].smem_buffer2; + + copy_func_index1 = (abe_uint8) abe_dma_port_copy_subroutine_id(id); + before_func_index = after_func_index = copy_func_index2 = NULL_COPY_CFPID; + + switch (prot->protocol_switch) { + case DMIC_PORT_PROT: + /* DMIC port is read in two steps */ + x_io = x_io >> 1; + nsamp = nsamp >> 1; + atc_desc_address1 = ABE_ATC_DMIC_DMA_REQ*ATC_SIZE; + io_sub_id = IO_IP_CFPID; + break; + case MCPDMDL_PORT_PROT: + /* PDMDL port is written to in two steps */ + x_io = x_io >> 1; + atc_desc_address1 = ABE_ATC_MCPDMDL_DMA_REQ*ATC_SIZE; + io_sub_id = IO_IP_CFPID; + break; + case MCPDMUL_PORT_PROT: + atc_desc_address1 = ABE_ATC_MCPDMUL_DMA_REQ*ATC_SIZE; + io_sub_id = IO_IP_CFPID; + break; + case SLIMBUS_PORT_PROT: + atc_desc_address1 = abe_port[id].protocol.p.prot_slimbus.desc_addr1; + atc_desc_address2 = abe_port[id].protocol.p.prot_slimbus.desc_addr2; + copy_func_index2 = NULL_COPY_CFPID; +/* @@@@@@ +#define SPLIT_SMEM_CFPID 9 +#define MERGE_SMEM_CFPID 10 +#define SPLIT_TDM_12_CFPID 11 +#define MERGE_TDM_12_CFPID 12 +*/ + io_sub_id = IO_IP_CFPID; + case SERIAL_PORT_PROT: /* McBSP/McASP */ + atc_desc_address1 = (abe_int16) abe_port[id].protocol.p.prot_serial.desc_addr; + io_sub_id = IO_IP_CFPID; + break; + case DMAREQ_PORT_PROT: /* DMA w/wo CBPr */ + dmareq_addr = abe_port[id].protocol.p.prot_dmareq.dma_addr; + dmareq_field = 0; + atc_desc_address1 = abe_port[id].protocol.p.prot_dmareq.desc_addr; + io_sub_id = IO_DMAREQ_CFPID; + break; + default: + break; + } + + /* special situation of the PING_PONG protocol which has its own SIO descriptor format */ + /* Sequence of operations on ping-pong buffers B0/B1 + * ---------- time --------------------------------------------->>>> + * Host Application is ready to send data from DDR to B0 + * SDMA is initialized from "abe_connect_irq_ping_pong_port" to B0 + * ABE HAL init FW to B0 + * send DMAreq to fill B0 + * FIRMWARE starts sending B1 data, sends DMAreq v + * continue with B0, sends DMAreq v continue with B1 + * DMAreq v (direct access from HAL to AESS regs) + * v (from ABE_FW) v (from ABE_FW) + * SDMA | fills B0 | fills B1...| fills B0... + */ + + if (MM_UL_PORT == id) { + copy_func_index1 = sub_copy_mm_ul; + before_func_index = ROUTE_MM_UL_CFPID; + } + + /* check for 8kHz/16kHz */ + if (VX_DL_PORT == id) { + abe_block_copy(COPY_FROM_ABE_TO_HOST, ABE_DMEM, D_multiFrame_ADDR, + (abe_uint32*)VirtAudio_aMultiFrame, sizeof (VirtAudio_aMultiFrame)); + if (abe_port[id].format.f == 8000) { + //@@@ VirtAudio_aMultiFrame[TASK_ASRC_VX_DL_SLT][TASK_ASRC_VX_DL_IDX] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_ASRC_VX_DL_8; + VirtAudio_aMultiFrame[TASK_VX_DL_SLT][TASK_VX_DL_IDX] = + D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_VX_DL_8_48; + smem1 = Voice_8k_DL_labelID; //@@@ IO_VX_DL_ASRC_labelID + } else { + //@@@ VirtAudio_aMultiFrame[TASK_ASRC_VX_DL_SLT][TASK_ASRC_VX_DL_IDX] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_ASRC_VX_DL_16; + VirtAudio_aMultiFrame[TASK_VX_DL_SLT][TASK_VX_DL_IDX] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_VX_DL_16_48; + smem1 = Voice_16k_DL_labelID; //@@@ IO_VX_DL_ASRC_labelID + } + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, D_multiFrame_ADDR, + (abe_uint32*)VirtAudio_aMultiFrame, sizeof (VirtAudio_aMultiFrame)); + } + /* check for 8kHz/16kHz */ + if (VX_UL_PORT == id) { + abe_block_copy(COPY_FROM_ABE_TO_HOST, ABE_DMEM, D_multiFrame_ADDR, (abe_uint32*)VirtAudio_aMultiFrame, sizeof(VirtAudio_aMultiFrame)); + if (abe_port[id].format.f == 8000) { + //@@@ VirtAudio_aMultiFrame[TASK_ASRC_VX_UL_SLT][TASK_ASRC_VX_UL_IDX] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_ASRC_VX_UL_8; + VirtAudio_aMultiFrame[TASK_VX_UL_SLT][TASK_VX_UL_IDX] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_VX_UL_48_8; + //@@@ VirtAudio_aMultiFrame[TASK_ECHO_SLT][TASK_ECHO_IDX] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_ECHO_REF_48_8; + //@@@ VirtAudio_aMultiFrame[TASK_ASRC_ECHO_SLT][TASK_ASRC_ECHO_IDX] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_ASRC_ECHO_REF_8; + smem1 = Voice_8k_UL_labelID; //@@@ XinASRC_UL_VX_labelID + } else { + //@@@ VirtAudio_aMultiFrame[TASK_ASRC_VX_UL_SLT][TASK_ASRC_VX_UL_IDX] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_ASRC_VX_UL_16; + VirtAudio_aMultiFrame[TASK_VX_UL_SLT][TASK_VX_UL_IDX] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_VX_UL_48_16; + //@@@ VirtAudio_aMultiFrame[TASK_ECHO_SLT][TASK_ECHO_IDX] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_ECHO_REF_48_16; + //@@@ VirtAudio_aMultiFrame[TASK_ASRC_ECHO_SLT][TASK_ASRC_ECHO_IDX] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_ASRC_ECHO_REF_16; + smem1 = Voice_16k_UL_labelID; //@@@ XinASRC_UL_VX_labelID + } + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, D_multiFrame_ADDR, (abe_uint32*)VirtAudio_aMultiFrame, sizeof(VirtAudio_aMultiFrame)); + } + + /* check for 8kHz/16kHz */ + if (BT_VX_DL_PORT == id) { + abe_block_copy(COPY_FROM_ABE_TO_HOST, ABE_DMEM, + D_multiFrame_ADDR, + (abe_uint32*)VirtAudio_aMultiFrame, + sizeof (VirtAudio_aMultiFrame)); + if (abe_port[id].format.f == 8000) { + VirtAudio_aMultiFrame[TASK_BT_DL_48_8_SLT][TASK_BT_DL_48_8_IDX] = + D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_BT_DL_48_8; + smem1 = BT_DL_8k_labelID; + } else { + VirtAudio_aMultiFrame[TASK_BT_DL_48_8_SLT][TASK_BT_DL_48_8_IDX] = + D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_BT_DL_48_16; + smem1 = BT_DL_16k_labelID; + } + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, + D_multiFrame_ADDR, (abe_uint32*)VirtAudio_aMultiFrame, + sizeof (VirtAudio_aMultiFrame)); + } + + /* check for 8kHz/16kHz */ + if (BT_VX_UL_PORT == id) { + abe_block_copy(COPY_FROM_ABE_TO_HOST, ABE_DMEM, D_multiFrame_ADDR, + (abe_uint32*)VirtAudio_aMultiFrame, sizeof (VirtAudio_aMultiFrame)); + if (abe_port[id].format.f == 8000) { + VirtAudio_aMultiFrame[TASK_BT_UL_8_48_SLT][TASK_BT_UL_8_48_IDX] = + D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_BT_UL_8_48; + smem1 = BT_UL_8k_labelID; + } else { + VirtAudio_aMultiFrame[TASK_BT_UL_8_48_SLT][TASK_BT_UL_8_48_IDX] = + D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_BT_UL_16_48; + smem1 = BT_UL_16k_labelID; + } + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, + D_multiFrame_ADDR, (abe_uint32*)VirtAudio_aMultiFrame, + sizeof (VirtAudio_aMultiFrame)); + } + + if (MM_DL_PORT == id) { + //@@@ abe_block_copy (COPY_FROM_ABE_TO_HOST, ABE_DMEM, D_multiFrame_ADDR, (abe_uint32*)VirtAudio_aMultiFrame, sizeof (VirtAudio_aMultiFrame)); + //@@@ VirtAudio_aMultiFrame[TASK_IO_MM_DL_SLT][TASK_IO_MM_DL_IDX] = D_tasksList_ADDR + sizeof(ABE_STask)*C_ABE_FW_TASK_IO2_MM_DL; + //@@@ abe_block_copy (COPY_FROM_HOST_TO_ABE, ABE_DMEM, D_multiFrame_ADDR, (abe_uint32*)VirtAudio_aMultiFrame, sizeof (VirtAudio_aMultiFrame)); + /* set the SMEM buffer @@@@@ programming sequence : OPP must be set before channel is defined */ + abe_block_copy (COPY_FROM_ABE_TO_HOST, ABE_DMEM, D_maxTaskBytesInSlot_ADDR, &dOppMode32, sizeof(abe_uint32)); + if (dOppMode32 == DOPPMODE32_OPP100) + smem1 = smem_mm_dl_opp100; /* ASRC input buffer, size 40 */ + else + smem1 = smem_mm_dl_opp25; /* at OPP 25/50 or without ASRC */ + } + /* MM_EXT_IN takes the PDM_UL path */ + if (MM_EXT_IN_PORT == id) { + /* set the PDM_UL SMEM buffer to /nul */ + sio_desc_address = dmem_port_descriptors + (PDM_UL_PORT * sizeof(ABE_SIODescriptor)); + abe_block_copy (COPY_FROM_ABE_TO_HOST, ABE_DMEM, sio_desc_address, (abe_uint32*)&desc, sizeof(desc)); + desc.smem_addr1 = (abe_uint16) Dummy_AM_labelID; + abe_block_copy (COPY_FROM_HOST_TO_ABE, ABE_DMEM, sio_desc_address, (abe_uint32*)&desc, sizeof(desc)); + } + + if (abe_port[id].protocol.direction == ABE_ATC_DIRECTION_IN) + direction = 0; + else + direction = 3; /* offset of the write pointer in the ATC descriptor */ + + desc.drift_ASRC = 0; + desc.drift_io = 0; + desc.io_type_idx = (abe_uint8) io_sub_id; + desc.samp_size = (abe_uint8) datasize; + //desc.unused1 = (abe_uint8)0; + //desc.unused2 = (abe_uint8)0; + + desc.hw_ctrl_addr = (abe_uint16) (dmareq_addr << 2); + desc.atc_irq_data = (abe_uint8) dmareq_field; + desc.flow_counter = (abe_uint16) 0; + + desc.direction_rw = (abe_uint8) direction; + desc.nsamp = (abe_uint8) nsamp; + desc.x_io = (abe_uint8) x_io; + desc.on_off = 0x80; // set ATC ON + + desc.split_addr1 = (abe_uint16) smem1; + desc.split_addr2 = (abe_uint16) smem2; + desc.split_addr3 = (abe_uint16) smem3; + desc.before_f_index = (abe_uint8) before_func_index; + desc.after_f_index = (abe_uint8) after_func_index; + + desc.smem_addr1 = (abe_uint16) smem1; + desc.atc_address1 = (abe_uint16) atc_desc_address1; + desc.atc_pointer_saved1 = (abe_uint16) atc_ptr_saved; + desc.data_size1 = (abe_uint8) datasize; + desc.copy_f_index1 = (abe_uint8) copy_func_index1; + + desc.smem_addr2 = (abe_uint16) smem2; + desc.atc_address2 = (abe_uint16) atc_desc_address2; + desc.atc_pointer_saved2 = (abe_uint16) atc_ptr_saved2; + desc.data_size2 = (abe_uint8) datasize2; + desc.copy_f_index2 = (abe_uint8) copy_func_index2; + + sio_desc_address = dmem_port_descriptors + (id * sizeof(ABE_SIODescriptor)); + abe_block_copy(COPY_FROM_HOST_TO_ABE, ABE_DMEM, + sio_desc_address, (abe_uint32*)&desc, sizeof(desc)); + } +} + +/* + * ABE_INIT_DMIC + * + * Parameter : + * x : d + * + * Operations : + * + * + * Return value : + * + */ +void abe_init_dmic(abe_uint32 x) +{ + just_to_avoid_the_many_warnings = x; +} + +/* + * ABE_INIT_MCPDM + * + * Parameter : + * x : d + * + * Operations : + * + * + * Return value : + * + */ +void abe_init_mcpdm(abe_uint32 x) +{ + just_to_avoid_the_many_warnings = x; +} + +/* + * ABE_RESET_FEATURE + * + * Parameter : + * x : index of the feature to be initialized + * + * Operations : + * reload the configuration + * + * Return value : + * + */ +void abe_reset_one_feature(abe_uint32 x) +{ + all_feature[x] = all_feature_init[x]; /* load default fields */ + /* abe_call_subroutine ((all_feature[x]).disable_feature, NOPARAMETER, NOPARAMETER, NOPARAMETER, NOPARAMETER); */ +} + +/* + * ABE_RESET_ALL_FEATURE + * + * Parameter : + * none + * + * Operations : + * load default configuration for all features + * struct { + * uint16 load_default_data; + * uint16 read_parameter; + * uint16 write_parameter; + * uint16 running_status; + * uint16 fw_input_buffer_address; + * uint16 fw_output_buffer_address; + * uint16 fw_scheduler_slot_position; + * uint16 fw_scheduler_subslot_position; + * uint16 min_opp; + * char name[NBCHARFEATURENAME]; + * } abe_feature_t; + * + * Return value : + * + */ +void abe_reset_all_features(void) +{ + abe_uint16 i; + + for (i = 0; i < FEAT_GAINS_DMIC1; i++) + abe_reset_one_feature(i); +} + +/* ABE_RESET_ONE_PORT + * + * Parameter : + * none + * + * Operations : + * load default configuration for one port + * + * Return value : + * + */ +void abe_reset_one_port(abe_uint32 x) +{ + abe_port[x] = abe_port_init[x]; +} + +/* + * ABE_RESET_ALL_PORTS + * + * Parameter : + * none + * + * Operations : + * load default configuration for all features + * + * Return value : + * + */ +void abe_reset_all_ports(void) +{ + abe_uint16 i; + + for (i = 0; i < MAXNBABEPORTS; i++) + abe_reset_one_port(i); + + /* mixers' configuration */ + abe_write_mixer(MIXDL1, GAIN_M6dB, RAMP_100MS, MIX_DL1_INPUT_MM_DL); + abe_write_mixer(MIXDL1, MUTE_GAIN, RAMP_100MS, MIX_DL1_INPUT_MM_UL2); + abe_write_mixer(MIXDL1, GAIN_M6dB, RAMP_100MS, MIX_DL1_INPUT_VX_DL); + abe_write_mixer(MIXDL1, GAIN_M6dB, RAMP_100MS, MIX_DL1_INPUT_TONES); + + abe_write_mixer(MIXDL2, GAIN_0dB , RAMP_100MS, MIX_DL2_INPUT_TONES); + abe_write_mixer(MIXDL2, GAIN_0dB , RAMP_100MS, MIX_DL2_INPUT_VX_DL); + abe_write_mixer(MIXDL2, GAIN_0dB , RAMP_100MS, MIX_DL2_INPUT_MM_DL); + abe_write_mixer(MIXDL2, MUTE_GAIN, RAMP_100MS, MIX_DL2_INPUT_MM_UL2); + + abe_write_mixer(MIXSDT, MUTE_GAIN, RAMP_100MS, MIX_SDT_INPUT_UP_MIXER); + abe_write_mixer(MIXSDT, GAIN_0dB , RAMP_100MS, MIX_SDT_INPUT_DL1_MIXER); + + abe_write_mixer(MIXECHO, GAIN_0dB, RAMP_100MS, GAIN_LEFT_OFFSET); + abe_write_mixer(MIXECHO, GAIN_0dB, RAMP_100MS, GAIN_RIGHT_OFFSET); + + abe_write_mixer(MIXAUDUL, MUTE_GAIN, RAMP_100MS, MIX_AUDUL_INPUT_MM_DL); + abe_write_mixer(MIXAUDUL, MUTE_GAIN, RAMP_100MS, MIX_AUDUL_INPUT_TONES); + abe_write_mixer(MIXAUDUL, GAIN_0dB, RAMP_100MS, MIX_AUDUL_INPUT_UPLINK); + abe_write_mixer(MIXAUDUL, MUTE_GAIN, RAMP_100MS, MIX_AUDUL_INPUT_VX_DL); + + abe_write_mixer(MIXVXREC, GAIN_0dB, RAMP_100MS, MIX_VXREC_INPUT_TONES); + abe_write_mixer(MIXVXREC, GAIN_0dB, RAMP_100MS, MIX_VXREC_INPUT_VX_DL); + abe_write_mixer(MIXVXREC, GAIN_0dB, RAMP_100MS, MIX_VXREC_INPUT_MM_DL); + abe_write_mixer(MIXVXREC, GAIN_0dB, RAMP_100MS, MIX_VXREC_INPUT_VX_UL); + + abe_write_gain(GAINS_DMIC1,GAIN_0dB, RAMP_100MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_DMIC1,GAIN_0dB, RAMP_100MS, GAIN_RIGHT_OFFSET); + abe_write_gain(GAINS_DMIC2,GAIN_0dB, RAMP_100MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_DMIC2,GAIN_0dB, RAMP_100MS, GAIN_RIGHT_OFFSET); + abe_write_gain(GAINS_DMIC3,GAIN_0dB, RAMP_100MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_DMIC3,GAIN_0dB, RAMP_100MS, GAIN_RIGHT_OFFSET); + abe_write_gain(GAINS_AMIC,GAIN_0dB, RAMP_100MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_AMIC, GAIN_0dB, RAMP_100MS, GAIN_RIGHT_OFFSET); + + abe_write_gain(GAINS_SPLIT, GAIN_0dB, RAMP_100MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_SPLIT, GAIN_0dB, RAMP_100MS, GAIN_RIGHT_OFFSET); + //abe_write_gain(GAINS_EANC ,GAIN_0dB , RAMP_100MS, GAIN_LEFT_OFFSET); + //abe_write_gain(GAINS_EANC, GAIN_0dB , RAMP_100MS, GAIN_RIGHT_OFFSET); + + abe_write_gain(GAINS_DL1, GAIN_0dB, RAMP_100MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_DL1, GAIN_0dB, RAMP_100MS, GAIN_RIGHT_OFFSET); + abe_write_gain(GAINS_DL2, GAIN_0dB, RAMP_100MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_DL2, GAIN_0dB, RAMP_100MS, GAIN_RIGHT_OFFSET); +} + +/* + * ABE_CLEAN_TEMPORARY_BUFFERS + * + * Parameter : + * none + * + * Operations : + * clear temporary buffers + * + * Return value : + * + */ +void abe_clean_temporary_buffers(abe_port_id id) +{ + switch (id) { + case DMIC_PORT: + abe_reset_mem(ABE_DMEM, D_DMIC_UL_FIFO_ADDR,D_DMIC_UL_FIFO_sizeof); + abe_reset_mem(ABE_SMEM, S_DMIC0_96_48_data_ADDR << 3, S_DMIC0_96_48_data_sizeof << 3); + abe_reset_mem(ABE_SMEM, S_DMIC1_96_48_data_ADDR << 3, S_DMIC1_96_48_data_sizeof << 3); + abe_reset_mem(ABE_SMEM, S_DMIC2_96_48_data_ADDR << 3, S_DMIC1_96_48_data_sizeof << 3); + break; + case PDM_UL_PORT: + abe_reset_mem(ABE_DMEM, D_McPDM_UL_FIFO_ADDR, D_McPDM_UL_FIFO_sizeof); + abe_reset_mem(ABE_SMEM, S_BT_UL_ADDR << 3, S_BT_UL_sizeof << 3); + abe_reset_mem(ABE_SMEM, S_AMIC_96_48_data_ADDR << 3, S_AMIC_96_48_data_sizeof << 3); + break; + case BT_VX_UL_PORT: // ABE <-- BT (8/16kHz) + abe_reset_mem(ABE_DMEM, D_BT_UL_FIFO_ADDR, D_BT_UL_FIFO_sizeof); + abe_reset_mem(ABE_SMEM, S_BT_UL_ADDR << 3, S_BT_UL_sizeof << 3); + abe_reset_mem(ABE_SMEM, S_BT_UL_ADDR << 3, S_BT_UL_sizeof << 3); + break; + case MM_UL_PORT: + abe_reset_mem(ABE_DMEM, D_MM_UL_FIFO_ADDR, D_MM_UL_FIFO_sizeof); + abe_reset_mem(ABE_SMEM, S_MM_UL_ADDR << 3, S_MM_UL_sizeof << 3); + abe_reset_mem(ABE_SMEM, S_MM_UL2_ADDR << 3, D_MM_UL2_FIFO_sizeof << 3); + break; + case MM_UL2_PORT: + abe_reset_mem(ABE_DMEM, D_MM_UL2_FIFO_ADDR, D_MM_UL2_FIFO_sizeof); + abe_reset_mem(ABE_SMEM, S_MM_UL2_ADDR << 3, S_MM_UL2_sizeof << 3); + break; + case VX_UL_PORT: + abe_reset_mem(ABE_DMEM, D_VX_UL_FIFO_ADDR, D_VX_UL_FIFO_sizeof); + abe_reset_mem(ABE_SMEM, S_VX_UL_ADDR << 3, S_VX_UL_sizeof << 3); + abe_reset_mem(ABE_SMEM, S_VX_UL_48_8_BP_data_ADDR << 3, S_VX_UL_48_8_BP_data_sizeof << 3); + abe_reset_mem(ABE_SMEM, S_VX_UL_48_8_LP_data_ADDR << 3, S_VX_UL_48_8_LP_data_sizeof << 3); + abe_reset_mem(ABE_SMEM, S_VX_UL_48_16_HP_data_ADDR << 3, S_VX_UL_48_16_HP_data_sizeof << 3); + abe_reset_mem(ABE_SMEM, S_VX_UL_48_16_LP_data_ADDR << 3, S_VX_UL_48_16_LP_data_sizeof << 3); + break; + case MM_DL_PORT: + abe_reset_mem(ABE_DMEM, D_MM_DL_FIFO_ADDR, D_MM_DL_FIFO_sizeof); + abe_reset_mem(ABE_SMEM, S_MM_DL_ADDR << 3, S_MM_DL_sizeof << 3); + break; + case VX_DL_PORT: + abe_reset_mem(ABE_DMEM, D_VX_DL_FIFO_ADDR, D_VX_DL_FIFO_sizeof); + abe_reset_mem(ABE_SMEM, S_VX_DL_ADDR << 3, S_VX_DL_sizeof << 3); + abe_reset_mem(ABE_SMEM, S_VX_DL_8_48_BP_data_ADDR << 3, S_VX_DL_8_48_BP_data_sizeof << 3); + abe_reset_mem(ABE_SMEM, S_VX_DL_8_48_LP_data_ADDR << 3, S_VX_DL_8_48_LP_data_sizeof << 3); + abe_reset_mem(ABE_SMEM, S_VX_DL_16_48_HP_data_ADDR << 3, S_VX_DL_16_48_HP_data_sizeof << 3); + abe_reset_mem(ABE_SMEM, S_VX_DL_16_48_LP_data_ADDR << 3, S_VX_DL_16_48_LP_data_sizeof << 3); + break; + case TONES_DL_PORT: + abe_reset_mem(ABE_DMEM, D_TONES_DL_FIFO_ADDR, D_TONES_DL_FIFO_sizeof); + abe_reset_mem(ABE_SMEM, S_Tones_ADDR << 3, S_Tones_sizeof << 3); + break; + case VIB_DL_PORT: + abe_reset_mem(ABE_DMEM, D_VIB_DL_FIFO_ADDR, D_VIB_DL_FIFO_sizeof); + abe_reset_mem(ABE_SMEM, S_VIBRA_ADDR << 3, S_VIBRA_sizeof << 3); + break; + case BT_VX_DL_PORT:// ABE --> BT (8/16kHz) + abe_reset_mem(ABE_DMEM, D_BT_DL_FIFO_ADDR, D_BT_DL_FIFO_sizeof); + abe_reset_mem(ABE_SMEM, S_BT_DL_ADDR << 3, S_BT_DL_sizeof << 3); + break; + case PDM_DL_PORT: + abe_reset_mem(ABE_DMEM, D_McPDM_DL_FIFO_ADDR, D_McPDM_DL_FIFO_sizeof); + abe_reset_mem(ABE_SMEM, S_DMIC2_96_48_data_ADDR << 3, S_DMIC1_96_48_data_sizeof << 3); + abe_reset_mem(ABE_SMEM, S_DL2_M_LR_EQ_data_ADDR << 3, S_DL2_M_LR_EQ_data_sizeof << 3); + abe_reset_mem(ABE_SMEM, S_DL1_M_EQ_data_ADDR << 3, S_DL1_M_EQ_data_sizeof << 3); + abe_reset_mem(ABE_SMEM, S_EARP_48_96_LP_data_ADDR << 3, S_EARP_48_96_LP_data_sizeof << 3); + abe_reset_mem(ABE_SMEM, S_IHF_48_96_LP_data_ADDR << 3, S_IHF_48_96_LP_data_sizeof << 3); + abe_reset_mem(ABE_SMEM, S_APS_DL1_EQ_data_ADDR << 3, S_APS_DL1_EQ_data_sizeof << 3); + abe_reset_mem(ABE_SMEM, S_APS_DL2_EQ_data_ADDR << 3, S_APS_DL2_EQ_data_sizeof << 3); + break; + case MM_EXT_OUT_PORT: + abe_reset_mem(ABE_DMEM, D_MM_EXT_OUT_FIFO_ADDR, D_MM_EXT_OUT_FIFO_sizeof); + break; + case MM_EXT_IN_PORT: + abe_reset_mem(ABE_DMEM, D_MM_EXT_IN_FIFO_ADDR, D_MM_EXT_IN_FIFO_sizeof); + break; + default: + break; + } +} diff --git a/sound/soc/codecs/abe/abe_initxxx_labels.h b/sound/soc/codecs/abe/abe_initxxx_labels.h new file mode 100644 index 000000000000..d18907dbf6a6 --- /dev/null +++ b/sound/soc/codecs/abe/abe_initxxx_labels.h @@ -0,0 +1,293 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ + +#ifndef _ABE_INITXXX_LABELS_H_ +#define _ABE_INITXXX_LABELS_H_ + +#define Dummy_Regs_labelID 0 +#define Dummy_AM_labelID 1 +#define Voice_8k_UL_labelID 2 +#define Voice_8k_DL_labelID 3 +#define ECHO_REF_8K_labelID 4 +#define Voice_16k_UL_labelID 5 +#define Voice_16k_DL_labelID 6 +#define ECHO_REF_16K_labelID 7 +#define MM_DL_labelID 8 +#define IO_VX_DL_ASRC_labelID 9 +#define IO_MM_DL_ASRC_labelID 10 +#define IO_VIBRA_DL_labelID 11 +#define ZERO_labelID 12 +#define GTarget_labelID 13 +#define GCurrent_labelID 14 +#define Gr_1_labelID 15 +#define Gr_2_labelID 16 +#define Gr_Regs_labelID 17 +#define DMIC0_Gain_labelID 18 +#define DMIC1_Gain_labelID 19 +#define DMIC2_Gain_labelID 20 +#define DMIC3_Gain_labelID 21 +#define AMIC_Gain_labelID 22 +#define DL1_Gain_labelID 23 +#define DL2_Gain_labelID 24 +#define DEFAULT_Gain_labelID 25 +#define DL1_M_G_Tones_labelID 26 +#define DL2_M_G_Tones_labelID 27 +#define Echo_M_G_labelID 28 +#define SDT_M_G_labelID 29 +#define VXREC_M_G_VX_DL_labelID 30 +#define UL_M_G_VX_DL_labelID 31 +#define DL1_M_labelID 32 +#define DL2_M_labelID 33 +#define MM_UL2_labelID 34 +#define VX_DL_labelID 35 +#define Tones_labelID 36 +#define DL_M_MM_UL2_VX_DL_labelID 37 +#define Echo_M_labelID 38 +#define VX_UL_labelID 39 +#define VX_UL_M_labelID 40 +#define SDT_F_labelID 41 +#define SDT_F_data_labelID 42 +#define SDT_Coef_labelID 43 +#define SDT_Regs_labelID 44 +#define SDT_M_labelID 45 +#define DL1_labelID 46 +#define DMIC1_labelID 47 +#define DMIC1_L_labelID 48 +#define DMIC1_R_labelID 49 +#define DMIC2_labelID 50 +#define DMIC2_L_labelID 51 +#define DMIC2_R_labelID 52 +#define DMIC3_labelID 53 +#define DMIC3_L_labelID 54 +#define DMIC3_R_labelID 55 +#define BT_UL_L_labelID 56 +#define BT_UL_R_labelID 57 +#define AMIC_labelID 58 +#define AMIC_L_labelID 59 +#define AMIC_R_labelID 60 +#define EANC_FBK_In_labelID 61 +#define EANC_FBK_Out_labelID 62 +#define EANC_FBK_L_labelID 63 +#define EANC_FBK_R_labelID 64 +#define EchoRef_L_labelID 65 +#define EchoRef_R_labelID 66 +#define MM_DL_L_labelID 67 +#define MM_DL_R_labelID 68 +#define MM_UL_labelID 69 +#define AMIC_96_labelID 70 +#define DMIC0_96_labelID 71 +#define DMIC1_96_labelID 72 +#define DMIC2_96_labelID 73 +#define DMIC_desc_labelID 74 +#define UL_MIC_48K_labelID 75 +#define EQ_DL_48K_labelID 76 +#define EQ_48K_labelID 77 +#define UP_DOWN_8_48_labelID 78 +#define McPDM_Out1_labelID 79 +#define McPDM_Out2_labelID 80 +#define McPDM_Out3_labelID 81 +#define VX_UL_MUX_labelID 82 +#define MM_UL2_MUX_labelID 83 +#define MM_UL_MUX_labelID 84 +#define XinASRC_DL_VX_labelID 85 +#define ASRC_DL_VX_Coefs_labelID 86 +#define ASRC_DL_VX_Alpha_labelID 87 +#define ASRC_DL_VX_VarsBeta_labelID 88 +#define ASRC_DL_VX_8k_Regs_labelID 89 +#define XinASRC_UL_VX_labelID 90 +#define ASRC_UL_VX_Coefs_labelID 91 +#define ASRC_UL_VX_Alpha_labelID 92 +#define ASRC_UL_VX_VarsBeta_labelID 93 +#define ASRC_UL_VX_8k_Regs_labelID 94 +#define UL_48_8_DEC_labelID 95 +#define UP_DOWN_16_48_labelID 96 +#define ASRC_DL_VX_16k_Regs_labelID 97 +#define ASRC_UL_VX_16k_Regs_labelID 98 +#define UL_48_16_DEC_labelID 99 +#define XinASRC_DL_MM_labelID 100 +#define ASRC_DL_MM_Coefs_labelID 101 +#define ASRC_DL_MM_Alpha_labelID 102 +#define ASRC_DL_MM_VarsBeta_labelID 103 +#define ASRC_DL_MM_Regs_labelID 104 +#define VX_REC_labelID 105 +#define VXREC_UL_M_Tones_VX_UL_labelID 106 +#define VX_REC_L_labelID 107 +#define VX_REC_R_labelID 108 +#define DL2_M_L_labelID 109 +#define DL2_M_R_labelID 110 +#define DL1_M_data_labelID 111 +#define DL1_M_Coefs_labelID 112 +#define DL2_M_LR_data_labelID 113 +#define DL2_M_LR_Coefs_labelID 114 +#define VX_DL_8_48_LP_COEFS_labelID 115 +#define VX_DL_8_48_BP_COEFS_labelID 116 +#define VX_DL_8_48_BP_DATA_labelID 117 +#define VX_DL_8_48_LP_DATA_labelID 118 +#define SRC_BP_8K_48K_labelID 119 +#define SRC_HP_16K_48K_labelID 120 +#define SRC_LP_48K_labelID 121 +#define EARP_48_96_LP_DATA_labelID 122 +#define SRC_48_96_LP_labelID 123 +#define IHF_48_96_LP_DATA_labelID 124 +#define VX_DL_16_48_HP_COEFS_labelID 125 +#define VX_DL_16_48_LP_COEFS_labelID 126 +#define VX_DL_16_48_HP_DATA_labelID 127 +#define VX_DL_16_48_LP_DATA_labelID 128 +#define VX_UL_48_8_LP_COEFS_labelID 129 +#define VX_UL_48_8_BP_DATA_labelID 130 +#define VX_UL_48_8_LP_DATA_labelID 131 +#define VX_UL_8_TEMP_labelID 132 +#define VX_UL_48_16_LP_COEFS_labelID 133 +#define VX_UL_48_16_HP_DATA_labelID 134 +#define VX_UL_48_16_LP_DATA_labelID 135 +#define EQ_VX_UL_16K_labelID 136 +#define VX_UL_16_TEMP_labelID 137 +#define pAPS_iir1_p23_labelID 138 +#define pAPS_iir1_p45_labelID 139 +#define APS_IIR_Regs_labelID 140 +#define pAPS_core_DL1_p1_labelID 141 +#define pAPS_core_DL1_p23_labelID 142 +#define pAPS_core_DL1_p45_labelID 143 +#define pAPS_core_DL1_r_labelID 144 +#define pAPS_DL2L_core_r_labelID 145 +#define pAPS_DL2R_core_r_labelID 146 +#define pAPS_COIL_core_DL1_p1_labelID 147 +#define pAPS_COIL_core_DL1_p23_labelID 148 +#define pAPS_COIL_core_DL1_p45_labelID 149 +#define pAPS_COIL_core_DL1_r_labelID 150 +#define XinASRC_ECHO_REF_labelID 151 +#define ASRC_ECHO_REF_Coefs_labelID 152 +#define ASRC_ECHO_REF_Alpha_labelID 153 +#define ASRC_ECHO_REF_VarsBeta_labelID 154 +#define ASRC_ECHO_REF_8k_Regs_labelID 155 +#define ASRC_ECHO_REF_16k_Regs_labelID 156 +#define DL2_L_APS_IIR_p23_labelID 157 +#define DL2_R_APS_IIR_p23_labelID 158 +#define DL2_L_APS_IIR_p45_labelID 159 +#define DL2_R_APS_IIR_p45_labelID 160 +#define DL2_L_APS_CORE_p1_labelID 161 +#define DL2_L_APS_CORE_p23_labelID 162 +#define DL2_L_APS_CORE_p45_labelID 163 +#define DL2_R_APS_CORE_p1_labelID 164 +#define DL2_R_APS_CORE_p23_labelID 165 +#define DL2_R_APS_CORE_p45_labelID 166 +#define DL2_L_APS_COIL_CORE_p1_labelID 167 +#define DL2_L_APS_COIL_CORE_p23_labelID 168 +#define DL2_L_APS_COIL_CORE_p45_labelID 169 +#define pAPS_COIL_DL2L_core_r_labelID 170 +#define DL2_R_APS_COIL_CORE_p1_labelID 171 +#define DL2_R_APS_COIL_CORE_p23_labelID 172 +#define DL2_R_APS_COIL_CORE_p45_labelID 173 +#define pAPS_COIL_DL2R_core_r_labelID 174 +#define DL1_APS_labelID 175 +#define DL2_L_APS_labelID 176 +#define DL2_R_APS_labelID 177 +#define ECHO_REF_48_16_HP_DATA_labelID 178 +#define ECHO_REF_48_16_LP_DATA_labelID 179 +#define ECHO_REF_48_8_BP_DATA_labelID 180 +#define ECHO_REF_48_8_LP_DATA_labelID 181 +#define ECHO_REF_DEC_labelID 182 +#define pEANC_p0_labelID 183 +#define pEANC_p1_labelID 184 +#define pEANC_p23_labelID 185 +#define pEANC_p45_labelID 186 +#define pEANC_reg1_labelID 187 +#define pEANC_reg2_labelID 188 +#define pEANC_reg3_labelID 189 +#define pEANC_r_labelID 190 +#define DL1_APS_EQ_p23_labelID 191 +#define DL1_APS_EQ_p45_labelID 192 +#define DL2_APS_EQ_p23_labelID 193 +#define DL2_APS_EQ_p45_labelID 194 +#define pDC_EANC_p23_labelID 195 +#define pDC_EANC_r_labelID 196 +#define pVIBRA1_p0_labelID 197 +#define pVIBRA1_p1_labelID 198 +#define pVIBRA1_p23_labelID 199 +#define pVIBRA1_p45_labelID 200 +#define pVibra1_pR1_labelID 201 +#define pVibra1_pR2_labelID 202 +#define pVibra1_pR3_labelID 203 +#define pVIBRA1_r_labelID 204 +#define pVIBRA2_p0_labelID 205 +#define pVIBRA2_p1_labelID 206 +#define pVIBRA2_p23_labelID 207 +#define pVIBRA2_p45_labelID 208 +#define pCtrl_p67_labelID 209 +#define pVIBRA2_r_labelID 210 +#define VIBRA_labelID 211 +#define PING_labelID 212 +#define PING_Regs_labelID 213 +#define UP_48_96_LP_COEFS_labelID 214 +#define AMIC_96_48_data_labelID 215 +#define DOWN_96_48_Coefs_labelID 216 +#define DOWN_96_48_Regs_labelID 217 +#define DMIC0_96_48_data_labelID 218 +#define DMIC1_96_48_data_labelID 219 +#define DMIC2_96_48_data_labelID 220 +#define EANC_FBK_96_48_data_labelID 221 +#define pDC_EANC_r2_labelID 222 +#define SIO_DMIC_labelID 223 +#define SIO_PDM_UL_labelID 224 +#define SIO_BT_VX_UL_labelID 225 +#define SIO_MM_UL_labelID 226 +#define SIO_MM_UL2_labelID 227 +#define SIO_VX_UL_labelID 228 +#define SIO_MM_DL_labelID 229 +#define SIO_VX_DL_labelID 230 +#define SIO_TONES_DL_labelID 231 +#define SIO_VIB_DL_labelID 232 +#define SIO_BT_VX_DL_labelID 233 +#define SIO_PDM_DL_labelID 234 +#define SIO_MM_EXT_OUT_labelID 235 +#define SIO_MM_EXT_IN_labelID 236 +#define DMIC_ATC_PTR_labelID 237 +#define MCPDM_UL_ATC_PTR_labelID 238 +#define BT_VX_UL_ATC_PTR_labelID 239 +#define MM_UL_ATC_PTR_labelID 240 +#define MM_UL2_ATC_PTR_labelID 241 +#define VX_UL_ATC_PTR_labelID 242 +#define MM_DL_ATC_PTR_labelID 243 +#define VX_DL_ATC_PTR_labelID 244 +#define TONES_DL_ATC_PTR_labelID 245 +#define VIB_DL_ATC_PTR_labelID 246 +#define BT_VX_DL_ATC_PTR_labelID 247 +#define PDM_DL_ATC_PTR_labelID 248 +#define MM_EXT_OUT_ATC_PTR_labelID 249 +#define MM_EXT_IN_ATC_PTR_labelID 250 +#define MCU_IRQ_FIFO_ptr_labelID 251 +#define DEBUG_ATC_ptrs_labelID 252 +#define DEBUG_IRQ_FIFO_reg_labelID 253 +#define UP_DOWN_48_96_labelID 254 +#define OSR96_2_labelID 255 +#define DEBUG_GAINS_labelID 256 +#define DBG_8K_PATTERN_labelID 257 +#define DBG_16K_PATTERN_labelID 258 +#define DBG_48K_PATTERN_labelID 259 +#define DBG_MCPDM_PATTERN_labelID 260 +#define SMEM_TEST_PATTERN_labelID 261 +#define UL_VX_UL_48_8K_labelID 262 +#define UL_VX_UL_48_16K_labelID 263 +#define BT_UL_8_48_BP_DATA_labelID 264 +#define BT_UL_8_48_LP_DATA_labelID 265 +#define BT_UL_16_48_HP_DATA_labelID 266 +#define BT_UL_16_48_LP_DATA_labelID 267 +#define BT_DL_48_8_BP_DATA_labelID 268 +#define BT_DL_48_8_LP_DATA_labelID 269 +#define BT_DL_48_16_HP_DATA_labelID 270 +#define BT_DL_48_16_LP_DATA_labelID 271 +#define BT_DL_labelID 272 +#define BT_UL_labelID 273 +#define BT_DL_8k_labelID 274 +#define BT_DL_16k_labelID 275 +#define BT_UL_8k_labelID 276 +#define BT_UL_16k_labelID 277 + +#endif /* _ABE_INITXXXX_LABELS_H_ */ diff --git a/sound/soc/codecs/abe/abe_irq.c b/sound/soc/codecs/abe/abe_irq.c new file mode 100644 index 000000000000..61bd1263c0da --- /dev/null +++ b/sound/soc/codecs/abe/abe_irq.c @@ -0,0 +1,71 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ + +#include "abe_main.h" + +/* + * initialize the default values for call-backs to subroutines + * - FIFO IRQ call-backs for sequenced tasks + * - FIFO IRQ call-backs for audio player/recorders (ping-pong protocols) + * - Remote debugger interface + * - Error monitoring + * - Activity Tracing + */ + +/* + * ABE_IRQ_PING_PONG + * Parameter : + * No parameter + * + * Operations : + * Call the respective subroutine depending on the IRQ FIFO content: + * APS interrupts : IRQtag_APS to [31:28], APS_IRQs to [27:16], loopCounter to [15:0] + * SEQ interrupts : IRQtag_COUNT to [31:28], Count_IRQs to [27:16], loopCounter to [15:0] + * Ping-Pong Interrupts : IRQtag_PP to [31:28], PP_MCU_IRQ to [27:16], loopCounter to [15:0] + * Check for ping-pong subroutines (low-power players) + * + * Return value : + * None. + */ +void abe_irq_ping_pong(void) +{ + abe_call_subroutine(abe_irq_pingpong_player_id, NOPARAMETER, NOPARAMETER, NOPARAMETER, NOPARAMETER); +} + +/* + * ABE_IRQ_CHECK_FOR_SEQUENCES + * Parameter : + * No parameter + * + * Operations : + * check the active sequence list + * + * Return value : + * None. + */ +void abe_irq_check_for_sequences(abe_uint32 i) +{ +} + +/* + * ABE_IRQ_APS + * Parameter : + * No parameter + * + * Operations : + * call the application subroutines that updates the acoustics protection filters + * + * Return value : + * None. + */ +void abe_irq_aps(abe_uint32 aps_info) +{ + abe_call_subroutine(abe_irq_aps_adaptation_id, NOPARAMETER, NOPARAMETER, NOPARAMETER, NOPARAMETER); +} diff --git a/sound/soc/codecs/abe/abe_lib.c b/sound/soc/codecs/abe/abe_lib.c new file mode 100644 index 000000000000..e7a9aa338f1a --- /dev/null +++ b/sound/soc/codecs/abe/abe_lib.c @@ -0,0 +1,712 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ + +#include "abe_main.h" +#include <linux/io.h> + +void __iomem *io_base; + +void abe_init_mem() +{ + io_base = ioremap(L4_ABE_44XX_PHYS, SZ_1M); +} + +#define ABE_PMEM_BASE_OFFSET_MPU 0xe0000 +#define ABE_CMEM_BASE_OFFSET_MPU 0xa0000 +#define ABE_SMEM_BASE_OFFSET_MPU 0xc0000 +#define ABE_DMEM_BASE_OFFSET_MPU 0x80000 +#define ABE_ATC_BASE_OFFSET_MPU 0xf1000 + +#if 0 +/* + * ABE_TRANSLATE_TO_XMEM_FORMAT + * + * Parameter : + * Operations : + * translates a floating point data to the cmem/smem/dmem data format + * Return value : + * None. + */ +void abe_translate_to_xmem_format(abe_int32 memory_bank, abe_float fc, abe_uint32 *c) +{ + abe_int32 l; + abe_float afc; + + l = 0; + afc = absolute(fc); + + switch (memory_bank) { + case ABE_CMEM: + if (afc >= 1.0 && afc < 32.0) { + /* ALU post shifter +6 */ + l = (abe_int32)(fc * (1 << 16)); + l = (l << 2) + 2; + } else if (afc >= 0.5 && afc < 1.0) { + /* ALU post shifter +1 */ + l = (abe_int32)(fc * (1 << 21)); + l = (l << 2) + 1; + } else if (afc >= 0.25 && afc < 0.5) { + /* ALU post shifter 0 */ + l = (abe_int32)(fc * (1 << 22)); + l = (l << 2) + 0; + } else if (afc < 0.25) { + /* ALU post shifter -6 */ + l = (abe_int32)(fc * (1 << 28)); + l = (l << 2) + 3; + } + break; + case ABE_SMEM: + /* Q23 data format */ + l = (abe_int32)(fc * (1 << 23)); + break; + case ABE_DMEM: + /* Q31 data format (1<<31)=0 */ + l = (abe_int32)(fc * 2* (1 << 30)); + break; + default: /* ABE_PMEM */ + /* Q31 data format */ + l = (abe_int32)(2 * fc * 2* (1 << 30)); + break; + } + + *c = l; +} + +/* + * ABE_TRANSLATE_GAIN_FORMAT + * + * Parameter : + * Operations : + * f: original format name for gain or frequency. + * 1=linear ABE => decibels + * 2=decibels => linear ABE firmware format + * + * lin = power(2, decibel/602); lin = [0.0001 .. 30.0] + * decibel = 6.02 * log2(lin), decibel = [-70 .. +30] + * + * g1: pointer to the original data + * g2: pointer to the translated gain data + * + * Return value : + * None. + */ +void abe_translate_gain_format(abe_uint32 f, abe_float g1, abe_float *g2) +{ + abe_float g, frac_part, gg1, gg2; + abe_int32 int_part, i; + + #define C_20LOG2 ((abe_float)6.020599913) + + gg1 = (g1); + int_part = 0; + frac_part = gg2 = 0; + + switch (f) { + case DECIBELS_TO_LINABE: + g = gg1 / C_20LOG2; + int_part = (abe_int32) g; + frac_part = g - int_part; + + gg2 = abe_power_of_two(frac_part); + + if (int_part > 0) + gg2 = gg2 * (1 << int_part); + else + gg2 = gg2 / (1 << (-int_part)); + + break; + case LINABE_TO_DECIBELS: + if (gg1 == 1.0) { + gg2 = 0.0; + return; + } + + /* find the power of 2 by iteration */ + if (gg1 > 1.0) { + for (i = 0; i < 63; i++) { + if ((1 << i) > gg1) { + int_part = (i-1); + frac_part = gg1 / (1 << int_part); + break; + } + } + gg2 = C_20LOG2 * (int_part + abe_log_of_two(frac_part)); + } else { + for (i = 0; i < 63; i++) { + if (((1 << i) * gg1) > 1) { + int_part = i; + frac_part = gg1 * (1 << int_part); + break; + } + } + /* compute the dB using polynomial + * interpolation in the [1..2] range + */ + gg2 = C_20LOG2 * (((-1)*int_part) + abe_log_of_two(frac_part));} + break; + } + + *g2 = gg2; + } + +/* + * ABE_TRANSLATE_RAMP_FORMAT + * + * Parameter : + * Operations : + * f: original format name for gain or frequency. + * 1=ABE IIR coef => microseconds + * 2=microseconds => ABE IIR coef + * + * g1: pointer to the original data + * g2: pointer to the translated gain data + * + * Return value : + * None. + */ +void abe_translate_ramp_format(abe_float ramp, abe_float *ramp_iir1) +{ + *ramp_iir1 = 0.125; +} + +/* + * ABE_TRANSLATE_EQU_FORMAT + * + * Parameter : + * Operations : + * Translate + * + * Return value : + * None. + */ +void abe_translate_equ_format(abe_equ_t *p, abe_float *iir, abe_uint32 n) +{ +#if 0 + switch (p->type +typedef struct { + abe_iir_t equ_param1; /* type of filter */ + abe_uint32 equ_param2; /* filter length */ + union { /* parameters are the direct and recursive coefficients in */ + abe_int32 type1 [NBEQ1]; /* Q6.26 integer fixed-point format. */ + struct { + abe_int32 freq [NBEQ2]; /* parameters are the frequency (type "freq") and Q factors */ + abe_int32 gain [NBEQ2]; /* (type "gain") of each band. */ + } type2; + } coef; + abe_int32 equ_param3; + } abe_equ_t; + + Fs = 48000; + f0 = 19000; + Q = sqrt(0.5) + dBgain = -40 + + + A = sqrt (power (10, dBgain/20)); + w0 = 2*pi*f0/Fs + alpha = sin(w0) / (2*Q); + + %PeakingEQ ========================================== + b_peak = print_ABE_data ([1+alpha*A -2*cos(w0) 1-alpha*A],3); + a_peak = print_ABE_data ([1+alpha/A -2*cos(w0) 1-alpha/A],3); + +#endif +} +#endif + +/* + * ABE_FPRINTF + * + * Parameter : + * character line to be printed + * + * Operations : + * + * Return value : + * None. + */ +#if 0 +void abe_fprintf(char *line) +{ + switch (abe_dbg_output) { + case NO_OUTPUT: + break; + case TERMINAL_OUTPUT: + break; + case LINE_OUTPUT: + break; + case DEBUG_TRACE_OUTPUT: + break; + default: + break; + } +} +#endif + +/* + * ABE_READ_FEATURE_FROM_PORT + * + * Parameter : + * x : d + * + * Operations : + * + * + * Return value : + * + */ +void abe_read_feature_from_port(abe_uint32 x) +{ + just_to_avoid_the_many_warnings = x; +} + +/* + * ABE_WRITE_FEATURE_TO_PORT + * + * Parameter : + * x : d + * + * Operations : + * + * + * Return value : + * + */ +void abe_write_feature_to_port(abe_uint32 x) +{ + just_to_avoid_the_many_warnings = x; +} + +/* + * ABE_READ_FIFO + * + * Parameter : + * x : d + * + * Operations : + * + * + * Return value : + * + */ +void abe_read_fifo(abe_uint32 x) +{ + just_to_avoid_the_many_warnings = x; +} + +/* + * ABE_WRITE_FIFO + * + * Parameter : + * x : d + * + * Operations : + * + * + * Return value : + * + */ +void abe_write_fifo(abe_uint32 x) +{ + just_to_avoid_the_many_warnings = x; +} + +/* + * ABE_BLOCK_COPY + * + * Parameter : + * direction of the data move (Read/Write) + * memory bank among PMEM, DMEM, CMEM, SMEM, ATC/IO + * address of the memory copy (byte addressing) + * long pointer to the data + * number of data to move + * + * Operations : + * block data move + * + * Return value : + * none + */ +void abe_block_copy(abe_int32 direction, abe_int32 memory_bank, abe_int32 address, abe_uint32 *data, abe_uint32 nb_bytes) +{ +#if PC_SIMULATION + abe_uint32 *smem_tmp, smem_offset, smem_base, nb_words48; + + if (direction == COPY_FROM_HOST_TO_ABE) { + switch (memory_bank) { + case ABE_PMEM: + target_server_write_pmem(address/4, data, nb_bytes/4); + break; + case ABE_CMEM: + target_server_write_cmem(address/4, data, nb_bytes/4); + break; + case ABE_ATC: + target_server_write_atc(address/4, data, nb_bytes/4); + break; + case ABE_SMEM: + nb_words48 = (nb_bytes +7)>>3; + /* temporary buffer manages the OCP access to 32bits boundaries */ + smem_tmp = malloc(nb_bytes + 64); + /* address is on SMEM 48bits lines boundary */ + smem_base = address - (address & 7); + target_server_read_smem(smem_base/8, smem_tmp, 2 + nb_words48); + smem_offset = address & 7; + memcpy(&(smem_tmp[smem_offset>>2]), data, nb_bytes); + target_server_write_smem(smem_base/8, smem_tmp, 2 + nb_words48); + free(smem_tmp); + break; + case ABE_DMEM: + target_server_write_dmem(address, data, nb_bytes); + break; + default: + abe_dbg_param |= ERR_LIB; + abe_dbg_error_log(ABE_BLOCK_COPY_ERR); + break; + } + } else { + switch (memory_bank) { + case ABE_PMEM: + target_server_read_pmem(address/4, data, nb_bytes/4); + break; + case ABE_CMEM: + target_server_read_cmem(address/4, data, nb_bytes/4); + break; + case ABE_ATC: + target_server_read_atc(address/4, data, nb_bytes/4); + break; + case ABE_SMEM: + nb_words48 = (nb_bytes +7)>>3; + /* temporary buffer manages the OCP access to 32bits boundaries */ + smem_tmp = malloc(nb_bytes + 64); + /* address is on SMEM 48bits lines boundary */ + smem_base = address - (address & 7); + target_server_read_smem(smem_base/8, smem_tmp, 2 + nb_words48); + smem_offset = address & 7; + memcpy(data, &(smem_tmp[smem_offset>>2]), nb_bytes); + free(smem_tmp); + break; + case ABE_DMEM: + target_server_read_dmem(address, data, nb_bytes); + break; + default: + abe_dbg_param |= ERR_LIB; + abe_dbg_error_log(ABE_BLOCK_COPY_ERR); + break; + } + } +#else + abe_uint32 i; + abe_uint32 base_address = 0, *src_ptr, *dst_ptr, n; + + switch (memory_bank) { + case ABE_PMEM: + base_address = (abe_uint32) io_base + ABE_PMEM_BASE_OFFSET_MPU; + break; + case ABE_CMEM: + base_address = (abe_uint32) io_base + ABE_CMEM_BASE_OFFSET_MPU; + break; + case ABE_SMEM: + base_address = (abe_uint32) io_base + ABE_SMEM_BASE_OFFSET_MPU; + break; + case ABE_DMEM: + base_address = (abe_uint32) io_base + ABE_DMEM_BASE_OFFSET_MPU; + break; + case ABE_ATC: + base_address = (abe_uint32) io_base + ABE_ATC_BASE_OFFSET_MPU; + break; + default: + base_address = (abe_uint32) io_base + ABE_SMEM_BASE_OFFSET_MPU; + abe_dbg_param |= ERR_LIB; + abe_dbg_error_log(ABE_BLOCK_COPY_ERR); + break; + } + + if (direction == COPY_FROM_HOST_TO_ABE) { + dst_ptr = (abe_uint32 *)(base_address + address); + src_ptr = (abe_uint32 *)data; + } else { + dst_ptr = (abe_uint32 *)data; + src_ptr = (abe_uint32 *)(base_address + address); + } + + n = (nb_bytes/4); + + for (i = 0; i < n; i++) + *dst_ptr++ = *src_ptr++; + +#endif +} +/* + * ABE_RESET_MEM + * + * Parameter : + * memory bank among DMEM, SMEM + * address of the memory copy (byte addressing) + * number of data to move + * + * Operations : + * reset memory + * + * Return value : + * none + */ + +void abe_reset_mem(abe_int32 memory_bank, abe_int32 address, abe_uint32 nb_bytes) +{ +#if PC_SIMULATION + extern void target_server_write_smem(abe_uint32 address_48bits, abe_uint32 *data, abe_uint32 nb_words_48bits); + extern void target_server_write_dmem(abe_uint32 address_byte, abe_uint32 *data, abe_uint32 nb_byte); + + abe_uint32 *smem_tmp, *data, smem_offset, smem_base, nb_words48; + + data = calloc(nb_bytes, 1); + + switch (memory_bank) { + case ABE_SMEM: + nb_words48 = (nb_bytes +7)>>3; + /* temporary buffer manages the OCP access to 32bits boundaries */ + smem_tmp = malloc (nb_bytes + 64); + /* address is on SMEM 48bits lines boundary */ + smem_base = address - (address & 7); + target_server_read_smem (smem_base/8, smem_tmp, 2 + nb_words48); + smem_offset = address & 7; + memcpy (&(smem_tmp[smem_offset>>2]), data, nb_bytes); + target_server_write_smem (smem_base/8, smem_tmp, 2 + nb_words48); + free (smem_tmp); + break; + case ABE_DMEM: + target_server_write_dmem(address, data, nb_bytes); + break; + default: + abe_dbg_param |= ERR_LIB; + abe_dbg_error_log(ABE_BLOCK_COPY_ERR); + } + free(data); +#else + abe_uint32 i; + abe_uint32 *dst_ptr, n; + abe_uint32 base_address = 0; + + switch (memory_bank) { + case ABE_SMEM: + base_address = (abe_uint32) io_base + ABE_SMEM_BASE_OFFSET_MPU; + break; + case ABE_DMEM: + base_address = (abe_uint32) io_base + ABE_DMEM_BASE_OFFSET_MPU; + break; + } + + if (memory_bank == ABE_SMEM) + dst_ptr = (abe_uint32 *) (base_address + address); + else + dst_ptr = (abe_uint32 *) (base_address + address); + + n = (nb_bytes/4); + + for (i = 0; i < n; i++) + *dst_ptr++ = 0; +#endif +} + +/* + * ABE_MONITORING + * + * Parameter : + * + * Operations : + * checks the internal status of ABE and HAL + * + * Return value : + * Call Backs on Errors + */ +void abe_monitoring(void) +{ + abe_dbg_param = 0; +} + +/* + * ABE_FORMAT_SWITCH + * + * Parameter : + * + * Operations : + * translates the sampling and data length to ITER number for the DMA + * and the multiplier factor to apply during data move with DMEM + * + * Return value : + * Call Backs on Errors + */ +void abe_format_switch(abe_data_format_t *f, abe_uint32 *iter, abe_uint32 *mulfac) +{ + abe_uint32 n_freq; + + /* scheduler loop ratio : + * 2 samples at 8kHz + * 4 samples at 16kHz + * 6 samples at 24kHz + * 12 samples at 48kHz + * 24 samples at 96kHz + */ + n_freq = (f->f)/FW_SCHED_LOOP_FREQ; + + switch (f->samp_format) { + case MONO_MSB: + *mulfac = 1; + break; + case STEREO_16_16: + *mulfac = 1; + break; + case STEREO_MSB: + *mulfac = 2; + break; + case THREE_MSB: + *mulfac = 3; + break; + case FOUR_MSB: + *mulfac = 4; + break; + case FIVE_MSB: + *mulfac = 5; + break; + case SIX_MSB: + *mulfac = 6; + break; + case SEVEN_MSB: + *mulfac = 7; + break; + case EIGHT_MSB: + *mulfac = 8; + break; + case NINE_MSB: + *mulfac = 9; + break; + default: + *mulfac = 1; + break; + } + + *iter = (n_freq * (*mulfac)); +} + +/* + * ABE_DMA_PORT_ITERATION + * + * Parameter : + * + * Operations : + * translates the sampling and data length to ITER number for the DMA + * + * Return value : + * Call Backs on Errors + */ +abe_uint32 abe_dma_port_iteration(abe_data_format_t *f) +{ + abe_uint32 iter, mulfac; + + abe_format_switch(f, &iter, &mulfac); + + return iter; +} + +/* + * ABE_DMA_PORT_ITER_FACTOR + * + * Parameter : + * + * Operations : + * returns the multiplier factor to apply during data move with DMEM + * + * Return value : + * Call Backs on Errors + */ +abe_uint32 abe_dma_port_iter_factor(abe_data_format_t *f) +{ + abe_uint32 iter, mulfac; + + abe_format_switch(f, &iter, &mulfac); + + return mulfac; +} + +/* + * ABE_DMA_PORT_COPY_SUBROUTINE_ID + * + * Parameter : + * + * Operations : + * returns the index of the function doing the copy in I/O tasks + * + * Return value : + * Call Backs on Errors + */ +abe_uint32 abe_dma_port_copy_subroutine_id(abe_port_id port_id) +{ + abe_uint32 sub_id; + + if (abe_port[port_id].protocol.direction == ABE_ATC_DIRECTION_IN) { + switch (abe_port[port_id].format.samp_format){ + case MONO_MSB: + sub_id = sub_copy_d2s_mono; + break; // VX_DL + case STEREO_16_16: + sub_id = sub_copy_d2s_1616; + break; // MM_DL + case STEREO_MSB: + sub_id = sub_copy_d2s; + break; // AMIC, MM_DL, VIB .. + case SIX_MSB: + if (port_id == DMIC_PORT) { + sub_id = sub_copy_dmic; + break; + } + case THREE_MSB: + case FOUR_MSB: + case FIVE_MSB: + case SEVEN_MSB: + case EIGHT_MSB: + case NINE_MSB: + default: + sub_id = sub_null_copy; + break; + } + } else { + switch (abe_port[port_id].format.samp_format) { + case MONO_MSB: + sub_id = sub_copy_s2d_mono; + break; // VX_UL + case STEREO_MSB: + sub_id = sub_copy_s2d; + break; // MM_UL2 + case SIX_MSB: + if (port_id == PDM_DL_PORT) { + sub_id = sub_copy_mcpdm_dl; + break; + } + if (port_id == MM_UL_PORT) { + sub_id = sub_copy_mm_ul; + break; + } + case THREE_MSB: + case FOUR_MSB: + case FIVE_MSB: + case SEVEN_MSB: + case EIGHT_MSB: + case NINE_MSB: + sub_id = sub_copy_mm_ul; + break; + case STEREO_16_16: + default: + sub_id = sub_null_copy; + break; + } + } + + return sub_id; +} diff --git a/sound/soc/codecs/abe/abe_lib.h b/sound/soc/codecs/abe/abe_lib.h new file mode 100644 index 000000000000..9dd64ce62d11 --- /dev/null +++ b/sound/soc/codecs/abe/abe_lib.h @@ -0,0 +1,124 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ + +#ifdef __cplusplus +extern "C" { +#endif + +void abe_init_mem(void); +void abe_translate_gain_format(abe_uint32 f, abe_float g1, abe_float *g2); +void abe_translate_ramp_format(abe_float g1, abe_float *g2); + +/* + * ABE_FPRINTF + * + * Parameter : + * character line to be printed + * + * Operations : + * + * Return value : + * None. + */ +void abe_fprintf(char *line); + +/* + * ABE_READ_FEATURE_FROM_PORT + * + * Parameter : + * x : d + * + * Operations : + * + * + * Return value : + * + */ +void abe_read_feature_from_port(abe_uint32 x); + +/* + * ABE_WRITE_FEATURE_TO_PORT + * + * Parameter : + * x : d + * + * Operations : + * + * + * Return value : + * + */ +void abe_write_feature_to_port(abe_uint32 x); + +/* + * ABE_READ_FIFO + * + * Parameter : + * x : d + * + * Operations : + * + * + * Return value : + * + */ +void abe_read_fifo(abe_uint32 x); + +/* + * ABE_WRITE_FIFO + * + * Parameter : + * x : d + * + * Operations : + * + * + * Return value : + * + */ +void abe_write_fifo(abe_uint32 x); + +/* + * ABE_BLOCK_COPY + * + * Parameter : + * direction of the data move (Read/Write) + * memory bank among PMEM, DMEM, CMEM, SMEM, ATC/IO + * address of the memory copy (byte addressing) + * long pointer to the data + * number of data to move + * + * Operations : + * block data move + * + * Return value : + * none + */ +void abe_block_copy(abe_int32 direction, abe_int32 memory_bank, abe_int32 address, abe_uint32 *data, abe_uint32 nb); + +/* + * ABE_RESET_MEM + * + *Parameter: + * memory bank among DMEM, SMEM + * address of the memory copy (byte addressing) + * number of data to move + * + * Operations: + * reset memory + * + * Return value: + * none + */ +void abe_reset_mem(abe_int32 memory_bank, abe_int32 address, abe_uint32 nb_bytes); + +#ifdef __cplusplus +} +#endif diff --git a/sound/soc/codecs/abe/abe_main.c b/sound/soc/codecs/abe/abe_main.c new file mode 100644 index 000000000000..3423fe62e50a --- /dev/null +++ b/sound/soc/codecs/abe/abe_main.c @@ -0,0 +1,99 @@ +/* ============================================================================= +* Texas Instruments OMAP(TM) Platform Software +* (c) Copyright 2009 Texas Instruments Incorporated. All Rights Reserved. +* +* Use of this software is controlled by the terms and conditions found +* in the license agreement under which this software has been supplied. +* =========================================================================== */ +/** + * @file ABE_MAIN.C + * + * 'ABEMAIN.C' dummy main of the HAL + * + * @path + * @rev 01.00 + */ +/* ---------------------------------------------------------------------------- +*! +*! Revision History +*! =================================== +*! 27-Nov-2008 Original (LLF) +*! 05-Jun-2009 V05 release +* =========================================================================== */ + + +#if !PC_SIMULATION + + +#include "abe_main.h" +#include "abe_test.h" + +void main (void) +{ + + abe_dma_t dma_sink, dma_source; + abe_data_format_t format; + abe_uint32 base_address; + + abe_auto_check_data_format_translation(); + abe_reset_hal(); + abe_check_opp(); + abe_check_dma(); + + /* + To be added here : + Device driver initialization: + McPDM_DL : threshold=1, 6 slots activated + DMIC : threshold=1, 6 microphones activated + McPDM_UL : threshold=1, two microphones activated + */ + + + /* MM_DL INIT + connect a DMA channel to MM_DL port (ATC FIFO) + format.f = 48000; + format.samp_format = STEREO_MSB; + abe_connect_cbpr_dmareq_port (MM_DL_PORT, &format, ABE_CBPR0_IDX, &dma_sink); + + connect a Ping-Pong SDMA protocol to MM_DL port with Ping-Pong 576 stereo samples + format.f = 48000; + format.samp_format = STEREO_MSB; + abe_connect_dmareq_ping_pong_port (MM_DL_PORT, &format, ABE_CBPR0_IDX, (576 * 4), &dma_sink); + + connect a Ping-Pong cache-flush protocol to MM_DL port with 50Hz (20ms) rate + */ + abe_add_subroutine(&abe_irq_pingpong_player_id, + (abe_subroutine2) abe_default_irq_pingpong_player, SUB_0_PARAM, (abe_uint32*)0 ); + format.f = 48000; + format.samp_format = STEREO_MSB; +/* ping-pong access to MM_DL at 48kHz Mono with 20ms packet sizes */ +#define N_SAMPLES ((int)(48000 * 0.020)) + abe_connect_irq_ping_pong_port(MM_DL_PORT, &format, abe_irq_pingpong_player_id, + N_SAMPLES, &base_address, PING_PONG_WITH_MCU_IRQ); + + /* VX_DL INIT + connect a DMA channel to VX_DL port (ATC FIFO) + */ + format.f = 8000; + format.samp_format = MONO_MSB; + abe_connect_cbpr_dmareq_port(VX_DL_PORT, &format, ABE_CBPR1_IDX, &dma_sink); + + /* VX_UL INIT + connect a DMA channel to VX_UL port (ATC FIFO) + */ + format.f = 8000; + format.samp_format = MONO_MSB; + abe_connect_cbpr_dmareq_port(VX_UL_PORT, &format, ABE_CBPR2_IDX, &dma_source); + + /* make the AE waking event to be the McPDM DMA requests */ + abe_write_event_generator(EVENT_MCPDM); + + abe_enable_data_transfer(MM_DL_PORT ); + abe_enable_data_transfer(VX_DL_PORT ); + abe_enable_data_transfer(VX_UL_PORT ); + abe_enable_data_transfer(PDM_UL_PORT); + abe_enable_data_transfer(PDM_DL1_PORT); + +} + +#endif diff --git a/sound/soc/codecs/abe/abe_main.h b/sound/soc/codecs/abe/abe_main.h new file mode 100644 index 000000000000..17aefd43b477 --- /dev/null +++ b/sound/soc/codecs/abe/abe_main.h @@ -0,0 +1,54 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ + +#ifndef _ABE_MAIN_H_ +#define _ABE_MAIN_H_ + +#include "abe_dm_addr.h" +#include "abe_def.h" +#include "abe_typ.h" +#include "abe_dbg.h" +#include "abe_ext.h" +#include "abe_lib.h" +#include "abe_ref.h" +#include "abe_api.h" +//#include "ABE_DAT.h" + +#include "abe_typedef.h" +#include "abe_functionsId.h" +#include "abe_taskId.h" +#include "abe_dm_addr.h" +#include "abe_sm_addr.h" +#include "abe_cm_addr.h" +#include "abe_initxxx_labels.h" + +#include "abe_fw.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ABE_HAL_VERSION 0x00000002L +#define ABE_FW_VERSION 0x00000000L +#define ABE_HW_VERSION 0x00000000L + +#define HAL_TIME_STAMP 0 /* generates the time-stamps used for the AESS verification */ + +#define ABE_DEBUG_CHECKERS 0 /* pipe connection to the TARGET simulator */ +#define ABE_DEBUG_HWFILE 0 /* simulator data extracted from a text-file */ +#define ABE_DEBUG_LL_LOG 0 /* low-level log files */ + +#define ABE_DEBUG (ABE_DEBUG_CHECKERS | ABE_DEBUG_HWFILE | ABE_DEBUG_LL_LOG) + +#ifdef __cplusplus +} +#endif + +#endif /* _ABE_MAIN_H_ */ diff --git a/sound/soc/codecs/abe/abe_ref.h b/sound/soc/codecs/abe/abe_ref.h new file mode 100644 index 000000000000..c38a065a96d0 --- /dev/null +++ b/sound/soc/codecs/abe/abe_ref.h @@ -0,0 +1,137 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ + +#ifndef _ABE_REF_H_ +#define _ABE_REF_H_ + +/* + * 'ABE_PRO.H' all non-API prototypes for INI, IRQ, SEQ ... + */ +#ifdef __cplusplus +extern "C" { +#endif + +/* + * HAL EXTERNAL API + */ + +/* + * HAL INTERNAL API + */ +void abe_load_embedded_patterns(void); +void abe_build_scheduler_table(void); +void abe_reset_one_feature(abe_uint32 x); +void abe_reset_all_features(void); +void abe_reset_one_port(abe_uint32 x); +void abe_reset_all_ports(void); +void abe_clean_temporary_buffers(abe_port_id id); +void abe_reset_all_fifo(void); +void abe_reset_all_sequence(void); +abe_uint32 abe_dma_port_iteration(abe_data_format_t *format); +void abe_read_global_counter(abe_time_stamp_t *t, abe_millis_t *m); +void abe_read_sys_clock(abe_micros_t *time); +void abe_enable_dma_request(abe_port_id id); +void abe_disable_dma_request(abe_port_id id); +void abe_enable_atc(abe_port_id id); +void abe_disable_atc(abe_port_id id); +void abe_init_atc(abe_port_id id); +void abe_init_io_tasks(abe_port_id id, abe_data_format_t *format, abe_port_protocol_t *prot); +void abe_init_dma_t(abe_port_id id, abe_port_protocol_t *prot); +abe_uint32 abe_dma_port_iter_factor(abe_data_format_t *f); +abe_uint32 abe_dma_port_copy_subroutine_id(abe_port_id i); +void abe_call_subroutine(abe_uint32 idx, abe_uint32 p1, abe_uint32 p2, abe_uint32 p3, abe_uint32 p4); +void abe_monitoring(void); +void abe_lock_execution(void); +void abe_unlock_execution(void); +void abe_hw_configuration(void); +void abe_add_subroutine(abe_uint32 *id, abe_subroutine2 f, abe_uint32 nparam, abe_uint32* params); +void abe_read_next_ping_pong_buffer(abe_port_id port, abe_uint32 *p, abe_uint32 *n); +void abe_irq_ping_pong(void); +void abe_irq_check_for_sequences(abe_uint32 seq_info); +void abe_default_irq_pingpong_player(void); +void abe_default_irq_pingping_player_32bits(void); +void abe_default_irq_aps_adaptation(void); +void abe_read_hardware_configuration(abe_use_case_id *u, abe_opp_t *o, abe_hw_config_init_t *hw); +void abe_irq_aps(abe_uint32 aps_info); + +void abe_translate_to_xmem_format(abe_int32 memory_bank, float fc, abe_uint32 *c); + +/* + * HAL INTERNAL DATA + */ + +extern abe_port_t abe_port[]; +extern abe_feature_t feature[]; +extern abe_subroutine2 callbacks[]; + +extern abe_port_t abe_port[]; +extern const abe_port_t abe_port_init[]; + +extern abe_feature_t all_feature[]; +extern const abe_feature_t all_feature_init[]; + +extern abe_seq_t all_sequence[]; +extern const abe_seq_t all_sequence_init[]; + +extern const abe_router_t abe_router_ul_table_preset[NBROUTE_CONFIG][NBROUTE_UL]; +extern abe_router_t abe_router_ul_table[NBROUTE_CONFIG_MAX][NBROUTE_UL]; + +extern abe_uint32 abe_dbg_output; +extern abe_uint32 abe_dbg_mask; +extern abe_uint32 abe_dbg_activity_log[DBG_LOG_SIZE]; +extern abe_uint32 abe_dbg_activity_log_write_pointer; +extern abe_uint32 abe_dbg_param; + +extern abe_uint32 abe_global_mcpdm_control; +extern abe_event_id abe_current_event_id; + +extern const abe_sequence_t seq_null; +extern abe_subroutine2 abe_all_subsubroutine[MAXNBSUBROUTINE]; /* table of new subroutines called in the sequence */ +extern abe_uint32 abe_all_subsubroutine_nparam[MAXNBSUBROUTINE]; /* number of parameters per calls */ +extern abe_uint32 abe_subroutine_id[MAXNBSUBROUTINE]; +extern abe_uint32* abe_all_subroutine_params[MAXNBSUBROUTINE]; +extern abe_uint32 abe_subroutine_write_pointer; +extern abe_sequence_t abe_all_sequence[MAXNBSEQUENCE]; /* table of all sequences */ +extern abe_uint32 abe_sequence_write_pointer; +extern abe_uint32 abe_nb_pending_sequences; /* current number of pending sequences (avoids to look in the table) */ +extern abe_uint32 abe_pending_sequences[MAXNBSEQUENCE]; /* pending sequences due to ressource collision */ +extern abe_uint32 abe_global_sequence_mask; /* mask of unsharable ressources among other sequences */ +extern abe_seq_t abe_active_sequence[MAXACTIVESEQUENCE][MAXSEQUENCESTEPS]; /* table of active sequences */ +extern abe_uint32 abe_irq_pingpong_player_id; /* index of the plugged subroutine doing ping-pong cache-flush DMEM accesses */ +extern abe_uint32 abe_irq_aps_adaptation_id; +extern abe_uint32 abe_base_address_pingpong[MAX_PINGPONG_BUFFERS]; /* base addresses of the ping pong buffers */ +extern abe_uint32 abe_size_pingpong; /* size of each ping/pong buffers */ +extern abe_uint32 abe_nb_pingpong; /* number of ping/pong buffer being used */ + +extern abe_uint32 abe_irq_dbg_read_ptr; + +extern volatile abe_uint32 just_to_avoid_the_many_warnings; +extern volatile abe_gain_t just_to_avoid_the_many_warnings_abe_gain_t; +extern volatile abe_ramp_t just_to_avoid_the_many_warnings_abe_ramp_t; +extern volatile abe_dma_t just_to_avoid_the_many_warnings_abe_dma_t; +extern volatile abe_port_id just_to_avoid_the_many_warnings_abe_port_id; +extern volatile abe_millis_t just_to_avoid_the_many_warnings_abe_millis_t; +extern volatile abe_micros_t just_to_avoid_the_many_warnings_abe_micros_t; +extern volatile abe_patch_rev just_to_avoid_the_many_warnings_abe_patch_rev; +extern volatile abe_sequence_t just_to_avoid_the_many_warnings_abe_sequence_t; +extern volatile abe_ana_port_id just_to_avoid_the_many_warnings_abe_ana_port_id; +extern volatile abe_time_stamp_t just_to_avoid_the_many_warnings_abe_time_stamp_t; +extern volatile abe_data_format_t just_to_avoid_the_many_warnings_abe_data_format_t; +extern volatile abe_port_protocol_t just_to_avoid_the_many_warnings_abe_port_protocol_t; +extern volatile abe_router_t just_to_avoid_the_many_warnings_abe_router_t; +extern volatile abe_router_id just_to_avoid_the_many_warnings_abe_router_id; + +extern const abe_uint32 abe_db2lin_table []; + +#ifdef __cplusplus +} +#endif + +#endif /* _ABE_REF_H_ */ diff --git a/sound/soc/codecs/abe/abe_seq.c b/sound/soc/codecs/abe/abe_seq.c new file mode 100644 index 000000000000..cddad003536a --- /dev/null +++ b/sound/soc/codecs/abe/abe_seq.c @@ -0,0 +1,283 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ + +#include "abe_main.h" + +/* + * SEQUENCES + * struct { + * micros_t time; Waiting time before executing next line + * seq_code_t code Subroutine index interpreted in the HAL and translated to + * FW subroutine codes in case of ABE tasks + * int32 param[2] Two parameters + * char param_tag[2] Flags used for parameters when launching the sequences + * } seq_t + * + */ + +/* + * ABE_NULL_SUBROUTINE + * + * Operations : nothing + */ +void abe_null_subroutine_0(void) { } +void abe_null_subroutine_2 (abe_uint32 a, abe_uint32 b) { + just_to_avoid_the_many_warnings = a; + just_to_avoid_the_many_warnings = b; +} +void abe_null_subroutine_4 (abe_uint32 a, abe_uint32 b, abe_uint32 c, abe_uint32 d) { + just_to_avoid_the_many_warnings = a; + just_to_avoid_the_many_warnings = b; + just_to_avoid_the_many_warnings = c; + just_to_avoid_the_many_warnings = d; +} +/* + * abe_init_subroutine_table + * + * parameter : + * none + * + * operations : + * initializes the default table of pointers to subroutines + * + * return value : + * + */ +void abe_init_subroutine_table(void) +{ + abe_uint32 id; + + /* reset the table's pointers */ + abe_subroutine_write_pointer = 0; + /* the first index is the NULL task */ + abe_add_subroutine(&id,(abe_subroutine2) abe_null_subroutine_2, SUB_0_PARAM, (abe_uint32*)0); + /* write mixer has 3 parameters @@@ TBD*/ + abe_add_subroutine(&(abe_subroutine_id[SUB_WRITE_MIXER]), (abe_subroutine2) abe_write_mixer, SUB_4_PARAM, (abe_uint32*)0); + /* ping-pong player IRQ */ + abe_add_subroutine(&abe_irq_pingpong_player_id,(abe_subroutine2) abe_null_subroutine_0, SUB_0_PARAM, (abe_uint32*)0); +} + +/* + * ABE_ADD_SUBROUTINE + * + * Parameter : + * port id + * pointer to the subroutines + * number of parameters to push on the stack before call + * + * Operations : + * add one function pointer more and returns the index to it + * + * Return value : + * + */ +void abe_add_subroutine (abe_uint32 *id, abe_subroutine2 f, abe_uint32 nparam, abe_uint32* params) +{ + abe_uint32 i, i_found; + + if ((abe_subroutine_write_pointer >= MAXNBSUBROUTINE) || ((abe_uint32)f == 0)) { + abe_dbg_param |= ERR_SEQ; + abe_dbg_error_log(ABE_PARAMETER_OVERFLOW); + } else { + /* search if this subroutine address was not already + * declared, then return the previous index + */ + for (i_found = abe_subroutine_write_pointer, i = 0; i < abe_subroutine_write_pointer; i++) { + if (f == abe_all_subsubroutine[i]) + i_found = i; + } + + if (i_found == abe_subroutine_write_pointer) { + *id = abe_subroutine_write_pointer; + abe_all_subsubroutine[abe_subroutine_write_pointer] = (f); + abe_all_subroutine_params[abe_subroutine_write_pointer] = params; + abe_all_subsubroutine_nparam[abe_subroutine_write_pointer] = nparam; + abe_subroutine_write_pointer++; + } else { + abe_all_subroutine_params[i_found] = params; + *id = i_found; + } + } +} + +/* + * ABE_ADD_SEQUENCE + * + * Parameter : + * Id: returned sequence index after pluging a new sequence (index in the tables) + * s : sequence to be inserted + * + * Operations : + * Load a time-sequenced operations. + * + * Return value : + * None. + */ + +void abe_add_sequence(abe_uint32 *id, abe_sequence_t *s) +{ + abe_seq_t *seq_src, *seq_dst; + abe_uint32 i, no_end_of_sequence_found; + + seq_src = &(s->seq1); + seq_dst = &((abe_all_sequence[abe_sequence_write_pointer]).seq1); + + if ((abe_sequence_write_pointer >= MAXNBSEQUENCE) || ((abe_uint32)s == 0)) { + abe_dbg_param |= ERR_SEQ; + abe_dbg_error_log(ABE_PARAMETER_OVERFLOW); + } else { + *id = abe_subroutine_write_pointer; + (abe_all_sequence[abe_sequence_write_pointer]).mask = s->mask; /* copy the mask */ + + for (no_end_of_sequence_found = 1, i = 0; i < MAXSEQUENCESTEPS; i++, seq_src++, seq_dst++) { + (*seq_dst) = (*seq_src); /* sequence copied line by line */ + + if ((*(abe_int32 *)seq_src) == -1) { + /* stop when the line start with time=(-1) */ + no_end_of_sequence_found = 0; + break; + } + } + abe_subroutine_write_pointer++; + + if (no_end_of_sequence_found) + abe_dbg_error_log(ABE_SEQTOOLONG); + } +} + +/* + * ABE_RESET_ONE_SEQUENCE + * + * Parameter : + * sequence ID + * + * Operations : + * load default configuration for that sequence + * kill running activities + * + * Return value : + * + */ +void abe_reset_one_sequence(abe_uint32 id) +{ + just_to_avoid_the_many_warnings = id; +} + +/* + * ABE_RESET_ALL_SEQUENCE + * + * Parameter : + * none + * + * Operations : + * load default configuration for all sequences + * kill any running activities + * + * Return value : + * + */ +void abe_reset_all_sequence(void) +{ + abe_uint32 i; + + abe_init_subroutine_table(); + + /* arrange to have the first sequence index=0 to the NULL operation sequence */ + abe_add_sequence(&i, (abe_sequence_t *)&seq_null); + + /* reset the the collision protection mask */ + abe_global_sequence_mask = 0; + + /* reset the pending sequences list */ + for (abe_nb_pending_sequences = i = 0; i < MAXNBSEQUENCE; i++) + abe_pending_sequences[i] = 0; +} + +/* + * ABE_CALL_SUBROUTINE + * + * Parameter : + * index to the table of all registered Call-backs and subroutines + * + * Operations : + * run and log a subroutine + * + * Return value : + * None. + */ +void abe_call_subroutine(abe_uint32 idx, abe_uint32 p1, abe_uint32 p2, abe_uint32 p3, abe_uint32 p4) +{ + abe_subroutine0 f0; + abe_subroutine1 f1; + abe_subroutine2 f2; + abe_subroutine3 f3; + abe_subroutine4 f4; + abe_uint32* params; + + if (idx >= MAXNBSUBROUTINE) + return; + + switch (idx) { +#if 0 + /* call the subroutines defined at compilation time (const .. sequences) */ + case SUB_WRITE_MIXER_DL1 : + /@@@@ abe_write_mixer_dl1 (p1, p2, p3) + abe_fprintf ("write_mixer"); + break; +#endif + /* call the subroutines defined at execution time (dynamic sequences) */ + default : + switch(abe_all_subsubroutine_nparam[idx]) { + case SUB_0_PARAM: + f0 = (abe_subroutine0)abe_all_subsubroutine[idx]; + (*f0)(); + break; + case SUB_1_PARAM: + f1 = (abe_subroutine1) abe_all_subsubroutine[idx]; + params = abe_all_subroutine_params[abe_irq_pingpong_player_id]; + if (params != (abe_uint32*)0) + p1 = params[0]; + (*f1) (p1); + break; + case SUB_2_PARAM: + f2 = abe_all_subsubroutine[idx]; + params = abe_all_subroutine_params[abe_irq_pingpong_player_id]; + if (params != (abe_uint32*)0) { + p1 = params[0]; + p2 = params[1]; + } + (*f2) (p1, p2); + break; + case SUB_3_PARAM: + f3 = (abe_subroutine3) abe_all_subsubroutine[idx]; + params = abe_all_subroutine_params[abe_irq_pingpong_player_id]; + if (params != (abe_uint32*)0) { + p1 = params[0]; + p2 = params[1]; + p3 = params[2]; + } + (*f3) (p1, p2, p3); + break; + case SUB_4_PARAM: + f4 = (abe_subroutine4) abe_all_subsubroutine[idx]; + params = abe_all_subroutine_params[abe_irq_pingpong_player_id]; + if (params != (abe_uint32*)0) { + p1 = params[0]; + p2 = params[1]; + p3 = params[2]; + p4 = params[3]; + } + (*f4) (p1, p2, p3, p4); + break; + default: + break; + } + } +} diff --git a/sound/soc/codecs/abe/abe_seq.h b/sound/soc/codecs/abe/abe_seq.h new file mode 100644 index 000000000000..6e15531e920e --- /dev/null +++ b/sound/soc/codecs/abe/abe_seq.h @@ -0,0 +1,127 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ + +void abe_init_subroutine_table(void); + +/* + * Register Programming Examples + * + * 1. Power on sequence + * + * The modules HSLDO, NCP, LSLDO, LPPLL are enabled/disabled automatically by the TWL6040 power state machine after pin AUDPWRON transitions from 0 ' 1. No register writes are necessary. + * + * For the purposes of test it is possible to bypass the power state machine and manually enable these modules in the same order as described in Fig 2-XX. This can be done after VIO comes up and I2C register writes are possible. + * + * The manual sequence could be as follows + * LDOCTL = 0x04 (Enable HSLDO) + * NCPCTL = 0x03 (Enable NCP in auto mode) + * LDOCTL = 0x05 (Enable LSLDO) + * LPPLLCTL = 0x09 (Enable LPPLL with output frequency = 19.2MHz) + * + * Please see Fig 2-64 for details on details to be maintained between successive I2C register writes. + * + * Further if the system MCLK is active the HPPLL could be enabled instead of the LPPLL. + * (a) For a square wave where slicer is not required + * HPPLLCTL = 0x11 (Select HPPLL output, Enable HPPLL) + * (a) For a sine wave where slicer is required + * HPPLLCTL = 0x19 (Select HPPLL output, Enable Slicer, Enable HPPLL) + * + */ + +/* + * 2. Setting up a stereo UPLINK path through MICAMPL, MICAMPR input amplifiers + * AMICBCTL = 0x10 + * MICGAIN = 0x0F (Gain to 24 dB for L and R) + * HPPLLCTL = 0x19 (Select HPPLL output, Enable Slicer, Enable HPPLL) + * MICLCTL = 0x0D (Select MMIC input, Enable ADC) + * MICRCTL = 0x0D (Select SMIC input, Enable ADC) + * + */ + +/* + * 3. Setting up a stereo headset MP3 playback DNLINK path + * Please see section 2.3.1.1 for details + * + * (b) HP + * HSGAIN = 0x22 (-4 dB gain on L and R amplifiers) + * HSLCTL = 0x01 (Enable HSDAC L, HP mode) + * HSRCTL = 0x01 (Enable HSDAC R, HP mode) + * Wait 80us + * HSLCTL = 0x05 (Enable HSLDRV, HP mode) + * HSRCTL = 0x05 (Enable HSRDRV, HP mode) + * Wait 2ms + * HSLCTL = 0x25 (Close HSDACL switch) + * HSRCTL = 0x25 (Close HSDACR switch) + * + */ + +/* + * (a) LP + * HSGAIN = 0x22 (-4 dB gain on L and R amplifiers) + * HSLCTL = 0x03 (Enable HSDAC L, LP mode) + * HSRCTL = 0x03 (Enable HSDAC R, LP mode) + * Wait 80us + * HSLCTL = 0x0F (Enable HSLDRV, LP mode) + * HSRCTL = 0x0F (Enable HSRDRV, LP mode) + * Wait 2ms + * HSLCTL = 0x2F (Close HSDACL switch) + * HSRCTL = 0x2F (Close HSDACR switch) + * + */ + +/* + * 4. Setting up a stereo FM playback path on headset + * (a) HP + * LINEGAIN = 0x1B (0dB gain on L and R inputs) + * MICLCTL = 0x02 (Enable Left LINEAMP) + * MICRCTL = 0x02 (Enable Right LINEAMP) + * HSGAIN = 0x22 (-4 dB gain on L and R amplifiers) + * HSLCTL = 0x04 (Enable HSLDRV in HP mode) + * HSRCTL = 0x04 (Enable HSRDRV in HP mode) + * Wait 2ms + * HSLCTL = 0x44 (Close FMLOOP switch) + * HSRCTL = 0x44 (Close FMLOOP switch) + * + * + */ + +/* + * (b) LP + * LINEGAIN = 0x1B (0dB gain on L and R inputs) + * MICLCTL = 0x02 (Enable Left LINEAMP) + * MICRCTL = 0x02 (Enable Right LINEAMP) + * HSGAIN = 0x22 (-4 dB gain on L and R amplifiers) + * HSLCTL = 0x0C (Enable HSLDRV in LP mode) + * HSRCTL = 0x0C (Enable HSRDRV in LP mode) + * Wait 2ms + * HSLCTL = 0x4C (Close FMLOOP switch) + * HSRCTL = 0x4C (Close FMLOOP switch) + * + */ + + +/* + * 5. Setting up a handset call + * + * UPLINK + * + * AMICBCTL = 0x10 + * MICGAIN = 0x0F (Gain to 24 dB for L and R) + * HPPLLCTL = 0x19 (Select HPPLL output, Enable Slicer, Enable HPPLL) + * MICLCTL = 0x0D (Select MMIC input, Enable ADC) + * MICRCTL = 0x0D (Select SMIC input, Enable ADC) + * + * DNLINK + * + * HSLCTL = 0x01 (Enable HSDACL, HP mode) + * Wait 80us + * EARCTL = 0x03 (Enable EAR, Gain = min, by default enabling EAR connects HSDACL output to EAR) + * + */ diff --git a/sound/soc/codecs/abe/abe_sm_addr.h b/sound/soc/codecs/abe/abe_sm_addr.h new file mode 100644 index 000000000000..d961cef43334 --- /dev/null +++ b/sound/soc/codecs/abe/abe_sm_addr.h @@ -0,0 +1,630 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ + +#ifndef _ABE_SM_ADDR_H_ +#define _ABE_SM_ADDR_H_ + +#define init_SM_ADDR 0 +#define init_SM_ADDR_END 284 +#define init_SM_sizeof 285 + +#define S_Data0_ADDR 285 +#define S_Data0_ADDR_END 285 +#define S_Data0_sizeof 1 + +#define S_Temp_ADDR 286 +#define S_Temp_ADDR_END 286 +#define S_Temp_sizeof 1 + +#define S_PhoenixOffset_ADDR 287 +#define S_PhoenixOffset_ADDR_END 287 +#define S_PhoenixOffset_sizeof 1 + +#define S_GTarget1_ADDR 288 +#define S_GTarget1_ADDR_END 294 +#define S_GTarget1_sizeof 7 + +#define S_Gtarget_DL1_ADDR 295 +#define S_Gtarget_DL1_ADDR_END 296 +#define S_Gtarget_DL1_sizeof 2 + +#define S_Gtarget_DL2_ADDR 297 +#define S_Gtarget_DL2_ADDR_END 298 +#define S_Gtarget_DL2_sizeof 2 + +#define S_Gtarget_Echo_ADDR 299 +#define S_Gtarget_Echo_ADDR_END 299 +#define S_Gtarget_Echo_sizeof 1 + +#define S_Gtarget_SDT_ADDR 300 +#define S_Gtarget_SDT_ADDR_END 300 +#define S_Gtarget_SDT_sizeof 1 + +#define S_Gtarget_VxRec_ADDR 301 +#define S_Gtarget_VxRec_ADDR_END 302 +#define S_Gtarget_VxRec_sizeof 2 + +#define S_Gtarget_UL_ADDR 303 +#define S_Gtarget_UL_ADDR_END 304 +#define S_Gtarget_UL_sizeof 2 + +#define S_Gtarget_unused_ADDR 305 +#define S_Gtarget_unused_ADDR_END 305 +#define S_Gtarget_unused_sizeof 1 + +#define S_GCurrent_ADDR 306 +#define S_GCurrent_ADDR_END 323 +#define S_GCurrent_sizeof 18 + +#define S_GAIN_ONE_ADDR 324 +#define S_GAIN_ONE_ADDR_END 324 +#define S_GAIN_ONE_sizeof 1 + +#define S_Tones_ADDR 325 +#define S_Tones_ADDR_END 336 +#define S_Tones_sizeof 12 + +#define S_VX_DL_ADDR 337 +#define S_VX_DL_ADDR_END 348 +#define S_VX_DL_sizeof 12 + +#define S_MM_UL2_ADDR 349 +#define S_MM_UL2_ADDR_END 360 +#define S_MM_UL2_sizeof 12 + +#define S_MM_DL_ADDR 361 +#define S_MM_DL_ADDR_END 372 +#define S_MM_DL_sizeof 12 + +#define S_DL1_M_Out_ADDR 373 +#define S_DL1_M_Out_ADDR_END 384 +#define S_DL1_M_Out_sizeof 12 + +#define S_DL2_M_Out_ADDR 385 +#define S_DL2_M_Out_ADDR_END 396 +#define S_DL2_M_Out_sizeof 12 + +#define S_Echo_M_Out_ADDR 397 +#define S_Echo_M_Out_ADDR_END 408 +#define S_Echo_M_Out_sizeof 12 + +#define S_SDT_M_Out_ADDR 409 +#define S_SDT_M_Out_ADDR_END 420 +#define S_SDT_M_Out_sizeof 12 + +#define S_VX_UL_ADDR 421 +#define S_VX_UL_ADDR_END 432 +#define S_VX_UL_sizeof 12 + +#define S_VX_UL_M_ADDR 433 +#define S_VX_UL_M_ADDR_END 444 +#define S_VX_UL_M_sizeof 12 + +#define S_BT_DL_ADDR 445 +#define S_BT_DL_ADDR_END 456 +#define S_BT_DL_sizeof 12 + +#define S_BT_UL_ADDR 457 +#define S_BT_UL_ADDR_END 468 +#define S_BT_UL_sizeof 12 + +#define S_BT_DL_8k_ADDR 469 +#define S_BT_DL_8k_ADDR_END 470 +#define S_BT_DL_8k_sizeof 2 + +#define S_BT_DL_16k_ADDR 471 +#define S_BT_DL_16k_ADDR_END 474 +#define S_BT_DL_16k_sizeof 4 + +#define S_BT_UL_8k_ADDR 475 +#define S_BT_UL_8k_ADDR_END 476 +#define S_BT_UL_8k_sizeof 2 + +#define S_BT_UL_16k_ADDR 477 +#define S_BT_UL_16k_ADDR_END 480 +#define S_BT_UL_16k_sizeof 4 + +#define S_BT_UL_8_48_BP_data_ADDR 481 +#define S_BT_UL_8_48_BP_data_ADDR_END 493 +#define S_BT_UL_8_48_BP_data_sizeof 13 + +#define S_BT_UL_8_48_LP_data_ADDR 494 +#define S_BT_UL_8_48_LP_data_ADDR_END 506 +#define S_BT_UL_8_48_LP_data_sizeof 13 + +#define S_BT_UL_16_48_HP_data_ADDR 507 +#define S_BT_UL_16_48_HP_data_ADDR_END 513 +#define S_BT_UL_16_48_HP_data_sizeof 7 + +#define S_BT_UL_16_48_LP_data_ADDR 514 +#define S_BT_UL_16_48_LP_data_ADDR_END 526 +#define S_BT_UL_16_48_LP_data_sizeof 13 + +#define S_BT_DL_48_8_BP_data_ADDR 527 +#define S_BT_DL_48_8_BP_data_ADDR_END 539 +#define S_BT_DL_48_8_BP_data_sizeof 13 + +#define S_BT_DL_48_8_LP_data_ADDR 540 +#define S_BT_DL_48_8_LP_data_ADDR_END 552 +#define S_BT_DL_48_8_LP_data_sizeof 13 + +#define S_BT_DL_48_16_HP_data_ADDR 553 +#define S_BT_DL_48_16_HP_data_ADDR_END 559 +#define S_BT_DL_48_16_HP_data_sizeof 7 + +#define S_BT_DL_48_16_LP_data_ADDR 560 +#define S_BT_DL_48_16_LP_data_ADDR_END 572 +#define S_BT_DL_48_16_LP_data_sizeof 13 + +#define S_SDT_F_ADDR 573 +#define S_SDT_F_ADDR_END 584 +#define S_SDT_F_sizeof 12 + +#define S_SDT_F_data_ADDR 585 +#define S_SDT_F_data_ADDR_END 593 +#define S_SDT_F_data_sizeof 9 + +#define S_MM_DL_OSR_ADDR 594 +#define S_MM_DL_OSR_ADDR_END 617 +#define S_MM_DL_OSR_sizeof 24 + +#define S_24_zeros_ADDR 618 +#define S_24_zeros_ADDR_END 641 +#define S_24_zeros_sizeof 24 + +#define S_DMIC1_ADDR 642 +#define S_DMIC1_ADDR_END 653 +#define S_DMIC1_sizeof 12 + +#define S_DMIC2_ADDR 654 +#define S_DMIC2_ADDR_END 665 +#define S_DMIC2_sizeof 12 + +#define S_DMIC3_ADDR 666 +#define S_DMIC3_ADDR_END 677 +#define S_DMIC3_sizeof 12 + +#define S_AMIC_ADDR 678 +#define S_AMIC_ADDR_END 689 +#define S_AMIC_sizeof 12 + +#define S_EANC_FBK_in_ADDR 690 +#define S_EANC_FBK_in_ADDR_END 713 +#define S_EANC_FBK_in_sizeof 24 + +#define S_EANC_FBK_out_ADDR 714 +#define S_EANC_FBK_out_ADDR_END 725 +#define S_EANC_FBK_out_sizeof 12 + +#define S_DMIC1_L_ADDR 726 +#define S_DMIC1_L_ADDR_END 737 +#define S_DMIC1_L_sizeof 12 + +#define S_DMIC1_R_ADDR 738 +#define S_DMIC1_R_ADDR_END 749 +#define S_DMIC1_R_sizeof 12 + +#define S_DMIC2_L_ADDR 750 +#define S_DMIC2_L_ADDR_END 761 +#define S_DMIC2_L_sizeof 12 + +#define S_DMIC2_R_ADDR 762 +#define S_DMIC2_R_ADDR_END 773 +#define S_DMIC2_R_sizeof 12 + +#define S_DMIC3_L_ADDR 774 +#define S_DMIC3_L_ADDR_END 785 +#define S_DMIC3_L_sizeof 12 + +#define S_DMIC3_R_ADDR 786 +#define S_DMIC3_R_ADDR_END 797 +#define S_DMIC3_R_sizeof 12 + +#define S_BT_UL_L_ADDR 798 +#define S_BT_UL_L_ADDR_END 809 +#define S_BT_UL_L_sizeof 12 + +#define S_BT_UL_R_ADDR 810 +#define S_BT_UL_R_ADDR_END 821 +#define S_BT_UL_R_sizeof 12 + +#define S_AMIC_L_ADDR 822 +#define S_AMIC_L_ADDR_END 833 +#define S_AMIC_L_sizeof 12 + +#define S_AMIC_R_ADDR 834 +#define S_AMIC_R_ADDR_END 845 +#define S_AMIC_R_sizeof 12 + +#define S_EANC_FBK_L_ADDR 846 +#define S_EANC_FBK_L_ADDR_END 857 +#define S_EANC_FBK_L_sizeof 12 + +#define S_EANC_FBK_R_ADDR 858 +#define S_EANC_FBK_R_ADDR_END 869 +#define S_EANC_FBK_R_sizeof 12 + +#define S_EchoRef_L_ADDR 870 +#define S_EchoRef_L_ADDR_END 881 +#define S_EchoRef_L_sizeof 12 + +#define S_EchoRef_R_ADDR 882 +#define S_EchoRef_R_ADDR_END 893 +#define S_EchoRef_R_sizeof 12 + +#define S_MM_DL_L_ADDR 894 +#define S_MM_DL_L_ADDR_END 905 +#define S_MM_DL_L_sizeof 12 + +#define S_MM_DL_R_ADDR 906 +#define S_MM_DL_R_ADDR_END 917 +#define S_MM_DL_R_sizeof 12 + +#define S_MM_UL_ADDR 918 +#define S_MM_UL_ADDR_END 1041 +#define S_MM_UL_sizeof 124 + +#define S_AMIC_96k_ADDR 1042 +#define S_AMIC_96k_ADDR_END 1065 +#define S_AMIC_96k_sizeof 24 + +#define S_DMIC0_96k_ADDR 1066 +#define S_DMIC0_96k_ADDR_END 1089 +#define S_DMIC0_96k_sizeof 24 + +#define S_DMIC1_96k_ADDR 1090 +#define S_DMIC1_96k_ADDR_END 1113 +#define S_DMIC1_96k_sizeof 24 + +#define S_DMIC2_96k_ADDR 1114 +#define S_DMIC2_96k_ADDR_END 1137 +#define S_DMIC2_96k_sizeof 24 + +#define S_UL_VX_UL_48_8K_ADDR 1138 +#define S_UL_VX_UL_48_8K_ADDR_END 1149 +#define S_UL_VX_UL_48_8K_sizeof 12 + +#define S_UL_VX_UL_48_16K_ADDR 1150 +#define S_UL_VX_UL_48_16K_ADDR_END 1161 +#define S_UL_VX_UL_48_16K_sizeof 12 + +#define S_UL_MIC_48K_ADDR 1162 +#define S_UL_MIC_48K_ADDR_END 1173 +#define S_UL_MIC_48K_sizeof 12 + +#define S_Voice_8k_UL_ADDR 1174 +#define S_Voice_8k_UL_ADDR_END 1176 +#define S_Voice_8k_UL_sizeof 3 + +#define S_Voice_8k_DL_ADDR 1177 +#define S_Voice_8k_DL_ADDR_END 1178 +#define S_Voice_8k_DL_sizeof 2 + +#define S_McPDM_Out1_ADDR 1179 +#define S_McPDM_Out1_ADDR_END 1202 +#define S_McPDM_Out1_sizeof 24 + +#define S_McPDM_Out2_ADDR 1203 +#define S_McPDM_Out2_ADDR_END 1226 +#define S_McPDM_Out2_sizeof 24 + +#define S_McPDM_Out3_ADDR 1227 +#define S_McPDM_Out3_ADDR_END 1250 +#define S_McPDM_Out3_sizeof 24 + +#define S_Voice_16k_UL_ADDR 1251 +#define S_Voice_16k_UL_ADDR_END 1255 +#define S_Voice_16k_UL_sizeof 5 + +#define S_Voice_16k_DL_ADDR 1256 +#define S_Voice_16k_DL_ADDR_END 1259 +#define S_Voice_16k_DL_sizeof 4 + +#define S_XinASRC_DL_VX_ADDR 1260 +#define S_XinASRC_DL_VX_ADDR_END 1299 +#define S_XinASRC_DL_VX_sizeof 40 + +#define S_XinASRC_UL_VX_ADDR 1300 +#define S_XinASRC_UL_VX_ADDR_END 1339 +#define S_XinASRC_UL_VX_sizeof 40 + +#define S_XinASRC_DL_MM_ADDR 1340 +#define S_XinASRC_DL_MM_ADDR_END 1379 +#define S_XinASRC_DL_MM_sizeof 40 + +#define S_VX_REC_ADDR 1380 +#define S_VX_REC_ADDR_END 1391 +#define S_VX_REC_sizeof 12 + +#define S_VX_REC_L_ADDR 1392 +#define S_VX_REC_L_ADDR_END 1403 +#define S_VX_REC_L_sizeof 12 + +#define S_VX_REC_R_ADDR 1404 +#define S_VX_REC_R_ADDR_END 1415 +#define S_VX_REC_R_sizeof 12 + +#define S_DL2_M_L_ADDR 1416 +#define S_DL2_M_L_ADDR_END 1427 +#define S_DL2_M_L_sizeof 12 + +#define S_DL2_M_R_ADDR 1428 +#define S_DL2_M_R_ADDR_END 1439 +#define S_DL2_M_R_sizeof 12 + +#define S_DL2_M_LR_EQ_data_ADDR 1440 +#define S_DL2_M_LR_EQ_data_ADDR_END 1464 +#define S_DL2_M_LR_EQ_data_sizeof 25 + +#define S_DL1_M_EQ_data_ADDR 1465 +#define S_DL1_M_EQ_data_ADDR_END 1489 +#define S_DL1_M_EQ_data_sizeof 25 + +#define S_VX_DL_8_48_BP_data_ADDR 1490 +#define S_VX_DL_8_48_BP_data_ADDR_END 1502 +#define S_VX_DL_8_48_BP_data_sizeof 13 + +#define S_VX_DL_8_48_LP_data_ADDR 1503 +#define S_VX_DL_8_48_LP_data_ADDR_END 1515 +#define S_VX_DL_8_48_LP_data_sizeof 13 + +#define S_EARP_48_96_LP_data_ADDR 1516 +#define S_EARP_48_96_LP_data_ADDR_END 1530 +#define S_EARP_48_96_LP_data_sizeof 15 + +#define S_IHF_48_96_LP_data_ADDR 1531 +#define S_IHF_48_96_LP_data_ADDR_END 1545 +#define S_IHF_48_96_LP_data_sizeof 15 + +#define S_VX_DL_16_48_HP_data_ADDR 1546 +#define S_VX_DL_16_48_HP_data_ADDR_END 1552 +#define S_VX_DL_16_48_HP_data_sizeof 7 + +#define S_VX_DL_16_48_LP_data_ADDR 1553 +#define S_VX_DL_16_48_LP_data_ADDR_END 1565 +#define S_VX_DL_16_48_LP_data_sizeof 13 + +#define S_VX_UL_48_8_BP_data_ADDR 1566 +#define S_VX_UL_48_8_BP_data_ADDR_END 1578 +#define S_VX_UL_48_8_BP_data_sizeof 13 + +#define S_VX_UL_48_8_LP_data_ADDR 1579 +#define S_VX_UL_48_8_LP_data_ADDR_END 1591 +#define S_VX_UL_48_8_LP_data_sizeof 13 + +#define S_VX_UL_8_TEMP_ADDR 1592 +#define S_VX_UL_8_TEMP_ADDR_END 1593 +#define S_VX_UL_8_TEMP_sizeof 2 + +#define S_VX_UL_48_16_HP_data_ADDR 1594 +#define S_VX_UL_48_16_HP_data_ADDR_END 1600 +#define S_VX_UL_48_16_HP_data_sizeof 7 + +#define S_VX_UL_48_16_LP_data_ADDR 1601 +#define S_VX_UL_48_16_LP_data_ADDR_END 1613 +#define S_VX_UL_48_16_LP_data_sizeof 13 + +#define S_VX_UL_16_TEMP_ADDR 1614 +#define S_VX_UL_16_TEMP_ADDR_END 1617 +#define S_VX_UL_16_TEMP_sizeof 4 + +#define S_EANC_IIR_data_ADDR 1618 +#define S_EANC_IIR_data_ADDR_END 1634 +#define S_EANC_IIR_data_sizeof 17 + +#define S_EANC_SignalTemp_ADDR 1635 +#define S_EANC_SignalTemp_ADDR_END 1655 +#define S_EANC_SignalTemp_sizeof 21 + +#define S_EANC_Input_ADDR 1656 +#define S_EANC_Input_ADDR_END 1656 +#define S_EANC_Input_sizeof 1 + +#define S_EANC_Output_ADDR 1657 +#define S_EANC_Output_ADDR_END 1657 +#define S_EANC_Output_sizeof 1 + +#define S_APS_IIRmem1_ADDR 1658 +#define S_APS_IIRmem1_ADDR_END 1666 +#define S_APS_IIRmem1_sizeof 9 + +#define S_APS_M_IIRmem2_ADDR 1667 +#define S_APS_M_IIRmem2_ADDR_END 1669 +#define S_APS_M_IIRmem2_sizeof 3 + +#define S_APS_C_IIRmem2_ADDR 1670 +#define S_APS_C_IIRmem2_ADDR_END 1672 +#define S_APS_C_IIRmem2_sizeof 3 + +#define S_APS_DL1_OutSamples_ADDR 1673 +#define S_APS_DL1_OutSamples_ADDR_END 1674 +#define S_APS_DL1_OutSamples_sizeof 2 + +#define S_APS_DL1_COIL_OutSamples_ADDR 1675 +#define S_APS_DL1_COIL_OutSamples_ADDR_END 1676 +#define S_APS_DL1_COIL_OutSamples_sizeof 2 + +#define S_APS_DL2_L_OutSamples_ADDR 1677 +#define S_APS_DL2_L_OutSamples_ADDR_END 1678 +#define S_APS_DL2_L_OutSamples_sizeof 2 + +#define S_APS_DL2_L_COIL_OutSamples_ADDR 1679 +#define S_APS_DL2_L_COIL_OutSamples_ADDR_END 1680 +#define S_APS_DL2_L_COIL_OutSamples_sizeof 2 + +#define S_APS_DL2_R_OutSamples_ADDR 1681 +#define S_APS_DL2_R_OutSamples_ADDR_END 1682 +#define S_APS_DL2_R_OutSamples_sizeof 2 + +#define S_APS_DL2_R_COIL_OutSamples_ADDR 1683 +#define S_APS_DL2_R_COIL_OutSamples_ADDR_END 1684 +#define S_APS_DL2_R_COIL_OutSamples_sizeof 2 + +#define S_XinASRC_ECHO_REF_ADDR 1685 +#define S_XinASRC_ECHO_REF_ADDR_END 1724 +#define S_XinASRC_ECHO_REF_sizeof 40 + +#define S_ECHO_REF_16K_ADDR 1725 +#define S_ECHO_REF_16K_ADDR_END 1729 +#define S_ECHO_REF_16K_sizeof 5 + +#define S_ECHO_REF_8K_ADDR 1730 +#define S_ECHO_REF_8K_ADDR_END 1732 +#define S_ECHO_REF_8K_sizeof 3 + +#define S_DL1_ADDR 1733 +#define S_DL1_ADDR_END 1744 +#define S_DL1_sizeof 12 + +#define S_APS_DL2_L_IIRmem1_ADDR 1745 +#define S_APS_DL2_L_IIRmem1_ADDR_END 1753 +#define S_APS_DL2_L_IIRmem1_sizeof 9 + +#define S_APS_DL2_R_IIRmem1_ADDR 1754 +#define S_APS_DL2_R_IIRmem1_ADDR_END 1762 +#define S_APS_DL2_R_IIRmem1_sizeof 9 + +#define S_APS_DL2_L_M_IIRmem2_ADDR 1763 +#define S_APS_DL2_L_M_IIRmem2_ADDR_END 1765 +#define S_APS_DL2_L_M_IIRmem2_sizeof 3 + +#define S_APS_DL2_R_M_IIRmem2_ADDR 1766 +#define S_APS_DL2_R_M_IIRmem2_ADDR_END 1768 +#define S_APS_DL2_R_M_IIRmem2_sizeof 3 + +#define S_APS_DL2_L_C_IIRmem2_ADDR 1769 +#define S_APS_DL2_L_C_IIRmem2_ADDR_END 1771 +#define S_APS_DL2_L_C_IIRmem2_sizeof 3 + +#define S_APS_DL2_R_C_IIRmem2_ADDR 1772 +#define S_APS_DL2_R_C_IIRmem2_ADDR_END 1774 +#define S_APS_DL2_R_C_IIRmem2_sizeof 3 + +#define S_DL1_APS_ADDR 1775 +#define S_DL1_APS_ADDR_END 1786 +#define S_DL1_APS_sizeof 12 + +#define S_DL2_L_APS_ADDR 1787 +#define S_DL2_L_APS_ADDR_END 1798 +#define S_DL2_L_APS_sizeof 12 + +#define S_DL2_R_APS_ADDR 1799 +#define S_DL2_R_APS_ADDR_END 1810 +#define S_DL2_R_APS_sizeof 12 + +#define S_ECHO_REF_48_8_BP_data_ADDR 1811 +#define S_ECHO_REF_48_8_BP_data_ADDR_END 1823 +#define S_ECHO_REF_48_8_BP_data_sizeof 13 + +#define S_ECHO_REF_48_8_LP_data_ADDR 1824 +#define S_ECHO_REF_48_8_LP_data_ADDR_END 1836 +#define S_ECHO_REF_48_8_LP_data_sizeof 13 + +#define S_ECHO_REF_48_16_HP_data_ADDR 1837 +#define S_ECHO_REF_48_16_HP_data_ADDR_END 1843 +#define S_ECHO_REF_48_16_HP_data_sizeof 7 + +#define S_ECHO_REF_48_16_LP_data_ADDR 1844 +#define S_ECHO_REF_48_16_LP_data_ADDR_END 1856 +#define S_ECHO_REF_48_16_LP_data_sizeof 13 + +#define S_APS_DL1_EQ_data_ADDR 1857 +#define S_APS_DL1_EQ_data_ADDR_END 1865 +#define S_APS_DL1_EQ_data_sizeof 9 + +#define S_APS_DL2_EQ_data_ADDR 1866 +#define S_APS_DL2_EQ_data_ADDR_END 1874 +#define S_APS_DL2_EQ_data_sizeof 9 + +#define S_DC_DCvalue_ADDR 1875 +#define S_DC_DCvalue_ADDR_END 1875 +#define S_DC_DCvalue_sizeof 1 + +#define S_VIBRA_ADDR 1876 +#define S_VIBRA_ADDR_END 1881 +#define S_VIBRA_sizeof 6 + +#define S_Vibra2_in_ADDR 1882 +#define S_Vibra2_in_ADDR_END 1887 +#define S_Vibra2_in_sizeof 6 + +#define S_Vibra2_addr_ADDR 1888 +#define S_Vibra2_addr_ADDR_END 1888 +#define S_Vibra2_addr_sizeof 1 + +#define S_VibraCtrl_forRightSM_ADDR 1889 +#define S_VibraCtrl_forRightSM_ADDR_END 1912 +#define S_VibraCtrl_forRightSM_sizeof 24 + +#define S_Rnoise_mem_ADDR 1913 +#define S_Rnoise_mem_ADDR_END 1913 +#define S_Rnoise_mem_sizeof 1 + +#define S_Ctrl_ADDR 1914 +#define S_Ctrl_ADDR_END 1931 +#define S_Ctrl_sizeof 18 + +#define S_Vibra1_in_ADDR 1932 +#define S_Vibra1_in_ADDR_END 1937 +#define S_Vibra1_in_sizeof 6 + +#define S_Vibra1_temp_ADDR 1938 +#define S_Vibra1_temp_ADDR_END 1961 +#define S_Vibra1_temp_sizeof 24 + +#define S_VibraCtrl_forLeftSM_ADDR 1962 +#define S_VibraCtrl_forLeftSM_ADDR_END 1985 +#define S_VibraCtrl_forLeftSM_sizeof 24 + +#define S_Vibra1_mem_ADDR 1986 +#define S_Vibra1_mem_ADDR_END 1996 +#define S_Vibra1_mem_sizeof 11 + +#define S_VibraCtrl_Stereo_ADDR 1997 +#define S_VibraCtrl_Stereo_ADDR_END 2020 +#define S_VibraCtrl_Stereo_sizeof 24 + +#define S_AMIC_96_48_data_ADDR 2021 +#define S_AMIC_96_48_data_ADDR_END 2035 +#define S_AMIC_96_48_data_sizeof 15 + +#define S_DMIC0_96_48_data_ADDR 2036 +#define S_DMIC0_96_48_data_ADDR_END 2050 +#define S_DMIC0_96_48_data_sizeof 15 + +#define S_DMIC1_96_48_data_ADDR 2051 +#define S_DMIC1_96_48_data_ADDR_END 2065 +#define S_DMIC1_96_48_data_sizeof 15 + +#define S_DMIC2_96_48_data_ADDR 2066 +#define S_DMIC2_96_48_data_ADDR_END 2080 +#define S_DMIC2_96_48_data_sizeof 15 + +#define S_EANC_FBK_96_48_data_ADDR 2081 +#define S_EANC_FBK_96_48_data_ADDR_END 2095 +#define S_EANC_FBK_96_48_data_sizeof 15 + +#define S_DBG_8K_PATTERN_ADDR 2096 +#define S_DBG_8K_PATTERN_ADDR_END 2103 +#define S_DBG_8K_PATTERN_sizeof 8 + +#define S_DBG_16K_PATTERN_ADDR 2104 +#define S_DBG_16K_PATTERN_ADDR_END 2119 +#define S_DBG_16K_PATTERN_sizeof 16 + +#define S_DBG_48K_PATTERN_ADDR 2120 +#define S_DBG_48K_PATTERN_ADDR_END 2143 +#define S_DBG_48K_PATTERN_sizeof 24 + +#define S_DBG_MCPDM_PATTERN_ADDR 2144 +#define S_DBG_MCPDM_PATTERN_ADDR_END 2215 +#define S_DBG_MCPDM_PATTERN_sizeof 72 + +#endif /* _ABESM_ADDR_H_ */ diff --git a/sound/soc/codecs/abe/abe_sys.h b/sound/soc/codecs/abe/abe_sys.h new file mode 100644 index 000000000000..f4d50d2132ff --- /dev/null +++ b/sound/soc/codecs/abe/abe_sys.h @@ -0,0 +1,9 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ diff --git a/sound/soc/codecs/abe/abe_taskId.h b/sound/soc/codecs/abe/abe_taskId.h new file mode 100644 index 000000000000..4f6ace57a021 --- /dev/null +++ b/sound/soc/codecs/abe/abe_taskId.h @@ -0,0 +1,129 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ + +#ifndef _ABE_TASKID_H_ +#define _ABE_TASKID_H_ + +#define C_ABE_FW_TASK_DL1_APS_CORE 0 +#define C_ABE_FW_TASK_DL1_APS_COIL_CORE 1 +#define C_ABE_FW_TASK_DL2_L_APS_CORE 2 +#define C_ABE_FW_TASK_DL2_L_APS_COIL_CORE 3 +#define C_ABE_FW_TASK_DL2_R_APS_CORE 4 +#define C_ABE_FW_TASK_DL2_R_APS_COIL_CORE 5 +#define C_ABE_FW_TASK_ASRC_VX_DL_8 6 +#define C_ABE_FW_TASK_ASRC_VX_DL_16 7 +#define C_ABE_FW_TASK_ASRC_MM_DL 8 +#define C_ABE_FW_TASK_ASRC_VX_UL_8 9 +#define C_ABE_FW_TASK_ASRC_VX_UL_16 10 +#define C_ABE_FW_TASK_ASRC_ECHO_REF_8 11 +#define C_ABE_FW_TASK_ASRC_ECHO_REF_16 12 +#define C_ABE_FW_TASK_DC_REMOVAL2 13 +#define C_ABE_FW_TASK_VX_UL_48_8_DEC 14 +#define C_ABE_FW_TASK_VX_UL_48_16_DEC 15 +#define C_ABE_FW_TASK_BT_DL_48_8_DEC 16 +#define C_ABE_FW_TASK_BT_DL_48_16_DEC 17 +#define C_ABE_FW_TASK_ECHO_REF_48_8_DEC 18 +#define C_ABE_FW_TASK_ECHO_REF_48_16_DEC 19 +#define C_ABE_FW_TASK_DL2_EQ 20 +#define C_ABE_FW_TASK_DL2_L_APS_IIR 21 +#define C_ABE_FW_TASK_DL2_R_APS_IIR 22 +#define C_ABE_FW_TASK_DL2_APS_EQ 23 +#define C_ABE_FW_TASK_ECHO_REF_48_16 24 +#define C_ABE_FW_TASK_ECHO_REF_48_8 25 +#define C_ABE_FW_TASK_GAIN_UPDATE 26 +#define C_ABE_FW_TASK_SideTone 27 +#define C_ABE_FW_TASK_VX_DL_8_48_BP 28 +#define C_ABE_FW_TASK_VX_DL_8_48_LP 29 +#define C_ABE_FW_TASK_VX_DL_16_48_HP 30 +#define C_ABE_FW_TASK_VX_DL_16_48_LP 31 +#define C_ABE_FW_TASK_VX_UL_48_8_LP 32 +#define C_ABE_FW_TASK_VX_UL_48_8_BP 33 +#define C_ABE_FW_TASK_VX_UL_48_16_LP 34 +#define C_ABE_FW_TASK_VX_UL_48_16_HP 35 +#define C_ABE_FW_TASK_BT_UL_8_48_BP 36 +#define C_ABE_FW_TASK_BT_UL_8_48_LP 37 +#define C_ABE_FW_TASK_BT_UL_16_48_HP 38 +#define C_ABE_FW_TASK_BT_UL_16_48_LP 39 +#define C_ABE_FW_TASK_BT_DL_48_8_LP 40 +#define C_ABE_FW_TASK_BT_DL_48_8_BP 41 +#define C_ABE_FW_TASK_BT_DL_48_16_LP 42 +#define C_ABE_FW_TASK_BT_DL_48_16_HP 43 +#define C_ABE_FW_TASK_DL1_EQ 44 +#define C_ABE_FW_TASK_DL1_APS_IIR 45 +#define C_ABE_FW_TASK_ECHO_REF_48_8_LP 46 +#define C_ABE_FW_TASK_ECHO_REF_48_8_BP 47 +#define C_ABE_FW_TASK_ECHO_REF_48_16_LP 48 +#define C_ABE_FW_TASK_ECHO_REF_48_16_HP 49 +#define C_ABE_FW_TASK_DL1_APS_EQ 50 +#define C_ABE_FW_TASK_IHF_48_96_LP 51 +#define C_ABE_FW_TASK_EARP_48_96_LP 52 +#define C_ABE_FW_TASK_DL1_GAIN 53 +#define C_ABE_FW_TASK_DL2_GAIN 54 +#define C_ABE_FW_TASK_IO_PING_PONG 55 +#define C_ABE_FW_TASK_IO_DMIC 56 +#define C_ABE_FW_TASK_IO_PDM_UL 57 +#define C_ABE_FW_TASK_IO_BT_VX_UL 58 +#define C_ABE_FW_TASK_IO_MM_UL 59 +#define C_ABE_FW_TASK_IO_MM_UL2 60 +#define C_ABE_FW_TASK_IO_VX_UL 61 +#define C_ABE_FW_TASK_IO_MM_DL 62 +#define C_ABE_FW_TASK_IO_VX_DL 63 +#define C_ABE_FW_TASK_IO_TONES_DL 64 +#define C_ABE_FW_TASK_IO_VIB_DL 65 +#define C_ABE_FW_TASK_IO_BT_VX_DL 66 +#define C_ABE_FW_TASK_IO_PDM_DL 67 +#define C_ABE_FW_TASK_IO_MM_EXT_OUT 68 +#define C_ABE_FW_TASK_IO_MM_EXT_IN 69 +#define C_ABE_FW_TASK_DEBUG_IRQFIFO 70 +#define C_ABE_FW_TASK_EchoMixer 71 +#define C_ABE_FW_TASK_SDTMixer 72 +#define C_ABE_FW_TASK_DL1Mixer 73 +#define C_ABE_FW_TASK_DL2Mixer 74 +#define C_ABE_FW_TASK_VXRECMixer 75 +#define C_ABE_FW_TASK_ULMixer 76 +#define C_ABE_FW_TASK_VIBRA_PACK 77 +#define C_ABE_FW_TASK_VX_DL_8_48_0SR 78 +#define C_ABE_FW_TASK_VX_DL_16_48_0SR 79 +#define C_ABE_FW_TASK_BT_UL_8_48_0SR 80 +#define C_ABE_FW_TASK_BT_UL_16_48_0SR 81 +#define C_ABE_FW_TASK_IHF_48_96_0SR 82 +#define C_ABE_FW_TASK_EARP_48_96_0SR 83 +#define C_ABE_FW_TASK_AMIC_SPLIT 84 +#define C_ABE_FW_TASK_DMIC1_SPLIT 85 +#define C_ABE_FW_TASK_DMIC2_SPLIT 86 +#define C_ABE_FW_TASK_DMIC3_SPLIT 87 +#define C_ABE_FW_TASK_VXREC_SPLIT 88 +#define C_ABE_FW_TASK_BT_UL_SPLIT 89 +#define C_ABE_FW_TASK_MM_SPLIT 90 +#define C_ABE_FW_TASK_DL2_APS_SPLIT 91 +#define C_ABE_FW_TASK_VIBRA_SPLIT 92 +#define C_ABE_FW_TASK_EANC_FBK_SPLIT 93 +#define C_ABE_FW_TASK_VX_UL_ROUTING 94 +#define C_ABE_FW_TASK_MM_UL2_ROUTING 95 +#define C_ABE_FW_TASK_VIBRA1 96 +#define C_ABE_FW_TASK_VIBRA2 97 +#define C_ABE_FW_TASK_BT_UL_16_48 98 +#define C_ABE_FW_TASK_BT_UL_8_48 99 +#define C_ABE_FW_TASK_BT_DL_48_16 100 +#define C_ABE_FW_TASK_BT_DL_48_8 101 +#define C_ABE_FW_TASK_VX_DL_16_48 102 +#define C_ABE_FW_TASK_VX_DL_8_48 103 +#define C_ABE_FW_TASK_VX_UL_48_16 104 +#define C_ABE_FW_TASK_VX_UL_48_8 105 +#define C_ABE_FW_TASK_DBG_SYNC 106 +#define C_ABE_FW_TASK_APS_DL1_IRQs 107 +#define C_ABE_FW_TASK_APS_DL2_L_IRQs 108 +#define C_ABE_FW_TASK_APS_DL2_R_IRQs 109 +#define C_ABE_FW_TASK_AMIC_96_48_LP 110 +#define C_ABE_FW_TASK_DMIC1_96_48_LP 111 +#define C_ABE_FW_TASK_DMIC2_96_48_LP 112 +#define C_ABE_FW_TASK_DMIC3_96_48_LP 113 + +#endif /* _ABE_TASKID_H_ */ diff --git a/sound/soc/codecs/abe/abe_test.c b/sound/soc/codecs/abe/abe_test.c new file mode 100644 index 000000000000..0841eca8cb31 --- /dev/null +++ b/sound/soc/codecs/abe/abe_test.c @@ -0,0 +1,954 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include "ABE_MAIN.h" +#include "ABE_DEF.h" + +void abe_test_scenario_1(void); +void abe_test_scenario_2(void); +void abe_test_scenario_3(void); +void abe_test_scenario_4(void); + +/* +* @fn ABE_TEST_SCENARIO() +*/ +void abe_test_scenario(abe_int32 scenario_id) +{ + switch (scenario_id) { + case 1: + abe_test_scenario_1(); + break; + case 2: + abe_test_scenario_2(); + break; + case 3: + abe_test_scenario_3(); + break; + case 4: + abe_test_scenario_4(); + break; + } +} + +/* +* @fn abe_test_read_time () +*/ +abe_uint32 abe_test_read_time(void) +{ + abe_uint32 time; + abe_block_copy(COPY_FROM_ABE_TO_HOST, ABE_DMEM, D_slotCounter_ADDR, + (abe_uint32*)&time, sizeof (time)); + return (time & 0xFFFF); +} + +/* +* @fn ABE_TEST_SCENARIO_1 () +* +* DMA AUDIO PLAYER + DMA VOICE CALL 16kHz +*/ +void abe_test_scenario_1(void) +{ + static abe_int32 time_offset, state; + abe_data_format_t format; + abe_dma_t dma_sink; + abe_uint32 current_time; + abe_use_case_id UC2[] = { + ABE_AUDIO_PLAYER_ON_HEADSET_OR_EARPHONE, + ABE_RINGER_TONES, + (abe_use_case_id)0 + }; + // abe_use_case_id UC5[] = {ABE_AUDIO_PLAYER_ON_HEADSET_OR_EARPHONE, (abe_use_case_id)0}; + abe_opp_t OPP; + abe_hw_config_init_t CONFIG; + + /* Scenario 1- 16kHz first */ + switch (state) { + case 0: + state ++; + time_offset = abe_test_read_time(); + abe_reset_hal(); + + /* check HW config and OPP config */ + abe_read_hardware_configuration(UC2, &OPP, &CONFIG); + /* sets the OPP100 on FW05.xx */ + abe_set_opp_processing(OPP); + /* "tick" of the audio engine */ + abe_write_event_generator(CONFIG.HAL_EVENT_SELECTION); + + abe_set_router_configuration(UPROUTE, UPROUTE_CONFIG_BT, + (abe_router_t *) abe_router_ul_table_preset[UPROUTE_CONFIG_BT]); + + format.f = 48000; + format.samp_format = SIX_MSB; + abe_connect_cbpr_dmareq_port(MM_UL_PORT, &format, ABE_CBPR3_IDX, &dma_sink); + format.f = 48000; + format.samp_format = STEREO_MSB; + abe_connect_cbpr_dmareq_port(MM_UL2_PORT, &format, ABE_CBPR4_IDX, &dma_sink); + format.f = 8000; + format.samp_format = MONO_MSB; + abe_connect_cbpr_dmareq_port(VX_UL_PORT, &format, ABE_CBPR2_IDX, &dma_sink); + /* enable all DMIC aquisition */ + abe_enable_data_transfer(MM_UL_PORT); + /* enable large-band DMIC aquisition */ + abe_enable_data_transfer(MM_UL2_PORT); + abe_enable_data_transfer(VX_UL_PORT); + + format.f = 48000; + format.samp_format = STEREO_MSB; + abe_connect_cbpr_dmareq_port(TONES_DL_PORT, &format, ABE_CBPR5_IDX, &dma_sink); + format.f = 8000; + format.samp_format = MONO_MSB; + abe_connect_cbpr_dmareq_port(VX_DL_PORT, &format, ABE_CBPR1_IDX, &dma_sink); + format.f = 48000; + format.samp_format = STEREO_MSB; + abe_connect_cbpr_dmareq_port(MM_DL_PORT, &format, ABE_CBPR0_IDX, &dma_sink); + format.f = 24000; + format.samp_format = STEREO_MSB; + abe_connect_cbpr_dmareq_port(VIB_DL_PORT, &format, ABE_CBPR6_IDX, &dma_sink); + abe_enable_data_transfer(TONES_DL_PORT); + abe_enable_data_transfer(VX_DL_PORT); + /* enable all the data paths */ + abe_enable_data_transfer(MM_DL_PORT); + abe_enable_data_transfer(VIB_DL_PORT); + + /* SERIAL PORTS TEST */ + format.f = 8000; + format.samp_format = STEREO_MSB; + abe_connect_serial_port(BT_VX_UL_PORT, &format, MCBSP1_RX); + format.f = 8000; + format.samp_format = STEREO_MSB; + abe_connect_serial_port(BT_VX_DL_PORT, &format, MCBSP1_TX); + format.f = 48000; + format.samp_format = STEREO_MSB; + abe_connect_serial_port(MM_EXT_IN_PORT, &format, MCBSP2_RX); + format.f = 48000; + format.samp_format = STEREO_MSB; + abe_connect_serial_port(MM_EXT_OUT_PORT, &format, MCBSP2_TX); + abe_enable_data_transfer(BT_VX_UL_PORT); + abe_enable_data_transfer(BT_VX_DL_PORT); + abe_enable_data_transfer(MM_EXT_IN_PORT); + abe_enable_data_transfer(MM_EXT_OUT_PORT); + + /* DMIC ATC can be enabled even if the DMIC */ + abe_enable_data_transfer(DMIC_PORT); + abe_enable_data_transfer(PDM_DL_PORT); + abe_enable_data_transfer(PDM_UL_PORT); + + /* mixers' configuration = voice on earphone + music on hands-free path */ + abe_write_mixer(MIXDL1, GAIN_M6dB, RAMP_0MS, MIX_DL1_INPUT_MM_DL); + abe_write_mixer(MIXDL1, MUTE_GAIN, RAMP_0MS, MIX_DL1_INPUT_MM_UL2); + abe_write_mixer(MIXDL1, GAIN_M6dB, RAMP_0MS, MIX_DL1_INPUT_VX_DL); + abe_write_mixer(MIXDL1, MUTE_GAIN, RAMP_0MS, MIX_DL1_INPUT_TONES); + + abe_write_mixer(MIXDL2, GAIN_M6dB, RAMP_0MS, MIX_DL2_INPUT_TONES); + abe_write_mixer(MIXDL2, MUTE_GAIN, RAMP_0MS, MIX_DL2_INPUT_VX_DL); + abe_write_mixer(MIXDL2, MUTE_GAIN, RAMP_0MS, MIX_DL2_INPUT_MM_DL); + abe_write_mixer(MIXDL2, GAIN_M6dB, RAMP_0MS, MIX_DL2_INPUT_MM_UL2); + + abe_write_mixer(MIXSDT, MUTE_GAIN, RAMP_0MS, MIX_SDT_INPUT_UP_MIXER); + abe_write_mixer(MIXSDT, GAIN_0dB, RAMP_0MS, MIX_SDT_INPUT_DL1_MIXER); + + abe_write_mixer(MIXECHO, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_mixer(MIXECHO, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + + abe_write_mixer(MIXAUDUL, MUTE_GAIN, RAMP_0MS, MIX_AUDUL_INPUT_MM_DL); + abe_write_mixer(MIXAUDUL, MUTE_GAIN, RAMP_0MS, MIX_AUDUL_INPUT_TONES); + abe_write_mixer(MIXAUDUL, GAIN_0dB, RAMP_0MS, MIX_AUDUL_INPUT_UPLINK); + abe_write_mixer(MIXAUDUL, MUTE_GAIN, RAMP_0MS, MIX_AUDUL_INPUT_VX_DL); + + abe_write_mixer(MIXVXREC, MUTE_GAIN, RAMP_0MS, MIX_VXREC_INPUT_TONES); + abe_write_mixer(MIXVXREC, GAIN_M6dB, RAMP_0MS, MIX_VXREC_INPUT_VX_DL); + abe_write_mixer(MIXVXREC, MUTE_GAIN, RAMP_0MS, MIX_VXREC_INPUT_MM_DL); + abe_write_mixer(MIXVXREC, GAIN_M6dB, RAMP_0MS, MIX_VXREC_INPUT_VX_UL); + + abe_write_gain(GAINS_DMIC1, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_DMIC1, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + abe_write_gain(GAINS_DMIC2, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_DMIC2, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + abe_write_gain(GAINS_DMIC3, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_DMIC3, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + abe_write_gain(GAINS_AMIC , GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_AMIC, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + + abe_write_gain(GAINS_SPLIT, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_SPLIT, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + //abe_write_gain(GAINS_EANC , GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + //abe_write_gain(GAINS_EANC, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + + abe_write_gain(GAINS_DL1, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_DL1, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + abe_write_gain(GAINS_DL2, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_DL2, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + break; + case 1: + current_time = abe_test_read_time(); + if ((current_time - time_offset) < 100) + break; + else + state ++; + break; + case 2: + current_time = abe_test_read_time(); + if ((current_time - time_offset) < 100000) + break; + else + state ++; // Internal buffer analysis + break; + default: + state = 0; + break; + } +} + +/* +* @fn ABE_TEST_SCENARIO_2 () +* +* DMA AUDIO PLAYER + DMA VOICE CALL 8kHz +*/ +void abe_test_scenario_2 (void) +{ + static abe_int32 time_offset, state; + abe_data_format_t format; + abe_dma_t dma_sink; + abe_uint32 current_time; + abe_use_case_id UC2[] = { + ABE_AUDIO_PLAYER_ON_HEADSET_OR_EARPHONE, + ABE_RINGER_TONES, + (abe_use_case_id)0 + }; + // abe_use_case_id UC5[] = {ABE_AUDIO_PLAYER_ON_HEADSET_OR_EARPHONE, (abe_use_case_id)0}; + abe_opp_t OPP; + abe_hw_config_init_t CONFIG; + + /* Scenario 1- 16kHz first */ + switch (state) { + case 0: + state ++; + time_offset = abe_test_read_time(); + + /* check HW config and OPP config */ + abe_read_hardware_configuration(UC2, &OPP, &CONFIG); + /* sets the OPP100 on FW05.xx */ + abe_set_opp_processing(OPP); + /* "tick" of the audio engine */ + abe_write_event_generator(CONFIG.HAL_EVENT_SELECTION); + + abe_set_router_configuration(UPROUTE, UPROUTE_CONFIG_AMIC, + (abe_router_t *) abe_router_ul_table_preset[UPROUTE_CONFIG_AMIC]); + + format.f = 48000; + format.samp_format = STEREO_MSB; + abe_connect_cbpr_dmareq_port(MM_UL_PORT, &format, ABE_CBPR3_IDX, &dma_sink); + format.f = 48000; + format.samp_format = STEREO_MSB; + abe_connect_cbpr_dmareq_port(MM_UL2_PORT, &format, ABE_CBPR4_IDX, &dma_sink); + format.f = 8000; + format.samp_format = MONO_MSB; + abe_connect_cbpr_dmareq_port(VX_UL_PORT, &format, ABE_CBPR2_IDX, &dma_sink); + /* enable all DMIC aquisition */ + abe_enable_data_transfer(MM_UL_PORT); + /* enable large-band DMIC aquisition */ + abe_enable_data_transfer(MM_UL2_PORT); + abe_enable_data_transfer(VX_UL_PORT); + + format.f = 48000; + format.samp_format = STEREO_MSB; + abe_connect_cbpr_dmareq_port(TONES_DL_PORT, &format, ABE_CBPR5_IDX, &dma_sink); + format.f = 8000; + format.samp_format = MONO_MSB; + abe_connect_cbpr_dmareq_port(VX_DL_PORT, &format, ABE_CBPR1_IDX, &dma_sink); + format.f = 48000; + format.samp_format = STEREO_MSB; + abe_connect_cbpr_dmareq_port(MM_DL_PORT, &format, ABE_CBPR0_IDX, &dma_sink); + format.f = 24000; + format.samp_format = STEREO_MSB; + abe_connect_cbpr_dmareq_port(VIB_DL_PORT, &format, ABE_CBPR6_IDX, &dma_sink); + abe_enable_data_transfer(TONES_DL_PORT); + abe_enable_data_transfer(VX_DL_PORT); + /* enable all the data paths */ + abe_enable_data_transfer(MM_DL_PORT); + abe_enable_data_transfer(VIB_DL_PORT); + + /* DMIC ATC can be enabled even if the DMIC */ + abe_enable_data_transfer(DMIC_PORT); + abe_enable_data_transfer(PDM_DL_PORT); + abe_enable_data_transfer(PDM_UL_PORT); + + /* mixers' configuration = voice on earphone + music on hands-free path */ + abe_write_mixer(MIXDL1, MUTE_GAIN, RAMP_0MS, MIX_DL1_INPUT_TONES); + abe_write_mixer(MIXDL1, GAIN_M6dB, RAMP_0MS, MIX_DL1_INPUT_VX_DL); + abe_write_mixer(MIXDL1, GAIN_M6dB, RAMP_0MS, MIX_DL1_INPUT_MM_DL); + abe_write_mixer(MIXDL1, MUTE_GAIN, RAMP_0MS, MIX_DL1_INPUT_MM_UL2); + + abe_write_mixer(MIXDL2, MUTE_GAIN, RAMP_0MS, MIX_DL2_INPUT_TONES); + abe_write_mixer(MIXDL2, GAIN_M6dB, RAMP_0MS, MIX_DL2_INPUT_VX_DL); + abe_write_mixer(MIXDL2, GAIN_M6dB, RAMP_0MS, MIX_DL2_INPUT_MM_DL); + abe_write_mixer(MIXDL2, MUTE_GAIN, RAMP_0MS, MIX_DL2_INPUT_MM_UL2); + + abe_write_mixer(MIXSDT, MUTE_GAIN, RAMP_0MS, MIX_SDT_INPUT_UP_MIXER); + abe_write_mixer(MIXSDT, GAIN_0dB, RAMP_0MS, MIX_SDT_INPUT_DL1_MIXER); + + abe_write_mixer(MIXECHO, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_mixer(MIXECHO, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + + abe_write_mixer(MIXAUDUL, MUTE_GAIN, RAMP_0MS, MIX_AUDUL_INPUT_TONES); + abe_write_mixer(MIXAUDUL, GAIN_0dB, RAMP_0MS, MIX_AUDUL_INPUT_UPLINK); + abe_write_mixer(MIXAUDUL, MUTE_GAIN, RAMP_0MS, MIX_AUDUL_INPUT_MM_DL); + abe_write_mixer(MIXAUDUL, MUTE_GAIN, RAMP_0MS, MIX_AUDUL_INPUT_VX_DL); + + abe_write_mixer(MIXVXREC, MUTE_GAIN, RAMP_0MS, MIX_VXREC_INPUT_TONES); + abe_write_mixer(MIXVXREC, GAIN_M6dB, RAMP_0MS, MIX_VXREC_INPUT_VX_DL); + abe_write_mixer(MIXVXREC, MUTE_GAIN, RAMP_0MS, MIX_VXREC_INPUT_MM_DL); + abe_write_mixer(MIXVXREC, GAIN_M6dB, RAMP_0MS, MIX_VXREC_INPUT_VX_UL); + + abe_write_gain(GAINS_DMIC1, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_DMIC1, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + abe_write_gain(GAINS_DMIC2, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_DMIC2, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + abe_write_gain(GAINS_DMIC3, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_DMIC3, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + abe_write_gain(GAINS_AMIC, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_AMIC, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + + abe_write_gain(GAINS_SPLIT , GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_SPLIT, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + //abe_write_gain(GAINS_EANC , GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + //abe_write_gain(GAINS_EANC, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + abe_write_gain(GAINS_DL1, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_DL1, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + abe_write_gain(GAINS_DL2, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_DL2, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + break; + case 1: + current_time = abe_test_read_time(); + if ((current_time - time_offset) < 100) + break; + else + state ++; /* Gains switch */ + break; + case 2: + current_time = abe_test_read_time(); + if ((current_time - time_offset) < 100000) + break; + else + state ++; /* Internal buffer analysis */ + break; + default: + state = 0; + break; + } +} + +/* +* @fn ABE_TEST_SCENARIO_3 () +* DMA AUDIO PLAYER 44100Hz OPP 25% +*/ +void abe_test_scenario_3 (void) +{ + static abe_int32 time_offset, state; + abe_data_format_t format; + abe_dma_t dma_sink; + abe_uint32 current_time; + abe_use_case_id UC2[] = { + ABE_AUDIO_PLAYER_ON_HEADSET_OR_EARPHONE, + ABE_RINGER_TONES, + (abe_use_case_id)0 + }; + abe_opp_t OPP; + abe_hw_config_init_t CONFIG; + + /* Scenario 1- 16kHz first */ + switch (state) { + case 0: + state ++; + time_offset = abe_test_read_time(); + + /* check HW config and OPP config */ + abe_read_hardware_configuration(UC2, &OPP, &CONFIG); + /* sets the OPP100 on FW05.xx */ + abe_set_opp_processing(OPP); + /* "tick" of the audio engine */ + abe_write_event_generator(CONFIG.HAL_EVENT_SELECTION); + + format.f = 44100; + format.samp_format = STEREO_MSB; + abe_connect_cbpr_dmareq_port(MM_DL_PORT, &format, ABE_CBPR0_IDX, &dma_sink); + /* enable all the data paths */ + abe_enable_data_transfer(MM_DL_PORT); + abe_enable_data_transfer(PDM_DL_PORT); + + /* mixers' configuration = voice on earphone + music on hands-free path */ + abe_write_mixer(MIXDL1, MUTE_GAIN, RAMP_0MS, MIX_DL1_INPUT_TONES); + abe_write_mixer(MIXDL1, GAIN_M6dB, RAMP_0MS, MIX_DL1_INPUT_VX_DL); + abe_write_mixer(MIXDL1, GAIN_M6dB, RAMP_0MS, MIX_DL1_INPUT_MM_DL); + abe_write_mixer(MIXDL1, MUTE_GAIN, RAMP_0MS, MIX_DL1_INPUT_MM_UL2); + + abe_write_mixer(MIXDL2, MUTE_GAIN, RAMP_0MS, MIX_DL2_INPUT_TONES); + abe_write_mixer(MIXDL2, GAIN_M6dB, RAMP_0MS, MIX_DL2_INPUT_VX_DL); + abe_write_mixer(MIXDL2, GAIN_M6dB, RAMP_0MS, MIX_DL2_INPUT_MM_DL); + abe_write_mixer(MIXDL2, MUTE_GAIN, RAMP_0MS, MIX_DL2_INPUT_MM_UL2); + + abe_write_mixer(MIXSDT, MUTE_GAIN, RAMP_0MS, MIX_SDT_INPUT_UP_MIXER); + abe_write_mixer(MIXSDT, GAIN_0dB, RAMP_0MS, MIX_SDT_INPUT_DL1_MIXER); + + abe_write_mixer(MIXECHO, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_mixer(MIXECHO, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + + abe_write_mixer(MIXAUDUL, MUTE_GAIN, RAMP_0MS, MIX_AUDUL_INPUT_TONES); + abe_write_mixer(MIXAUDUL, GAIN_0dB, RAMP_0MS, MIX_AUDUL_INPUT_UPLINK); + abe_write_mixer(MIXAUDUL, MUTE_GAIN, RAMP_0MS, MIX_AUDUL_INPUT_MM_DL); + abe_write_mixer(MIXAUDUL, MUTE_GAIN, RAMP_0MS, MIX_AUDUL_INPUT_VX_DL); + + abe_write_mixer(MIXVXREC, MUTE_GAIN, RAMP_0MS, MIX_VXREC_INPUT_TONES); + abe_write_mixer(MIXVXREC, GAIN_M6dB, RAMP_0MS, MIX_VXREC_INPUT_VX_DL); + abe_write_mixer(MIXVXREC, MUTE_GAIN, RAMP_0MS, MIX_VXREC_INPUT_MM_DL); + abe_write_mixer(MIXVXREC, GAIN_M6dB, RAMP_0MS, MIX_VXREC_INPUT_VX_UL); + + abe_write_gain(GAINS_DMIC1, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_DMIC1, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + abe_write_gain(GAINS_DMIC2, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_DMIC2, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + abe_write_gain(GAINS_DMIC3, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_DMIC3, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + abe_write_gain(GAINS_AMIC, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_AMIC, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + + abe_write_gain(GAINS_SPLIT, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_SPLIT, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + //abe_write_gain(GAINS_EANC , GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + //abe_write_gain(GAINS_EANC, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + + abe_write_gain(GAINS_DL1, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_DL1, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + abe_write_gain(GAINS_DL2, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_DL2, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + break; + case 1: + current_time = abe_test_read_time(); + if ((current_time - time_offset) < 100) + break; + else + state ++; + break; + case 2: + current_time = abe_test_read_time(); + if ((current_time - time_offset) < 100000) + break; + else + /* Internal buffer analysis */ + state ++; + break; + default: + state = 0; + break; + } +} + +/* + * @fn ABE_TEST_SCENARIO_4 () + * + * DMA AUDIO PLAYER + DMA VOICE CALL 8kHz OPP 50% + */ +void abe_test_scenario_4 (void) +{ + static abe_int32 time_offset, state; + abe_data_format_t format; + abe_dma_t dma_sink; + abe_uint32 current_time; + abe_use_case_id UC2[] = {ABE_AUDIO_PLAYER_ON_HEADSET_OR_EARPHONE, ABE_RINGER_TONES, (abe_use_case_id)0}; + abe_opp_t OPP; + abe_hw_config_init_t CONFIG; + + /* Scenario 1- 16kHz first */ + switch (state) { + case 0: + state ++; + time_offset = abe_test_read_time(); + + /* check HW config and OPP config */ + abe_read_hardware_configuration(UC2, &OPP, &CONFIG); + /* sets the OPP100 on FW05.xx */ + abe_set_opp_processing(OPP); + /* "tick" of the audio engine */ + abe_write_event_generator(CONFIG.HAL_EVENT_SELECTION); + abe_set_router_configuration(UPROUTE, UPROUTE_CONFIG_AMIC, (abe_router_t *) abe_router_ul_table_preset[UPROUTE_CONFIG_AMIC]); + + format.f = 48000; + format.samp_format = STEREO_MSB; + abe_connect_cbpr_dmareq_port(MM_UL_PORT, &format, ABE_CBPR3_IDX, &dma_sink); + format.f = 48000; + format.samp_format = STEREO_MSB; + abe_connect_cbpr_dmareq_port(MM_UL2_PORT, &format, ABE_CBPR4_IDX, &dma_sink); + format.f = 8000; + format.samp_format = MONO_MSB; + abe_connect_cbpr_dmareq_port(VX_UL_PORT, &format, ABE_CBPR2_IDX, &dma_sink); + /* enable all DMIC aquisition */ + abe_enable_data_transfer(MM_UL_PORT); + /* enable large-band DMIC aquisition */ + abe_enable_data_transfer(MM_UL2_PORT); + abe_enable_data_transfer(VX_UL_PORT); + + format.f = 48000; + format.samp_format = STEREO_MSB; + abe_connect_cbpr_dmareq_port(TONES_DL_PORT, &format, ABE_CBPR5_IDX, &dma_sink); + format.f = 8000; + format.samp_format = MONO_MSB; + abe_connect_cbpr_dmareq_port(VX_DL_PORT, &format, ABE_CBPR1_IDX, &dma_sink); + format.f = 48000; + format.samp_format = STEREO_MSB; + abe_connect_cbpr_dmareq_port(MM_DL_PORT, &format, ABE_CBPR0_IDX, &dma_sink); + format.f = 24000; + format.samp_format = STEREO_MSB; + abe_connect_cbpr_dmareq_port(VIB_DL_PORT, &format, ABE_CBPR6_IDX, &dma_sink); + abe_enable_data_transfer(TONES_DL_PORT); + abe_enable_data_transfer(VX_DL_PORT); + /* enable all the data paths */ + abe_enable_data_transfer(MM_DL_PORT); + abe_enable_data_transfer(VIB_DL_PORT); + /* DMIC ATC can be enabled even if the DMIC */ + abe_enable_data_transfer(DMIC_PORT); + abe_enable_data_transfer(PDM_DL_PORT); + abe_enable_data_transfer(PDM_UL_PORT); + + /* mixers' configuration = voice on earphone + music on hands-free path */ + abe_write_mixer(MIXDL1, MUTE_GAIN, RAMP_0MS, MIX_DL1_INPUT_TONES); + abe_write_mixer(MIXDL1, GAIN_M6dB, RAMP_0MS, MIX_DL1_INPUT_VX_DL); + abe_write_mixer(MIXDL1, GAIN_M6dB, RAMP_0MS, MIX_DL1_INPUT_MM_DL); + abe_write_mixer(MIXDL1, MUTE_GAIN, RAMP_0MS, MIX_DL1_INPUT_MM_UL2); + + abe_write_mixer(MIXDL2, MUTE_GAIN, RAMP_0MS, MIX_DL2_INPUT_TONES); + abe_write_mixer(MIXDL2, GAIN_M6dB, RAMP_0MS, MIX_DL2_INPUT_VX_DL); + abe_write_mixer(MIXDL2, GAIN_M6dB, RAMP_0MS, MIX_DL2_INPUT_MM_DL); + abe_write_mixer(MIXDL2, MUTE_GAIN, RAMP_0MS, MIX_DL2_INPUT_MM_UL2); + + abe_write_mixer(MIXSDT, MUTE_GAIN, RAMP_0MS, MIX_SDT_INPUT_UP_MIXER); + abe_write_mixer(MIXSDT, GAIN_0dB, RAMP_0MS, MIX_SDT_INPUT_DL1_MIXER); + + abe_write_mixer(MIXECHO, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_mixer(MIXECHO, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + + abe_write_mixer(MIXAUDUL, MUTE_GAIN, RAMP_0MS, MIX_AUDUL_INPUT_TONES); + abe_write_mixer(MIXAUDUL, GAIN_0dB, RAMP_0MS, MIX_AUDUL_INPUT_UPLINK); + abe_write_mixer(MIXAUDUL, MUTE_GAIN, RAMP_0MS, MIX_AUDUL_INPUT_MM_DL); + abe_write_mixer(MIXAUDUL, MUTE_GAIN, RAMP_0MS, MIX_AUDUL_INPUT_VX_DL); + + abe_write_mixer(MIXVXREC, MUTE_GAIN, RAMP_0MS, MIX_VXREC_INPUT_TONES); + abe_write_mixer(MIXVXREC, GAIN_M6dB, RAMP_0MS, MIX_VXREC_INPUT_VX_DL); + abe_write_mixer(MIXVXREC, MUTE_GAIN, RAMP_0MS, MIX_VXREC_INPUT_MM_DL); + abe_write_mixer(MIXVXREC, GAIN_M6dB, RAMP_0MS, MIX_VXREC_INPUT_VX_UL); + + abe_write_gain(GAINS_DMIC1, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_DMIC1, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + abe_write_gain(GAINS_DMIC2, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_DMIC2, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + abe_write_gain(GAINS_DMIC3, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_DMIC3, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + abe_write_gain(GAINS_AMIC , GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_AMIC, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + + abe_write_gain(GAINS_SPLIT, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_SPLIT, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + //abe_write_gain(GAINS_EANC , GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + //abe_write_gain(GAINS_EANC, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + + abe_write_gain(GAINS_DL1, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_DL1, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + abe_write_gain(GAINS_DL2, GAIN_0dB, RAMP_0MS, GAIN_LEFT_OFFSET); + abe_write_gain(GAINS_DL2, GAIN_0dB, RAMP_0MS, GAIN_RIGHT_OFFSET); + break; + case 1: + current_time = abe_test_read_time(); + if ((current_time - time_offset) < 100) + break; + else + /* Gains switch */ + state ++; + break; + case 2: + current_time = abe_test_read_time(); + if ((current_time - time_offset) < 100000) + break; + else + /* Internal buffer analysis */ + state ++; + break; + default: + state = 0; + break; + } +} + +#if 0 + + /* + * build the default uplink router configurations + */ + abe_set_router_configuration(UPROUTE, UPROUTE_CONFIG_AMIC, + (abe_router_t *) abe_router_ul_table_preset[UPROUTE_CONFIG_AMIC]); +#if 0 + abe_set_router_configuration(UPROUTE, UPROUTE_CONFIG_DMIC1, + (abe_router_t *) abe_router_ul_table_preset[UPROUTE_CONFIG_DMIC1]); + abe_set_router_configuration(UPROUTE, UPROUTE_CONFIG_DMIC2, + (abe_router_t *) abe_router_ul_table_preset[UPROUTE_CONFIG_DMIC2]); + abe_set_router_configuration(UPROUTE, UPROUTE_CONFIG_DMIC3, + (abe_router_t *) abe_router_ul_table_preset[UPROUTE_CONFIG_DMIC3]); +#endif + /* meaningful other microphone configuration can be added here */ + /* init hardware components */ + abe_hw_configuration(); + + /* enable the VX_UL path with Analog microphones from Phoenix */ + /* MM_DL INIT + connect a DMA channel to MM_DL port (ATC FIFO) */ + format.f = 48000; + format.samp_format = STEREO_MSB; + abe_connect_cbpr_dmareq_port(MM_DL_PORT, &format, ABE_CBPR0_IDX, &dma_sink); + + /* VX_DL INIT + connect a DMA channel to VX_DL port (ATC FIFO) */ + format.f = 16000; + format.samp_format = STEREO_MSB; + abe_connect_cbpr_dmareq_port(VX_DL_PORT, &format, ABE_CBPR1_IDX, &dma_sink); + + /* VX_UL INIT + connect a DMA channel to VX_UL port (ATC FIFO) */ + format.f = 16000; + format.samp_format = STEREO_MSB; + abe_connect_cbpr_dmareq_port(VX_UL_PORT, &format, ABE_CBPR2_IDX, &dma_sink); + + /* MM_UL2 INIT + connect a DMA channel to MM_UL2 port (ATC FIFO) */ + format.f = 48000; + format.samp_format = STEREO_MSB; + abe_connect_cbpr_dmareq_port(MM_UL2_PORT, &format, ABE_CBPR4_IDX, &dma_sink); + + /* MM_UL INIT + connect a DMA channel to MM_UL port (ATC FIFO) */ + format.f = 48000; + format.samp_format = STEREO_MSB; + abe_connect_cbpr_dmareq_port(MM_UL_PORT, &format, ABE_CBPR3_IDX, &dma_sink); + + /* TONES INIT + connect a DMA channel to TONES port (ATC FIFO) */ + format.f = 48000; + format.samp_format = STEREO_MSB; + abe_connect_cbpr_dmareq_port(TONES_DL_PORT, &format, ABE_CBPR5_IDX, &dma_sink); + + /* VIBRA/HAPTICS INIT + connect a DMA channel to VIBRA/HAPTICS port (ATC FIFO) */ + format.f = 24000; + format.samp_format = STEREO_MSB; + abe_connect_cbpr_dmareq_port(VIB_DL_PORT, &format, ABE_CBPR6_IDX, &dma_sink); + + /* mixers' default configuration = voice on earphone + music on hands-free path */ + case 2: + /* Scenario 2- 8kHz first */ + switch (time10us) { + case 1: + /* check HW config and OPP config */ + abe_read_hardware_configuration(UC2, &OPP, &CONFIG); + /* sets the OPP100 on FW05.xx */ + abe_set_opp_processing(OPP); + /* "tick" of the audio engine */ + abe_write_event_generator(CONFIG.HAL_EVENT_SELECTION); + // enables VOICECALL-MMDL-MMUL-8/16kHz-ROUTING + abe_reset_hal(); + format.f = 8000; + format.samp_format = MONO_MSB; + abe_connect_cbpr_dmareq_port(VX_DL_PORT, &format, ABE_CBPR1_IDX, &dma_sink); + format.f = 8000; + format.samp_format = MONO_MSB; + abe_connect_cbpr_dmareq_port(VX_UL_PORT, &format, ABE_CBPR2_IDX, &dma_sink); + + abe_write_mixer(MIXDL1, GAIN_0dB, RAMP_1MS, MIX_DL1_INPUT_VX_DL); + abe_write_mixer(MIXDL2, GAIN_0dB, RAMP_50MS, MIX_DL2_INPUT_MM_DL); + + /* enable large-band DMIC aquisition */ + abe_enable_data_transfer(MM_UL2_PORT); + /* enable all DMIC aquisition */ + abe_enable_data_transfer(MM_UL_PORT); + /* enable all the data paths */ + abe_enable_data_transfer(MM_DL_PORT); + abe_enable_data_transfer(VX_DL_PORT); + abe_enable_data_transfer(VX_UL_PORT); + abe_enable_data_transfer(PDM_UL_PORT); + /* DMIC ATC can be enabled even if the DMIC */ + abe_enable_data_transfer(DMIC_PORT); + abe_enable_data_transfer(PDM_DL_PORT); + abe_enable_data_transfer(TONES_DL_PORT); + break; + case 100: + abe_write_mixer(MIXDL1, GAIN_M6dB, RAMP_0MS, MIX_DL1_INPUT_TONES); + abe_write_mixer(MIXDL1, GAIN_M6dB, RAMP_1MS, MIX_DL1_INPUT_VX_DL); + abe_write_mixer(MIXDL1, GAIN_M6dB, RAMP_2MS, MIX_DL1_INPUT_MM_DL); + abe_write_mixer(MIXDL1, GAIN_M6dB, RAMP_5MS, MIX_DL1_INPUT_MM_UL2); + break; + case 1200: + abe_set_router_configuration(UPROUTE, UPROUTE_CONFIG_DMIC1, + (abe_router_t *) abe_router_ul_table_preset[UPROUTE_CONFIG_DMIC1]); + break; + case 8000: // end + fcloseall(); + exit(-2); + } + /* case scenario_id ==2 */ + break; + case 3: + /* Scenario 3 PING-PONG DMAreq */ + switch (time10us) { + case 1: + /* Ping-Pong access through MM_DL using Left/Right 16bits/16bits data format */ + /* To be added here : Device driver initialization following + abe_read_hardware_configuration() returned data + McPDM_DL : 6 slots activated (5 + Commands) + DMIC : 6 microphones activated + McPDM_UL : 2 microphones activated (No status) + */ + abe_read_hardware_configuration(UC5, &OPP, &CONFIG); + abe_set_opp_processing(OPP); + abe_write_event_generator(CONFIG.HAL_EVENT_SELECTION); + + /* MM_DL INIT (overwrite the previous default initialization made above */ + format.f = 48000; + format.samp_format = MONO_MSB; + + /* connect a Ping-Pong SDMA protocol to MM_DL port with Ping-Pong 12 mono + * samples (12x4 bytes for each ping & pong size)*/ + abe_connect_dmareq_ping_pong_port(MM_DL_PORT, &format, ABE_CBPR0_IDX, (12 * 4), &dma_sink); + + /* mixers' configuration = voice on earphone + music on hands-free path */ + abe_write_mixer(MIXDL1, GAIN_0dB, RAMP_2MS, MIX_DL1_INPUT_MM_DL); + abe_write_mixer(MIXDL2, GAIN_0dB, RAMP_50MS, MIX_DL2_INPUT_MM_DL); + + /* Here : connect the sDMA to "dma_sink" content */ + /* enable all the data paths */ + abe_enable_data_transfer(MM_DL_PORT); + abe_enable_data_transfer(PDM_DL_PORT); + break; + case 8000: // end + fcloseall(); + exit(-3); + } + /* case scenario_id ==3 */ + break; + case 40: + /* Scenario 4.0 PING_PONG+ IRQ TO MCU */ + switch (time10us) { + case 1: + /* check HW config and OPP config */ + abe_read_hardware_configuration(UC5, &OPP, &CONFIG); + /* sets the OPP100 on FW05.xx */ + abe_set_opp_processing(OPP); + /* "tick" of the audio engine */ + abe_write_event_generator(CONFIG.HAL_EVENT_SELECTION); + + /* MM_DL INIT (overwrite the previous default initialization made above */ + format.f = 48000; + format.samp_format = STEREO_16_16; + + /* connect a Ping-Pong cache-flush protocol to MM_DL port with 50Hz (20ms) rate */ + abe_add_subroutine(&abe_irq_pingpong_player_id, + (abe_subroutine2) abe_default_irq_pingpong_player, SUB_0_PARAM, (abe_uint32*)0); + + #define N_SAMPLES_BYTES (24 *4) // @@@@ to be tuned + abe_connect_irq_ping_pong_port(MM_DL_PORT, &format, + abe_irq_pingpong_player_id, N_SAMPLES_BYTES, &data_sink, PING_PONG_WITH_MCU_IRQ); + + abe_write_mixer(MIXDL1, GAIN_0dB, RAMP_0MS, MIX_DL1_INPUT_TONES); + abe_write_mixer(MIXDL1, GAIN_0dB, RAMP_0MS, MIX_DL1_INPUT_VX_DL); + abe_write_mixer(MIXDL1, GAIN_0dB, RAMP_0MS, MIX_DL1_INPUT_MM_DL); + abe_write_mixer(MIXDL1, GAIN_0dB, RAMP_0MS, MIX_DL1_INPUT_MM_UL2); + abe_write_mixer(MIXDL2, GAIN_0dB, RAMP_0MS, MIX_DL2_INPUT_TONES); + abe_write_mixer(MIXDL2, GAIN_0dB, RAMP_0MS, MIX_DL2_INPUT_VX_DL); + abe_write_mixer(MIXDL2, GAIN_0dB, RAMP_0MS, MIX_DL2_INPUT_MM_DL); + abe_write_mixer(MIXDL2, GAIN_0dB, RAMP_0MS, MIX_DL2_INPUT_MM_UL2); + + abe_write_mixer(MIXSDT, GAIN_0dB, RAMP_0MS, MIX_SDT_INPUT_UP_MIXER); + abe_write_mixer(MIXSDT, MUTE_GAIN, RAMP_0MS, MIX_SDT_INPUT_DL1_MIXER); + + /* enable all the data paths */ + abe_enable_data_transfer(MM_DL_PORT); + abe_enable_data_transfer(PDM_DL_PORT); + break; + case 1200: + abe_set_router_configuration(UPROUTE, UPROUTE_CONFIG_DMIC1, + (abe_router_t *) abe_router_ul_table_preset[UPROUTE_CONFIG_DMIC1]); + break; + case 2400: // end + fcloseall(); + exit(-4); + } + /* case scenario_id ==4 */ + break; + case 41: + /* Scenario 4.1 PING_PONG+ IRQ TO MCU 32BITS */ + switch (time10us) { + case 1: + /* check HW config and OPP config */ + abe_read_hardware_configuration(UC5, &OPP, &CONFIG); + /* sets the OPP100 on FW05.xx */ + abe_set_opp_processing(OPP); + /* "tick" of the audio engine */ + abe_write_event_generator(CONFIG.HAL_EVENT_SELECTION); + + /* MM_DL INIT(overwrite the previous default initialization made above */ + format.f = 48000; + format.samp_format = STEREO_MSB; + + /* connect a Ping-Pong cache-flush protocol to MM_DL port with 50Hz (20ms) rate */ + abe_add_subroutine(&abe_irq_pingpong_player_id, + (abe_subroutine2) abe_default_irq_pingpong_player_32bits, SUB_0_PARAM, (abe_uint32*)0); + + #define N_SAMPLES_BYTES (24 * 4) // @@@@ to be tuned + abe_connect_irq_ping_pong_port(MM_DL_PORT, &format, + abe_irq_pingpong_player_id, N_SAMPLES_BYTES, &data_sink, PING_PONG_WITH_MCU_IRQ); + + abe_write_mixer(MIXDL1, MUTE_GAIN, RAMP_0MS, MIX_DL1_INPUT_TONES); + abe_write_mixer(MIXDL1, MUTE_GAIN, RAMP_0MS, MIX_DL1_INPUT_VX_DL); + abe_write_mixer(MIXDL1, GAIN_0dB, RAMP_0MS, MIX_DL1_INPUT_MM_DL); + abe_write_mixer(MIXDL1, MUTE_GAIN, RAMP_0MS, MIX_DL1_INPUT_MM_UL2); + + abe_write_mixer(MIXDL2, MUTE_GAIN, RAMP_0MS, MIX_DL2_INPUT_TONES); + abe_write_mixer(MIXDL2, MUTE_GAIN, RAMP_0MS, MIX_DL2_INPUT_VX_DL); + abe_write_mixer(MIXDL2, GAIN_0dB, RAMP_0MS, MIX_DL2_INPUT_MM_DL); + abe_write_mixer(MIXDL2, MUTE_GAIN, RAMP_0MS, MIX_DL2_INPUT_MM_UL2); + + abe_write_mixer(MIXSDT, GAIN_0dB, RAMP_0MS, MIX_SDT_INPUT_UP_MIXER); + abe_write_mixer(MIXSDT, MUTE_GAIN, RAMP_0MS, MIX_SDT_INPUT_DL1_MIXER); + + /* enable all the data paths */ + abe_enable_data_transfer(MM_DL_PORT ); + abe_enable_data_transfer(PDM_DL_PORT); + + break; + case 1200: + abe_set_router_configuration(UPROUTE, UPROUTE_CONFIG_DMIC1, + (abe_router_t *) abe_router_ul_table_preset[UPROUTE_CONFIG_DMIC1]); + break; + + case 2400: // end + fcloseall(); + exit(-4); + } + /* case scenario_id ==4 */ + break; + + case 5: + /* Scenario 5 CHECK APS ADAPTATION ALGO */ + switch (time10us) { + case 1: + /* check HW config and OPP config */ + abe_read_hardware_configuration(UC5, &OPP, &CONFIG); + /* sets the OPP100 on FW05.xx */ + abe_set_opp_processing(OPP); + /* "tick" of the audio engine */ + abe_write_event_generator(CONFIG.HAL_EVENT_SELECTION); + + /* MM_DL INIT(overwrite the previous default initialization made above */ + format.f = 48000; + format.samp_format = STEREO_16_16; + + /* connect a Ping-Pong cache-flush protocol to MM_DL port with 50Hz (20ms) rate */ + abe_add_subroutine(&abe_irq_pingpong_player_id, + (abe_subroutine2) abe_default_irq_pingpong_player, SUB_0_PARAM, (abe_uint32*)0); + + #define N_SAMPLES_BYTES (24 *4) // @@@@ to be tuned + abe_connect_irq_ping_pong_port(MM_DL_PORT, + &format, abe_irq_pingpong_player_id, N_SAMPLES_BYTES, + &data_sink, PING_PONG_WITH_MCU_IRQ); + + /* mixers' configuration = voice on earphone + music on hands-free path */ + abe_write_mixer(MIXDL1, GAIN_0dB, RAMP_2MS, MIX_DL1_INPUT_MM_DL); + abe_write_mixer(MIXDL2, GAIN_0dB, RAMP_50MS, MIX_DL2_INPUT_MM_DL); + + /* enable all the data paths */ + abe_enable_data_transfer(MM_DL_PORT); + abe_enable_data_transfer(PDM_DL_PORT); + + /* connect a Ping-Pong cache-flush protocol to MM_DL port with 50Hz (20ms) rate */ + abe_add_subroutine(&abe_irq_aps_adaptation_id, + (abe_subroutine2) abe_default_irq_aps_adaptation, SUB_0_PARAM, (abe_uint32*)0); + break; + } /* case scenario_id ==5 */ + + abe_set_router_configuration(UPROUTE, UPROUTE_CONFIG_AMIC, + (abe_router_t *) abe_router_ul_table_preset[UPROUTE_CONFIG_AMIC]); + abe_set_router_configuration(UPROUTE, UPROUTE_CONFIG_DMIC1, + (abe_router_t *) abe_router_ul_table_preset[UPROUTE_CONFIG_DMIC1]); + abe_set_router_configuration(UPROUTE, UPROUTE_CONFIG_DMIC2, + (abe_router_t *) abe_router_ul_table_preset[UPROUTE_CONFIG_DMIC2]); + abe_set_router_configuration(UPROUTE, UPROUTE_CONFIG_DMIC3, + (abe_router_t *) abe_router_ul_table_preset[UPROUTE_CONFIG_DMIC3]); + case UC31_VOICE_CALL_8KMONO: + abe_disable_data_transfer(VX_DL_PORT); + abe_disable_data_transfer(VX_UL_PORT); + format.f = 8000; + format.samp_format = MONO_MSB; + abe_connect_cbpr_dmareq_port(VX_DL_PORT, &format, ABE_CBPR1_IDX, &dma_sink); + format.f = 8000; + format.samp_format = MONO_MSB; + abe_connect_cbpr_dmareq_port(VX_UL_PORT, &format, ABE_CBPR2_IDX, &dma_sink); + abe_enable_data_transfer(VX_DL_PORT); + abe_enable_data_transfer(VX_UL_PORT); + case UC32_VOICE_CALL_8KSTEREO: + format.f = 8000; + format.samp_format = STEREO_MSB; + abe_connect_cbpr_dmareq_port(VX_DL_PORT, &format, ABE_CBPR1_IDX, &dma_sink); + format.f = 8000; + format.samp_format = STEREO_MSB; + abe_connect_cbpr_dmareq_port(VX_UL_PORT, &format, ABE_CBPR2_IDX, &dma_sink); + case UC33_VOICE_CALL_16KMONO: + format.f = 16000; + format.samp_format = MONO_MSB; + abe_connect_cbpr_dmareq_port(VX_DL_PORT, &format, ABE_CBPR1_IDX, &dma_sink); + format.f = 16000; + format.samp_format = MONO_MSB; + abe_connect_cbpr_dmareq_port(VX_UL_PORT, &format, ABE_CBPR2_IDX, &dma_sink); + case UC34_VOICE_CALL_16KSTEREO: + format.f = 16000; + format.samp_format = STEREO_MSB; + abe_connect_cbpr_dmareq_port(VX_DL_PORT, &format, ABE_CBPR1_IDX, &dma_sink); + format.f = 16000; + format.samp_format = STEREO_MSB; + abe_connect_cbpr_dmareq_port(VX_UL_PORT, &format, ABE_CBPR2_IDX, &dma_sink); + case UC35_MMDL_MONO: + format.f = 48000; + format.samp_format = MONO_MSB; + abe_connect_cbpr_dmareq_port(MM_DL_PORT, &format, ABE_CBPR0_IDX, &dma_sink); + case UC36_MMDL_STEREO: + format.f = 48000; + format.samp_format = STEREO_MSB; + abe_connect_cbpr_dmareq_port(MM_DL_PORT, &format, ABE_CBPR0_IDX, &dma_sink); + case UC37_MMUL2_MONO: + format.f = 48000; + format.samp_format = MONO_MSB; + abe_connect_cbpr_dmareq_port(MM_UL2_PORT, &format, ABE_CBPR4_IDX, &dma_sink); + case UC38_MMUL2_STEREO: + format.f = 48000; + format.samp_format = MONO_MSB; + abe_connect_cbpr_dmareq_port(MM_UL2_PORT, &format, ABE_CBPR4_IDX, &dma_sink); + case UC91_ASRC_DRIFT1: + abe_set_asrc_drift_control(VX_UL_PORT, FORCED_DRIFT_CONTROL); + abe_write_asrc(VX_UL_PORT, 100); + abe_set_asrc_drift_control(VX_DL_PORT, FORCED_DRIFT_CONTROL); + abe_write_asrc(VX_DL_PORT, 200); + abe_set_asrc_drift_control(MM_DL_PORT, FORCED_DRIFT_CONTROL); + abe_write_asrc(MM_DL_PORT, 300); + case UC92_ASRC_DRIFT2: + abe_set_asrc_drift_control(VX_UL_PORT, FORCED_DRIFT_CONTROL); + abe_write_asrc(VX_UL_PORT, -100); + abe_set_asrc_drift_control(VX_DL_PORT, FORCED_DRIFT_CONTROL); + abe_write_asrc(VX_DL_PORT, -200); + abe_set_asrc_drift_control(MM_DL_PORT, FORCED_DRIFT_CONTROL); + abe_write_asrc(MM_DL_PORT, -300); +#endif diff --git a/sound/soc/codecs/abe/abe_test.h b/sound/soc/codecs/abe/abe_test.h new file mode 100644 index 000000000000..b84ee3dafcde --- /dev/null +++ b/sound/soc/codecs/abe/abe_test.h @@ -0,0 +1,28 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ + +#ifndef _ABE_TEST_H_ +#define _ABE_TEST_H_ + +/* + * HAL test API + */ +void abe_auto_check_data_format_translation(void); +void abe_check_opp(void); +void abe_check_dma(void); +void abe_debug_and_non_regression(void); +void abe_check_mixers_gain_update(void); +void abe_test_scenario(abe_int32 scenario_id); + +/* + * HAL test DATA + */ + +#endif /* _ABE_TEST_H_ */ diff --git a/sound/soc/codecs/abe/abe_typ.h b/sound/soc/codecs/abe/abe_typ.h new file mode 100644 index 000000000000..f85771a55bd3 --- /dev/null +++ b/sound/soc/codecs/abe/abe_typ.h @@ -0,0 +1,666 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ + +#include "abe_def.h" +#include "abe_ext.h" +#ifndef _ABE_TYP_H_ +#define _ABE_TYP_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * BASIC TYPES + */ + +typedef char abe_flag; +typedef unsigned char abe_uint8; +typedef char abe_int8; +typedef unsigned short abe_uint16; +typedef short abe_int16; +typedef unsigned long abe_uint32; +typedef long abe_int32; +typedef float abe_float; +typedef double abe_double; + +typedef abe_uint32 abe_errc_t; +typedef abe_int32 abe_millibel; + +//typedef abe_uint32 abe_millisecond; +//typedef abe_uint32 abe_milliHertz; +//typedef abe_uint32 abe_millimeter; +//typedef abe_uint32 abe_millidegree; +//typedef abe_uint32 abe_permille; +//typedef abe_uint32 abe_microsecond; + +typedef abe_uint32 abe_result; +typedef abe_millibel abe_gain_t; /* smoothed gain amplitude and ramp */ +typedef abe_uint32 abe_ramp_t; + +typedef abe_uint32 abe_freq_t; /* 4 bytes millihertz */ +typedef abe_uint32 abe_millis_t; /* 4 bytes milliseconds */ +typedef abe_uint32 abe_micros_t; /* 4 bytes microseconds */ + +typedef abe_uint32 abe_dbg_mask_t; /* 4 bytes Bit field indicating the type of informations to be traced */ +typedef abe_uint32 abe_time_stamp_t; /* 4 bytes infinite loop 32bits counter incremented on each firmware loop */ + /* scheduling task loops (250us / 272us with respectively 48kHz / 44.1kHz on Phoenix). */ +typedef abe_uint32 abe_dbg_t; /* debug filter */ + +typedef abe_uint32 abe_seq_code_t; /* Index to the table of sequences */ +typedef abe_uint32 abe_sub_code_t; /* Index to the table of subroutines called in the sequence */ + +typedef void (* abe_subroutine0)(void); /* subroutine with no parameter */ +typedef void (* abe_subroutine1)(abe_uint32); /* subroutine with one parameter */ +typedef void (* abe_subroutine2)(abe_uint32, abe_uint32); /* subroutine with two parameters */ +typedef void (* abe_subroutine3)(abe_uint32, abe_uint32, abe_uint32); /* subroutine with three parameters */ +typedef void (* abe_subroutine4)(abe_uint32, abe_uint32, abe_uint32, abe_uint32); /* subroutine with four parameters */ + +/* + * CODE PORTABILITY - FUTURE PATCHES + * + * 32bits field for having the code compatible with future revisions of the hardware (audio integration) + * or evolution of the software partitionning. Used for the highest level APIs (launch_sequences) + */ +typedef abe_uint32 abe_patch_rev; + +/* + * ENUMS + */ + +/* + * MEMORY CONFIG TYPE + * + * 0: Ultra Lowest power consumption audio player + * 1: OPP 25% (simple multimedia features) + * 2: OPP 50% (multimedia and voice calls) + * 3: OPP100% (EANC, multimedia complex use-cases) + */ +typedef enum { + ABE_AUDIO_PLAYER_ON_HEADSET_OR_EARPHONE = 1, + ABE_DRIFT_MANAGEMENT_FOR_AUDIO_PLAYER, + ABE_VOICE_CALL_ON_HEADSET_OR_EARPHONE_OR_BT, + ABE_MULTIMEDIA_AUDIO_RECORDER, + ABE_VIBRATOR_OR_HAPTICS, + ABE_VOICE_CALL_ON_HANDS_FREE_SPEAKER, + ABE_RINGER_TONES, + ABE_VOICE_CALL_WITH_EARPHONE_ACTIVE_NOISE_CANCELLER, + + ABE_LAST_USE_CASE +} abe_use_case_id; + +/* + * OPP TYPE + * + * 0: Ultra Lowest power consumption audio player + * 1: OPP 25% (simple multimedia features) + * 2: OPP 50% (multimedia and voice calls) + * 3: OPP100% (EANC, multimedia complex use-cases) + */ +typedef enum { + ABE_OPP0 = 0, + ABE_OPP25, ABE_OPP50, ABE_OPP100 +} abe_opp_t; + +/* + * IIR TYPE + * + * 0: Ultra Lowest power consumption audio player + * 1: OPP 25% (simple multimedia features) + */ +typedef enum { + ABE_IIR_TYPE_1 = 0, + ABE_IIR_TYPE_2 +} abe_iir_t; + +/* + * DMIC DECIMATION RATIO + * + */ +typedef enum { + ABE_DEC16 = 16, + ABE_DEC25 = 25, + ABE_DEC32 = 32, + ABE_DEC40 = 40 +} abe_dmic_ratio_t; + +/* + * SAMPLES TYPE + * + * mono 16bits sample LSB aligned, 16 MSB bits are unused + * mono sample MSB aligned (16/24/32bits) + * two successive mono samples in one 32bits container + * Two L/R 16bits samples in a 32bits container, + * Two channels defined with two MSB aligned samples + * Three channels defined with three MSB aligned samples (MIC) + * Four channels defined with four MSB aligned samples (MIC) + * . . . + * Eight channels defined with six MSB aligned samples (MIC) + */ +typedef enum { + MONO_MSB = 1, + STEREO_16_16, + STEREO_MSB, THREE_MSB, FOUR_MSB, FIVE_MSB, SIX_MSB, SEVEN_MSB, EIGHT_MSB, NINE_MSB, TEN_MSB, +} abe_samp_t; + +/* + * PORT PROTOCOL TYPE + */ +typedef enum { + SLIMBUS_PORT_PROT = 1, + SERIAL_PORT_PROT, + DMIC_PORT_PROT, + MCPDMDL_PORT_PROT, + MCPDMUL_PORT_PROT, + PINGPONG_PORT_PROT, + DMAREQ_PORT_PROT, + FIFO_PORT_PROT, +} abe_port_protocol_switch_id; + +/* + * PORT IDs, this list is aligned with the FW data mapping + */ +typedef enum { + DMIC_PORT = 0, + PDM_UL_PORT, /* analog MICs */ + BT_VX_UL_PORT, /* BT uplink (8/16 kHz)*/ + + /* AE source ports - Uplink */ + MM_UL_PORT, /* up to 5 stereo channels */ + MM_UL2_PORT, /* stereo FM record path (4) */ + VX_UL_PORT, /* stereo FM record path */ + + /* AE sink ports - Downlink */ + MM_DL_PORT, /* multimedia player audio path */ + VX_DL_PORT, + TONES_DL_PORT, /* 8 */ + VIB_DL_PORT, + + /* AE source ports - Downlink */ + BT_VX_DL_PORT, + PDM_DL_PORT, /* ABE --> BT (8/16kHz) */ + MM_EXT_OUT_PORT, /* 12 */ + MM_EXT_IN_PORT, + + LAST_PORT_ID /* dummy port used to declare the other tasks of the scheduler */ +} abe_port_id; + +/* + * Definition for the compatibility with HAL05xx + */ +#define PDM_DL1_PORT PDM_DL_PORT +#define PDM_DL2_PORT PDM_DL_PORT +#define PDM_VIB_PORT PDM_DL_PORT +#define DMIC_PORT1 DMIC_PORT +#define DMIC_PORT2 DMIC_PORT +#define DMIC_PORT3 DMIC_PORT + +/* + * ANA_PORT_ID Analog companion audio port + */ +typedef enum { + EAR_PHOENIX = 1, + HS_L, HS_R, + IHF_L, IHF_R, + VIBRA1, VIBRA2 +} abe_ana_port_id ; + +typedef abe_int32 headset_offset_t; /* Calibration data from the analog companion */ + +/* + * Signal processing module names - EQ APS MIX ROUT + */ +#define FEAT_EQ1 1 /* equalizer downlink path headset + earphone */ +#define FEAT_EQ2L FEAT_EQ1+1 /* equalizer downlink path integrated handsfree LEFT */ +#define FEAT_EQ2R FEAT_EQ2L+1 /* equalizer downlink path integrated handsfree RIGHT */ +#define FEAT_EQVIB1 FEAT_EQ2R+1 /* equalizer downlink path vibra 1 */ +#define FEAT_EQVIB2 FEAT_EQVIB1+1 /* equalizer downlink path vibra 2 */ +#define FEAT_EQSDT FEAT_EQVIB2+1 /* equalizer downlink path side-tone */ +#define FEAT_EQDMIC1 FEAT_EQSDT+1 /* equalizer uplink path first DMIC pair */ +#define FEAT_EQDMIC2 FEAT_EQDMIC1+1 /* equalizer uplink path second DMIC pair */ +#define FEAT_EQDMIC3 FEAT_EQDMIC2+1 /* equalizer uplink path third DMIC pair */ +#define FEAT_EQAMIC FEAT_EQDMIC3+1 /* equalizer uplink path AMIC pair */ +#define FEAT_APS1 FEAT_EQAMIC+1 /* Acoustic protection for headset */ +#define FEAT_APS2 FEAT_APS1+1 /* acoustic protection high-pass filter for handsfree "Left" */ +#define FEAT_APS3 FEAT_APS2+1 /* acoustic protection high-pass filter for handsfree "Right" */ +#define FEAT_ASRC1 FEAT_APS3+1 /* asynchronous sample-rate-converter for the downlink voice path */ +#define FEAT_ASRC2 FEAT_ASRC1+1 /* asynchronous sample-rate-converter for the uplink voice path */ +#define FEAT_ASRC3 FEAT_ASRC2+1 /* asynchronous sample-rate-converter for the multimedia player */ +#define FEAT_ASRC4 FEAT_ASRC3+1 /* asynchronous sample-rate-converter for the echo reference */ +#define FEAT_MIXDL1 FEAT_ASRC4+1 /* mixer of the headset and earphone path */ +#define FEAT_MIXDL2 FEAT_MIXDL1+1 /* mixer of the hands-free path */ +#define FEAT_MIXAUDUL FEAT_MIXDL2+1 /* mixer for audio being sent on the voice_ul path */ +#define FEAT_MIXVXREC FEAT_MIXAUDUL+1 /* mixer for voice communication recording */ +#define FEAT_MIXSDT FEAT_MIXVXREC+1 /* mixer for side-tone */ +#define FEAT_MIXECHO FEAT_MIXSDT+1 /* mixer for echo reference */ +#define FEAT_UPROUTE FEAT_MIXECHO+1 /* router of the uplink path */ +#define FEAT_GAINS FEAT_UPROUTE+1 /* all gains */ +#define FEAT_GAINS_DMIC1 FEAT_GAINS+1 +#define FEAT_GAINS_DMIC2 FEAT_GAINS_DMIC1+1 +#define FEAT_GAINS_DMIC3 FEAT_GAINS_DMIC2+1 +#define FEAT_GAINS_AMIC FEAT_GAINS_DMIC3+1 +#define FEAT_GAINS_SPLIT FEAT_GAINS_AMIC+1 +#define FEAT_GAINS_DL1 FEAT_GAINS_SPLIT+1 +#define FEAT_GAINS_DL2 FEAT_GAINS_DL1+1 +#define FEAT_GAIN_EANC FEAT_GAINS_DL2+1 /* active noise canceller */ +#define FEAT_SEQ FEAT_GAIN_EANC+1 /* sequencing queue of micro tasks */ +#define FEAT_CTL FEAT_SEQ+1 /* Phoenix control queue through McPDM */ + +#define MAXNBFEATURE FEAT_CTL /* list of features of the firmware */ + +typedef enum { + EQ1 = FEAT_EQ1, /* equalizer downlink path headset + earphone */ + EQ2L = FEAT_EQ2L, /* equalizer downlink path integrated handsfree LEFT */ + EQ2R = FEAT_EQ2R, + EQSDT = FEAT_EQSDT, /* equalizer downlink path side-tone */ + EQDMIC1 = FEAT_EQDMIC1, + EQDMIC2 = FEAT_EQDMIC2, + EQDMIC3 = FEAT_EQDMIC3, + EQAMIC = FEAT_EQAMIC, /* equalizer uplink path AMIC pair */ +} abe_equ_id; + +typedef enum { + APS1 = FEAT_APS1, /* Acoustic protection for headset */ + APS2L = FEAT_APS2, + APS2R = FEAT_APS3 +} abe_aps_id; + +typedef enum { + ASRC1 = FEAT_ASRC1, /* asynchronous sample-rate-converter for the downlink voice path */ + ASRC2 = FEAT_ASRC2, /* asynchronous sample-rate-converter for the uplink voice path */ + ASRC3 = FEAT_ASRC3, /* asynchronous sample-rate-converter for the multimedia player */ + ASRC4 = FEAT_ASRC4, /* asynchronous sample-rate-converter for the voice uplink echo_reference */ +} abe_asrc_id; + +typedef enum { + MIXDL1 = FEAT_MIXDL1, + MIXDL2 = FEAT_MIXDL2, + MIXSDT = FEAT_MIXSDT, + MIXECHO = FEAT_MIXECHO, + MIXEANC = FEAT_GAIN_EANC, + MIXAUDUL = FEAT_MIXAUDUL, + MIXVXREC = FEAT_MIXVXREC, +} abe_mixer_id; + +typedef enum { + UPROUTE = FEAT_UPROUTE, /* there is only one router up to now */ +} abe_router_id; + +typedef enum { + GAINS = FEAT_GAINS, /* Misc tasks of the scheduler */ + SEQUENCE = FEAT_SEQ, + CONTROL = FEAT_CTL +} abe_schd_id; + +/* + * GAIN IDs + */ +typedef enum { + GAINS_DMIC1 = FEAT_GAINS_DMIC1, + GAINS_DMIC2 = FEAT_GAINS_DMIC2, + GAINS_DMIC3 = FEAT_GAINS_DMIC3, + GAINS_AMIC = FEAT_GAINS_AMIC, + GAINS_SPLIT = FEAT_GAINS_SPLIT, + GAINS_DL1 = FEAT_GAINS_DL1, + GAINS_DL2 = FEAT_GAINS_DL2, + GAINS_EANC = FEAT_GAIN_EANC, +} abe_gain_id; + +#if 0 +typedef enum { + VX_DL_IN_GAIN = 1, /* mixer's gain */ + MM_DL_IN_GAIN, + TONES_DL_IN_GAIN, + MM_VX_DL_IN_GAIN, + MM_IHF_DL_IN_GAIN, /* mixer's gain */ + MM_HS_DL_OUT_GAIN, /* Output Left gain */ + MM_IHF_L_DL_OUT_GAIN, /* Output Left gain */ + MM_IHF_R_DL_OUT_GAIN, /* Output Right gain */ + MM_VIB1_DL_GAIN, + MM_VIB2_DL_GAIN, /* no gain in fact */ + DMIC_UL_IN_GAIN_0, + DMIC_UL_IN_GAIN_1, /* today = same GAIN on DMIC pairs */ + DMIC_UL_IN_GAIN_2, + DMIC_UL_IN_GAIN_3, + DMIC_UL_IN_GAIN_4, + DMIC_UL_IN_GAIN_5, + AMIC_UL_IN_GAIN_L, + AMIC_UL_IN_GAIN_R, /* today = same gain on AMIC pair */ + ECHO_REF_GAIN, + BT_VX_DL_OUT_GAIN, + BT_VX_UL_IN_GAIN, +} abe_gain_id; +#endif + +/* + * EVENT GENERATORS + */ +typedef enum { + EVENT_MCPDM = 1, + EVENT_DMIC, EVENT_TIMER, + EVENT_McBSP, EVENT_McASP, EVENT_SLIMBUS, EVENT_44100, EVENT_DEFAULT, +} abe_event_id; + +/* + * SERIAL PORTS IDs + */ +typedef enum { + MCBSP1_TX = MCBSP1_DMA_TX, + MCBSP1_RX = MCBSP1_DMA_RX, + MCBSP2_TX = MCBSP2_DMA_TX, + MCBSP2_RX = MCBSP2_DMA_RX, + MCBSP3_TX = MCBSP3_DMA_TX, + MCBSP3_RX = MCBSP3_DMA_RX, +} abe_mcbsp_id; + + +/* + * TYPES USED FOR APIS + */ + +/* + * HARDWARE CONFIG TYPE + */ +typedef struct { + abe_uint32 AESS_EVENT_GENERATOR_COUNTER__COUNTER_VALUE; /* EVENT_GENERATOR_COUNTER_DEFAULT gives about 96kHz */ + abe_uint32 AESS_EVENT_SOURCE_SELECTION__SELECTION; /* 0: DMAreq, 1:Counter */ + abe_uint32 AESS_AUDIO_ENGINE_SCHEDULER__DMA_REQ_SELECTION; /* 5bits DMAreq selection */ + abe_event_id HAL_EVENT_SELECTION; + + abe_uint32 MCPDM_CTRL__DIV_SEL; /* 0: 96kHz 1:192kHz */ + abe_uint32 MCPDM_CTRL__CMD_INT; /* 0: no command in the FIFO, 1: 6 data on each lines (with commands) */ + abe_uint32 MCPDM_CTRL__PDMOUTFORMAT; /* 0:MSB aligned 1:LSB aligned */ + abe_uint32 MCPDM_CTRL__PDM_DN5_EN; + abe_uint32 MCPDM_CTRL__PDM_DN4_EN; + abe_uint32 MCPDM_CTRL__PDM_DN3_EN; + abe_uint32 MCPDM_CTRL__PDM_DN2_EN; + abe_uint32 MCPDM_CTRL__PDM_DN1_EN; + abe_uint32 MCPDM_CTRL__PDM_UP3_EN; + abe_uint32 MCPDM_CTRL__PDM_UP2_EN; + abe_uint32 MCPDM_CTRL__PDM_UP1_EN; + abe_uint32 MCPDM_FIFO_CTRL_DN__DN_TRESH; + abe_uint32 MCPDM_FIFO_CTRL_UP__UP_TRESH; + + abe_uint32 DMIC_CTRL__DMIC_CLK_DIV; /* 0:2.4MHz 1:3.84MHz */ + abe_uint32 DMIC_CTRL__DMICOUTFORMAT; /* 0:MSB aligned 1:LSB aligned */ + abe_uint32 DMIC_CTRL__DMIC_UP3_EN; + abe_uint32 DMIC_CTRL__DMIC_UP2_EN; + abe_uint32 DMIC_CTRL__DMIC_UP1_EN; + abe_uint32 DMIC_FIFO_CTRL__DMIC_TRESH; /* 1*(DMIC_UP1_EN+ 2+ 3)*2 OCP read access every 96/88.1 KHz. */ + + abe_uint32 MCBSP_SPCR1_REG__RJUST; /* 1:MSB 2:LSB aligned */ + abe_uint32 MCBSP_THRSH2_REG_REG__XTHRESHOLD; + abe_uint32 MCBSP_THRSH1_REG_REG__RTHRESHOLD; +} abe_hw_config_init_t; + +/* + * EANC_T + * + * TBD : coefficients of the EANC + */ +typedef struct { + abe_int32 dmic_index; + abe_int32 fir_coef[NBEANC1]; + abe_int32 lambda; + abe_int32 iir_filter[NBEANC2]; + abe_int32 loop_gain; +} abe_eanc_t; + +/* + * EQU_T + * + * coefficients of the equalizer + */ +typedef struct { + abe_iir_t equ_type; /* type of filter */ + abe_uint32 equ_length; /* filter length */ + union { /* parameters are the direct and recursive coefficients in */ + abe_int32 type1[NBEQ1]; /* Q6.26 integer fixed-point format. */ + struct { + abe_int32 freq [NBEQ2]; /* center frequency of the band [Hz] */ + abe_int32 gain [NBEQ2]; /* gain of each band. [dB]*/ + abe_int32 q [NBEQ2]; /* Q factor of this band [dB] */ + } type2; + } coef; + abe_int32 equ_param3; +} abe_equ_t; + +/* + * APS_T + * + * coefficients of the Acoustics Protection and Safety + */ +typedef struct { + abe_int32 coef1[NBAPS1]; + abe_int32 coef2[NBAPS2]; +} abe_aps_t; + +typedef struct { + abe_millibel e1; /* structure of two energy_t estimation for coil and membrane */ + abe_millibel e2; +} abe_aps_energy_t; + +/* + * ROUTER_T + * + * table of indexes in unsigned bytes + */ +typedef abe_uint32 abe_router_t; + +/* + * DATA_FORMAT_T + * + * used in port declaration + */ +typedef struct { + abe_freq_t f; /* Sampling frequency of the stream */ + abe_samp_t samp_format; /* Sample format type */ +} abe_data_format_t; + +/* + * PORT_PROTOCOL_T + * + * port declaration + */ +typedef struct { + abe_uint32 direction; /* Direction=0 means input from AESS point of view */ + abe_port_protocol_switch_id protocol_switch; /* Protocol type (switch) during the data transfers */ + union { + struct { /* Slimbus peripheral connected to ATC */ + abe_uint32 desc_addr1; /* Address of ATC Slimbus descriptor's index */ + abe_uint32 desc_addr2; /* Second ATC index for SlimBus reception (or NULL) */ + abe_uint32 buf_addr1; /* DMEM address 1 in bytes */ + abe_uint32 buf_addr2; /* DMEM address 2 in bytes */ + abe_uint32 buf_size; /* DMEM buffer size size in bytes */ + abe_uint32 iter; /* ITERation on each DMAreq signals */ + } prot_slimbus; + + struct { + abe_uint32 desc_addr; /* McBSP/McASP peripheral connected to ATC */ + abe_uint32 buf_addr; /* Address of ATC McBSP/McASP descriptor's in bytes */ + abe_uint32 buf_size; /* DMEM address in bytes */ + abe_uint32 iter; /* ITERation on each DMAreq signals */ + } prot_serial; + + struct { /* DMIC peripheral connected to ATC */ + abe_uint32 buf_addr; /* DMEM address in bytes */ + abe_uint32 buf_size; /* DMEM buffer size in bytes */ + abe_uint32 nbchan; /* Number of activated DMIC */ + } prot_dmic; + + struct { /* McPDMDL peripheral connected to ATC */ + abe_uint32 buf_addr; /* DMEM address in bytes */ + abe_uint32 buf_size; /* DMEM size in bytes */ + abe_uint32 control; /* Control allowed on McPDM DL */ + } prot_mcpdmdl; + + struct { /* McPDMUL peripheral connected to ATC */ + abe_uint32 buf_addr; /* DMEM address size in bytes */ + abe_uint32 buf_size; /* DMEM buffer size size in bytes */ + } prot_mcpdmul; + + struct { /* Ping-Pong interface to the Host using cache-flush */ + abe_uint32 desc_addr; /* Address of ATC descriptor's */ + abe_uint32 buf_addr; /* DMEM buffer base address in bytes */ + abe_uint32 buf_size; /* DMEM size in bytes for each ping and pong buffers */ + abe_uint32 irq_addr; /* IRQ address (either DMA (0) MCU (1) or DSP(2)) */ + abe_uint32 irq_data; /* IRQ data content loaded in the AESS IRQ register */ + abe_uint32 callback; /* Call-back function upon IRQ reception */ + } prot_pingpong; + + struct { /* DMAreq line to CBPr */ + abe_uint32 desc_addr; /* Address of ATC descriptor's */ + abe_uint32 buf_addr; /* DMEM buffer address in bytes */ + abe_uint32 buf_size; /* DMEM buffer size size in bytes */ + abe_uint32 iter; /* ITERation on each DMAreq signals */ + abe_uint32 dma_addr; /* DMAreq address */ + abe_uint32 dma_data; /* DMA/AESS = 1 << #DMA */ + } prot_dmareq; + + struct { /* Circular buffer - direct addressing to DMEM */ + abe_uint32 buf_addr; /* DMEM buffer base address in bytes */ + abe_uint32 buf_size; /* DMEM buffer size in bytes */ + abe_uint32 dma_addr; /* DMAreq address */ + abe_uint32 dma_data; /* DMA/AESS = 1 << #DMA */ + } prot_circular_buffer; + }p; +} abe_port_protocol_t; + +/* + * DMA_T + * + * dma structure for easing programming + */ +typedef struct { + void *data; /* OCP L3 pointer to the first address of the */ + /* destination buffer (either DMA or Ping-Pong read/write pointers). */ + void *l3_dmem; /* address L3 when addressing the DMEM buffer instead of CBPr */ + void *l4_dmem; /* address L3 translated to L4 the ARM memory space */ + abe_uint32 iter; /* number of iterations for the DMA data moves. */ +} abe_dma_t; + +typedef struct { + abe_uint32 data; /* Offset to the first address of the */ + abe_uint32 iter; /* number of iterations for the DMA data moves. */ +} abe_dma_t_offset; + +/* + * SEQ_T + * + * struct { + * micros_t time; Waiting time before executing next line + * seq_code_t code Subroutine index interpreted in the HAL and translated to + * FW subroutine codes in case of ABE tasks + * int32 param[2] Two parameters + * } seq_t + * + */ +typedef struct { + abe_micros_t delta_time; + abe_sub_code_t code; + abe_uint32 param[4]; + abe_uint8 tag; +} abe_seq_t; + +typedef struct { + abe_uint32 mask; + abe_seq_t seq1; + abe_seq_t seq2; +} abe_sequence_t; + +/* + * DRIFT_T + * + * ASRC drift parameter in [ppm] value + */ +typedef abe_int32 abe_drift_t; + +/* + * INTERNAL DATA TYPES + */ + +/* + * ABE_IRQ_DATA_T + * + * IRQ FIFO content declaration + * APS interrupts: + * IRQtag_APS to [31:28], APS_IRQs to [27:16], loopCounter to [15:0] + * SEQ interrupts: + * IRQtag_COUNT to [31:28], Count_IRQs to [27:16], loopCounter to [15:0] + * Ping-Pong Interrupts: + * IRQtag_PP to [31:28], PP_MCU_IRQ to [27:16], loopCounter to [15:0] + */ +typedef struct { + unsigned int counter: 16; + unsigned int data: 12; + unsigned int tag: 4; +} abe_irq_data_t; + +/* + * ABE_PORT_T status / format / sampling / protocol(call_back) / features / gain / name .. + * + */ +typedef struct { + abe_uint16 status; /* running / idled */ + abe_data_format_t format; /* Sample format type */ + abe_drift_t drift; /* API : for ASRC */ + abe_uint16 callback; /* optionnal call-back index for errors and ack */ + abe_uint16 smem_buffer1; /* IO tasks buffers */ + abe_uint16 smem_buffer2; + abe_port_protocol_t protocol; + abe_dma_t_offset dma; /* pointer and iteration counter of the xDMA */ + abe_uint16 feature_index [MAXFEATUREPORT]; /* list of features associated to a port (EQ, APS, ... , ends with 0) */ + // abe_millibel gain_calibration; /* gain tuning, default=0dB */ + char name[NBCHARPORTNAME]; +} abe_port_t; + +/* + * ABE_SUBROUTINE_T + * + */ +typedef struct { + abe_uint32 sub_id; + abe_int32 param[4]; +} abe_subroutine_t; + +/* + * ABE_PORT_INFO_T + * + * OPP, subroutines to call on reset + */ +typedef struct { + abe_opp_t min_opp; + abe_subroutine_t sub1; + abe_subroutine_t sub2; +} abe_port_info_t; + +/* + * ABE_FEATURE_T + * + */ +typedef struct { + abe_uint16 enable_with_default_data; + abe_uint16 disable_feature; + abe_uint16 read_parameter; + abe_uint16 write_parameter; + abe_uint16 running_status; + abe_uint16 fw_input_buffer_address; + abe_uint16 fw_output_buffer_address; + abe_uint16 fw_scheduler_slot_position; + abe_uint16 fw_scheduler_subslot_position; + abe_opp_t min_opp; + char name[NBCHARFEATURENAME]; +} abe_feature_t; + +#ifdef __cplusplus +} +#endif + +#endif /* _ABE_TYP_H_ */ diff --git a/sound/soc/codecs/abe/abe_typedef.h b/sound/soc/codecs/abe/abe_typedef.h new file mode 100644 index 000000000000..a3877ddbd936 --- /dev/null +++ b/sound/soc/codecs/abe/abe_typedef.h @@ -0,0 +1,187 @@ +/* + * ========================================================================== + * Texas Instruments OMAP(TM) Platform Firmware + * (c) Copyright 2009, Texas Instruments Incorporated. All Rights Reserved. + * + * Use of this firmware is controlled by the terms and conditions found + * in the license agreement under which this firmware has been supplied. + * ========================================================================== + */ + +#ifndef _ABE_TYPEDEF_H_ +#define _ABE_TYPEDEF_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "abe_define.h" + +/* + * Basic types definition +*/ +typedef unsigned char ABE_uchar; +typedef char ABE_char; +typedef unsigned short ABE_uint16; +typedef short ABE_int16; +typedef long ABE_int32; +typedef unsigned long ABE_uint32; + +typedef ABE_uchar* pABE_uchar; +typedef ABE_char* pABE_char; +typedef ABE_uint16* pABE_uint16; +typedef ABE_int16* pABE_int16; +typedef ABE_int32* pABE_int32; +typedef ABE_uint32* pABE_uint32; + +/* + * Hard-coded data generated in the XLS sheet (to be removed later@@@@) + */ +#ifdef __chess__ +typedef struct abeatcdescTag { + unsigned long a; + unsigned long b; +} ABE_SAtcDescriptor; +typedef void (*pABE_voidFunction)()clobbers(R0, R1, R2, R3, R4, R5, R6, R7, R13); +typedef void (*pABE_voidFunctionsList[])()clobbers(R0, R1, R2, R3, R4, R5, R6, R7, R13); +typedef void (*pABE_cmdFunction)() clobbers(R0, R1, R2, R3, R4, R5, R6, R7, R13); +typedef void (*pABE_cmdFunctionsList[])() clobbers(R0, R1, R2, R3, R4, R5, R6, R7, R13); +typedef void (*pABE_copyFunction)(ABE_uint16 chess_storage(R13))clobbers(R13); +typedef void (*pABE_copyFunctionsList[])(ABE_uint16 chess_storage(R13))clobbers(R13); +#endif +/* + * Commonly used structures + */ + +typedef struct abetaskTag{ + ABE_uint16 iF; /* 0 Index of called function */ + ABE_uint16 A0; /* 2 for INITPTR of A0 */ + ABE_uint16 A1; /* 4 for INITPTR of A1 */ + ABE_uint16 A2_3; /* 6 for INITPTR of A2 & A3 */ + ABE_uint16 A4_5; /* 8 for INITPTR of A4 & A5 */ + ABE_uint16 R; /* 10 for INITREG of R0, R1, R2, R3 */ + ABE_uint16 misc0; /* 12 */ + ABE_uint16 misc1; /* 14 */ +} ABE_STask; +typedef ABE_STask* pABE_STask; +typedef ABE_STask** ppABE_STask; + +typedef struct { + ABE_uint16 drift_ASRC; /* 0 */ + ABE_uint16 drift_io; /* 2 */ + ABE_uchar io_type_idx; /* 4 */ + ABE_uchar samp_size; /* 5 */ + ABE_uchar unused1; /* 6 */ + ABE_uchar unused2; /* 7 */ + + ABE_uint16 hw_ctrl_addr; /* 8 */ + ABE_uchar atc_irq_data; /* 10 */ + ABE_uchar direction_rw; /* 11 */ + ABE_uchar flow_counter; /* 12 */ + ABE_uchar nsamp; /* 13 */ + ABE_uchar x_io; /* 14 */ + ABE_uchar on_off; /* 15 */ + + ABE_uint16 split_addr1; /* 16 */ + ABE_uint16 split_addr2; /* 18 */ + ABE_uint16 split_addr3; /* 20 */ + ABE_uchar before_f_index; /* 22 */ + ABE_uchar after_f_index; /* 23 */ + + ABE_uint16 smem_addr1; /* 24 */ + ABE_uint16 atc_address1; /* 26 */ + ABE_uint16 atc_pointer_saved1; /* 28 */ + ABE_uchar data_size1; /* 30 */ + ABE_uchar copy_f_index1; /* 31 */ + + ABE_uint16 smem_addr2; /* 32 */ + ABE_uint16 atc_address2; /* 34 */ + ABE_uint16 atc_pointer_saved2; /* 36 */ + ABE_uchar data_size2; /* 38 */ + ABE_uchar copy_f_index2; /* 39 */ + +} ABE_SIODescriptor; + + +#define drift_asrc_ 0 /* [w] asrc output used for the next asrc call (+/- 1 / 0) */ +#define drift_io_ 2 /* [w] asrc output used for controlling the number of samples to be exchanged (+/- 1 / 0) */ +#define io_type_idx_ 4 /* address of the IO subroutine */ +#define samp_size_ 5 +#define unused1 6 +#define unused2 7 +#define hw_ctrl_addr_ 8 /* dmareq address or host irq buffer address (atc address) */ +#define atc_irq_data_ 10 /* data content to be loaded to "hw_ctrl_addr" */ +#define direction_rw_ 11 /* read dmem =0, write dmem =3 (atc offset of the access pointer) */ +#define flow_counter_ 12 /* flow error counter */ +#define nsamp_ 13 /* number of samples (either mono stereo...) */ +#define x_io_ 14 /* x number of raw DMEM data moved */ +#define on_off_ 15 + +#define split_addr1_ 16 /* internal smem buffer initptr pointer index */ +#define split_addr2_ 18 /* internal smem buffer initptr pointer index */ +#define split_addr3_ 20 /* internal smem buffer initptr pointer index */ +#define before_f_index_ 22 /* index of the copy subroutine */ +#define after_f_index_ 23 /* index of the copy subroutine */ + +#define minidesc1_ 24 +#define rel_smem_ 0 /* internal smem buffer initptr pointer index */ +#define rel_atc_ 2 /* atc descriptor address (byte address x4) */ +#define rel_atc_saved 4 /* location of the saved ATC pointer (+debug info) */ +#define rel_size_ 6 /* size of each sample (1:mono/1616 2:stereo ) */ +#define rel_f_ 7 /* index of the copy subroutine */ + +#define s_mem_mm_ul 24 +#define s_mm_ul_size 30 + +#define minidesc2_ 32 +#define Struct_Size 40 + +typedef ABE_SIODescriptor* pABE_SIODescriptor; +typedef ABE_SIODescriptor** ppABE_SIODescriptor; + +typedef struct abepingpongdescriptorTag{ + ABE_uint16 drift_ASRC; /* 0 [W] asrc output used for the next ASRC call (+/- 1 / 0)*/ + ABE_uint16 drift_io; /* 2 [W] asrc output used for controlling the number of samples to be exchanged (+/- 1 / 0) */ + ABE_uint16 hw_ctrl_addr; /* 4 DMAReq address or HOST IRQ buffer address (ATC ADDRESS) */ + ABE_uchar copy_func_index; /* 6 index of the copy subroutine */ + ABE_uchar x_io; /* 7 X number of SMEM samples to move */ + ABE_uchar data_size; /* 8 0 for mono data, 1 for stereo data */ + ABE_uchar smem_addr; /* 9 internal SMEM buffer INITPTR pointer index */ + ABE_uchar atc_irq_data; /* 10 data content to be loaded to "hw_ctrl_addr" */ + ABE_uchar counter; /* 11 ping/pong buffer flag */ + ABE_uint16 workbuff_BaseAddr; /* 12 current Base address of the working buffer */ + ABE_uint16 workbuff_Samples; /* 14 samples left in the working buffer */ + ABE_uint16 nextbuff0_BaseAddr; /* 6 Base address of the ping/pong buffer 0 */ + ABE_uint16 nextbuff0_Samples; /* 18 samples available in the ping/pong buffer 0 */ + ABE_uint16 nextbuff1_BaseAddr; /* 20 Base address of the ping/pong buffer 1 */ + ABE_uint16 nextbuff1_Samples; /* 22 samples available in the ping/pong buffer 1 */ +} ABE_SPingPongDescriptor; + +typedef ABE_SPingPongDescriptor* pABE_SPingPongDescriptor; + +#ifdef __chess__ +#define drift_ASRC 0 /* [W] asrc output used for the next ASRC call (+/- 1 / 0)*/ +#define drift_io 2 /* [W] asrc output used for controlling the number of samples to be exchanged (+/- 1 / 0) */ +#define hw_ctrl_addr 4 /* DMAReq address or HOST IRQ buffer address (ATC ADDRESS) */ +#define copy_func_index 6 /* index of the copy subroutine */ +#define x_io 7 /* X number of SMEM samples to move */ +#define data_size 8 /* 0 for mono data, 1 for stereo data */ +#define smem_addr 9 /* internal SMEM buffer INITPTR pointer index */ +#define atc_irq_data 10 /* data content to be loaded to "hw_ctrl_addr" */ +#define atc_address 11 /* ATC descriptor address */ +#define threshold_1 12 /* THR1; For stereo data, THR1 is provided by HAL as THR1<<1 */ +#define threshold_2 13 /* THR2; For stereo data, THR2 is provided by HAL as THR2<<1 */ +#define update_1 14 /* UP_1; For stereo data, UP_1 is provided by HAL as UP_1<<1 */ +#define update_2 15 /* UP_2; For stereo data, UP_2 is provided by HAL as UP_2<<1 */ +#define flow_counter 16 /* Flow error counter */ +#define direction_rw 17 /* Read DMEM =0, Write DMEM =3 (ATC offset of the access pointer) */ +#define counter 11 /* ping/pong buffer flag */ +#define workbuff_BaseAddr 12 /* current Base address of the working buffer */ +#define workbuff_Samples 14 /* samples left in the working buffer */ +#define nextbuff0_BaseAddr 16 /* Base address of the ping/pong buffer 0 */ +#define nextbuff0_Samples 18 /* samples available in the ping/pong buffer 0 */ +#define nextbuff1_BaseAddr 20 /* Base address of the ping/pong buffer 1 */ +#define nextbuff1_Samples 22 /* samples available in the ping/pong buffer 1 */ +#endif + +#endif /* _ABE_TYPEDEF_H_ */ diff --git a/sound/soc/codecs/abe/abehal.dsp b/sound/soc/codecs/abe/abehal.dsp new file mode 100644 index 000000000000..e350f139a678 --- /dev/null +++ b/sound/soc/codecs/abe/abehal.dsp @@ -0,0 +1,242 @@ +# Microsoft Developer Studio Project File - Name="ABEHAL" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=ABEHAL - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "ABEHAL.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "ABEHAL.mak" CFG="ABEHAL - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "ABEHAL - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "ABEHAL - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "ABEHAL" +# PROP Scc_LocalPath "m:\a0918484_L1doc\ABE_Firmware\HAL\src" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "ABEHAL - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x3009 /d "NDEBUG" +# ADD RSC /l 0x3009 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "ABEHAL - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W4 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c +# ADD BASE RSC /l 0x3009 /d "_DEBUG" +# ADD RSC /l 0x3009 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "ABEHAL - Win32 Release" +# Name "ABEHAL - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\ABE_API.c +# End Source File +# Begin Source File + +SOURCE=.\ABE_DBG.c +# End Source File +# Begin Source File + +SOURCE=.\ABE_EXT.c +# End Source File +# Begin Source File + +SOURCE=.\ABE_INI.c +# End Source File +# Begin Source File + +SOURCE=.\ABE_IRQ.c +# End Source File +# Begin Source File + +SOURCE=.\ABE_LIB.c +# End Source File +# Begin Source File + +SOURCE=.\ABE_MAIN.c +# End Source File +# Begin Source File + +SOURCE=.\ABE_SEQ.c +# End Source File +# Begin Source File + +SOURCE=.\ABE_TEST.C +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\ABE_API.H +# End Source File +# Begin Source File + +SOURCE=.\ABE_CM_ADDR.h +# End Source File +# Begin Source File + +SOURCE=.\ABE_COF.H +# End Source File +# Begin Source File + +SOURCE=.\ABE_DAT.H +# End Source File +# Begin Source File + +SOURCE=.\ABE_DBG.H +# End Source File +# Begin Source File + +SOURCE=.\ABE_DEF.H +# End Source File +# Begin Source File + +SOURCE=.\ABE_define.h +# End Source File +# Begin Source File + +SOURCE=.\ABE_DM_ADDR.h +# End Source File +# Begin Source File + +SOURCE=.\ABE_EXT.h +# End Source File +# Begin Source File + +SOURCE=.\ABE_functionsId.h +# End Source File +# Begin Source File + +SOURCE=.\ABE_FW.H +# End Source File +# Begin Source File + +SOURCE=.\ABE_INITxxx_labels.h +# End Source File +# Begin Source File + +SOURCE=.\ABE_LIB.H +# End Source File +# Begin Source File + +SOURCE=.\ABE_MAIN.H +# End Source File +# Begin Source File + +SOURCE=.\ABE_REF.H +# End Source File +# Begin Source File + +SOURCE=.\ABE_SEQ.H +# End Source File +# Begin Source File + +SOURCE=.\ABE_SM_ADDR.h +# End Source File +# Begin Source File + +SOURCE=.\ABE_SYS.H +# End Source File +# Begin Source File + +SOURCE=.\ABE_taskId.h +# End Source File +# Begin Source File + +SOURCE=.\ABE_TEST.h +# End Source File +# Begin Source File + +SOURCE=.\ABE_TYP.H +# End Source File +# Begin Source File + +SOURCE=.\ABE_typedef.h +# End Source File +# Begin Source File + +SOURCE=.\C_ABE_FW.CM +# End Source File +# Begin Source File + +SOURCE=.\C_ABE_FW.lDM +# End Source File +# Begin Source File + +SOURCE=.\C_ABE_FW.PM +# End Source File +# Begin Source File + +SOURCE=.\C_ABE_FW.SM32 +# End Source File +# Begin Source File + +SOURCE=.\CodingStyle.txt +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/sound/soc/codecs/abe/abehal.dsw b/sound/soc/codecs/abe/abehal.dsw new file mode 100644 index 000000000000..f28cce8c49d5 --- /dev/null +++ b/sound/soc/codecs/abe/abehal.dsw @@ -0,0 +1,33 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "ABEHAL"=.\ABEHAL.dsp - Package Owner=<4> + +Package=<5> +{{{ + begin source code control + ABEHAL + m:\a0918484_L1doc\ABE_Firmware\HAL\src + end source code control +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/sound/soc/codecs/twl6040.h b/sound/soc/codecs/twl6040.h new file mode 100644 index 000000000000..876d5b69b6d8 --- /dev/null +++ b/sound/soc/codecs/twl6040.h @@ -0,0 +1,139 @@ +/* + * ALSA SoC TWL6040 codec driver + * + * Author: Misael Lopez Cruz <x0052729@ti.com> + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __TWL6040_H__ +#define __TWL6040_H__ + +#define TWL6040_REG_ASICID 0x01 +#define TWL6040_REG_ASICREV 0x02 +#define TWL6040_REG_INTID 0x03 +#define TWL6040_REG_INTMR 0x04 +#define TWL6040_REG_NCPCTL 0x05 +#define TWL6040_REG_LDOCTL 0x06 +#define TWL6040_REG_HPPLLCTL 0x07 +#define TWL6040_REG_LPPLLCTL 0x08 +#define TWL6040_REG_LPPLLDIV 0x09 +#define TWL6040_REG_AMICBCTL 0x0A +#define TWL6040_REG_DMICBCTL 0x0B +#define TWL6040_REG_MICLCTL 0x0C +#define TWL6040_REG_MICRCTL 0x0D +#define TWL6040_REG_MICGAIN 0x0E +#define TWL6040_REG_LINEGAIN 0x0F +#define TWL6040_REG_HSLCTL 0x10 +#define TWL6040_REG_HSRCTL 0x11 +#define TWL6040_REG_HSGAIN 0x12 +#define TWL6040_REG_EARCTL 0x13 +#define TWL6040_REG_HFLCTL 0x14 +#define TWL6040_REG_HFLGAIN 0x15 +#define TWL6040_REG_HFRCTL 0x16 +#define TWL6040_REG_HFRGAIN 0x17 +#define TWL6040_REG_VIBCTLL 0x18 +#define TWL6040_REG_VIBDATL 0x19 +#define TWL6040_REG_VIBCTLR 0x1A +#define TWL6040_REG_VIBDATR 0x1B +#define TWL6040_REG_HKCTL1 0x1C +#define TWL6040_REG_HKCTL2 0x1D +#define TWL6040_REG_GPOCTL 0x1E +#define TWL6040_REG_ALB 0x1F +#define TWL6040_REG_DLB 0x20 +#define TWL6040_REG_TRIM1 0x28 +#define TWL6040_REG_TRIM2 0x29 +#define TWL6040_REG_TRIM3 0x2A +#define TWL6040_REG_HSOTRIM 0x2B +#define TWL6040_REG_HFOTRIM 0x2C +#define TWL6040_REG_ACCCTL 0x2D +#define TWL6040_REG_STATUS 0x2E +#define TWL6040_REG_SHADOW 0x2F + +#define TWL6040_CACHEREGNUM (TWL6040_REG_SHADOW + 1) + +#define TWL6040_VIOREGNUM 18 +#define TWL6040_VDDREGNUM 21 + +/* INTID (0x03) fields */ + +#define TWL6040_THINT 0x01 +#define TWL6040_PLUGINT 0x02 +#define TWL6040_UNPLUGINT 0x04 +#define TWL6040_HOOKINT 0x08 +#define TWL6040_HFINT 0x10 +#define TWL6040_VIBINT 0x20 +#define TWL6040_READYINT 0x40 + +/* INTMR (0x04) fields */ + +#define TWL6040_READYMSK 0x40 +#define TWL6040_ALLINT_MSK 0x7B + +/* NCPCTL (0x05) fields */ + +#define TWL6040_NCPENA 0x01 +#define TWL6040_NCPOPEN 0x40 + +/* LDOCTL (0x06) fields */ + +#define TWL6040_LSLDOENA 0x01 +#define TWL6040_HSLDOENA 0x04 +#define TWL6040_REFENA 0x40 +#define TWL6040_OSCENA 0x80 + +/* HPPLLCTL (0x07) fields */ + +#define TWL6040_HPLLENA 0x01 +#define TWL6040_HPLLRST 0x02 +#define TWL6040_HPLLBP 0x04 +#define TWL6040_HPLLSQRENA 0x08 +#define TWL6040_HPLLSQRBP 0x10 +#define TWL6040_MCLK_12000KHZ (0 << 5) +#define TWL6040_MCLK_19200KHZ (1 << 5) +#define TWL6040_MCLK_26000KHZ (2 << 5) +#define TWL6040_MCLK_38400KHZ (3 << 5) +#define TWL6040_MCLK_MSK 0x60 + +/* LPPLLCTL (0x08) fields */ + +#define TWL6040_LPLLENA 0x01 +#define TWL6040_LPLLRST 0x02 +#define TWL6040_LPLLSEL 0x04 +#define TWL6040_LPLLFIN 0x08 +#define TWL6040_HPLLSEL 0x10 + +/* HSLCTL (0x10) fields */ + +#define TWL6040_HSDACMODEL 0x02 +#define TWL6040_HSDRVMODEL 0x08 + +/* HSRCTL (0x11) fields */ + +#define TWL6040_HSDACMODER 0x02 +#define TWL6040_HSDRVMODER 0x08 + +/* ACCCTL (0x2D) fields */ + +#define TWL6040_RESETSPLIT 0x04 + +#define TWL6040_SYSCLK_SEL_LPPLL 1 +#define TWL6040_SYSCLK_SEL_HPPLL 2 + +#define TWL6040_HPPLL_ID 1 +#define TWL6040_LPPLL_ID 2 + +#endif /* End of __TWL6040_H__ */ diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig index 61952aa6cd5a..7bc7da038d52 100644 --- a/sound/soc/omap/Kconfig +++ b/sound/soc/omap/Kconfig @@ -6,6 +6,13 @@ config SND_OMAP_SOC_MCBSP tristate select OMAP_MCBSP +config OMAP_MCPDM + tristate + +config SND_OMAP_SOC_ABE + tristate + select OMAP_MCPDM + config SND_OMAP_SOC_N810 tristate "SoC Audio support for Nokia N810" depends on SND_OMAP_SOC && MACH_NOKIA_N810 && I2C @@ -85,6 +92,21 @@ config SND_OMAP_SOC_SDP3430 Say Y if you want to add support for SoC audio on Texas Instruments SDP3430. +config SND_OMAP_SOC_SDP4430 + tristate "SoC Audio support for Texas Instruments SDP4430" + depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_4430SDP + select SND_OMAP_SOC_ABE + select SND_SOC_ABE_TWL6040 + help + Say Y if you want to add support for SoC audio on Texas Instruments + SDP4430. + +config SND_OMAP_SOC_HDMI + tristate "SoC Audio support for HDMI interface on SDP4430" + depends on SND_OMAP_SOC_SDP4430 && OMAP2_DSS_HDMI + help + Say Y if you want to add support for HDMI interface on SDP4430 + config SND_OMAP_SOC_OMAP3_PANDORA tristate "SoC Audio support for OMAP3 Pandora" depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3_PANDORA diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile index 3db8a6c523f4..05c4775c4e72 100644 --- a/sound/soc/omap/Makefile +++ b/sound/soc/omap/Makefile @@ -1,9 +1,13 @@ # OMAP Platform Support snd-soc-omap-objs := omap-pcm.o snd-soc-omap-mcbsp-objs := omap-mcbsp.o +snd-soc-omap-abe-objs := omap-abe.o mcpdm.o +snd-soc-omap-hdmi-objs:= omap-hdmi.o obj-$(CONFIG_SND_OMAP_SOC) += snd-soc-omap.o obj-$(CONFIG_SND_OMAP_SOC_MCBSP) += snd-soc-omap-mcbsp.o +obj-$(CONFIG_SND_OMAP_SOC_ABE) += snd-soc-omap-abe.o +obj-$(CONFIG_SND_OMAP_SOC_HDMI) += snd-soc-omap-hdmi.o # OMAP Machine Support snd-soc-n810-objs := n810.o @@ -14,6 +18,7 @@ snd-soc-omap2evm-objs := omap2evm.o snd-soc-omap3evm-objs := omap3evm.o snd-soc-am3517evm-objs := am3517evm.o snd-soc-sdp3430-objs := sdp3430.o +snd-soc-sdp4430-objs := sdp4430.o snd-soc-omap3pandora-objs := omap3pandora.o snd-soc-omap3beagle-objs := omap3beagle.o snd-soc-zoom2-objs := zoom2.o @@ -27,6 +32,7 @@ obj-$(CONFIG_SND_OMAP_SOC_OMAP2EVM) += snd-soc-omap2evm.o obj-$(CONFIG_SND_OMAP_SOC_OMAP3EVM) += snd-soc-omap3evm.o obj-$(CONFIG_SND_OMAP_SOC_OMAP3517EVM) += snd-soc-am3517evm.o obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o +obj-$(CONFIG_SND_OMAP_SOC_SDP4430) += snd-soc-sdp4430.o obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o obj-$(CONFIG_SND_OMAP_SOC_ZOOM2) += snd-soc-zoom2.o diff --git a/sound/soc/omap/mcpdm.c b/sound/soc/omap/mcpdm.c new file mode 100644 index 000000000000..9a9b56060b32 --- /dev/null +++ b/sound/soc/omap/mcpdm.c @@ -0,0 +1,519 @@ +/* + * mcpdm.c -- McPDM interface driver + * + * Author: Jorge Eduardo Candelaria <x0107209@ti.com> + * Copyright (C) 2009 - Texas Instruments, Inc. + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/platform_device.h> +#include <linux/wait.h> +#include <linux/interrupt.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/irq.h> + +#include "mcpdm.h" + +static struct omap_mcpdm *mcpdm; + +static inline void omap_mcpdm_write(u16 reg, u32 val) +{ + __raw_writel(val, mcpdm->io_base + reg); +} + +static inline int omap_mcpdm_read(u16 reg) +{ + return __raw_readl(mcpdm->io_base + reg); +} + +static void omap_mcpdm_reg_dump(void) +{ + dev_dbg(mcpdm->dev, "***********************\n"); + dev_dbg(mcpdm->dev, "IRQSTATUS_RAW: 0x%04x\n", + omap_mcpdm_read(MCPDM_IRQSTATUS_RAW)); + dev_dbg(mcpdm->dev, "IRQSTATUS: 0x%04x\n", + omap_mcpdm_read(MCPDM_IRQSTATUS)); + dev_dbg(mcpdm->dev, "IRQENABLE_SET: 0x%04x\n", + omap_mcpdm_read(MCPDM_IRQENABLE_SET)); + dev_dbg(mcpdm->dev, "IRQENABLE_CLR: 0x%04x\n", + omap_mcpdm_read(MCPDM_IRQENABLE_CLR)); + dev_dbg(mcpdm->dev, "IRQWAKE_EN: 0x%04x\n", + omap_mcpdm_read(MCPDM_IRQWAKE_EN)); + dev_dbg(mcpdm->dev, "DMAENABLE_SET: 0x%04x\n", + omap_mcpdm_read(MCPDM_DMAENABLE_SET)); + dev_dbg(mcpdm->dev, "DMAENABLE_CLR: 0x%04x\n", + omap_mcpdm_read(MCPDM_DMAENABLE_CLR)); + dev_dbg(mcpdm->dev, "DMAWAKEEN: 0x%04x\n", + omap_mcpdm_read(MCPDM_DMAWAKEEN)); + dev_dbg(mcpdm->dev, "CTRL: 0x%04x\n", + omap_mcpdm_read(MCPDM_CTRL)); + dev_dbg(mcpdm->dev, "DN_DATA: 0x%04x\n", + omap_mcpdm_read(MCPDM_DN_DATA)); + dev_dbg(mcpdm->dev, "UP_DATA: 0x%04x\n", + omap_mcpdm_read(MCPDM_UP_DATA)); + dev_dbg(mcpdm->dev, "FIFO_CTRL_DN: 0x%04x\n", + omap_mcpdm_read(MCPDM_FIFO_CTRL_DN)); + dev_dbg(mcpdm->dev, "FIFO_CTRL_UP: 0x%04x\n", + omap_mcpdm_read(MCPDM_FIFO_CTRL_UP)); + dev_dbg(mcpdm->dev, "DN_OFFSET: 0x%04x\n", + omap_mcpdm_read(MCPDM_DN_OFFSET)); + dev_dbg(mcpdm->dev, "***********************\n"); +} + +/* + * Takes the McPDM module in and out of reset state. + * Uplink and downlink can be reset individually. + */ +static void omap_mcpdm_reset_capture(int reset) +{ + int ctrl = omap_mcpdm_read(MCPDM_CTRL); + + if (reset) + ctrl |= SW_UP_RST; + else + ctrl &= ~SW_UP_RST; + + omap_mcpdm_write(MCPDM_CTRL, ctrl); +} + +static void omap_mcpdm_reset_playback(int reset) +{ + int ctrl = omap_mcpdm_read(MCPDM_CTRL); + + if (reset) + ctrl |= SW_DN_RST; + else + ctrl &= ~SW_DN_RST; + + omap_mcpdm_write(MCPDM_CTRL, ctrl); +} + +/* + * Enables the transfer through the PDM interface to/from the Phoenix + * codec by enabling the corresponding UP or DN channels. + */ +void omap_mcpdm_start(int stream) +{ + int ctrl = omap_mcpdm_read(MCPDM_CTRL); + + if (stream) + ctrl |= mcpdm->up_channels; + else + ctrl |= mcpdm->dn_channels; + + omap_mcpdm_write(MCPDM_CTRL, ctrl); +} + +/* + * Disables the transfer through the PDM interface to/from the Phoenix + * codec by disabling the corresponding UP or DN channels. + */ +void omap_mcpdm_stop(int stream) +{ + int ctrl = omap_mcpdm_read(MCPDM_CTRL); + + if (stream) + ctrl &= ~mcpdm->up_channels; + else + ctrl &= ~mcpdm->dn_channels; + + omap_mcpdm_write(MCPDM_CTRL, ctrl); +} + +/* + * Configures McPDM uplink for audio recording. + * This function should be called before omap_mcpdm_start. + */ +int omap_mcpdm_capture_open(struct omap_mcpdm_link *uplink) +{ + int irq_mask = 0; + int ctrl; + + if (!uplink) + return -EINVAL; + + mcpdm->uplink = uplink; + + /* Enable irq request generation */ + irq_mask |= uplink->irq_mask & MCPDM_UPLINK_IRQ_MASK; + omap_mcpdm_write(MCPDM_IRQENABLE_SET, irq_mask); + + /* Configure uplink threshold */ + if (uplink->threshold > UP_THRES_MAX) + uplink->threshold = UP_THRES_MAX; + + omap_mcpdm_write(MCPDM_FIFO_CTRL_UP, uplink->threshold); + + /* Configure DMA controller */ + omap_mcpdm_write(MCPDM_DMAENABLE_SET, DMA_UP_ENABLE); + + /* Set pdm out format */ + ctrl = omap_mcpdm_read(MCPDM_CTRL); + ctrl &= ~PDMOUTFORMAT; + ctrl |= uplink->format & PDMOUTFORMAT; + + /* Uplink channels */ + mcpdm->up_channels = uplink->channels & (PDM_UP_MASK | PDM_STATUS_MASK); + + omap_mcpdm_write(MCPDM_CTRL, ctrl); + + return 0; +} + +/* + * Configures McPDM downlink for audio playback. + * This function should be called before omap_mcpdm_start. + */ +int omap_mcpdm_playback_open(struct omap_mcpdm_link *downlink) +{ + int irq_mask = 0; + int ctrl; + + if (!downlink) + return -EINVAL; + + mcpdm->downlink = downlink; + + /* Enable irq request generation */ + irq_mask |= downlink->irq_mask & MCPDM_DOWNLINK_IRQ_MASK; + omap_mcpdm_write(MCPDM_IRQENABLE_SET, irq_mask); + + /* Configure uplink threshold */ + if (downlink->threshold > DN_THRES_MAX) + downlink->threshold = DN_THRES_MAX; + + omap_mcpdm_write(MCPDM_FIFO_CTRL_DN, downlink->threshold); + + /* Enable DMA request generation */ + omap_mcpdm_write(MCPDM_DMAENABLE_SET, DMA_DN_ENABLE); + + /* Set pdm out format */ + ctrl = omap_mcpdm_read(MCPDM_CTRL); + ctrl &= ~PDMOUTFORMAT; + ctrl |= downlink->format & PDMOUTFORMAT; + + /* Downlink channels */ + mcpdm->dn_channels = downlink->channels & (PDM_DN_MASK | PDM_CMD_MASK); + + omap_mcpdm_write(MCPDM_CTRL, ctrl); + + return 0; +} + +/* + * Cleans McPDM uplink configuration. + * This function should be called when the stream is closed. + */ +int omap_mcpdm_capture_close(struct omap_mcpdm_link *uplink) +{ + int irq_mask = 0; + + if (!uplink) + return -EINVAL; + + /* Disable irq request generation */ + irq_mask |= uplink->irq_mask & MCPDM_UPLINK_IRQ_MASK; + omap_mcpdm_write(MCPDM_IRQENABLE_CLR, irq_mask); + + /* Disable DMA request generation */ + omap_mcpdm_write(MCPDM_DMAENABLE_CLR, DMA_UP_ENABLE); + + /* Clear Downlink channels */ + mcpdm->up_channels = 0; + + mcpdm->uplink = NULL; + + return 0; +} + +/* + * Cleans McPDM downlink configuration. + * This function should be called when the stream is closed. + */ +int omap_mcpdm_playback_close(struct omap_mcpdm_link *downlink) +{ + int irq_mask = 0; + + if (!downlink) + return -EINVAL; + + /* Disable irq request generation */ + irq_mask |= downlink->irq_mask & MCPDM_DOWNLINK_IRQ_MASK; + omap_mcpdm_write(MCPDM_IRQENABLE_CLR, irq_mask); + + /* Disable DMA request generation */ + omap_mcpdm_write(MCPDM_DMAENABLE_CLR, DMA_DN_ENABLE); + + /* clear Downlink channels */ + mcpdm->dn_channels = 0; + + mcpdm->downlink = NULL; + + return 0; +} + +static irqreturn_t omap_mcpdm_irq_handler(int irq, void *dev_id) +{ + struct omap_mcpdm *mcpdm_irq = dev_id; + int irq_status; + + irq_status = omap_mcpdm_read(MCPDM_IRQSTATUS); + + /* Acknowledge irq event */ + omap_mcpdm_write(MCPDM_IRQSTATUS, irq_status); + + if (irq & MCPDM_DN_IRQ_FULL) { + dev_err(mcpdm_irq->dev, "DN FIFO error %x\n", irq_status); + omap_mcpdm_reset_playback(1); + omap_mcpdm_playback_open(mcpdm_irq->downlink); + omap_mcpdm_reset_playback(0); + } + + if (irq & MCPDM_DN_IRQ_EMPTY) { + dev_err(mcpdm_irq->dev, "DN FIFO error %x\n", irq_status); + omap_mcpdm_reset_playback(1); + omap_mcpdm_playback_open(mcpdm_irq->downlink); + omap_mcpdm_reset_playback(0); + } + + if (irq & MCPDM_DN_IRQ) { + dev_dbg(mcpdm_irq->dev, "DN write request\n"); + } + + if (irq & MCPDM_UP_IRQ_FULL) { + dev_err(mcpdm_irq->dev, "UP FIFO error %x\n", irq_status); + omap_mcpdm_reset_capture(1); + omap_mcpdm_capture_open(mcpdm_irq->uplink); + omap_mcpdm_reset_capture(0); + } + + if (irq & MCPDM_UP_IRQ_EMPTY) { + dev_err(mcpdm_irq->dev, "UP FIFO error %x\n", irq_status); + omap_mcpdm_reset_capture(1); + omap_mcpdm_capture_open(mcpdm_irq->uplink); + omap_mcpdm_reset_capture(0); + } + + if (irq & MCPDM_UP_IRQ) { + dev_dbg(mcpdm_irq->dev, "UP write request\n"); + } + + return IRQ_HANDLED; +} + +int omap_mcpdm_request(void) +{ + struct platform_device *pdev; + struct omap_mcpdm_platform_data *pdata; + int ret; + + pdev = container_of(mcpdm->dev, struct platform_device, dev); + pdata = pdev->dev.platform_data; + + if (pdata->device_enable) + pdata->device_enable(pdev); + + spin_lock(&mcpdm->lock); + + if (!mcpdm->free) { + dev_err(mcpdm->dev, "McPDM interface is in use\n"); + spin_unlock(&mcpdm->lock); + ret = -EBUSY; + goto err; + } + mcpdm->free = 0; + + spin_unlock(&mcpdm->lock); + + /* Disable lines while request is ongoing */ + omap_mcpdm_write(MCPDM_CTRL, 0x00); + + ret = request_irq(mcpdm->irq, omap_mcpdm_irq_handler, + 0, "McPDM", (void *)mcpdm); + if (ret) { + dev_err(mcpdm->dev, "Request for McPDM IRQ failed\n"); + goto err; + } + + return 0; + +err: + if (pdata->device_disable) + pdata->device_disable(pdev); + return ret; +} + +void omap_mcpdm_free(void) +{ + struct platform_device *pdev; + struct omap_mcpdm_platform_data *pdata; + + pdev = container_of(mcpdm->dev, struct platform_device, dev); + pdata = pdev->dev.platform_data; + + spin_lock(&mcpdm->lock); + if (mcpdm->free) { + dev_err(mcpdm->dev, "McPDM interface is already free\n"); + spin_unlock(&mcpdm->lock); + return; + } + mcpdm->free = 1; + spin_unlock(&mcpdm->lock); + + if (pdata->device_idle) + pdata->device_idle(pdev); + +#if 0 + clk_disable(mcpdm->clk); +#endif + free_irq(mcpdm->irq, (void *)mcpdm); +} + +/* Enable/disable DC offset cancelation for the analog + * headset path (PDM channels 1 and 2). + */ +int omap_mcpdm_set_offset(int offset1, int offset2) +{ + int offset; + + if ((offset1 > DN_OFST_MAX) || (offset2 > DN_OFST_MAX)) + return -EINVAL; + + offset = (offset1 << DN_OFST_RX1) | (offset2 << DN_OFST_RX2); + + /* offset cancellation for channel 1 */ + if (offset1) + offset |= DN_OFST_RX1_EN; + else + offset &= ~DN_OFST_RX1_EN; + + /* offset cancellation for channel 2 */ + if (offset2) + offset |= DN_OFST_RX2_EN; + else + offset &= ~DN_OFST_RX2_EN; + + omap_mcpdm_write(MCPDM_DN_OFFSET, offset); + + return 0; +} + +#ifdef CONFIG_PM +static int omap_mcpdm_suspend(struct platform_device *dev, pm_message_t state) +{ + return 0; +} + +static int omap_mcpdm_resume(struct platform_device *dev) +{ + return 0; +} +#else +#define omap_mcpdm_suspend NULL +#define omap_mcpdm_resume NULL +#endif + +static int __devinit omap_mcpdm_probe(struct platform_device *pdev) +{ + struct resource *res; + int ret = 0; + + mcpdm = kzalloc(sizeof(struct omap_mcpdm), GFP_KERNEL); + if (!mcpdm) { + ret = -ENOMEM; + goto exit; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) { + dev_err(&pdev->dev, "no resource\n"); + goto err_resource; + } + + spin_lock_init(&mcpdm->lock); + mcpdm->free = 1; + + mcpdm->io_base = ioremap(res->start, resource_size(res)); + if (!mcpdm->io_base) { + ret = -ENOMEM; + goto err_resource; + } + + mcpdm->irq = platform_get_irq(pdev, 0); + if (!mcpdm->irq) { + ret = -EINVAL; + goto err_irq; + } + + mcpdm->dev = &pdev->dev; + platform_set_drvdata(pdev, mcpdm); + + return 0; + +err_irq: + iounmap(mcpdm->io_base); +err_resource: + kfree(mcpdm); +exit: + return ret; +} + +static int __devexit omap_mcpdm_remove(struct platform_device *pdev) +{ + struct omap_mcpdm *mcpdm_ptr = platform_get_drvdata(pdev); + struct omap_mcpdm_platform_data *pdata = pdev->dev.platform_data; + + platform_set_drvdata(pdev, NULL); +#if 0 + clk_put(mcpdm_ptr->clk); +#endif + + if (pdata->device_shutdown) + pdata->device_shutdown(pdev); + + iounmap(mcpdm_ptr->io_base); + + mcpdm_ptr->clk = NULL; + mcpdm_ptr->free = 0; + mcpdm_ptr->dev = NULL; + + kfree(mcpdm_ptr); + + return 0; +} + +static struct platform_driver omap_mcpdm_driver = { + .probe = omap_mcpdm_probe, + .remove = __devexit_p(omap_mcpdm_remove), + .driver = { + .name = "omap-mcpdm", + }, +}; + +static struct platform_device *omap_mcpdm_device; + +static int __init omap_mcpdm_init(void) +{ + return platform_driver_register(&omap_mcpdm_driver); +} +arch_initcall(omap_mcpdm_init); diff --git a/sound/soc/omap/mcpdm.h b/sound/soc/omap/mcpdm.h new file mode 100644 index 000000000000..a3cf273a3fb6 --- /dev/null +++ b/sound/soc/omap/mcpdm.h @@ -0,0 +1,156 @@ +/* + * mcpdm.h -- Defines for McPDM driver + * + * Author: Jorge Eduardo Candelaria <x0107209@ti.com> + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +/* McPDM registers */ + +#define MCPDM_REVISION 0x00 +#define MCPDM_SYSCONFIG 0x10 +#define MCPDM_IRQSTATUS_RAW 0x24 +#define MCPDM_IRQSTATUS 0x28 +#define MCPDM_IRQENABLE_SET 0x2C +#define MCPDM_IRQENABLE_CLR 0x30 +#define MCPDM_IRQWAKE_EN 0x34 +#define MCPDM_DMAENABLE_SET 0x38 +#define MCPDM_DMAENABLE_CLR 0x3C +#define MCPDM_DMAWAKEEN 0x40 +#define MCPDM_CTRL 0x44 +#define MCPDM_DN_DATA 0x48 +#define MCPDM_UP_DATA 0x4C +#define MCPDM_FIFO_CTRL_DN 0x50 +#define MCPDM_FIFO_CTRL_UP 0x54 +#define MCPDM_DN_OFFSET 0x58 + +/* + * MCPDM_IRQ bit fields + * IRQSTATUS_RAW, IRQSTATUS, IRQENABLE_SET, IRQENABLE_CLR + */ + +#define MCPDM_DN_IRQ (1 << 0) +#define MCPDM_DN_IRQ_EMPTY (1 << 1) +#define MCPDM_DN_IRQ_ALMST_EMPTY (1 << 2) +#define MCPDM_DN_IRQ_FULL (1 << 3) + +#define MCPDM_UP_IRQ (1 << 8) +#define MCPDM_UP_IRQ_EMPTY (1 << 9) +#define MCPDM_UP_IRQ_ALMST_FULL (1 << 10) +#define MCPDM_UP_IRQ_FULL (1 << 11) + +#define MCPDM_DOWNLINK_IRQ_MASK 0x00F +#define MCPDM_UPLINK_IRQ_MASK 0xF00 + +/* + * MCPDM_DMAENABLE bit fields + */ + +#define DMA_DN_ENABLE 0x1 +#define DMA_UP_ENABLE 0x2 + +/* + * MCPDM_CTRL bit fields + */ + +#define PDM_UP1_EN 0x0001 +#define PDM_UP2_EN 0x0002 +#define PDM_UP3_EN 0x0004 +#define PDM_DN1_EN 0x0008 +#define PDM_DN2_EN 0x0010 +#define PDM_DN3_EN 0x0020 +#define PDM_DN4_EN 0x0040 +#define PDM_DN5_EN 0x0080 +#define PDMOUTFORMAT 0x0100 +#define CMD_INT 0x0200 +#define STATUS_INT 0x0400 +#define SW_UP_RST 0x0800 +#define SW_DN_RST 0x1000 +#define PDM_UP_MASK 0x007 +#define PDM_DN_MASK 0x0F8 +#define PDM_CMD_MASK 0x200 +#define PDM_STATUS_MASK 0x400 + + +#define PDMOUTFORMAT_LJUST (0 << 8) +#define PDMOUTFORMAT_RJUST (1 << 8) + +/* + * MCPDM_FIFO_CTRL bit fields + */ + +#define UP_THRES_MAX 0xF +#define DN_THRES_MAX 0xF + +/* + * MCPDM_DN_OFFSET bit fields + */ + +#define DN_OFST_RX1_EN 0x0001 +#define DN_OFST_RX2_EN 0x0100 + +#define DN_OFST_RX1 1 +#define DN_OFST_RX2 9 +#define DN_OFST_MAX 0x1F + +#define MCPDM_UPLINK 1 +#define MCPDM_DOWNLINK 2 + +struct omap_mcpdm_link { + int irq_mask; + int threshold; + int format; + int channels; +}; + +struct omap_mcpdm_platform_data { + unsigned long phys_base; + u16 irq; + + int (*device_enable) (struct platform_device *pdev); + int (*device_shutdown) (struct platform_device *pdev); + int (*device_idle) (struct platform_device *pdev); + int (*device_disable) (struct platform_device *pdev); +}; + +struct omap_mcpdm { + struct device *dev; + unsigned long phys_base; + void __iomem *io_base; + u8 free; + int irq; + + spinlock_t lock; + struct omap_mcpdm_platform_data *pdata; + struct clk *clk; + struct omap_mcpdm_link *downlink; + struct omap_mcpdm_link *uplink; + struct completion irq_completion; + + int dn_channels; + int up_channels; +}; + +extern void omap_mcpdm_start(int stream); +extern void omap_mcpdm_stop(int stream); +extern int omap_mcpdm_capture_open(struct omap_mcpdm_link *uplink); +extern int omap_mcpdm_playback_open(struct omap_mcpdm_link *downlink); +extern int omap_mcpdm_capture_close(struct omap_mcpdm_link *uplink); +extern int omap_mcpdm_playback_close(struct omap_mcpdm_link *downlink); +extern int omap_mcpdm_request(void); +extern void omap_mcpdm_free(void); +extern int omap_mcpdm_set_offset(int offset1, int offset2); diff --git a/sound/soc/omap/omap-abe.c b/sound/soc/omap/omap-abe.c new file mode 100644 index 000000000000..9c1b9bc4e317 --- /dev/null +++ b/sound/soc/omap/omap-abe.c @@ -0,0 +1,308 @@ +/* + * omap-abe.c -- OMAP ALSA SoC DAI driver using Audio Backend + * + * Copyright (C) 2009 Texas Instruments + * + * Contact: Misael Lopez Cruz <x0052729@ti.com> + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/device.h> +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/initval.h> +#include <sound/soc.h> + +#include <plat/control.h> +#include <plat/dma.h> +#include "mcpdm.h" +#include "omap-pcm.h" +#include "omap-abe.h" +#include "../codecs/abe/abe_main.h" + +#define OMAP_ABE_FORMATS (SNDRV_PCM_FMTBIT_S32_LE) + +struct omap_mcpdm_data { + struct omap_mcpdm_link *links; + int active[2]; + int requested; +}; + +static struct omap_mcpdm_link omap_mcpdm_links[] = { + /* downlink */ + { + .irq_mask = MCPDM_DN_IRQ_EMPTY | MCPDM_DN_IRQ_FULL, + .threshold = 1, + .format = PDMOUTFORMAT_LJUST, + .channels = PDM_DN_MASK | PDM_CMD_MASK, + }, + /* uplink */ + { + .irq_mask = MCPDM_UP_IRQ_EMPTY | MCPDM_UP_IRQ_FULL, + .threshold = 1, + .format = PDMOUTFORMAT_LJUST, + .channels = PDM_UP1_EN | PDM_UP2_EN | + PDM_DN_MASK | PDM_CMD_MASK, + }, +}; + +static struct omap_mcpdm_data mcpdm_data = { + .links = omap_mcpdm_links, + .active = {0}, + .requested = 0, +}; + +/* + * Stream DMA parameters + */ +static struct omap_pcm_dma_data omap_abe_dai_dma_params[] = { + { + .name = "Audio playback", + .dma_req = OMAP44XX_DMA_ABE_REQ0, + .data_type = OMAP_DMA_DATA_TYPE_S32, + .sync_mode = OMAP_DMA_SYNC_PACKET, + }, + { + .name = "Audio capture", + .dma_req = OMAP44XX_DMA_ABE_REQ2, + .data_type = OMAP_DMA_DATA_TYPE_S32, + .sync_mode = OMAP_DMA_SYNC_PACKET, + }, +}; + +static int omap_abe_dai_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + struct omap_mcpdm_data *mcpdm_priv = cpu_dai->private_data; + int err = 0; + + if (!mcpdm_priv->requested++) + err = omap_mcpdm_request(); + + return err; +} + +static void omap_abe_dai_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + struct omap_mcpdm_data *mcpdm_priv = cpu_dai->private_data; + + if (!--mcpdm_priv->requested) + omap_mcpdm_free(); +} + +static int omap_abe_dai_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + struct omap_mcpdm_data *mcpdm_priv = cpu_dai->private_data; + struct omap_mcpdm_link *mcpdm_links = mcpdm_priv->links; + int err, stream = substream->stream, dma_req; + abe_dma_t dma_params; + + /* get abe dma data */ + switch (cpu_dai->id) { + case OMAP_ABE_MM_DAI: + if (stream == SNDRV_PCM_STREAM_CAPTURE) { + abe_read_port_address(MM_UL2_PORT, &dma_params); + dma_req = OMAP44XX_DMA_ABE_REQ4; + } else { + abe_read_port_address(MM_DL_PORT, &dma_params); + dma_req = OMAP44XX_DMA_ABE_REQ0; + } + break; + case OMAP_ABE_TONES_DL_DAI: + if (stream == SNDRV_PCM_STREAM_CAPTURE) { + return -EINVAL; + } else { + abe_read_port_address(TONES_DL_PORT, &dma_params); + dma_req = OMAP44XX_DMA_ABE_REQ5; + } + break; + case OMAP_ABE_VOICE_DAI: + if (stream == SNDRV_PCM_STREAM_CAPTURE) { + abe_read_port_address(VX_UL_PORT, &dma_params); + dma_req = OMAP44XX_DMA_ABE_REQ2; + } else { + abe_read_port_address(VX_DL_PORT, &dma_params); + dma_req = OMAP44XX_DMA_ABE_REQ1; + } + break; + case OMAP_ABE_DIG_UPLINK_DAI: + if (stream == SNDRV_PCM_STREAM_CAPTURE) { + abe_read_port_address(MM_UL_PORT, &dma_params); + dma_req = OMAP44XX_DMA_ABE_REQ3; + + } else { + return -EINVAL; + } + break; + case OMAP_ABE_VIB_DAI: + if (stream == SNDRV_PCM_STREAM_CAPTURE) { + return -EINVAL; + } else { + abe_read_port_address(VIB_DL_PORT, &dma_params); + dma_req = OMAP44XX_DMA_ABE_REQ6; + } + break; + default: + return -EINVAL; + } + + omap_abe_dai_dma_params[stream].dma_req = dma_req; + omap_abe_dai_dma_params[stream].port_addr = + (unsigned long)dma_params.data; + omap_abe_dai_dma_params[stream].packet_size = dma_params.iter; + cpu_dai->dma_data = &omap_abe_dai_dma_params[stream]; + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) + err = omap_mcpdm_playback_open(&mcpdm_links[stream]); + else + err = omap_mcpdm_capture_open(&mcpdm_links[stream]); + + omap_mcpdm_start(stream); + + return err; +} + +static int omap_abe_dai_hw_free(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + struct omap_mcpdm_data *mcpdm_priv = cpu_dai->private_data; + struct omap_mcpdm_link *mcpdm_links = mcpdm_priv->links; + int stream = substream->stream; + int err; + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) + err = omap_mcpdm_playback_close(&mcpdm_links[stream]); + else + err = omap_mcpdm_capture_close(&mcpdm_links[stream]); + + omap_mcpdm_stop(stream); + + return err; +} + +static struct snd_soc_dai_ops omap_abe_dai_ops = { + .startup = omap_abe_dai_startup, + .shutdown = omap_abe_dai_shutdown, + .hw_params = omap_abe_dai_hw_params, + .hw_free = omap_abe_dai_hw_free, +}; + +struct snd_soc_dai omap_abe_dai[] = { + { + .name = "omap-abe-mm", + .id = OMAP_ABE_MM_DAI, + .playback = { + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, + .formats = OMAP_ABE_FORMATS, + }, + .capture = { + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_48000, + .formats = OMAP_ABE_FORMATS, + }, + .ops = &omap_abe_dai_ops, + .private_data = &mcpdm_data, + }, + { + .name = "omap-abe-tone-dl", + .id = OMAP_ABE_TONES_DL_DAI, + .playback = { + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, + .formats = OMAP_ABE_FORMATS, + }, + .ops = &omap_abe_dai_ops, + .private_data = &mcpdm_data, + }, + { + .name = "omap-abe-voice", + .id = OMAP_ABE_VOICE_DAI, + .playback = { + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, + .formats = OMAP_ABE_FORMATS, + }, + .capture = { + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, + .formats = OMAP_ABE_FORMATS, + }, + .ops = &omap_abe_dai_ops, + .private_data = &mcpdm_data, + }, + { + .name = "omap-abe-dig-ul", + .id = OMAP_ABE_DIG_UPLINK_DAI, + .capture = { + .channels_min = 2, + .channels_max = 8, + .rates = SNDRV_PCM_RATE_48000, + .formats = OMAP_ABE_FORMATS, + }, + .ops = &omap_abe_dai_ops, + .private_data = &mcpdm_data, + }, + { + .name = "omap-abe-vib", + .id = OMAP_ABE_VIB_DAI, + .playback = { + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_48000, + .formats = OMAP_ABE_FORMATS, + }, + .ops = &omap_abe_dai_ops, + .private_data = &mcpdm_data, + }, +}; +EXPORT_SYMBOL_GPL(omap_abe_dai); + +static int __init snd_omap_abe_init(void) +{ + return snd_soc_register_dais(omap_abe_dai, ARRAY_SIZE(omap_abe_dai)); +} +module_init(snd_omap_abe_init); + +static void __exit snd_omap_abe_exit(void) +{ + snd_soc_unregister_dais(omap_abe_dai, ARRAY_SIZE(omap_abe_dai)); +} +module_exit(snd_omap_abe_exit); + +MODULE_AUTHOR("Misael Lopez Cruz <x0052729@ti.com>"); +MODULE_DESCRIPTION("OMAP ABE SoC Interface"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/omap/omap-abe.h b/sound/soc/omap/omap-abe.h new file mode 100644 index 000000000000..44f23940601f --- /dev/null +++ b/sound/soc/omap/omap-abe.h @@ -0,0 +1,35 @@ +/* + * omap-abe.h + * + * Copyright (C) 2009 Texas Instruments + * + * Contact: Misael Lopez Cruz <x0052729@ti.com> + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __OMAP_MCPDM_H__ +#define __OMAP_MCPDM_H__ + +#define OMAP_ABE_MM_DAI 0 +#define OMAP_ABE_TONES_DL_DAI 1 +#define OMAP_ABE_VOICE_DAI 2 +#define OMAP_ABE_DIG_UPLINK_DAI 3 +#define OMAP_ABE_VIB_DAI 4 + +extern struct snd_soc_dai omap_abe_dai[]; + +#endif /* End of __OMAP_MCPDM_H__ */ diff --git a/sound/soc/omap/omap-hdmi.c b/sound/soc/omap/omap-hdmi.c new file mode 100644 index 000000000000..1b535fad57cf --- /dev/null +++ b/sound/soc/omap/omap-hdmi.c @@ -0,0 +1,240 @@ +/* + * omap-hdmi.c -- OMAP ALSA SoC DAI driver for HDMI audio + * + * Copyright (C) 2009 Texas Instruments + * + * Contact: Jorge Candelaria <x0107209@ti.com> + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/device.h> +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/initval.h> +#include <sound/soc.h> + +#include <plat/control.h> +#include <plat/dma.h> +#include "omap-pcm.h" +#include "omap-hdmi.h" + +#define CONFIG_HDMI_NO_IP_MODULE +#define OMAP_HDMI_RATES (SNDRV_PCM_RATE_48000) + +/* Currently, we support only 16b samples at HDMI */ +#define OMAP_HDMI_FORMATS (SNDRV_PCM_FMTBIT_S16_LE) + +#ifdef CONFIG_HDMI_NO_IP_MODULE +#include <plat/hdmi_lib.h> +#else +struct hdmi_ip_driver hdmi_audio_core; +#endif + +static struct omap_pcm_dma_data omap_hdmi_dai_dma_params = { + .name = "HDMI playback", + .dma_req = OMAP44XX_DMA_DSS_HDMI_REQ, + .port_addr = HDMI_WP + HDMI_WP_AUDIO_DATA, + .sync_mode = OMAP_DMA_SYNC_PACKET, +}; + +static int omap_hdmi_dai_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + int err = 0; +#ifdef CONFIG_HDMI_NO_IP_MODULE + err = hdmi_w1_wrapper_enable(HDMI_WP); +#else + if (hdmi_audio_core.module_loaded) + err = hdmi_audio_core.wrapper_enable(HDMI_WP); + else + printk(KERN_WARNING "Warning: hdmi_core.ko is not enabled"); +#endif + return err; +} + +static void omap_hdmi_dai_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + int err = 0; +#ifdef CONFIG_HDMI_NO_IP_MODULE + err = hdmi_w1_wrapper_disable(HDMI_WP); +#else + if (hdmi_audio_core.module_loaded) + err = hdmi_audio_core.wrapper_disable(HDMI_WP); + else + printk(KERN_WARNING "Warning: hdmi_core.ko is not enabled"); +#endif + return err; +} + +static int omap_hdmi_dai_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + int err = 0; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: +#ifdef CONFIG_HDMI_NO_IP_MODULE + err = hdmi_w1_start_audio_transfer(HDMI_WP); +#else + if (hdmi_audio_core.module_loaded) + err = hdmi_audio_core.start_audio(HDMI_WP); + else + printk(KERN_WARNING "Warning: hdmi_core.ko is " + "not enabled"); +#endif + break; + + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: +#ifdef CONFIG_HDMI_NO_IP_MODULE + err = hdmi_w1_stop_audio_transfer(HDMI_WP); +#else + if (hdmi_audio_core.module_loaded) + err = hdmi_audio_core.stop_audio(HDMI_WP); + else + printk(KERN_WARNING "Warning: hdmi_core.ko is " + "not enabled"); +#endif + break; + default: + err = -EINVAL; + } + + return err; +} + +static int omap_hdmi_dai_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + int err = 0; + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + case SNDRV_PCM_FORMAT_S32_LE: + omap_hdmi_dai_dma_params.data_type = OMAP_DMA_DATA_TYPE_S32; + break; + + default: + err = -EINVAL; + } + omap_hdmi_dai_dma_params.packet_size = 0x20; + + cpu_dai->dma_data = &omap_hdmi_dai_dma_params; + + return err; +} + +static struct snd_soc_dai_ops omap_hdmi_dai_ops = { + .startup = omap_hdmi_dai_startup, + .shutdown = omap_hdmi_dai_shutdown, + .trigger = omap_hdmi_dai_trigger, + .hw_params = omap_hdmi_dai_hw_params, +}; + +struct snd_soc_dai omap_hdmi_dai = { + .name = "omap-hdmi-dai", + .id = -1, + .playback = { + .channels_min = 2, + /* currently we support only stereo HDMI */ + .channels_max = 2, + .rates = OMAP_HDMI_RATES, + .formats = OMAP_HDMI_FORMATS, + }, + .ops = &omap_hdmi_dai_ops, +}; +EXPORT_SYMBOL_GPL(omap_hdmi_dai); + +static int __init snd_omap_hdmi_init(void) +{ +#ifdef CONFIG_HDMI_NO_IP_MODULE + hdmi_lib_init(); +#else + hdmi_audio_core_stub_init(); +#endif + return snd_soc_register_dai(&omap_hdmi_dai); +} +module_init(snd_omap_hdmi_init); + +static void __exit snd_omap_hdmi_exit(void) +{ + snd_soc_unregister_dai(&omap_hdmi_dai); +} +module_exit(snd_omap_hdmi_exit); + +#ifndef CONFIG_HDMI_NO_IP_MODULE + +/* stub */ +int audio_stub_lib_init(void) +{ + printk(KERN_WARNING "ERR: please install HDMI IP kernel module\n"); + return -1; +} +void audio_stub_lib_exit(void) +{ + printk(KERN_WARNING "HDMI module does not exist!\n"); +} + +#define EXPORT_SYMTAB + +/* HDMI panel driver */ +void hdmi_audio_core_stub_init(void) +{ + hdmi_audio_core.stop_video = NULL; + hdmi_audio_core.start_video = NULL; + hdmi_audio_core.wrapper_enable = NULL; + hdmi_audio_core.wrapper_disable = NULL; + hdmi_audio_core.stop_audio = NULL; + hdmi_audio_core.start_audio = NULL; + hdmi_audio_core.config_video = NULL; + hdmi_audio_core.set_wait_pll = NULL; + hdmi_audio_core.set_wait_pwr = NULL; + hdmi_audio_core.set_wait_srst = NULL; + hdmi_audio_core.read_edid = NULL; + hdmi_audio_core.ip_init = audio_stub_lib_init; + hdmi_audio_core.ip_exit = audio_stub_lib_exit; + hdmi_audio_core.module_loaded = 0; +} + +void hdmi_audio_core_lib_set(struct hdmi_ip_driver *ipc) +{ + hdmi_audio_core.module_loaded = ipc->module_loaded; + if (ipc->module_loaded) { + hdmi_audio_core.wrapper_enable = ipc->wrapper_enable; + hdmi_audio_core.wrapper_disable = ipc->wrapper_disable; + hdmi_audio_core.start_audio = ipc->start_audio; + hdmi_audio_core.stop_audio = ipc->stop_audio; + } +} +EXPORT_SYMBOL(hdmi_audio_core_lib_set); + +#endif + + +MODULE_AUTHOR("Jorge Candelaria <x0107209@ti.com"); +MODULE_DESCRIPTION("OMAP HDMI SoC Interface"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/omap/omap-hdmi.h b/sound/soc/omap/omap-hdmi.h new file mode 100644 index 000000000000..34142c9a551e --- /dev/null +++ b/sound/soc/omap/omap-hdmi.h @@ -0,0 +1,54 @@ +/* + * omap-hdmi.h + * + * Copyright (C) 2009 Texas Instruments + * + * Contact: Jorge Candelaria <x0107209@ti.com> + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __OMAP_HDMI_H__ +#define __OMAP_HDMI_H__ + +extern struct snd_soc_dai omap_hdmi_dai; + +#ifndef CONFIG_HDMI_NO_IP_MODULE + +#define HDMI_WP 0x58006000 +#define HDMI_WP_AUDIO_DATA 0x8Cul + +struct hdmi_ip_driver { + int (*stop_video)(u32); + int (*start_video)(u32); + int (*wrapper_enable)(u32); + int (*wrapper_disable)(u32); + int (*stop_audio)(u32); + int (*start_audio)(u32); + int (*config_video)(struct hdmi_timing_t, u32, u32); + int (*set_wait_pll)(u32, enum hdmi_pllpwr_cmd); + int (*set_wait_pwr)(u32, enum hdmi_phypwr_cmd); + int (*set_wait_srst)(void); + int (*read_edid)(u32, u8 *d); + int (*ip_init)(void); + void (*ip_exit)(void); + int module_loaded; +}; + +extern void hdmi_audio_core_stub_init(void); +#endif + +#endif /* End of __OMAP_HDMI_H__ */ diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 6bbbd2ab0ee7..d29725664185 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -287,6 +287,8 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, omap_mcbsp_dai_dma_params[id][substream->stream].dma_req = dma; omap_mcbsp_dai_dma_params[id][substream->stream].port_addr = port; omap_mcbsp_dai_dma_params[id][substream->stream].sync_mode = sync_mode; + omap_mcbsp_dai_dma_params[id][substream->stream].data_type = + OMAP_DMA_DATA_TYPE_S16; cpu_dai->dma_data = &omap_mcbsp_dai_dma_params[id][substream->stream]; if (mcbsp_data->configured) { diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c new file mode 100644 index 000000000000..9fe0dea89756 --- /dev/null +++ b/sound/soc/omap/omap-mcpdm.c @@ -0,0 +1,224 @@ +/* + * omap-mcpdm.c -- OMAP ALSA SoC DAI driver using McPDM port + * + * Copyright (C) 2009 Texas Instruments + * + * Author: Misael Lopez Cruz <x0052729@ti.com> + * Contact: Jorge Eduardo Candelaria <x0107209@ti.com> + * Margarita Olaya <magi.olaya@ti.com> + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/device.h> +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/initval.h> +#include <sound/soc.h> + +#include <plat/control.h> +#include <plat/dma.h> +#include <plat/mcbsp.h> +#include "mcpdm.h" +#include "omap-mcpdm.h" +#include "omap-pcm.h" + +struct omap_mcpdm_data { + struct omap_mcpdm_link *links; + int active; +}; + +static struct omap_mcpdm_link omap_mcpdm_links[] = { + /* downlink */ + { + .irq_mask = MCPDM_DN_IRQ_EMPTY | MCPDM_DN_IRQ_FULL, + .threshold = 1, + .format = PDMOUTFORMAT_LJUST, + }, + /* uplink */ + { + .irq_mask = MCPDM_UP_IRQ_EMPTY | MCPDM_UP_IRQ_FULL, + .threshold = 1, + .format = PDMOUTFORMAT_LJUST, + }, +}; + +static struct omap_mcpdm_data mcpdm_data = { + .links = omap_mcpdm_links, + .active = 0, +}; + +/* + * Stream DMA parameters + */ +static struct omap_pcm_dma_data omap_mcpdm_dai_dma_params[] = { + { + .name = "Audio playback", + .dma_req = OMAP44XX_DMA_MCPDM_DL, + .data_type = OMAP_DMA_DATA_TYPE_S32, + .sync_mode = OMAP_DMA_SYNC_PACKET, + .packet_size = 16, + .port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_DN_DATA, + }, + { + .name = "Audio capture", + .dma_req = OMAP44XX_DMA_MCPDM_UP, + .data_type = OMAP_DMA_DATA_TYPE_S32, + .sync_mode = OMAP_DMA_SYNC_PACKET, + .packet_size = 16, + .port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_UP_DATA, + }, +}; + +static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + int err = 0; + + if (!cpu_dai->active) + err = omap_mcpdm_request(); + + return err; +} + +static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + + if (!cpu_dai->active) + omap_mcpdm_free(); +} + +static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + struct omap_mcpdm_data *mcpdm_priv = cpu_dai->private_data; + struct omap_mcpdm_link *mcpdm_links = mcpdm_priv->links; + int stream = substream->stream; + int channels, err, link_mask = 0; + + cpu_dai->dma_data = &omap_mcpdm_dai_dma_params[stream]; + + channels = params_channels(params); + switch (channels) { + case 4: + if (stream == SNDRV_PCM_STREAM_CAPTURE) + /* up to 2 channels for capture */ + return -EINVAL; + link_mask |= 1 << 3; + case 3: + if (stream == SNDRV_PCM_STREAM_CAPTURE) + /* up to 2 channels for capture */ + return -EINVAL; + link_mask |= 1 << 2; + case 2: + link_mask |= 1 << 1; + case 1: + link_mask |= 1 << 0; + break; + default: + /* unsupported number of channels */ + return -EINVAL; + } + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + mcpdm_links[stream].channels = link_mask << 3; + err = omap_mcpdm_playback_open(&mcpdm_links[stream]); + } else { + mcpdm_links[stream].channels = link_mask << 0; + err = omap_mcpdm_capture_open(&mcpdm_links[stream]); + } + + omap_mcpdm_start(stream); + + return err; +} + +static int omap_mcpdm_dai_hw_free(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + struct omap_mcpdm_data *mcpdm_priv = cpu_dai->private_data; + struct omap_mcpdm_link *mcpdm_links = mcpdm_priv->links; + int stream = substream->stream; + int err; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + err = omap_mcpdm_playback_close(&mcpdm_links[stream]); + else + err = omap_mcpdm_capture_close(&mcpdm_links[stream]); + + omap_mcpdm_stop(stream); + + return err; +} + +static struct snd_soc_dai_ops omap_mcpdm_dai_ops = { + .startup = omap_mcpdm_dai_startup, + .shutdown = omap_mcpdm_dai_shutdown, + .hw_params = omap_mcpdm_dai_hw_params, + .hw_free = omap_mcpdm_dai_hw_free, +}; + +#define OMAP_MCPDM_RATES (SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) +#define OMAP_MCPDM_FORMATS (SNDRV_PCM_FMTBIT_S32_LE) + +struct snd_soc_dai omap_mcpdm_dai = { + .name = "omap-mcpdm", + .id = -1, + .playback = { + .channels_min = 1, + .channels_max = 4, + .rates = OMAP_MCPDM_RATES, + .formats = OMAP_MCPDM_FORMATS, + }, + .capture = { + .channels_min = 1, + .channels_max = 2, + .rates = OMAP_MCPDM_RATES, + .formats = OMAP_MCPDM_FORMATS, + }, + .ops = &omap_mcpdm_dai_ops, + .private_data = &mcpdm_data, +}; +EXPORT_SYMBOL_GPL(omap_mcpdm_dai); + +static int __init snd_omap_mcpdm_init(void) +{ + return snd_soc_register_dai(&omap_mcpdm_dai); +} +module_init(snd_omap_mcpdm_init); + +static void __exit snd_omap_mcpdm_exit(void) +{ + snd_soc_unregister_dai(&omap_mcpdm_dai); +} +module_exit(snd_omap_mcpdm_exit); + +MODULE_AUTHOR("Misael Lopez Cruz <x0052729@ti.com>"); +MODULE_DESCRIPTION("OMAP PDM SoC Interface"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/omap/omap-mcpdm.h b/sound/soc/omap/omap-mcpdm.h new file mode 100644 index 000000000000..73b80d559345 --- /dev/null +++ b/sound/soc/omap/omap-mcpdm.h @@ -0,0 +1,29 @@ +/* + * omap-mcpdm.h + * + * Copyright (C) 2009 Texas Instruments + * + * Contact: Misael Lopez Cruz <x0052729@ti.com> + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __OMAP_MCPDM_H__ +#define __OMAP_MCPDM_H__ + +extern struct snd_soc_dai omap_mcpdm_dai; + +#endif /* End of __OMAP_MCPDM_H__ */ diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index 9db2770e9640..e1b94e92eb4a 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -37,7 +37,8 @@ static const struct snd_pcm_hardware omap_pcm_hardware = { SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME, - .formats = SNDRV_PCM_FMTBIT_S16_LE, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S32_LE, .period_bytes_min = 32, .period_bytes_max = 64 * 1024, .periods_min = 2, @@ -149,6 +150,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream) struct omap_runtime_data *prtd = runtime->private_data; struct omap_pcm_dma_data *dma_data = prtd->dma_data; struct omap_dma_channel_params dma_params; + int bytes; /* return if this is a bufferless transfer e.g. * codec <--> BT codec or GSM modem -- lg FIXME */ @@ -156,11 +158,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream) return 0; memset(&dma_params, 0, sizeof(dma_params)); - /* - * Note: Regardless of interface data formats supported by OMAP McBSP - * or EAC blocks, internal representation is always fixed 16-bit/sample - */ - dma_params.data_type = OMAP_DMA_DATA_TYPE_S16; + dma_params.data_type = dma_data->data_type; dma_params.trigger = dma_data->dma_req; dma_params.sync_mode = dma_data->sync_mode; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { @@ -170,6 +168,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream) dma_params.src_start = runtime->dma_addr; dma_params.dst_start = dma_data->port_addr; dma_params.dst_port = OMAP_DMA_PORT_MPUI; + dma_params.dst_fi = dma_data->packet_size; } else { dma_params.src_amode = OMAP_DMA_AMODE_CONSTANT; dma_params.dst_amode = OMAP_DMA_AMODE_POST_INC; @@ -177,6 +176,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream) dma_params.src_start = dma_data->port_addr; dma_params.dst_start = runtime->dma_addr; dma_params.src_port = OMAP_DMA_PORT_MPUI; + dma_params.src_fi = dma_data->packet_size; } /* * Set DMA transfer frame size equal to ALSA period size and frame @@ -184,7 +184,8 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream) * we can transfer the whole ALSA buffer with single DMA transfer but * still can get an interrupt at each period bounary */ - dma_params.elem_count = snd_pcm_lib_period_bytes(substream) / 2; + bytes = snd_pcm_lib_period_bytes(substream); + dma_params.elem_count = bytes >> dma_data->data_type; dma_params.frame_count = runtime->periods; omap_set_dma_params(prtd->dma_ch, &dma_params); @@ -231,6 +232,11 @@ static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_PAUSE_PUSH: prtd->period_index = -1; omap_stop_dma(prtd->dma_ch); + /* Since we are using self linking, there is a + chance that the DMA as re-enabled the channel + just after disabling it */ + while (omap_get_dma_active_status(prtd->dma_ch)) + omap_stop_dma(prtd->dma_ch); break; default: ret = -EINVAL; @@ -276,6 +282,14 @@ static int omap_pcm_open(struct snd_pcm_substream *substream) if (ret < 0) goto out; + /* ABE needs a step of 24 * 4 data bits, and HDMI 32 * 4 + * Ensure buffer size satisfies both constraints. + */ + ret = snd_pcm_hw_constraint_step(runtime, 0, + SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 384); + if (ret < 0) + goto out; + prtd = kzalloc(sizeof(*prtd), GFP_KERNEL); if (prtd == NULL) { ret = -ENOMEM; diff --git a/sound/soc/omap/omap-pcm.h b/sound/soc/omap/omap-pcm.h index 38a821dd4118..b19975d26907 100644 --- a/sound/soc/omap/omap-pcm.h +++ b/sound/soc/omap/omap-pcm.h @@ -29,8 +29,10 @@ struct omap_pcm_dma_data { char *name; /* stream identifier */ int dma_req; /* DMA request line */ unsigned long port_addr; /* transmit/receive register */ - int sync_mode; /* DMA sync mode */ void (*set_threshold)(struct snd_pcm_substream *substream); + int data_type; /* data type 8,16,32 */ + int sync_mode; /* DMA sync mode */ + int packet_size; /* packet size only in PACKET mode */ }; extern struct snd_soc_platform omap_soc_platform; diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c new file mode 100644 index 000000000000..20fc588f452b --- /dev/null +++ b/sound/soc/omap/sdp4430.c @@ -0,0 +1,289 @@ +/* + * sdp4430.c -- SoC audio for TI OMAP4430 SDP + * + * Author: Misael Lopez Cruz <x0052729@ti.com> + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include <linux/clk.h> +#include <linux/platform_device.h> +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/soc.h> +#include <sound/soc-dapm.h> + +#include <asm/mach-types.h> +#include <plat/hardware.h> +#include <plat/mux.h> + +#include "mcpdm.h" +#include "omap-abe.h" +#include "omap-pcm.h" +#include "../codecs/twl6040.h" +#include "../codecs/abe-twl6040.h" + +#ifdef CONFIG_SND_OMAP_SOC_HDMI +#include "omap-hdmi.h" +#endif + +static struct snd_soc_dai_link sdp4430_dai[]; +static struct snd_soc_card snd_soc_sdp4430; +static int twl6040_power_mode; + +static int sdp4430_get_power_mode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = twl6040_power_mode; + return 0; +} + +static int sdp4430_set_power_mode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int clk_id, freq; + int ret; + + if (twl6040_power_mode == ucontrol->value.integer.value[0]) + return 0; + + if (ucontrol->value.integer.value[0]) { + clk_id = TWL6040_SYSCLK_SEL_HPPLL; + freq = 38400000; + } else { + clk_id = TWL6040_SYSCLK_SEL_LPPLL; + freq = 32768; + } + + /* set the codec mclk */ + ret = snd_soc_dai_set_sysclk(sdp4430_dai[0].codec_dai, clk_id, freq, + SND_SOC_CLOCK_IN); + if (ret) { + printk(KERN_ERR "can't set codec system clock\n"); + return ret; + } + + twl6040_power_mode = ucontrol->value.integer.value[0]; + + return 1; +} + +static const char *power_texts[] = {"Low-Power", "High-Performance"}; + +static const struct soc_enum sdp4430_enum[] = { + SOC_ENUM_SINGLE_EXT(2, power_texts), +}; + +static const struct snd_kcontrol_new sdp4430_controls[] = { + SOC_ENUM_EXT("TWL6040 Power Mode", sdp4430_enum[0], + sdp4430_get_power_mode, sdp4430_set_power_mode), +}; + +/* SDP4430 machine DAPM */ +static const struct snd_soc_dapm_widget sdp4430_twl6040_dapm_widgets[] = { + SND_SOC_DAPM_MIC("Ext Mic", NULL), + SND_SOC_DAPM_SPK("Ext Spk", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_HP("Headset Stereophone", NULL), + SND_SOC_DAPM_SPK("Earphone Spk", NULL), +}; + +static const struct snd_soc_dapm_route audio_map[] = { + /* External Mics: MAINMIC, SUBMIC with bias*/ + {"MAINMIC", NULL, "Main Mic Bias"}, + {"SUBMIC", NULL, "Main Mic Bias"}, + {"Main Mic Bias", NULL, "Ext Mic"}, + + /* External Speakers: HFL, HFR */ + {"Ext Spk", NULL, "HFL"}, + {"Ext Spk", NULL, "HFR"}, + + /* Headset Mic: HSMIC with bias */ + {"HSMIC", NULL, "Headset Mic Bias"}, + {"Headset Mic Bias", NULL, "Headset Mic"}, + + /* Headset Stereophone (Headphone): HSOL, HSOR */ + {"Headset Stereophone", NULL, "HSOL"}, + {"Headset Stereophone", NULL, "HSOR"}, + + /* Earphone speaker */ + {"Earphone Spk", NULL, "EP"}, + +}; + +static int sdp4430_twl6040_init(struct snd_soc_codec *codec) +{ + int ret; + + /* Add SDP4430 specific controls */ + ret = snd_soc_add_controls(codec, sdp4430_controls, + ARRAY_SIZE(sdp4430_controls)); + if (ret) + return ret; + + /* Add SDP4430 specific widgets */ + ret = snd_soc_dapm_new_controls(codec, sdp4430_twl6040_dapm_widgets, + ARRAY_SIZE(sdp4430_twl6040_dapm_widgets)); + if (ret) + return ret; + + /* Set up SDP4430 specific audio path audio_map */ + snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + + /* SDP4430 connected pins */ + snd_soc_dapm_enable_pin(codec, "Ext Mic"); + snd_soc_dapm_enable_pin(codec, "Ext Spk"); + snd_soc_dapm_enable_pin(codec, "Headset Mic"); + snd_soc_dapm_enable_pin(codec, "Headset Stereophone"); + + /* TWL6040 not connected pins */ + snd_soc_dapm_nc_pin(codec, "AFML"); + snd_soc_dapm_nc_pin(codec, "AFMR"); + + ret = snd_soc_dapm_sync(codec); + + return ret; +} + +#ifdef CONFIG_SND_OMAP_SOC_HDMI +struct snd_soc_dai null_dai = { + .name = "null", + .playback = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 8, + .rates = SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, + }, +}; +#endif + +/* Digital audio interface glue - connects codec <--> CPU */ +static struct snd_soc_dai_link sdp4430_dai[] = { + { + .name = "abe-twl6040", + .stream_name = "Multimedia", + .cpu_dai = &omap_abe_dai[OMAP_ABE_MM_DAI], + .codec_dai = &abe_dai[0], + .init = sdp4430_twl6040_init, + }, + { + .name = "abe-twl6040", + .stream_name = "Tones DL", + .cpu_dai = &omap_abe_dai[OMAP_ABE_TONES_DL_DAI], + .codec_dai = &abe_dai[1], + }, + { + .name = "abe-twl6040", + .stream_name = "Voice", + .cpu_dai = &omap_abe_dai[OMAP_ABE_VOICE_DAI], + .codec_dai = &abe_dai[2], + }, + { + .name = "abe-twl6040", + .stream_name = "Digital Uplink", + .cpu_dai = &omap_abe_dai[OMAP_ABE_DIG_UPLINK_DAI], + .codec_dai = &abe_dai[3], + }, + { + .name = "abe-twl6040", + .stream_name = "Vibrator", + .cpu_dai = &omap_abe_dai[OMAP_ABE_VIB_DAI], + .codec_dai = &abe_dai[4], + }, +#ifdef CONFIG_SND_OMAP_SOC_HDMI + { + .name = "hdmi", + .stream_name = "HDMI", + .cpu_dai = &omap_hdmi_dai, + .codec_dai = &null_dai, + }, +#endif +}; + +/* Audio machine driver */ +static struct snd_soc_card snd_soc_sdp4430 = { + .name = "SDP4430", + .platform = &omap_soc_platform, + .dai_link = sdp4430_dai, + .num_links = ARRAY_SIZE(sdp4430_dai), +}; + +/* Audio subsystem */ +static struct snd_soc_device sdp4430_snd_devdata = { + .card = &snd_soc_sdp4430, + .codec_dev = &soc_codec_dev_abe_twl6040, +}; + +static struct platform_device *sdp4430_snd_device; + +static int __init sdp4430_soc_init(void) +{ + int ret; + + if (!machine_is_omap_4430sdp()) { + pr_debug("Not SDP4430!\n"); + return -ENODEV; + } + printk(KERN_INFO "SDP4430 SoC init\n"); + +#ifdef CONFIG_SND_OMAP_SOC_HDMI + snd_soc_register_dais(&null_dai, 1); +#endif + + sdp4430_snd_device = platform_device_alloc("soc-audio", -1); + if (!sdp4430_snd_device) { + printk(KERN_ERR "Platform device allocation failed\n"); + return -ENOMEM; + } + + platform_set_drvdata(sdp4430_snd_device, &sdp4430_snd_devdata); + sdp4430_snd_devdata.dev = &sdp4430_snd_device->dev; + + ret = platform_device_add(sdp4430_snd_device); + if (ret) + goto err; + + ret = snd_soc_dai_set_sysclk(sdp4430_dai[0].codec_dai, + TWL6040_SYSCLK_SEL_HPPLL, 38400000, + SND_SOC_CLOCK_IN); + if (ret) { + printk(KERN_ERR "can't set codec system clock\n"); + goto err; + } + + /* Codec starts in HP mode */ + twl6040_power_mode = 1; + + return 0; + +err: + printk(KERN_ERR "Unable to add platform device\n"); + platform_device_put(sdp4430_snd_device); + return ret; +} +module_init(sdp4430_soc_init); + +static void __exit sdp4430_soc_exit(void) +{ + platform_device_unregister(sdp4430_snd_device); +} +module_exit(sdp4430_soc_exit); + +MODULE_AUTHOR("Misael Lopez Cruz <x0052729@ti.com>"); +MODULE_DESCRIPTION("ALSA SoC SDP4430"); +MODULE_LICENSE("GPL"); + |