diff options
210 files changed, 74806 insertions, 821 deletions
diff --git a/Documentation/arm/OMAP/DSS b/Documentation/arm/OMAP/DSS new file mode 100644 index 000000000000..0af0e9eed5d6 --- /dev/null +++ b/Documentation/arm/OMAP/DSS @@ -0,0 +1,317 @@ +OMAP2/3 Display Subsystem +------------------------- + +This is an almost total rewrite of the OMAP FB driver in drivers/video/omap +(let's call it DSS1). The main differences between DSS1 and DSS2 are DSI, +TV-out and multiple display support, but there are lots of small improvements +also. + +The DSS2 driver (omapdss module) is in arch/arm/plat-omap/dss/, and the FB, +panel and controller drivers are in drivers/video/omap2/. DSS1 and DSS2 live +currently side by side, you can choose which one to use. + +Features +-------- + +Working and tested features include: + +- MIPI DPI (parallel) output +- MIPI DSI output in command mode +- MIPI DBI (RFBI) output +- SDI output +- TV output +- All pieces can be compiled as a module or inside kernel +- Use DISPC to update any of the outputs +- Use CPU to update RFBI or DSI output +- OMAP DISPC planes +- RGB16, RGB24 packed, RGB24 unpacked +- YUV2, UYVY +- Scaling +- Adjusting DSS FCK to find a good pixel clock +- Use DSI DPLL to create DSS FCK + +Tested boards include: +- OMAP3 SDP board +- Beagle board +- N810 + +omapdss driver +-------------- + +The DSS driver does not itself have any support for Linux framebuffer, V4L or +such like the current ones, but it has an internal kernel API that upper level +drivers can use. + +The DSS driver models OMAP's overlays, overlay managers and displays in a +flexible way to enable non-common multi-display configuration. In addition to +modelling the hardware overlays, omapdss supports virtual overlays and overlay +managers. These can be used when updating a display with CPU or system DMA. + +Panel and controller drivers +---------------------------- + +The drivers implement panel or controller specific functionality and are not +usually visible to users except through omapfb driver. They register +themselves to the DSS driver. + +omapfb driver +------------- + +The omapfb driver implements arbitrary number of standard linux framebuffers. +These framebuffers can be routed flexibly to any overlays, thus allowing very +dynamic display architecture. + +The driver exports some omapfb specific ioctls, which are compatible with the +ioctls in the old driver. + +The rest of the non standard features are exported via sysfs. Whether the final +implementation will use sysfs, or ioctls, is still open. + +V4L2 drivers +------------ + +V4L2 is being implemented in TI. + +From omapdss point of view the V4L2 drivers should be similar to framebuffer +driver. + +Architecture +-------------------- + +Some clarification what the different components do: + + - Framebuffer is a memory area inside OMAP's SRAM/SDRAM that contains the + pixel data for the image. Framebuffer has width and height and color + depth. + - Overlay defines where the pixels are read from and where they go on the + screen. The overlay may be smaller than framebuffer, thus displaying only + part of the framebuffer. The position of the overlay may be changed if + the overlay is smaller than the display. + - Overlay manager combines the overlays in to one image and feeds them to + display. + - Display is the actual physical display device. + +A framebuffer can be connected to multiple overlays to show the same pixel data +on all of the overlays. Note that in this case the overlay input sizes must be +the same, but, in case of video overlays, the output size can be different. Any +framebuffer can be connected to any overlay. + +An overlay can be connected to one overlay manager. Also DISPC overlays can be +connected only to DISPC overlay managers, and virtual overlays can be only +connected to virtual overlays. + +An overlay manager can be connected to one display. There are certain +restrictions which kinds of displays an overlay manager can be connected: + + - DISPC TV overlay manager can be only connected to TV display. + - Virtual overlay managers can only be connected to DBI or DSI displays. + - DISPC LCD overlay manager can be connected to all displays, except TV + display. + +Sysfs +----- +The sysfs interface is mainly used for testing. I don't think sysfs +interface is the best for this in the final version, but I don't quite know +what would be the best interfaces for these things. + +The sysfs interface is divided to two parts: DSS and FB. + +/sys/class/graphics/fb? directory: +mirror 0=off, 1=on +rotate Rotation 0-3 for 0, 90, 180, 270 degrees +rotate_type 0 = DMA rotation, 1 = VRFB rotation +overlays List of overlay numbers to which framebuffer pixels go +phys_addr Physical address of the framebuffer +virt_addr Virtual address of the framebuffer +size Size of the framebuffer + +/sys/devices/platform/omapdss/overlay? directory: +enabled 0=off, 1=on +input_size width,height (ie. the framebuffer size) +manager Destination overlay manager name +name +output_size width,height +position x,y +screen_width width +global_alpha global alpha 0-255 0=transparent 255=opaque + +/sys/devices/platform/omapdss/manager? directory: +display Destination display +name +alpha_blending_enabled 0=off, 1=on +trans_key_enabled 0=off, 1=on +trans_key_type gfx-destination, video-source +trans_key_value transparency color key (RGB24) +default_color default background color (RGB24) + +/sys/devices/platform/omapdss/display? directory: +ctrl_name Controller name +mirror 0=off, 1=on +update_mode 0=off, 1=auto, 2=manual +enabled 0=off, 1=on +name +rotate Rotation 0-3 for 0, 90, 180, 270 degrees +timings Display timings (pixclock,xres/hfp/hbp/hsw,yres/vfp/vbp/vsw) + When writing, two special timings are accepted for tv-out: + "pal" and "ntsc" +panel_name +tear_elim Tearing elimination 0=off, 1=on + +There are also some debugfs files at <debugfs>/omapdss/ which show information +about clocks and registers. + +Examples +-------- + +The following definitions have been made for the examples below: + +ovl0=/sys/devices/platform/omapdss/overlay0 +ovl1=/sys/devices/platform/omapdss/overlay1 +ovl2=/sys/devices/platform/omapdss/overlay2 + +mgr0=/sys/devices/platform/omapdss/manager0 +mgr1=/sys/devices/platform/omapdss/manager1 + +lcd=/sys/devices/platform/omapdss/display0 +dvi=/sys/devices/platform/omapdss/display1 +tv=/sys/devices/platform/omapdss/display2 + +fb0=/sys/class/graphics/fb0 +fb1=/sys/class/graphics/fb1 +fb2=/sys/class/graphics/fb2 + +Default setup on OMAP3 SDP +-------------------------- + +Here's the default setup on OMAP3 SDP board. All planes go to LCD. DVI +and TV-out are not in use. The columns from left to right are: +framebuffers, overlays, overlay managers, displays. Framebuffers are +handled by omapfb, and the rest by the DSS. + +FB0 --- GFX -\ DVI +FB1 --- VID1 --+- LCD ---- LCD +FB2 --- VID2 -/ TV ----- TV + +Example: Switch from LCD to DVI +---------------------- + +w=`cat $dvi/timings | cut -d "," -f 2 | cut -d "/" -f 1` +h=`cat $dvi/timings | cut -d "," -f 3 | cut -d "/" -f 1` + +echo "0" > $lcd/enabled +echo "" > $mgr0/display +fbset -fb /dev/fb0 -xres $w -yres $h -vxres $w -vyres $h +# at this point you have to switch the dvi/lcd dip-switch from the omap board +echo "dvi" > $mgr0/display +echo "1" > $dvi/enabled + +After this the configuration looks like: + +FB0 --- GFX -\ -- DVI +FB1 --- VID1 --+- LCD -/ LCD +FB2 --- VID2 -/ TV ----- TV + +Example: Clone GFX overlay to LCD and TV +------------------------------- + +w=`cat $tv/timings | cut -d "," -f 2 | cut -d "/" -f 1` +h=`cat $tv/timings | cut -d "," -f 3 | cut -d "/" -f 1` + +echo "0" > $ovl0/enabled +echo "0" > $ovl1/enabled + +echo "" > $fb1/overlays +echo "0,1" > $fb0/overlays + +echo "$w,$h" > $ovl1/output_size +echo "tv" > $ovl1/manager + +echo "1" > $ovl0/enabled +echo "1" > $ovl1/enabled + +echo "1" > $tv/enabled + +After this the configuration looks like (only relevant parts shown): + +FB0 +-- GFX ---- LCD ---- LCD + \- VID1 ---- TV ---- TV + +Misc notes +---------- + +OMAP FB allocates the framebuffer memory using the OMAP VRAM allocator. + +Using DSI DPLL to generate pixel clock it is possible produce the pixel clock +of 86.5MHz (max possible), and with that you get 1280x1024@57 output from DVI. + +Rotation and mirroring currently only supports RGB565 and RGB8888 modes. VRFB +does not support mirroring. + +VRFB rotation requires much more memory than non-rotated framebuffer, so you +probably need to increase your vram setting before using VRFB rotation. Also, +many applications may not work with VRFB if they do not pay attention to all +framebuffer parameters. + +Kernel boot arguments +--------------------- + +vram=<size> + - Amount of total VRAM to preallocate. For example, "10M". omapfb + allocates memory for framebuffers from VRAM. + +omapfb.mode=<display>:<mode>[,...] + - Default video mode for specified displays. For example, + "dvi:800x400MR-24@60". See drivers/video/modedb.c. + There are also two special modes: "pal" and "ntsc" that + can be used to tv out. + +omapfb.vram=<fbnum>:<size>[@<physaddr>][,...] + - VRAM allocated for a framebuffer. Normally omapfb allocates vram + depending on the display size. With this you can manually allocate + more or define the physical address of each framebuffer. For example, + "1:4M" to allocate 4M for fb1. + +omapfb.debug=<y|n> + - Enable debug printing. You have to have OMAPFB debug support enabled + in kernel config. + +omapfb.test=<y|n> + - Draw test pattern to framebuffer whenever framebuffer settings change. + You need to have OMAPFB debug support enabled in kernel config. + +omapfb.vrfb=<y|n> + - Use VRFB rotation for all framebuffers. + +omapfb.rotate=<angle> + - Default rotation applied to all framebuffers. + 0 - 0 degree rotation + 1 - 90 degree rotation + 2 - 180 degree rotation + 3 - 270 degree rotation + +omapfb.mirror=<y|n> + - Default mirror for all framebuffers. Only works with DMA rotation. + +omapdss.def_disp=<display> + - Name of default display, to which all overlays will be connected. + Common examples are "lcd" or "tv". + +omapdss.debug=<y|n> + - Enable debug printing. You have to have DSS debug support enabled in + kernel config. + +TODO +---- + +DSS locking + +Error checking +- Lots of checks are missing or implemented just as BUG() + +System DMA update for DSI +- Can be used for RGB16 and RGB24P modes. Probably not for RGB24U (how + to skip the empty byte?) + +OMAP1 support +- Not sure if needed + 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..86b585e80d8c --- /dev/null +++ b/TI_OMAP4_Kernel_Release_Notes_L24.x.txt @@ -0,0 +1,467 @@ +Release notes for the Linux kernel for L24.0.11 +---------------------------------------------- + +21 AUGUST 2009 + +Copyright (C) 2009 Texas Instruments Incorporated. All rights reserved. + + +1. Introduction +---------------- +This document accompanies OMAP(TM) Software Release L24.0.11 for Linux 2.6.31 +on OMAP4430 VPOM4430_1.09a_Patch17. 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 Linux Baseport Release for SDP4430 on Virtio. +The kernel is based on Linux-omap version 2.6.31 -rc5 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://git.omapzoom.org/?p=repo/u-boot.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=summary + L24.0.11 branch +Virtio version used: VPOM4430_1.09a + VPOM4430_1.09a_Patch17.var + +All drivers planned for this release are working as expected and +overall platform stability is good. + +current L24.0.11 support: + SMP OS Kernel boot-up on with UART, GPTimers, McBSP, McSPI, I2c, + GPIO, WATCHDOG, Keypad, Phoenix PM IC, RTC, ALSA AUDIO. + +3. Instructions +---------------- + +3.1 Virtio Setup + +This release works on VPOM4430_1.09a_Patch17. + + +3.2 Virtio Installation Instructions + +a. Install to C:\Virtio +b. Once installation for virtio is started, you will be prompted for + installation + for virtual serial port. Say yes to it and give a port number (say 5 or 6). + Multiple serial ports can also be installed. +c. Install C:\Virtio\Shared\Disassembler\Setup\VirtioDisassembler.exe. + This is to enable debugging using virtio. +d. License for virtio has to be set in the environment variables + LM_LICENSE_FILE. +e. Install VPOM4430_1.09a_Patch17. + + +3.3 Virtio Configuration Instructions + +Run virtio and if modify the following parameters + +a. On some versions SSM is generating error due to illegal instruction fetch. + To workaround this you can disable SsmDisableSecurity user parameter. + Params->User Parameters-> SsmDisableSecurity = yes + Right click on SsmDisableSecurity parameter and change properties to editable + mode. Then you can set this parameter to Yes. Default value is no. +b. If IVAHD is enabled the image boot up takes lot of time. If IVAHD component + is not required it can be disabled. + Browse to VPOM4430::SDP::OMAP4430::TIOMAP4CORES and disable all the enabled + components under it +c. Open the Params tab and look at the User Parameters. Set the UARTx_COM_PORT + to the virtual port number you had provided while installation. +d. Both CPU cores support has been enabled. +e. L2 Cache is not enabled in software. This requires the cache to be turned + off in the Virtio parameter list too. For this browse to + VPOM4430::SDP::OMAP4430::CPU_SS::Cortex_1 and set the CacheDisabled parameter + to true. Browse to VPOM4430::SDP::OMAP4430::CPU_SS::Cortex_2 and set the + CacheDisabled parameter to true.Also browse to + VPOM4430::SDP::OMAP4430::CPU_SS::pl310_cache and set the CacheDisabled + parameter to true. +f. Once booted with two CPU, you can see two penguins on LCD instead on one. + Linux kernel shows one penguin per CPU. + +3.4 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.5 Compiling X-Loader + +Not yet supported + +3.6 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 Virtio4430 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. + +Filesystem: +NFS file system is not yet supported. Use ramdisk instead. +The default configuration for ramdisk is in the 4430 defconfig. + Load address = 0x81600000 + Default size = 20MB + + +3.7 Running U-Boot boot loader on RAM + +Go to the design tab. Open Scripts-> configs/Native Apps/Native Apps.script. +Replace it as shown below. +Then launch HyperTerminal and connect to the virtual serial port installed. +(e.g. COM5). +Now choose Native Apps in the configuration tabs at the top and select run. +The SDP4430 U-Boot prompt will appear in your terminal emulation program. + +----------------------- [start of Native Apps.script]-------------------------- + +[VPOM4430::SDP::OMAP4430::L3FW_GPMC] bypass on +[VPOM4430::SDP::OMAP4430::L3FW_EMIF] bypass on +g #10 + +cc VPOM4430::SDP::OMAP4430::CPU_SS::Cortex_1 + +# Configure DMM to allow SDRAM accesses during ELF load. +# DMM_LISA_MAP[0]: 0x80000000 mapped to 0x0 on SDRC0 (128MiB, no interleaving) +d 0x4E000100=0x80301000 + +#load up the u-boot,kernel and file system +[VPOM4430::SDP::OMAP4430::CPU_SS::Cortex_1]l 0x80300000 -bin <uImage PATH> +[VPOM4430::SDP::OMAP4430::CPU_SS::Cortex_1]l 0x81600000 -bin <ramfs PATH> +[VPOM4430::SDP::OMAP4430::CPU_SS::Cortex_1]l 0x80e80000 -bin <u-boot.bin PATH> + + +# PRCM setup +# WKUP Domain +dp 0x4a307800 = 0x3 +dp 0x4a307830 = 0x2 +dp 0x4a307838 = 0x102 +dp 0x4a307840 = 0x01000002 +dp 0x4a307858 = 0x2 +dp 0x4a307878 = 0x2 +dp 0x4a307880 = 0x1 + +# ABE Domain +dp 0x4A004500 = 0x3 +dp 0x4A004528 = 0x2 +dp 0x4A004530 = 0x2 +dp 0x4A004538 = 0x2 +dp 0x4A004540 = 0x2 +dp 0x4A004548 = 0x2 +dp 0x4A004550 = 0x2 +dp 0x4A004558 = 0x2 +dp 0x4A004560 = 0xf02 +dp 0x4A004568 = 0x2 +dp 0x4A004570 = 0x2 +dp 0x4A004578 = 0x2 +dp 0x4A004580 = 0x2 +dp 0x4A004588 = 0x2 + +# CORE Domain +# WakeUp Module domains +dp 0x4A008900 = 0x2 +dp 0x4A008a00 = 0x2 +dp 0x4A008b00 = 0x2 +dp 0x4A008c00 = 0x2 +dp 0x4A008900 = 0x3 + +# SDMA No Sleep!! +dp 0x4A008a00 = 0x0 +dp 0x4A008b00 = 0x3 +dp 0x4A008c00 = 0x3 +dp 0x4A008828 = 0x1 +dp 0x4A008920 = 0x1 + +# IVAHD Domain +dp 0x4A008F00 = 0x2 +dp 0x4A008F00 = 0x3 +dp 0x4A008F20 = 0x1 +dp 0x4A008F28 = 0x1 + +# CAM Domain +dp 0x4A009000 = 0x2 +dp 0x4A009000 = 0x3 +dp 0x4A009020 = 0x102 +dp 0x4A009028 = 0x2 + +# DSS Domain +dp 0x4A009100 = 0x2 +dp 0x4A009100 = 0x3 +dp 0x4A009120 = 0xf02 +dp 0x4A009128 = 0x2 + +# GFX Domain +dp 0x4A009200 = 0x2 +dp 0x4A009200 = 0x3 +dp 0x4A009220 = 0x2 + +# L3INT Domain +dp 0x4A009300 = 0x3 +dp 0x4A009328 = 0x2 +dp 0x4A009330 = 0x2 +dp 0x4A009338 = 0x2 +dp 0x4A009340 = 0x102 +dp 0x4A009358 = 0xff02 +dp 0x4A009360 = 0x102 +dp 0x4A009368 = 0x712 +dp 0x4A009380 = 0x2 +dp 0x4A009388 = 0x2 +dp 0x4A009390 = 0x2 +dp 0x4A009398 = 0x2 +dp 0x4A0093A8 = 0x2 +dp 0x4A0093C0 = 0x2 +dp 0x4A0093C8 = 0x2 +dp 0x4A0093D0 = 0x2 +dp 0x4A0093E0 = 0x2 + +# L4PER Domain +dp 0x4A009400 = 0x2 +dp 0x4A009580 = 0x2 +dp 0x4A009400 = 0x3 +dp 0x4A009580 = 0x3 +dp 0x4A009420 = 0x2 +dp 0x4A009428 = 0x2 +dp 0x4A009430 = 0x2 +dp 0x4A009438 = 0x2 +dp 0x4A009440 = 0x2 +dp 0x4A009448 = 0x2 +dp 0x4A009450 = 0x2 +dp 0x4A009458 = 0x2 +dp 0x4A009460 = 0x102 +dp 0x4A009468 = 0x102 +dp 0x4A009470 = 0x102 +dp 0x4A009478 = 0x102 +dp 0x4A009480 = 0x102 +dp 0x4A009488 = 0x2 +dp 0x4A009490 = 0x2 +dp 0x4A009498 = 0x2 +dp 0x4A0094A0 = 0x2 +dp 0x4A0094A8 = 0x2 +dp 0x4A0094B0 = 0x2 +dp 0x4A0094B8 = 0x2 +dp 0x4A0094D0 = 0x2 +dp 0x4A0094D8 = 0x2 +dp 0x4A0094E0 = 0x2 +dp 0x4A0094E8 = 0x2 +dp 0x4A0094F0 = 0x2 +dp 0x4A0094F8 = 0x2 +dp 0x4A009500 = 0x2 +dp 0x4A009508 = 0x2 +dp 0x4A009520 = 0x2 +dp 0x4A009528 = 0x2 +dp 0x4A009530 = 0x2 +dp 0x4A009538 = 0x702 +dp 0x4A009540 = 0x2 +dp 0x4A009548 = 0x2 +dp 0x4A009550 = 0x2 +dp 0x4A009558 = 0x2 +dp 0x4A009560 = 0x2 +dp 0x4A0095A0 = 0x2 +dp 0x4A0095A8 = 0x2 +dp 0x4A0095B0 = 0x2 +dp 0x4A0095B8 = 0x2 +dp 0x4A0095C0 = 0x2 +dp 0x4A0095C8 = 0x2 + +#Route UART1 signals +dp 0x4a10013C = 0x00010001 + +#Mux configuration for Keypad +dp 0x4A100188 = 0x01010101 +dp 0x4A10018C = 0x01010101 +dp 0x4A100190 = 0x01010101 + +dp 0x4A10017C = 0x01010101 +dp 0x4A100180 = 0x01010101 +dp 0x4A100184 = 0x01010101 + +#Route GPIO11 for Phoenix AudioCodec PowerUp +dp 0x4a31E084 = 0x01080003 + +# EMIF firewall bypass mode can now be turned off +[VPOM4430::SDP::OMAP4430::L3FW_EMIF] bypass off + +# Open up the EMIF and OCMRAM firewalls to all accessors before anything runs +d 0x4a20c08c=0xffffffff +d 0x4a21208c=0xffffffff +d 0x4a22808c=0xffffffff + +[VPOM4430::SDP::OMAP4430::CPU_SS::Cortex_1]r r15=0x80e80000 +[VPOM4430::SDP::OMAP4430::CPU_SS::Cortex_2]r r15=0x80e80000 +g + +------------------------- [End of Native Apps.script]--------------------------- + +3.8 Running Linux kernel + +The kernel binary used will be arch/arm/boot/uImage. + + +3.8.1 Loading the kernel image via Virtio +Note that the new NativeApp.script can load the kernel image & file sytem +image. + +Just give below command on u-boot prompt. + bootm 0x80300000 +You should see the kernel booting and ramdisk getting loaded in a few seconds + +3.8.2 Loading the kernel image via Trace32 + +Launch the T32. If console window is already running t32.cmm script is +automatically run and you will be attached to the system. If not you will have +to manually run t32.cmm script file. +Break the system through t32 +Use the following commands from T32 window to load up the kernel image and +file system + Data.load.binary <your Image path>/Image 0x80300000 + Data.load.binary <your ramdisk path> 0x81600000 + r r15=0x80e80054 + +Select 'go' in the T32 window +Go to the hyper terminal and execute the following + +>bootm 0x80300000 + +You should see the kernel booting and ramdisk getting loaded in a few seconds + +NOTE: The kernel binary used is arch/arm/boot/uImage and + not arch/arm/boot/Image. + + +4. Features +----------- + +4.1 New Features + + MMC/eMMC/SD + Tiler + +4.2 Supported Features + +- Boot-loader: + U-boot from RAM + +- OS Kernel + SMP Kernel with GIC, LOCAL timer support. + GP-Timers + 32 KHz Sync timer + Watchdog timer + I2C + DMA + GPIO + McBSP + McSPI + Console UART (Uart 1, Uart 2, Uart 3,Uart 4) + Phoenix Regulator + Phoenix core + RTC + KEYPAD + MMC/eMMC/SD + +- Power related + Clock nodes in PRM/CM1/CM2 modules modelled. + Clock nodes for ABE/PER/CORE/MPU/DSP/UNIPRO DPLL's modelled. + Not present: + USB DPLL not modelled + None of the DPLL set_rate and recalc functions are implemented. + +-Audio + Added Audio Backend playback support with MM interface + Added TWL6030 ALSA SoC codec driver + Support for Low Power and High Performance modes of TWL6030 codec + Basic support for audio interrupt: power-up sequence completion + Added McPDM base and SoC platform drivers + Added SDP4430 ALSA SoC machine driver + Additional Comments: + - Supported 44.1/48 kHz signed 32-bits LE format + - twl6030 i2c bus 1 speed was reduced to 400 kbits/s to match codec + requirements + NOTE: Audio support is disabled in SDP4430 kernel defconfig due to the + requirement of an additional license for dMACe component in Virtio, + which is used as a part of Audio Backend. + +-Video + Basic Frame Buffer support. + +-Display + Tiler + +4.3 Postponed Features + +None + + +4.4 Future Planned Features + +Refer to Program schedule. + + +4.5 Defects Fixed in This Release + +None + +4.6 Open Defects + +None + + +4.7 Open Change Requests + +None + + +4.8 Rejected Defects + +None + + +4.9 Postponed Defects + +None + +4.10 Limitations + +None + + +5. Tool Chain +------------- +The toolchain used to build the code can be obtained from CodeSourcery at the +following URL: + http://www.codesourcery.com/gnu_toolchains/arm/portal/release644 + +The tool chain version is Sourcery G++ Lite 2008q3-72 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/TI_OMAP4_Syslink_Release_Notes_L24.x.txt b/TI_OMAP4_Syslink_Release_Notes_L24.x.txt index a2c4af79b4b8..c7b71561e04b 100755 --- a/TI_OMAP4_Syslink_Release_Notes_L24.x.txt +++ b/TI_OMAP4_Syslink_Release_Notes_L24.x.txt @@ -554,5 +554,3 @@ Features Introduced -- Basic Tesla Bridge samples (both static and dynamic) have been validated. -- Basic Ducati Syslink IPC (Notify, MessageQ) and RCM samples have been validated. -- TILER sample validated with the latest Tiler drop - -
\ No newline at end of file diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 6530e394922d..93232d87579f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1477,6 +1477,8 @@ source "drivers/uio/Kconfig" source "drivers/staging/Kconfig" +source "drivers/media/video/tiler/Kconfig" + source "drivers/dsp/syslink/Kconfig" source "drivers/dsp/bridge/Kconfig" diff --git a/arch/arm/configs/omap3_pandora_defconfig b/arch/arm/configs/omap3_pandora_defconfig index b54ad2e2da36..3c962be8b8e3 100644 --- a/arch/arm/configs/omap3_pandora_defconfig +++ b/arch/arm/configs/omap3_pandora_defconfig @@ -1049,7 +1049,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8583 is not set # CONFIG_RTC_DRV_M41T80 is not set -CONFIG_RTC_DRV_TWL4030=y +CONFIG_RTC_DRV_TWL=y # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8581 is not set diff --git a/arch/arm/configs/omap_3430sdp_defconfig b/arch/arm/configs/omap_3430sdp_defconfig index 23df1fe7573f..4942ab1d0ff3 100644 --- a/arch/arm/configs/omap_3430sdp_defconfig +++ b/arch/arm/configs/omap_3430sdp_defconfig @@ -1632,7 +1632,7 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8583 is not set # CONFIG_RTC_DRV_M41T80 is not set -CONFIG_RTC_DRV_TWL4030=y +CONFIG_RTC_DRV_TWL=y # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8581 is not set diff --git a/arch/arm/configs/omap_4430sdp_defconfig b/arch/arm/configs/omap_4430sdp_defconfig index a767a61a1b57..5c0efaf1e2eb 100644 --- a/arch/arm/configs/omap_4430sdp_defconfig +++ b/arch/arm/configs/omap_4430sdp_defconfig @@ -110,6 +110,9 @@ CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y CONFIG_STOP_MACHINE=y CONFIG_BLOCK=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +CONFIG_MMC_OMAP_HS=y # CONFIG_LBD is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -183,8 +186,8 @@ CONFIG_ARCH_OMAP4=y # OMAP Feature Selections # # CONFIG_OMAP_RESET_CLOCKS is not set -# CONFIG_OMAP_MUX is not set -# CONFIG_OMAP_MCBSP 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 @@ -374,7 +377,8 @@ CONFIG_INPUT_EVDEV=y # # Input Device Drivers # -# CONFIG_INPUT_KEYBOARD is not set +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 @@ -425,10 +429,14 @@ CONFIG_HW_RANDOM=y # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set -# CONFIG_I2C is not set -# CONFIG_SPI 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 @@ -439,7 +447,9 @@ CONFIG_GPIOLIB=y # # I2C GPIO expanders: # - +CONFIG_I2C_OMAP=y +CONFIG_SPI_OMAP24XX=y +CONFIG_SPI_MASTER=y # # PCI GPIO expanders: # @@ -452,13 +462,14 @@ CONFIG_GPIOLIB=y # CONFIG_HWMON is not set # CONFIG_THERMAL is not set # CONFIG_THERMAL_HWMON is not set -# CONFIG_WATCHDOG is not set -CONFIG_SSB_POSSIBLE=y +CONFIG_WATCHDOG=y +CONFIG_OMAP_WATCHDOG=y # # Sonics Silicon Backplane # # CONFIG_SSB is not set +CONFIG_SSB_POSSIBLE=y # # Multifunction device drivers @@ -472,6 +483,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_T7L66XB is not set # CONFIG_MFD_TC6387XB is not set # CONFIG_MFD_TC6393XB is not set +CONFIG_TWL6030_CORE=y # # Multimedia devices @@ -493,28 +505,133 @@ CONFIG_DAB=y # # CONFIG_VGASTATE is not set # CONFIG_VIDEO_OUTPUT_CONTROL is not set -# CONFIG_FB is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set +CONFIG_OMAP2_DSS=y +CONFIG_OMAP2_DSS_VRAM_SIZE=4 +CONFIG_OMAP2_DSS_DEBUG_SUPPORT=y +# CONFIG_OMAP2_DSS_RFBI is not set +# CONFIG_OMAP2_DSS_VENC is not set +# CONFIG_OMAP2_DSS_FAKE_VSYNC is not set +CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=0 + +# +# OMAP2/3 Display Device Drivers +# +# CONFIG_PANEL_GENERIC is not set +# CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C is not set +# CONFIG_PANEL_SHARP_LS037V7DW01 is not set +# CONFIG_PANEL_N800 is not set +# CONFIG_CTRL_BLIZZARD is not set +CONFIG_LCD_4430SDP=y +CONFIG_FB_OMAP2=y +CONFIG_FB_OMAP2_DEBUG_SUPPORT=y +# CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE is not set +CONFIG_FB_OMAP2_NUM_FBS=3 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Display device support # -# CONFIG_DISPLAY_SUPPORT is not set +CONFIG_DISPLAY_SUPPORT=y + +# +# Display hardware drivers +# # # Console display driver support # # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y +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_SND_OMAP_SOC_ABE=y +CONFIG_SND_OMAP_SOC_SDP4430=y +CONFIG_SND_SOC_I2C_AND_SPI=y +# CONFIG_SND_SOC_ALL_CODECS is not set +CONFIG_SND_SOC_ABE_TWL6030=y +# CONFIG_SOUND_PRIME is not set +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y # CONFIG_SOUND is not set # CONFIG_HID_SUPPORT is not set # CONFIG_USB_SUPPORT is not set -# CONFIG_MMC is not set +CONFIG_MMC=y # CONFIG_MEMSTICK is not set # CONFIG_ACCESSIBILITY is not set # CONFIG_NEW_LEDS is not set CONFIG_RTC_LIB=y -# CONFIG_RTC_CLASS is not set +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_TWL=y # CONFIG_DMADEVICES is not set # CONFIG_AUXDISPLAY is not set # CONFIG_REGULATOR is not set diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index ed2a48a9ce74..45fc2ae2d2a6 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c @@ -19,6 +19,7 @@ #include <linux/spi/ads7846.h> #include <linux/workqueue.h> #include <linux/delay.h> +#include <linux/omapfb.h> #include <mach/hardware.h> #include <asm/mach-types.h> @@ -32,7 +33,6 @@ #include <mach/keypad.h> #include <mach/common.h> #include <mach/dsp_common.h> -#include <mach/omapfb.h> #include <mach/hwa742.h> #include <mach/lcd_mipid.h> #include <mach/mmc.h> diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 9e062c134be4..75bfb2b687c1 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -3,11 +3,11 @@ # # Common support -obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o +obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o clock.o prcm.o omap-2-3-common = irq.o sdrc.o -prcm-common = prcm.o powerdomain.o -clock-common = clock.o clockdomain.o +prcm-common = powerdomain.o +clock-common = clockdomain.o obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(clock-common) obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(prcm-common) $(clock-common) @@ -38,6 +38,7 @@ endif # Clock framework obj-$(CONFIG_ARCH_OMAP2) += clock24xx.o obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o +obj-$(CONFIG_ARCH_OMAP4) += clock44xx.o # MAILBOX obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox_mach.o @@ -74,8 +75,8 @@ obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom2.o \ mmc-twl4030.o \ board-zoom-debugboard.o -obj-$(CONFIG_MACH_OMAP_4430SDP) += board-4430sdp.o - +obj-$(CONFIG_MACH_OMAP_4430SDP) += board-4430sdp.o \ + mmc-twl4030.o # Platform specific device init code obj-y += usb-musb.o diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c index 9c3fdcdf76c3..fa3479809ead 100644 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ b/arch/arm/mach-omap2/board-2430sdp.c @@ -19,7 +19,7 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <linux/delay.h> -#include <linux/i2c/twl4030.h> +#include <linux/i2c/twl.h> #include <linux/err.h> #include <linux/clk.h> #include <linux/io.h> @@ -156,13 +156,13 @@ static struct omap_board_config_kernel sdp2430_config[] = { }; -static struct twl4030_gpio_platform_data sdp2430_gpio_data = { +static struct twl_gpio_platform_data sdp2430_gpio_data = { .gpio_base = OMAP_MAX_GPIO_LINES, .irq_base = TWL4030_GPIO_IRQ_BASE, .irq_end = TWL4030_GPIO_IRQ_END, }; -static struct twl4030_platform_data sdp2430_twldata = { +static struct twl_platform_data sdp2430_twldata = { .irq_base = TWL4030_IRQ_BASE, .irq_end = TWL4030_IRQ_END, diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index 496a90e4ea7a..85193d7359a3 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c @@ -19,7 +19,7 @@ #include <linux/input.h> #include <linux/spi/spi.h> #include <linux/spi/ads7846.h> -#include <linux/i2c/twl4030.h> +#include <linux/i2c/twl.h> #include <linux/regulator/machine.h> #include <linux/io.h> #include <linux/gpio.h> @@ -88,7 +88,7 @@ static int sdp3430_keymap[] = { 0 }; -static struct twl4030_keypad_data sdp3430_kp_data = { +static struct twl_keypad_data sdp3430_kp_data = { .rows = 5, .cols = 6, .keymap = sdp3430_keymap, @@ -198,7 +198,7 @@ static int sdp3430_batt_table[] = { 4040, 3910, 3790, 3670, 3550 }; -static struct twl4030_bci_platform_data sdp3430_bci_data = { +static struct twl_bci_platform_data sdp3430_bci_data = { .battery_tmp_tbl = sdp3430_batt_table, .tblsize = ARRAY_SIZE(sdp3430_batt_table), }; @@ -260,7 +260,7 @@ static int sdp3430_twl_gpio_setup(struct device *dev, return 0; } -static struct twl4030_gpio_platform_data sdp3430_gpio_data = { +static struct twl_gpio_platform_data sdp3430_gpio_data = { .gpio_base = OMAP_MAX_GPIO_LINES, .irq_base = TWL4030_GPIO_IRQ_BASE, .irq_end = TWL4030_GPIO_IRQ_END, @@ -269,11 +269,11 @@ static struct twl4030_gpio_platform_data sdp3430_gpio_data = { .setup = sdp3430_twl_gpio_setup, }; -static struct twl4030_usb_data sdp3430_usb_data = { +static struct twl_usb_data sdp3430_usb_data = { .usb_mode = T2_USB_MODE_ULPI, }; -static struct twl4030_madc_platform_data sdp3430_madc_data = { +static struct twl_madc_platform_data sdp3430_madc_data = { .irq_line = 1, }; @@ -409,7 +409,7 @@ static struct regulator_init_data sdp3430_vpll2 = { .consumer_supplies = &sdp3430_vdvi_supply, }; -static struct twl4030_platform_data sdp3430_twldata = { +static struct twl_platform_data sdp3430_twldata = { .irq_base = TWL4030_IRQ_BASE, .irq_end = TWL4030_IRQ_END, diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index 57e477bd89c6..038a21e2011f 100644..100755 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -17,35 +17,159 @@ #include <linux/platform_device.h> #include <linux/io.h> #include <linux/gpio.h> +#include <linux/spi/spi.h> +#include <linux/input.h> +#include <mach/keypad.h> #include <mach/hardware.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> +#include <mach/mux.h> +#include <mach/display.h> +#include <mach/mcspi.h> #include <mach/board.h> #include <mach/common.h> #include <mach/control.h> #include <mach/timer-gp.h> #include <asm/hardware/gic.h> +#include <linux/i2c/twl.h> +#include "mmc-twl4030.h" +#include <linux/regulator/machine.h> -static struct platform_device sdp4430_lcd_device = { - .name = "sdp4430_lcd", +#define OMAP4_KBDOCP_BASE 0x4A31C000 + +static int ts_gpio; + +static int omap_keymap[] = { + KEY(0, 0, KEY_SENDFILE), + KEY(0, 1, KEY_1), + KEY(0, 2, KEY_4), + KEY(0, 3, KEY_7), + KEY(1, 0, KEY_END), + KEY(1, 1, KEY_2), + KEY(1, 2, KEY_5), + KEY(1, 3, KEY_8), + KEY(1, 4, KEY_0), + KEY(2, 1, KEY_3), + KEY(2, 2, KEY_6), + KEY(2, 3, KEY_9), + KEY(3, 1, KEY_HOME), + KEY(3, 2, KEY_BACK), + KEY(3, 3, KEY_VOLUMEUP), + KEY(3, 4, KEY_VOLUMEDOWN), + KEY(4, 0, KEY_UP), + KEY(4, 1, KEY_RIGHT), + KEY(4, 2, KEY_LEFT), + KEY(4, 3, KEY_DOWN), + KEY(0, 4, KEY_DOT), + KEY(2, 4, KEY_LEFT), + KEY(4, 4, KEY_ENTER), + KEY(5, 0, KEY_SCROLLUP), + KEY(5, 1, KEY_SCROLLDOWN), + KEY(5, 2, KEY_RIGHT), + KEY(5, 3, KEY_RECORD), + 0, +}; + +static struct resource omap_kp_resources[] = { + [0] = { + .start = OMAP4_KBDOCP_BASE, + .end = OMAP4_KBDOCP_BASE, + .flags = IORESOURCE_MEM, + }, +}; + +static struct omap_kp_platform_data omap_kp_data = { + .rows = 5, + .cols = 6, + .keymap = omap_keymap, + .keymapsize = ARRAY_SIZE(omap_keymap), + .delay = 4, + .rep = 1, +}; + +static struct platform_device omap_kp_device = { + .name = "omap-keypad", .id = -1, + .dev = { + .platform_data = &omap_kp_data, + }, + .num_resources = ARRAY_SIZE(omap_kp_resources), + .resource = omap_kp_resources, }; -static struct platform_device *sdp4430_devices[] __initdata = { - &sdp4430_lcd_device, +static struct omap2_mcspi_device_config tsc2046_mcspi_config = { + .turbo_mode = 0, + .single_channel = 1, /* 0: slave, 1: master */ }; -static struct omap_uart_config sdp4430_uart_config __initdata = { - .enabled_uarts = (1 << 0) | (1 << 1) | (1 << 2), +static struct omap2_mcspi_device_config dummy1_mcspi_config = { + .turbo_mode = 0, + .single_channel = 1, /* 0: slave, 1: master */ }; +#ifdef CONFIG_SPI_TI_OMAP_TEST +static struct omap2_mcspi_device_config dummy2_mcspi_config = { + .turbo_mode = 0, + .single_channel = 0, /* 0: slave, 1: master */ +}; +#endif + static struct omap_lcd_config sdp4430_lcd_config __initdata = { .ctrl_name = "internal", }; +static int sdp4430_panel_enable_lcd(void) +{ + return 0; +} + +static int sdp4430_panel_disable_lcd(void) +{ + return 0; +} + +static void __init sdp4430_display_init(void) +{ + return; +} +static struct omap_dss_device sdp4430_lcd_device = { + .name = "sdp4430_lcd", + .driver_name = "sdp4430_panel", + .type = OMAP_DISPLAY_TYPE_DPI, + .phy.dpi.data_lines = 16, + .platform_enable = sdp4430_panel_enable_lcd, + .platform_disable = sdp4430_panel_disable_lcd, +}; + +static struct omap_dss_device *sdp4430_dss_devices[] = { + &sdp4430_lcd_device, +}; +static struct omap_dss_board_info sdp4430_dss_data = { + .num_devices = ARRAY_SIZE(sdp4430_dss_devices), + .devices = sdp4430_dss_devices, + .default_device = &sdp4430_lcd_device, +}; +static struct platform_device sdp4430_dss_device = { + .name = "omapdss", + .id = -1, + .dev = { + .platform_data = &sdp4430_dss_data, + }, +}; + +static struct platform_device *sdp4430_devices[] __initdata = { + &sdp4430_dss_device, + &omap_kp_device, +}; + +static struct omap_uart_config sdp4430_uart_config __initdata = { + .enabled_uarts = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3), +}; + + static struct omap_board_config_kernel sdp4430_config[] __initdata = { { OMAP_TAG_UART, &sdp4430_uart_config }, { OMAP_TAG_LCD, &sdp4430_lcd_config }, @@ -57,6 +181,66 @@ static void __init gic_init_irq(void) gic_cpu_init(0, IO_ADDRESS(OMAP44XX_GIC_CPU_BASE)); } +static struct spi_board_info sdp4430_spi_board_info[] __initdata = { + [0] = { + .modalias = "spitst", + .bus_num = 1, + .chip_select = 0, + .max_speed_hz = 1500000, + }, + [1] = { + .modalias = "ads7846", + .bus_num = 1, + .chip_select = 0, + .max_speed_hz = 1500000, + }, +#ifdef CONFIG_SPI_TI_OMAP_TEST + [2] = { + .modalias = "spidev", + .bus_num = 3, + .chip_select = 0, + .max_speed_hz = 6000000, + .controller_data = &dummy2_mcspi_config, /* Slave */ + }, + [3] = { + .modalias = "dummydevice1", + .bus_num = 2, + .chip_select = 0, + .max_speed_hz = 1500000, + .controller_data = &dummy1_mcspi_config, /*Master */ + }, +#endif +}; + +static struct twl4030_hsmmc_info mmc[] = { + { + .mmc = 1, + /* 8 bits (default) requires S6.3 == ON, + * so the SIM card isn't used; else 4 bits. + */ + .wires = 8, + .gpio_wp = 4, + }, + {} /* Terminator */ +}; + +static struct regulator_consumer_supply sdp4430_vmmc_supply = { + .supply = "vmmc", +}; + +static int __init sdp4430_mmc_init(void) +{ + /* Hard Coding Values for testing */ + printk(KERN_INFO"sdp4430_mmc_init\n"); + mmc[0].gpio_cd = 373; + twl4030_mmc_init(mmc); + /* link regulators to MMC adapters ... we "know" the + * regulators will be set up only *after* we return. + */ + sdp4430_vmmc_supply.dev = mmc[0].dev; + return 0; +} + static void __init omap_4430sdp_init_irq(void) { omap2_init_common_hw(NULL); @@ -67,13 +251,232 @@ static void __init omap_4430sdp_init_irq(void) omap_gpio_init(); } +#ifdef CONFIG_TWL6030_CORE +static struct regulator_init_data sdp4430_vaux1 = { + .constraints = { + .min_uV = 1000000, + .max_uV = 3000000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct regulator_init_data sdp4430_vaux2 = { + .constraints = { + .min_uV = 1200000, + .max_uV = 2800000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct regulator_init_data sdp4430_vaux3 = { + .constraints = { + .min_uV = 1000000, + .max_uV = 3000000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct regulator_init_data sdp4430_vmmc = { + .constraints = { + .min_uV = 1200000, + .max_uV = 3000000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &sdp4430_vmmc_supply, +}; + +static struct regulator_init_data sdp4430_vpp = { + .constraints = { + .min_uV = 1800000, + .max_uV = 2500000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct regulator_init_data sdp4430_vusim = { + .constraints = { + .min_uV = 1200000, + .max_uV = 2900000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct regulator_init_data sdp4430_vana = { + .constraints = { + .min_uV = 2100000, + .max_uV = 2100000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct regulator_init_data sdp4430_vcxio = { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct regulator_init_data sdp4430_vdac = { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct regulator_init_data sdp4430_vusb = { + .constraints = { + .min_uV = 3300000, + .max_uV = 3300000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct twl_platform_data sdp4430_twldata = { + .irq_base = TWL6030_IRQ_BASE, + .irq_end = TWL6030_IRQ_END, + + /* Regulators */ + .vmmc = &sdp4430_vmmc, + .vpp = &sdp4430_vpp, + .vusim = &sdp4430_vusim, + .vana = &sdp4430_vana, + .vcxio = &sdp4430_vcxio, + .vdac = &sdp4430_vdac, + .vusb = &sdp4430_vusb, + .vaux1 = &sdp4430_vaux1, + .vaux2 = &sdp4430_vaux2, + .vaux3 = &sdp4430_vaux3, +}; +#endif + +static struct i2c_board_info __initdata sdp4430_i2c_boardinfo[] = { + { + I2C_BOARD_INFO("twl6030", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = INT_44XX_SYS_NIRQ, +#ifdef CONFIG_TWL6030_CORE + .platform_data = &sdp4430_twldata, +#endif + }, +}; + +static int __init omap4_i2c_init(void) +{ + omap_register_i2c_bus(1, 400, sdp4430_i2c_boardinfo, + ARRAY_SIZE(sdp4430_i2c_boardinfo)); + omap_register_i2c_bus(2, 400, NULL, 0); + omap_register_i2c_bus(3, 400, NULL, 0); + return 0; +} +static void omap_mcbsp_init(void) +{ + omap_cfg_reg(AA3_4430_McBSP1_CLK); + omap_cfg_reg(Y3_4430_McBSP1_DR); + omap_cfg_reg(Y2_4430_McBSP1_DX); + omap_cfg_reg(Y4_4430_McBSP1_FSX); +} +void omap_kp_init(void) +{ + omap_cfg_reg(PAD0_4430_UNIPRO_TX0); + omap_cfg_reg(PAD1_4430_UNIPRO_TY0); + omap_cfg_reg(PAD0_4430_UNIPRO_TX1); + omap_cfg_reg(PAD1_4430_UNIPRO_TY1); + omap_cfg_reg(PAD0_4430_UNIPRO_TX2); + omap_cfg_reg(PAD1_4430_UNIPRO_TY2); + + omap_cfg_reg(PAD0_4430_UNIPRO_RX0); + omap_cfg_reg(PAD1_4430_UNIPRO_RY0); + omap_cfg_reg(PAD0_4430_UNIPRO_RX1); + omap_cfg_reg(PAD1_4430_UNIPRO_RY1); + omap_cfg_reg(PAD0_4430_UNIPRO_RX2); + omap_cfg_reg(PAD1_4430_UNIPRO_RY2); +} + +static void omap_abe_init(void) +{ + /* mcpdm */ + omap_cfg_reg(AG25_4430_ABE_PDM_UL_DATA); + omap_cfg_reg(AF25_4430_ABE_PDM_DL_DATA); + omap_cfg_reg(AE25_4430_ABE_PDM_FRAME); + omap_cfg_reg(AF26_4430_ABE_PDM_LB_CLK); + omap_cfg_reg(AH26_4430_ABE_PDM_CLKS); + + /* twl6030 audio power-on */ + omap_cfg_reg(AA27_4430_GPIO_127); +} + +static void omap_phoenix_init(void) +{ + omap_cfg_reg(PAD1_4430_SYS_NIRQ1); + omap_cfg_reg(PAD0_4430_SYS_NIRQ2); +} static void __init omap_4430sdp_init(void) { + omap4_i2c_init(); platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices)); omap_board_config = sdp4430_config; omap_board_config_size = ARRAY_SIZE(sdp4430_config); omap_serial_init(); + sdp4430_spi_board_info[0].irq = OMAP_GPIO_IRQ(ts_gpio); + spi_register_board_info(sdp4430_spi_board_info, + ARRAY_SIZE(sdp4430_spi_board_info)); + omap_mcbsp_init(); + sdp4430_mmc_init(); + sdp4430_display_init(); + omap_kp_init(); + omap_abe_init(); + omap_phoenix_init(); + } static void __init omap_4430sdp_map_io(void) diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c index d8bc0a7dcb8d..eb910565b5d1 100644 --- a/arch/arm/mach-omap2/board-ldp.c +++ b/arch/arm/mach-omap2/board-ldp.c @@ -23,7 +23,7 @@ #include <linux/spi/spi.h> #include <linux/spi/ads7846.h> #include <linux/regulator/machine.h> -#include <linux/i2c/twl4030.h> +#include <linux/i2c/twl.h> #include <linux/io.h> #include <linux/smsc911x.h> @@ -101,7 +101,7 @@ static int ldp_twl4030_keymap[] = { 0 }; -static struct twl4030_keypad_data ldp_kp_twl4030_data = { +static struct twl_keypad_data ldp_kp_twl4030_data = { .rows = 6, .cols = 6, .keymap = ldp_twl4030_keymap, @@ -294,17 +294,17 @@ static struct omap_board_config_kernel ldp_config[] __initdata = { { OMAP_TAG_LCD, &ldp_lcd_config }, }; -static struct twl4030_usb_data ldp_usb_data = { +static struct twl_usb_data ldp_usb_data = { .usb_mode = T2_USB_MODE_ULPI, }; -static struct twl4030_gpio_platform_data ldp_gpio_data = { +static struct twl_gpio_platform_data ldp_gpio_data = { .gpio_base = OMAP_MAX_GPIO_LINES, .irq_base = TWL4030_GPIO_IRQ_BASE, .irq_end = TWL4030_GPIO_IRQ_END, }; -static struct twl4030_madc_platform_data ldp_madc_data = { +static struct twl_madc_platform_data ldp_madc_data = { .irq_line = 1, }; @@ -327,7 +327,7 @@ static struct regulator_init_data ldp_vmmc1 = { .consumer_supplies = &ldp_vmmc1_supply, }; -static struct twl4030_platform_data ldp_twldata = { +static struct twl_platform_data ldp_twldata = { .irq_base = TWL4030_IRQ_BASE, .irq_end = TWL4030_IRQ_END, diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 991ac9c38032..ca6bebd731d9 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -29,7 +29,7 @@ #include <linux/mtd/nand.h> #include <linux/regulator/machine.h> -#include <linux/i2c/twl4030.h> +#include <linux/i2c/twl.h> #include <mach/hardware.h> #include <asm/mach-types.h> @@ -169,7 +169,7 @@ static int beagle_twl_gpio_setup(struct device *dev, return 0; } -static struct twl4030_gpio_platform_data beagle_gpio_data = { +static struct twl_gpio_platform_data beagle_gpio_data = { .gpio_base = OMAP_MAX_GPIO_LINES, .irq_base = TWL4030_GPIO_IRQ_BASE, .irq_end = TWL4030_GPIO_IRQ_END, @@ -249,7 +249,7 @@ static struct regulator_init_data beagle_vpll2 = { .consumer_supplies = &beagle_vdvi_supply, }; -static struct twl4030_platform_data beagle_twldata = { +static struct twl_platform_data beagle_twldata = { .irq_base = TWL4030_IRQ_BASE, .irq_end = TWL4030_IRQ_END, diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index e32aa23ce962..046964fc0ccf 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c @@ -24,7 +24,7 @@ #include <linux/spi/spi.h> #include <linux/spi/ads7846.h> #include <linux/regulator/machine.h> -#include <linux/i2c/twl4030.h> +#include <linux/i2c/twl.h> #include <linux/leds.h> #include <linux/input.h> #include <linux/gpio_keys.h> @@ -179,7 +179,7 @@ static int pandora_keypad_map[] = { KEY(5, 2, KEY_FN), }; -static struct twl4030_keypad_data pandora_kp_data = { +static struct twl_keypad_data pandora_kp_data = { .rows = 8, .cols = 6, .keymap = pandora_keypad_map, @@ -239,7 +239,7 @@ static int omap3pandora_twl_gpio_setup(struct device *dev, return 0; } -static struct twl4030_gpio_platform_data omap3pandora_gpio_data = { +static struct twl_gpio_platform_data omap3pandora_gpio_data = { .gpio_base = OMAP_MAX_GPIO_LINES, .irq_base = TWL4030_GPIO_IRQ_BASE, .irq_end = TWL4030_GPIO_IRQ_END, @@ -276,11 +276,11 @@ static struct regulator_init_data pandora_vmmc2 = { .consumer_supplies = &pandora_vmmc2_supply, }; -static struct twl4030_usb_data omap3pandora_usb_data = { +static struct twl_usb_data omap3pandora_usb_data = { .usb_mode = T2_USB_MODE_ULPI, }; -static struct twl4030_platform_data omap3pandora_twldata = { +static struct twl_platform_data omap3pandora_twldata = { .irq_base = TWL4030_IRQ_BASE, .irq_end = TWL4030_IRQ_END, .gpio = &omap3pandora_gpio_data, diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c index dff5528fbfb5..de9d516dd53c 100644 --- a/arch/arm/mach-omap2/board-overo.c +++ b/arch/arm/mach-omap2/board-overo.c @@ -26,7 +26,7 @@ #include <linux/io.h> #include <linux/kernel.h> #include <linux/platform_device.h> -#include <linux/i2c/twl4030.h> +#include <linux/i2c/twl.h> #include <linux/regulator/machine.h> #include <linux/mtd/mtd.h> @@ -305,14 +305,14 @@ static int overo_twl_gpio_setup(struct device *dev, return 0; } -static struct twl4030_gpio_platform_data overo_gpio_data = { +static struct twl_gpio_platform_data overo_gpio_data = { .gpio_base = OMAP_MAX_GPIO_LINES, .irq_base = TWL4030_GPIO_IRQ_BASE, .irq_end = TWL4030_GPIO_IRQ_END, .setup = overo_twl_gpio_setup, }; -static struct twl4030_usb_data overo_usb_data = { +static struct twl_usb_data overo_usb_data = { .usb_mode = T2_USB_MODE_ULPI, }; @@ -332,7 +332,7 @@ static struct regulator_init_data overo_vmmc1 = { /* mmc2 (WLAN) and Bluetooth don't use twl4030 regulators */ -static struct twl4030_platform_data overo_twldata = { +static struct twl_platform_data overo_twldata = { .irq_base = TWL4030_IRQ_BASE, .irq_end = TWL4030_IRQ_END, .gpio = &overo_gpio_data, diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index b0665f161c03..05a7f795c932 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -150,6 +150,7 @@ static int _dpll_test_fint(struct clk *clk, u8 n) * clockdomain pointer, and save it into the struct clk. Intended to be * called during clk_register(). No return value. */ +#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once clkdm f/w is in place */ void omap2_init_clk_clkdm(struct clk *clk) { struct clockdomain *clkdm; @@ -167,6 +168,7 @@ void omap2_init_clk_clkdm(struct clk *clk) "clkdm %s\n", clk->name, clk->clkdm_name); } } +#endif /** * omap2_init_clksel_parent - set a clksel clk's parent field from the hardware @@ -435,8 +437,10 @@ void omap2_clk_disable(struct clk *clk) _omap2_clk_disable(clk); if (clk->parent) omap2_clk_disable(clk->parent); +#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once clkdm f/w is in place */ if (clk->clkdm) omap2_clkdm_clk_disable(clk->clkdm, clk); +#endif } } @@ -446,8 +450,10 @@ int omap2_clk_enable(struct clk *clk) int ret = 0; if (clk->usecount++ == 0) { +#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once clkdm f/w is in place */ if (clk->clkdm) omap2_clkdm_clk_enable(clk->clkdm, clk); +#endif if (clk->parent) { ret = omap2_clk_enable(clk->parent); @@ -466,8 +472,10 @@ int omap2_clk_enable(struct clk *clk) return ret; err: +#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once clkdm f/w is in place */ if (clk->clkdm) omap2_clkdm_clk_disable(clk->clkdm, clk); +#endif clk->usecount--; return ret; } diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index 2679ddfa6424..460874ab766f 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h @@ -74,11 +74,13 @@ extern u8 cpu_mask; /* clksel_rate data common to 24xx/343x */ static const struct clksel_rate gpt_32k_rates[] = { { .div = 1, .val = 0, .flags = RATE_IN_24XX | RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 1, .flags = RATE_IN_443X | DEFAULT_RATE }, { .div = 0 } }; static const struct clksel_rate gpt_sys_rates[] = { { .div = 1, .val = 1, .flags = RATE_IN_24XX | RATE_IN_343X | DEFAULT_RATE }, + { .div = 1, .val = 0, .flags = RATE_IN_443X | DEFAULT_RATE }, { .div = 0 } }; diff --git a/arch/arm/mach-omap2/clock24xx.c b/arch/arm/mach-omap2/clock24xx.c index 44de0271fc2f..402a3d43faf9 100644 --- a/arch/arm/mach-omap2/clock24xx.c +++ b/arch/arm/mach-omap2/clock24xx.c @@ -103,10 +103,10 @@ static struct omap_clk omap24xx_clks[] = { CLK(NULL, "mdm_ick", &mdm_ick, CK_243X), CLK(NULL, "mdm_osc_ck", &mdm_osc_ck, CK_243X), /* DSS domain clocks */ - CLK("omapfb", "ick", &dss_ick, CK_243X | CK_242X), - CLK("omapfb", "dss1_fck", &dss1_fck, CK_243X | CK_242X), - CLK("omapfb", "dss2_fck", &dss2_fck, CK_243X | CK_242X), - CLK("omapfb", "tv_fck", &dss_54m_fck, CK_243X | CK_242X), + CLK("omapdss", "ick", &dss_ick, CK_243X | CK_242X), + CLK("omapdss", "dss1_fck", &dss1_fck, CK_243X | CK_242X), + CLK("omapdss", "dss2_fck", &dss2_fck, CK_243X | CK_242X), + CLK("omapdss", "tv_fck", &dss_54m_fck, CK_243X | CK_242X), /* L3 domain clocks */ CLK(NULL, "core_l3_ck", &core_l3_ck, CK_243X | CK_242X), CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_243X | CK_242X), diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c index 045da923e75b..dd7bba2d0571 100644 --- a/arch/arm/mach-omap2/clock34xx.c +++ b/arch/arm/mach-omap2/clock34xx.c @@ -200,11 +200,11 @@ static struct omap_clk omap34xx_clks[] = { CLK("omap_rng", "ick", &rng_ick, CK_343X), CLK(NULL, "sha11_ick", &sha11_ick, CK_343X), CLK(NULL, "des1_ick", &des1_ick, CK_343X), - CLK("omapfb", "dss1_fck", &dss1_alwon_fck, CK_343X), - CLK("omapfb", "tv_fck", &dss_tv_fck, CK_343X), - CLK("omapfb", "video_fck", &dss_96m_fck, CK_343X), - CLK("omapfb", "dss2_fck", &dss2_alwon_fck, CK_343X), - CLK("omapfb", "ick", &dss_ick, CK_343X), + CLK("omapdss", "dss1_fck", &dss1_alwon_fck, CK_343X), + CLK("omapdss", "tv_fck", &dss_tv_fck, CK_343X), + CLK("omapdss", "video_fck", &dss_96m_fck, CK_343X), + CLK("omapdss", "dss2_fck", &dss2_alwon_fck, CK_343X), + CLK("omapdss", "ick", &dss_ick, CK_343X), CLK(NULL, "cam_mclk", &cam_mclk, CK_343X), CLK(NULL, "cam_ick", &cam_ick, CK_343X), CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_343X), diff --git a/arch/arm/mach-omap2/clock44xx.c b/arch/arm/mach-omap2/clock44xx.c new file mode 100644 index 000000000000..462f4f3b024a --- /dev/null +++ b/arch/arm/mach-omap2/clock44xx.c @@ -0,0 +1,259 @@ +/* + * OMAP4-specific clock framework functions + * + * Copyright (C) 2009 Texas Instruments, Inc. + * + * Written by 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 version 2 as + * published by the Free Software Foundation. + */ +#undef DEBUG + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/device.h> +#include <linux/list.h> +#include <linux/errno.h> +#include <linux/delay.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/limits.h> +#include <linux/bitops.h> + +#include <mach/clock.h> +#include <mach/sram.h> +#include <asm/div64.h> +#include <asm/clkdev.h> + +#include <mach/sdrc.h> +#include "clock.h" +#include "prm.h" +#include "prm-regbits-44xx.h" +#include "cm.h" +#include "cm1-regbits-44xx.h" +#include "cm2-regbits-44xx.h" + +#include "clock44xx.h" + +struct omap_clk { + u32 cpu; + struct clk_lookup lk; +}; + +#define CLK(dev, con, ck, cp) \ + { \ + .cpu = cp, \ + .lk = { \ + .dev_id = dev, \ + .con_id = con, \ + .clk = ck, \ + }, \ + } + +#define CK_443X (1 << 0) + +static struct omap_clk omap44xx_clks[] = { + CLK(NULL, "omap_32k_fck", &omap_32k_fck, CK_443X), + CLK(NULL, "pad_cks", &pad_cks, CK_443X), + CLK(NULL, "slimbus_ck", &slimbus_ck, CK_443X), + CLK(NULL, "phy_clkout_ck", &phy_clkout_ck, CK_443X), + CLK(NULL, "xclk_60m_otg_ck", &xclk_60m_otg_ck, CK_443X), + CLK(NULL, "xclk_60m_hsp1_ck", &xclk_60m_hsp1_ck, CK_443X), + CLK(NULL, "xclk_60m_hsp2_ck", &xclk_60m_hsp2_ck, CK_443X), + CLK(NULL, "virt_12m_ck", &virt_12m_ck, CK_443X), + CLK(NULL, "virt_13m_ck", &virt_13m_ck, CK_443X), + CLK(NULL, "virt_19_2m_ck", &virt_19_2m_ck, CK_443X), + CLK(NULL, "virt_26m_ck", &virt_26m_ck, CK_443X), + CLK(NULL, "virt_27m_ck", &virt_27m_ck, CK_443X), + CLK(NULL, "virt_38_4m_ck", &virt_38_4m_ck, CK_443X), + CLK(NULL, "sys_ck", &sys_ck, CK_443X), + CLK(NULL, "abe_dss_sys_ck", &abe_dss_sys_ck, CK_443X), + CLK(NULL, "dpll_sys_ref_ck", &dpll_sys_ref_ck, CK_443X), + CLK(NULL, "abe_dpll_alwon_ck", &abe_dpll_alwon_ck, CK_443X), + CLK(NULL, "gpt1_fck", &gpt1_fck, CK_443X), + CLK(NULL, "gpt2_fck", &gpt2_fck, CK_443X), + CLK(NULL, "gpt3_fck", &gpt3_fck, CK_443X), + CLK(NULL, "gpt4_fck", &gpt4_fck, CK_443X), + CLK(NULL, "gpt9_fck", &gpt9_fck, CK_443X), + CLK(NULL, "gpt10_fck", &gpt10_fck, CK_443X), + CLK(NULL, "gpt11_fck", &gpt11_fck, CK_443X), + CLK(NULL, "gpmc_fck", &gpmc_fck, CK_443X), + CLK(NULL, "dpll_abe_ck", &dpll_abe_ck, CK_443X), + CLK(NULL, "dpll_abe_x2_ck", &dpll_abe_x2_ck, CK_443X), + CLK(NULL, "dpll_abe_m2_ck", &dpll_abe_m2_ck, CK_443X), + CLK(NULL, "dpll_abe_x2m2_ck", &dpll_abe_x2m2_ck, CK_443X), + CLK(NULL, "dpll_abe_x2m3_ck", &dpll_abe_x2m3_ck, CK_443X), + CLK(NULL, "per_abe_x1_fck", &per_abe_x1_fck, CK_443X), + CLK(NULL, "dpll_abe_x2_fck", &dpll_abe_x2_fck, CK_443X), + CLK(NULL, "core_dpll_hs_ck", &core_dpll_hs_ck, CK_443X), + CLK(NULL, "per_dpll_hs_ck", &per_dpll_hs_ck, CK_443X), + CLK(NULL, "usb_dpll_hs_ck", &usb_dpll_hs_ck, CK_443X), + CLK(NULL, "abe_ck", &abe_ck, CK_443X), + CLK(NULL, "aess_fck", &aess_fck, CK_443X), + CLK(NULL, "abe_lp_ck", &abe_lp_ck, CK_443X), + CLK(NULL, "abe_24m_fck", &abe_24m_fck, CK_443X), + CLK(NULL, "abe_gpt5_fck", &abe_gpt5_fck, CK_443X), + CLK(NULL, "abe_gpt6_fck", &abe_gpt6_fck, CK_443X), + CLK(NULL, "abe_gpt7_fck", &abe_gpt7_fck, CK_443X), + CLK(NULL, "abe_gpt8_fck", &abe_gpt8_fck, CK_443X), + CLK(NULL, "mcbsp1_int_fck", &mcbsp1_int_fck, CK_443X), + CLK(NULL, "mcbsp2_int_fck", &mcbsp2_int_fck, CK_443X), + CLK(NULL, "mcbsp3_int_fck", &mcbsp3_int_fck, CK_443X), + CLK(NULL, "mcasp1_int_fck", &mcasp1_int_fck, CK_443X), + CLK(NULL, "dmic_abe_int_fck", &dmic_abe_int_fck, CK_443X), + CLK(NULL, "mcbsp1_fck", &mcbsp1_fck, CK_443X), + CLK(NULL, "mcbsp2_fck", &mcbsp2_fck, CK_443X), + CLK(NULL, "mcbsp3_fck", &mcbsp3_fck, CK_443X), + CLK(NULL, "mcasp1_fck", &mcasp1_fck, CK_443X), + CLK(NULL, "dmic_abe_fck", &dmic_abe_fck, CK_443X), + CLK(NULL, "per_hsd_byp_ck", &per_hsd_byp_ck, CK_443X), + CLK(NULL, "dpll_per_ck", &dpll_per_ck, CK_443X), + CLK(NULL, "dpll_per_x2_ck", &dpll_per_x2_ck, CK_443X), + CLK(NULL, "dpll_per_m2_ck", &dpll_per_m2_ck, CK_443X), + CLK(NULL, "dpll_per_x2m2_ck", &dpll_per_x2m2_ck, CK_443X), + CLK(NULL, "dpll_per_x2m3_ck", &dpll_per_x2m3_ck, CK_443X), + CLK(NULL, "dpll_per_x2m4_ck", &dpll_per_x2m4_ck, CK_443X), + CLK(NULL, "dpll_per_x2m5_ck", &dpll_per_x2m5_ck, CK_443X), + CLK(NULL, "dpll_per_x2m6_ck", &dpll_per_x2m6_ck, CK_443X), + CLK(NULL, "dpll_per_x2m7_ck", &dpll_per_x2m7_ck, CK_443X), + CLK(NULL, "omap_96m_alwon_ck", &omap_96m_alwon_ck, CK_443X), + CLK(NULL, "omap_192m_fck", &omap_192m_fck, CK_443X), + CLK(NULL, "per_dpll_scrm_ck", &per_dpll_scrm_ck, CK_443X), + CLK(NULL, "omap_128m_fck", &omap_128m_fck, CK_443X), + CLK(NULL, "dss_fck", &dss_fck, CK_443X), + CLK(NULL, "per_mpu_m3", &per_mpu_m3, CK_443X), + CLK(NULL, "per_dpll_emu_ck", &per_dpll_emu_ck, CK_443X), + CLK(NULL, "core_phy_hsd_byp_ck", &core_phy_hsd_byp_ck, CK_443X), + CLK(NULL, "dpll_core_ck", &dpll_core_ck, CK_443X), + CLK(NULL, "dpll_core_x2_ck", &dpll_core_x2_ck, CK_443X), + CLK(NULL, "dpll_core_m2_ck", &dpll_core_m2_ck, CK_443X), + CLK(NULL, "dpll_core_x2m3_ck", &dpll_core_x2m3_ck, CK_443X), + CLK(NULL, "dpll_core_x2m4_ck", &dpll_core_x2m4_ck, CK_443X), + CLK(NULL, "dpll_core_x2m5_ck", &dpll_core_x2m5_ck, CK_443X), + CLK(NULL, "dpll_core_x2m6_ck", &dpll_core_x2m6_ck, CK_443X), + CLK(NULL, "dpll_core_x2m7_ck", &dpll_core_x2m7_ck, CK_443X), + CLK(NULL, "phy_root_ck", &phy_root_ck, CK_443X), + CLK(NULL, "core_dpll_scrm_ck", &core_dpll_scrm_ck, CK_443X), + CLK(NULL, "dpll_x2_ck", &dpll_x2_ck, CK_443X), + CLK(NULL, "core_x2_ck", &core_x2_ck, CK_443X), + CLK(NULL, "core_dpll_emu_ck", &core_dpll_emu_ck, CK_443X), + CLK(NULL, "core_sgx_fck", &core_sgx_fck, CK_443X), + CLK(NULL, "mpu_dpll_hs_ck", &mpu_dpll_hs_ck, CK_443X), + CLK(NULL, "dpll_mpu_ck", &dpll_mpu_ck, CK_443X), + CLK(NULL, "dpll_mpu_m2_ck", &dpll_mpu_m2_ck, CK_443X), + CLK(NULL, "mpu_dpll_ck", &mpu_dpll_ck, CK_443X), + CLK(NULL, "iva_dpll_hs_ck", &iva_dpll_hs_ck, CK_443X), + CLK(NULL, "dpll_iva_ck", &dpll_iva_ck, CK_443X), + CLK(NULL, "dpll_iva_x2_ck", &dpll_iva_x2_ck, CK_443X), + CLK(NULL, "dpll_iva_x2m4_ck", &dpll_iva_x2m4_ck, CK_443X), + CLK(NULL, "dpll_iva_x2m5_ck", &dpll_iva_x2m5_ck, CK_443X), + CLK(NULL, "dsp_root_ck", &dsp_root_ck, CK_443X), + CLK(NULL, "ivahd_ck", &ivahd_ck, CK_443X), + CLK(NULL, "dpll_unipro_ck", &dpll_unipro_ck, CK_443X), + CLK(NULL, "dpll_unipro_x2_ck", &dpll_unipro_x2_ck, CK_443X), + CLK(NULL, "dpll_unipro_x2m2_ck", &dpll_unipro_x2m2_ck, CK_443X), + CLK(NULL, "unipro1_phy_fck", &unipro1_phy_fck, CK_443X), + CLK(NULL, "dpll_usb_ck", &dpll_usb_ck, CK_443X), + CLK(NULL, "dpll_usb_m2_ck", &dpll_usb_m2_ck, CK_443X), + CLK(NULL, "init_480m_fck", &init_480m_fck, CK_443X), + CLK(NULL, "dpll_usb_clkdcoldo", &dpll_usb_clkdcoldo, CK_443X), + CLK(NULL, "init_960m_fck", &init_960m_fck, CK_443X), + CLK(NULL, "init_60m_fck", &init_60m_fck, CK_443X), + CLK(NULL, "utmi_p3_fck", &utmi_p3_fck, CK_443X), + CLK(NULL, "init_60m_p1_fck", &init_60m_p1_fck, CK_443X), + CLK(NULL, "init_60m_p2_fck", &init_60m_p2_fck, CK_443X), + CLK(NULL, "utmi_root_gfck", &utmi_root_gfck, CK_443X), + CLK(NULL, "tll_ch0_fck", &tll_ch0_fck, CK_443X), + CLK(NULL, "tll_ch1_fck", &tll_ch1_fck, CK_443X), + CLK(NULL, "tll_ch2_fck", &tll_ch2_fck, CK_443X), + CLK(NULL, "hsic_p1_480m_fck", &hsic_p1_480m_fck, CK_443X), + CLK(NULL, "hsic_p2_480m_fck", &hsic_p2_480m_fck, CK_443X), + CLK(NULL, "otg_60m_fck", &otg_60m_fck, CK_443X), + CLK(NULL, "utmi_p1_fck", &utmi_p1_fck, CK_443X), + CLK(NULL, "utmi_p2_fck", &utmi_p2_fck, CK_443X), + CLK(NULL, "core_ck", &core_ck, CK_443X), + CLK(NULL, "l3_ick", &l3_ick, CK_443X), + CLK(NULL, "l4_root_ck", &l4_root_ck, CK_443X), + CLK(NULL, "per_24m_fck", &per_24m_fck, CK_443X), + CLK(NULL, "fdif_fck", &fdif_fck, CK_443X), + CLK(NULL, "hsi_fck", &hsi_fck, CK_443X), + CLK(NULL, "mpu_m3_iss_ck", &mpu_m3_iss_ck, CK_443X), +}; + +static struct clk_functions omap2_clk_functions = { + .clk_enable = omap2_clk_enable, + .clk_disable = omap2_clk_disable, + .clk_round_rate = omap2_clk_round_rate, + .clk_set_rate = omap2_clk_set_rate, + .clk_set_parent = omap2_clk_set_parent, + .clk_disable_unused = omap2_clk_disable_unused, +}; + +void omap2_clk_prepare_for_reboot(void) +{ + return; +} + +static int omap4_noncore_dpll_set_rate(struct clk *clk, unsigned long rate) +{ + return 0; +} + +static unsigned long omap4_clkoutx2_recalc(struct clk *clk) +{ + return 0; +} + +static unsigned long omap4_dpll_recalc(struct clk *clk) +{ + return 0; +} + +static int __init omap2_clk_arch_init(void) +{ + if (!mpurate) + return -EINVAL; + + recalculate_root_clocks(); + return 0; +} +arch_initcall(omap2_clk_arch_init); + +int __init omap2_clk_init(void) +{ + /* struct prcm_config *prcm; */ + struct omap_clk *c; + /* u32 clkrate; */ + u32 cpu_clkflg; + + if (cpu_is_omap44xx()) { + cpu_mask = RATE_IN_443X; + cpu_clkflg = CK_443X; + } + + clk_init(&omap2_clk_functions); + + for (c = omap44xx_clks; c < omap44xx_clks + ARRAY_SIZE(omap44xx_clks); c++) + clk_preinit(c->lk.clk); + + for (c = omap44xx_clks; c < omap44xx_clks + ARRAY_SIZE(omap44xx_clks); c++) + if (c->cpu & cpu_clkflg) { + clkdev_add(&c->lk); + clk_register(c->lk.clk); + /* TODO + omap2_init_clk_clkdm(c->lk.clk); + */ + } + + recalculate_root_clocks(); + + /* + * Only enable those clocks we will need, let the drivers + * enable other clocks as necessary + */ + clk_enable_init_clocks(); + + return 0; +} diff --git a/arch/arm/mach-omap2/clock44xx.h b/arch/arm/mach-omap2/clock44xx.h new file mode 100644 index 000000000000..781230c3897e --- /dev/null +++ b/arch/arm/mach-omap2/clock44xx.h @@ -0,0 +1,1728 @@ +/* + * OMAP4 clock framework + * + * Copyright (C) 2009 Texas Instruments, Inc. + * + * Written by Rajendra Nayak (rnayak@ti.com) + * + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK44XX_H +#define __ARCH_ARM_MACH_OMAP2_CLOCK44XX_H + +#include <mach/control.h> + +#include "clock.h" +#include "cm.h" +#include "cm1-regbits-44xx.h" +#include "cm2-regbits-44xx.h" +#include "prm.h" +#include "prm-regbits-44xx.h" + +static unsigned long omap4_dpll_recalc(struct clk *clk); +static unsigned long omap4_clkoutx2_recalc(struct clk *clk); +static int omap4_noncore_dpll_set_rate(struct clk *clk, unsigned long rate); + +/* PRM CLOCKS */ + +static struct clk omap_32k_fck = { + .name = "omap_32k_fck", + .ops = &clkops_null, + .rate = 32768, + .flags = RATE_FIXED, +}; + +static struct clk secure_32k_fck = { + .name = "secure_32k_fck", + .ops = &clkops_null, + .rate = 32768, + .flags = RATE_FIXED, +}; + +static struct clk pad_cks = { + .name = "pad_cks", + .ops = &clkops_null, + .rate = 12000000, + .flags = RATE_FIXED, +}; + +static struct clk slimbus_ck = { + .name = "slimbus_ck", + .ops = &clkops_null, + .rate = 12000000, + .flags = RATE_FIXED, +}; + +static struct clk phy_clkout_ck = { + .name = "phy_clkout_ck", + .ops = &clkops_null, + .rate = 12000000, + .flags = RATE_FIXED, +}; + +static struct clk xclk_60m_otg_ck = { + .name = "xclk_60m_otg_ck", + .ops = &clkops_null, + .rate = 60000000, + .flags = RATE_FIXED, +}; + +static struct clk xclk_60m_hsp1_ck = { + .name = "xclk_60m_hsp1_ck", + .ops = &clkops_null, + .rate = 12000000, + .flags = RATE_FIXED, +}; + +static struct clk xclk_60m_hsp2_ck = { + .name = "xclk_60m_hsp2_ck", + .ops = &clkops_null, + .rate = 12000000, + .flags = RATE_FIXED, +}; + +static struct clk virt_12m_ck = { + .name = "virt_12m_ck", + .ops = &clkops_null, + .rate = 12000000, + .flags = RATE_FIXED, +}; + +static struct clk virt_13m_ck = { + .name = "virt_13m_ck", + .ops = &clkops_null, + .rate = 13000000, + .flags = RATE_FIXED, +}; + +static struct clk virt_19_2m_ck = { + .name = "virt_19_2m_ck", + .ops = &clkops_null, + .rate = 19200000, + .flags = RATE_FIXED, +}; + +static struct clk virt_26m_ck = { + .name = "virt_26m_ck", + .ops = &clkops_null, + .rate = 26000000, + .flags = RATE_FIXED, +}; + +static struct clk virt_27m_ck = { + .name = "virt_27m_ck", + .ops = &clkops_null, + .rate = 27000000, + .flags = RATE_FIXED, +}; + +static struct clk virt_38_4m_ck = { + .name = "virt_38_4m_ck", + .ops = &clkops_null, + .rate = 38400000, + .flags = RATE_FIXED, +}; + +static const struct clksel_rate sys_clk_12m_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 0 } +}; + +static const struct clksel_rate sys_clk_13m_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 0 } +}; + +static const struct clksel_rate sys_clk_19_2m_rates[] = { + { .div = 1, .val = 2, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 0 } +}; + +static const struct clksel_rate sys_clk_26m_rates[] = { + { .div = 1, .val = 3, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 0 } +}; + +static const struct clksel_rate sys_clk_27m_rates[] = { + { .div = 1, .val = 5, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 0 } +}; + +static const struct clksel_rate sys_clk_38_4m_rates[] = { + { .div = 1, .val = 4, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 0 } +}; + +static const struct clksel sys_clk_clksel[] = { + { .parent = &virt_12m_ck, .rates = sys_clk_12m_rates }, + { .parent = &virt_13m_ck, .rates = sys_clk_13m_rates }, + { .parent = &virt_19_2m_ck, .rates = sys_clk_19_2m_rates }, + { .parent = &virt_26m_ck, .rates = sys_clk_26m_rates }, + { .parent = &virt_27m_ck, .rates = sys_clk_27m_rates }, + { .parent = &virt_38_4m_ck, .rates = sys_clk_38_4m_rates }, + { .parent = NULL }, +}; + +/* sys_clk clock */ +/* 12, 13, 19.2, 26, 27 or 38.4 MHz */ +static struct clk sys_ck = { + .name = "sys_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .clksel_reg = OMAP4430_CM_SYS_CLKSEL, + .clksel_mask = OMAP4430_SYS_CLKSEL_MASK, + .clksel = sys_clk_clksel, + .flags = RATE_FIXED, + .recalc = &omap2_clksel_recalc, +}; + +static const struct clksel_rate div2_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 2, .val = 1, .flags = RATE_IN_443X }, + { .div = 0 } +}; + +static const struct clksel abe_dss_sys_ck_clksel[] = { + { .parent = &sys_ck, .rates = div2_rates }, + { .parent = NULL } +}; + +static struct clk abe_dss_sys_ck = { + .name = "abe_dss_sys_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .parent = &sys_ck, + .clksel_reg = OMAP4430_CM_ABE_DSS_SYS_CLKSEL, + .clksel_mask = OMAP4430_CLKSEL_MASK, + .clksel = abe_dss_sys_ck_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static const struct clksel dpll_sys_ref_ck_clksel[] = { + { .parent = &sys_ck, .rates = div2_rates }, + { .parent = NULL } +}; + +static struct clk dpll_sys_ref_ck = { + .name = "dpll_sys_ref_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .parent = &sys_ck, + .clksel_reg = OMAP4430_CM_DPLL_SYS_REF_CLKSEL, + .clksel_mask = OMAP4430_CLKSEL_MASK, + .clksel = dpll_sys_ref_ck_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static const struct clksel_rate dpll_sys_ref_ck_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 0 } +}; + +static const struct clksel_rate omap_32k_fck_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 0 } +}; + +static const struct clksel abe_dpll_alwon_ck_clksel[] = { + { .parent = &dpll_sys_ref_ck, .rates = dpll_sys_ref_ck_rates }, + { .parent = &omap_32k_fck, .rates = omap_32k_fck_rates }, + { .parent = NULL } +}; + +static struct clk abe_dpll_alwon_ck = { + .name = "abe_dpll_alwon_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .parent = &omap_32k_fck, + .clksel_reg = OMAP4430_CM_ABE_PLL_REF_CLKSEL, + .clksel_mask = OMAP4430_CLKSEL_MASK, + .clksel = abe_dpll_alwon_ck_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static const struct clksel omap443x_gpt_clksel[] = { + { .parent = &omap_32k_fck, .rates = gpt_32k_rates }, + { .parent = &sys_ck, .rates = gpt_sys_rates }, + { .parent = NULL} +}; + +static struct clk gpt1_fck = { + .name = "gpt1_fck", + .ops = &clkops_omap2_dflt_wait, + .parent = &sys_ck, + .init = &omap2_init_clksel_parent, + .enable_reg = OMAP4430_CM_WKUP_GPTIMER1_CLKCTRL, + .enable_bit = OMAP4430_EN_GPT_SHIFT, + .clksel_reg = OMAP4430_CM_WKUP_GPTIMER1_CLKCTRL, + .clksel_mask = OMAP4430_CLKSEL_MASK, + .clksel = omap443x_gpt_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk gpt2_fck = { + .name = "gpt2_fck", + .ops = &clkops_omap2_dflt_wait, + .parent = &sys_ck, + .init = &omap2_init_clksel_parent, + .enable_reg = OMAP4430_CM_L4PER_GPTIMER2_CLKCTRL, + .enable_bit = OMAP4430_EN_GPT_SHIFT, + .clksel_reg = OMAP4430_CM_L4PER_GPTIMER2_CLKCTRL, + .clksel_mask = OMAP4430_CLKSEL_MASK, + .clksel = omap443x_gpt_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk gpt3_fck = { + .name = "gpt3_fck", + .ops = &clkops_omap2_dflt_wait, + .parent = &sys_ck, + .init = &omap2_init_clksel_parent, + .enable_reg = OMAP4430_CM_L4PER_GPTIMER3_CLKCTRL, + .enable_bit = OMAP4430_EN_GPT_SHIFT, + .clksel_reg = OMAP4430_CM_L4PER_GPTIMER3_CLKCTRL, + .clksel_mask = OMAP4430_CLKSEL_MASK, + .clksel = omap443x_gpt_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk gpt4_fck = { + .name = "gpt4_fck", + .ops = &clkops_omap2_dflt_wait, + .parent = &sys_ck, + .init = &omap2_init_clksel_parent, + .enable_reg = OMAP4430_CM_L4PER_GPTIMER4_CLKCTRL, + .enable_bit = OMAP4430_EN_GPT_SHIFT, + .clksel_reg = OMAP4430_CM_L4PER_GPTIMER4_CLKCTRL, + .clksel_mask = OMAP4430_CLKSEL_MASK, + .clksel = omap443x_gpt_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk gpt9_fck = { + .name = "gpt9_fck", + .ops = &clkops_omap2_dflt_wait, + .parent = &sys_ck, + .init = &omap2_init_clksel_parent, + .enable_reg = OMAP4430_CM_L4PER_GPTIMER9_CLKCTRL, + .enable_bit = OMAP4430_EN_GPT_SHIFT, + .clksel_reg = OMAP4430_CM_L4PER_GPTIMER9_CLKCTRL, + .clksel_mask = OMAP4430_CLKSEL_MASK, + .clksel = omap443x_gpt_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk gpt10_fck = { + .name = "gpt10_fck", + .ops = &clkops_omap2_dflt_wait, + .parent = &sys_ck, + .init = &omap2_init_clksel_parent, + .enable_reg = OMAP4430_CM_L4PER_GPTIMER10_CLKCTRL, + .enable_bit = OMAP4430_EN_GPT_SHIFT, + .clksel_reg = OMAP4430_CM_L4PER_GPTIMER10_CLKCTRL, + .clksel_mask = OMAP4430_CLKSEL_MASK, + .clksel = omap443x_gpt_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk gpt11_fck = { + .name = "gpt11_fck", + .ops = &clkops_omap2_dflt_wait, + .parent = &sys_ck, + .init = &omap2_init_clksel_parent, + .enable_reg = OMAP4430_CM_L4PER_GPTIMER11_CLKCTRL, + .enable_bit = OMAP4430_EN_GPT_SHIFT, + .clksel_reg = OMAP4430_CM_L4PER_GPTIMER11_CLKCTRL, + .clksel_mask = OMAP4430_CLKSEL_MASK, + .clksel = omap443x_gpt_clksel, + .recalc = &omap2_clksel_recalc, +}; + +/* TODO:Dummy clock node still needed to boot on Omap4, remove later */ +static struct clk gpmc_fck = { + .name = "gpmc_fck", + .ops = &clkops_null, +}; + +/* DPLL's */ + +#define DPLL_LOW_POWER_STOP 0x1 +#define DPLL_LOW_POWER_BYPASS 0x5 +#define DPLL_LOCKED 0x7 + +static const struct clksel_rate div_mx_dpll_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 2, .val = 2, .flags = RATE_IN_443X }, + { .div = 3, .val = 3, .flags = RATE_IN_443X }, + { .div = 4, .val = 4, .flags = RATE_IN_443X }, + { .div = 5, .val = 5, .flags = RATE_IN_443X }, + { .div = 6, .val = 6, .flags = RATE_IN_443X }, + { .div = 7, .val = 7, .flags = RATE_IN_443X }, + { .div = 8, .val = 8, .flags = RATE_IN_443X }, + { .div = 9, .val = 9, .flags = RATE_IN_443X }, + { .div = 10, .val = 10, .flags = RATE_IN_443X }, + { .div = 11, .val = 11, .flags = RATE_IN_443X }, + { .div = 12, .val = 12, .flags = RATE_IN_443X }, + { .div = 13, .val = 13, .flags = RATE_IN_443X }, + { .div = 14, .val = 14, .flags = RATE_IN_443X }, + { .div = 15, .val = 15, .flags = RATE_IN_443X }, + { .div = 16, .val = 16, .flags = RATE_IN_443X }, + { .div = 17, .val = 17, .flags = RATE_IN_443X }, + { .div = 18, .val = 18, .flags = RATE_IN_443X }, + { .div = 19, .val = 19, .flags = RATE_IN_443X }, + { .div = 20, .val = 20, .flags = RATE_IN_443X }, + { .div = 21, .val = 21, .flags = RATE_IN_443X }, + { .div = 22, .val = 22, .flags = RATE_IN_443X }, + { .div = 23, .val = 23, .flags = RATE_IN_443X }, + { .div = 24, .val = 24, .flags = RATE_IN_443X }, + { .div = 25, .val = 25, .flags = RATE_IN_443X }, + { .div = 26, .val = 26, .flags = RATE_IN_443X }, + { .div = 27, .val = 27, .flags = RATE_IN_443X }, + { .div = 28, .val = 28, .flags = RATE_IN_443X }, + { .div = 29, .val = 29, .flags = RATE_IN_443X }, + { .div = 30, .val = 30, .flags = RATE_IN_443X }, + { .div = 31, .val = 31, .flags = RATE_IN_443X }, + { .div = 0 } +}; + +/* DPLL ABE */ + +static struct dpll_data dpll_abe_dd = { + .mult_div1_reg = OMAP4430_CM_CLKSEL_DPLL_ABE, + .mult_mask = OMAP4430_CM2_DPLL_MULT_MASK, + .div1_mask = OMAP4430_CM2_DPLL_DIV_MASK, + .clk_bypass = &sys_ck, + .clk_ref = &abe_dpll_alwon_ck, + .control_reg = OMAP4430_CM_CLKMODE_DPLL_ABE, + .enable_mask = OMAP4430_DPLL_EN_MASK, + .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), + .autoidle_reg = OMAP4430_CM_AUTOIDLE_DPLL_ABE, + .autoidle_mask = OMAP4430_AUTO_DPLL_MODE_MASK, + .idlest_reg = OMAP4430_CM_IDLEST_DPLL_ABE, + .idlest_mask = OMAP4430_ST_DPLL_CLK_MASK, +}; + +static struct clk dpll_abe_ck = { + .name = "dpll_abe_ck", + .ops = &clkops_null, + .parent = &abe_dpll_alwon_ck, + .dpll_data = &dpll_abe_dd, + .round_rate = &omap2_dpll_round_rate, + .set_rate = &omap4_noncore_dpll_set_rate, + .recalc = &omap4_dpll_recalc, +}; + +static struct clk dpll_abe_x2_ck = { + .name = "dpll_abe_x2_ck", + .ops = &clkops_null, + .parent = &dpll_abe_ck, + .recalc = &omap4_clkoutx2_recalc, +}; + +static const struct clksel dpll_abe_m2_clksel[] = { + { .parent = &dpll_abe_ck, .rates = div_mx_dpll_rates }, + { .parent = NULL } +}; + +static struct clk dpll_abe_m2_ck = { + .name = "dpll_abe_m2_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_ABE, + .clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK, + .clksel = dpll_abe_m2_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static const struct clksel dpll_abe_x2mx_clksel[] = { + { .parent = &dpll_abe_x2_ck, .rates = div_mx_dpll_rates }, + { .parent = NULL } +}; + +static struct clk dpll_abe_x2m2_ck = { + .name = "dpll_abe_x2m2_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_ABE, + .clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK, + .clksel = dpll_abe_x2mx_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk dpll_abe_x2m3_ck = { + .name = "dpll_abe_x2m3_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .clksel_reg = OMAP4430_CM_DIV_M3_DPLL_ABE, + .clksel_mask = OMAP4430_DPLL_CLKOUTHIF_DIV_MASK, + .clksel = dpll_abe_x2mx_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk per_abe_x1_fck = { + .name = "per_abe_x1_fck", + .ops = &clkops_null, + .parent = &dpll_abe_m2_ck, + .recalc = &followparent_recalc, +}; + +static struct clk dpll_abe_x2_fck = { + .name = "dpll_abe_x2_fck", + .ops = &clkops_null, + .parent = &dpll_abe_m2_ck, + .recalc = &followparent_recalc, +}; + +static struct clk core_dpll_hs_ck = { + .name = "core_dpll_hs_ck", + .ops = &clkops_null, + .parent = &dpll_abe_m2_ck, + .recalc = &followparent_recalc, +}; + +static struct clk per_dpll_hs_ck = { + .name = "per_dpll_hs_ck", + .ops = &clkops_null, + .parent = &core_dpll_hs_ck, + .fixed_div = 2, + .recalc = &omap2_fixed_divisor_recalc, +}; + +static struct clk usb_dpll_hs_ck = { + .name = "usb_dpll_hs_ck", + .ops = &clkops_null, + .parent = &core_dpll_hs_ck, + .fixed_div = 2, + .recalc = &omap2_fixed_divisor_recalc, +}; + +/* CM1_ABE clocks */ + +static const struct clksel_rate dpll_abe_x2_ck_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 2, .val = 1, .flags = RATE_IN_443X }, + { .div = 4, .val = 2, .flags = RATE_IN_443X }, + { .div = 0 }, +}; + +static const struct clksel abe_ck_clksel[] = { + { .parent = &dpll_abe_x2_ck, .rates = dpll_abe_x2_ck_rates }, + { .parent = NULL }, +}; + +static struct clk abe_ck = { + .name = "abe_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .parent = &dpll_abe_x2_ck, + .clksel_reg = OMAP4430_CM_CLKSEL_ABE, + .clksel_mask = OMAP4430_CLKSEL_OPP_MASK, + .clksel = abe_ck_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static const struct clksel_rate abe_ck_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 2, .val = 1, .flags = RATE_IN_443X }, + { .div = 0 }, +}; + +static const struct clksel aess_fck_clksel[] = { + { .parent = &abe_ck, .rates = abe_ck_rates }, + { .parent = NULL }, +}; + +static struct clk aess_fck = { + .name = "aess_fck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .parent = &abe_ck, + .clksel_reg = OMAP4430_CM1_ABE_AESS_CLKCTRL, + .clksel_mask = OMAP4430_CLKSEL_AESS_FCLK_MASK, + .clksel = aess_fck_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk abe_lp_ck = { + .name = "abe_lp_ck", + .ops = &clkops_null, + .parent = &dpll_abe_x2_ck, + .fixed_div = 16, + .recalc = &omap2_fixed_divisor_recalc, +}; + +static struct clk abe_24m_fck = { + .name = "abe_24m_fck", + .ops = &clkops_null, + .parent = &dpll_abe_x2_ck, + .fixed_div = 16, + .recalc = &omap2_fixed_divisor_recalc, +}; + +static struct clk abe_gpt5_fck = { + .name = "abe_gpt5_fck", + .ops = &clkops_omap2_dflt_wait, + .parent = &sys_ck, + .init = &omap2_init_clksel_parent, + .enable_reg = OMAP4430_CM1_ABE_TIMER5_CLKCTRL, + .enable_bit = OMAP4430_EN_GPT_SHIFT, + .clksel_reg = OMAP4430_CM1_ABE_TIMER5_CLKCTRL, + .clksel_mask = OMAP4430_GPTIMER_CLKSEL_MASK, + .clksel = omap443x_gpt_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk abe_gpt6_fck = { + .name = "abe_gpt6_fck", + .ops = &clkops_omap2_dflt_wait, + .parent = &sys_ck, + .init = &omap2_init_clksel_parent, + .enable_reg = OMAP4430_CM1_ABE_TIMER6_CLKCTRL, + .enable_bit = OMAP4430_EN_GPT_SHIFT, + .clksel_reg = OMAP4430_CM1_ABE_TIMER6_CLKCTRL, + .clksel_mask = OMAP4430_GPTIMER_CLKSEL_MASK, + .clksel = omap443x_gpt_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk abe_gpt7_fck = { + .name = "abe_gpt7_fck", + .ops = &clkops_omap2_dflt_wait, + .parent = &sys_ck, + .init = &omap2_init_clksel_parent, + .enable_reg = OMAP4430_CM1_ABE_TIMER7_CLKCTRL, + .enable_bit = OMAP4430_EN_GPT_SHIFT, + .clksel_reg = OMAP4430_CM1_ABE_TIMER7_CLKCTRL, + .clksel_mask = OMAP4430_GPTIMER_CLKSEL_MASK, + .clksel = omap443x_gpt_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk abe_gpt8_fck = { + .name = "abe_gpt8_fck", + .ops = &clkops_omap2_dflt_wait, + .parent = &sys_ck, + .init = &omap2_init_clksel_parent, + .enable_reg = OMAP4430_CM1_ABE_TIMER8_CLKCTRL, + .enable_bit = OMAP4430_EN_GPT_SHIFT, + .clksel_reg = OMAP4430_CM1_ABE_TIMER8_CLKCTRL, + .clksel_mask = OMAP4430_GPTIMER_CLKSEL_MASK, + .clksel = omap443x_gpt_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk per_24m_fck; + +static const struct clksel_rate abe_24m_fck_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 0 } +}; + +static const struct clksel_rate sys_ck_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 0 } +}; + +static const struct clksel_rate per_24m_fck_rates[] = { + { .div = 1, .val = 2, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 0 } +}; + +static const struct clksel mcbsp_int_fck_clksel[] = { + { .parent = &abe_24m_fck, .rates = abe_24m_fck_rates }, + { .parent = &sys_ck, .rates = sys_ck_rates }, + { .parent = &per_24m_fck, .rates = per_24m_fck_rates }, + { .parent = NULL }, +}; + +static const struct clksel mcasp_int_fck_clksel[] = { + { .parent = &abe_24m_fck, .rates = abe_24m_fck_rates }, + { .parent = &sys_ck, .rates = sys_ck_rates }, + { .parent = &per_24m_fck, .rates = per_24m_fck_rates }, + { .parent = NULL }, +}; + +static const struct clksel dmic_abe_int_fck_clksel[] = { + { .parent = &abe_24m_fck, .rates = abe_24m_fck_rates }, + { .parent = &sys_ck, .rates = sys_ck_rates }, + { .parent = &per_24m_fck, .rates = per_24m_fck_rates }, + { .parent = NULL }, +}; + +static struct clk mcbsp1_int_fck = { + .name = "mcbsp1_int_fck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .parent = &abe_24m_fck, + .clksel_reg = OMAP4430_CM1_ABE_MCBSP1_CLKCTRL, + .clksel_mask = OMAP4430_ABE_CLKSEL_INTERNAL_SOURCE, + .clksel = mcbsp_int_fck_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk mcbsp2_int_fck = { + .name = "mcbsp2_int_fck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .parent = &abe_24m_fck, + .clksel_reg = OMAP4430_CM1_ABE_MCBSP2_CLKCTRL, + .clksel_mask = OMAP4430_ABE_CLKSEL_INTERNAL_SOURCE, + .clksel = mcbsp_int_fck_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk mcbsp3_int_fck = { + .name = "mcbsp3_int_fck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .parent = &abe_24m_fck, + .clksel_reg = OMAP4430_CM1_ABE_MCBSP3_CLKCTRL, + .clksel_mask = OMAP4430_ABE_CLKSEL_INTERNAL_SOURCE, + .clksel = mcbsp_int_fck_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk mcasp1_int_fck = { + .name = "mcasp1_int_fck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .parent = &abe_24m_fck, + .clksel_reg = OMAP4430_CM1_ABE_MCASP_CLKCTRL, + .clksel_mask = OMAP4430_ABE_CLKSEL_INTERNAL_SOURCE, + .clksel = mcasp_int_fck_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk dmic_abe_int_fck = { + .name = "dmic_abe_int_fck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .parent = &abe_24m_fck, + .clksel_reg = OMAP4430_CM1_ABE_DMIC_CLKCTRL, + .clksel_mask = OMAP4430_ABE_CLKSEL_INTERNAL_SOURCE, + .clksel = dmic_abe_int_fck_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static const struct clksel_rate int_ck_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 0 } +}; + +static const struct clksel_rate pad_cks_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 0 } +}; + +static const struct clksel_rate slimbus_ck_rates[] = { + { .div = 1, .val = 2, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 0 } +}; + +static const struct clksel mcbsp1_fck_clksel[] = { + { .parent = &mcbsp1_int_fck, .rates = int_ck_rates }, + { .parent = &pad_cks, .rates = pad_cks_rates }, + { .parent = &slimbus_ck, .rates = slimbus_ck_rates }, + { .parent = NULL }, +}; + +static const struct clksel mcbsp2_fck_clksel[] = { + { .parent = &mcbsp2_int_fck, .rates = int_ck_rates }, + { .parent = &pad_cks, .rates = pad_cks_rates }, + { .parent = &slimbus_ck, .rates = slimbus_ck_rates }, + { .parent = NULL }, +}; +static const struct clksel mcbsp3_fck_clksel[] = { + { .parent = &mcbsp3_int_fck, .rates = int_ck_rates }, + { .parent = &pad_cks, .rates = pad_cks_rates }, + { .parent = &slimbus_ck, .rates = slimbus_ck_rates }, + { .parent = NULL }, +}; +static const struct clksel mcasp1_fck_clksel[] = { + { .parent = &mcasp1_int_fck, .rates = int_ck_rates }, + { .parent = &pad_cks, .rates = pad_cks_rates }, + { .parent = &slimbus_ck, .rates = slimbus_ck_rates }, + { .parent = NULL }, +}; +static const struct clksel dmic_abe_fck_clksel[] = { + { .parent = &dmic_abe_int_fck, .rates = int_ck_rates }, + { .parent = &pad_cks, .rates = pad_cks_rates }, + { .parent = &slimbus_ck, .rates = slimbus_ck_rates }, + { .parent = NULL }, +}; + +static struct clk mcbsp1_fck = { + .name = "mcbsp1_fck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .parent = &mcbsp1_int_fck, + .clksel_reg = OMAP4430_CM1_ABE_MCBSP1_CLKCTRL, + .clksel_mask = OMAP4430_CLKSEL_SOURCE, + .clksel = mcbsp1_fck_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk mcbsp2_fck = { + .name = "mcbsp2_fck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .parent = &mcbsp2_int_fck, + .clksel_reg = OMAP4430_CM1_ABE_MCBSP2_CLKCTRL, + .clksel_mask = OMAP4430_CLKSEL_SOURCE, + .clksel = mcbsp2_fck_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk mcbsp3_fck = { + .name = "mcbsp3_fck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .parent = &mcbsp3_int_fck, + .clksel_reg = OMAP4430_CM1_ABE_MCBSP3_CLKCTRL, + .clksel_mask = OMAP4430_CLKSEL_SOURCE, + .clksel = mcbsp3_fck_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk mcasp1_fck = { + .name = "mcasp1_fck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .parent = &mcasp1_int_fck, + .clksel_reg = OMAP4430_CM1_ABE_MCASP_CLKCTRL, + .clksel_mask = OMAP4430_CLKSEL_SOURCE, + .clksel = mcasp1_fck_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk dmic_abe_fck = { + .name = "dmic_abe_fck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .parent = &dmic_abe_int_fck, + .clksel_reg = OMAP4430_CM1_ABE_DMIC_CLKCTRL, + .clksel_mask = OMAP4430_CLKSEL_SOURCE, + .clksel = dmic_abe_fck_clksel, + .recalc = &omap2_clksel_recalc, +}; + +/* DPLL PER */ + +static const struct clksel_rate per_dpll_hs_ck_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 0 } +}; + +static const struct clksel per_hsd_byp_ck_clksel[] = { + { .parent = &dpll_sys_ref_ck, .rates = dpll_sys_ref_ck_rates }, + { .parent = &per_dpll_hs_ck, .rates = per_dpll_hs_ck_rates }, + { .parent = NULL } +}; + +static struct clk per_hsd_byp_ck = { + .name = "per_hsd_byp_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .parent = &dpll_sys_ref_ck, + .clksel_reg = OMAP4430_CM_CLKSEL_DPLL_PER, + .clksel_mask = OMAP4430_DPLL_BYP_CLKSEL_MASK, + .clksel = per_hsd_byp_ck_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct dpll_data dpll_per_dd = { + .mult_div1_reg = OMAP4430_CM_CLKSEL_DPLL_PER, + .mult_mask = OMAP4430_CM2_DPLL_MULT_MASK, + .div1_mask = OMAP4430_CM2_DPLL_DIV_MASK, + .clk_bypass = &per_dpll_hs_ck, + .clk_ref = &dpll_sys_ref_ck, + .clk_hsd_bypass = &per_hsd_byp_ck, + .control_reg = OMAP4430_CM_CLKMODE_DPLL_PER, + .enable_mask = OMAP4430_DPLL_EN_MASK, + .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), + .autoidle_reg = OMAP4430_CM_AUTOIDLE_DPLL_PER, + .autoidle_mask = OMAP4430_AUTO_DPLL_MODE_MASK, + .idlest_reg = OMAP4430_CM_IDLEST_DPLL_PER, + .idlest_mask = OMAP4430_ST_DPLL_CLK_MASK, +}; + +static struct clk dpll_per_ck = { + .name = "dpll_per_ck", + .ops = &clkops_null, + .parent = &dpll_sys_ref_ck, + .dpll_data = &dpll_per_dd, + .round_rate = &omap2_dpll_round_rate, + .set_rate = &omap4_noncore_dpll_set_rate, + .recalc = &omap4_dpll_recalc, +}; + +static struct clk dpll_per_x2_ck = { + .name = "dpll_per_x2_ck", + .ops = &clkops_null, + .parent = &dpll_per_ck, + .recalc = &omap4_clkoutx2_recalc, +}; + +static const struct clksel dpll_per_m2_clksel[] = { + { .parent = &dpll_per_ck, .rates = div_mx_dpll_rates }, + { .parent = NULL } +}; + +static struct clk dpll_per_m2_ck = { + .name = "dpll_per_m2_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_PER, + .clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK, + .clksel = dpll_per_m2_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static const struct clksel dpll_per_x2mx_clksel[] = { + { .parent = &dpll_per_x2_ck, .rates = div_mx_dpll_rates }, + { .parent = NULL } +}; + +static struct clk dpll_per_x2m2_ck = { + .name = "dpll_per_x2m2_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_PER, + .clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK, + .clksel = dpll_per_x2mx_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk dpll_per_x2m3_ck = { + .name = "dpll_per_x2m3_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .clksel_reg = OMAP4430_CM_DIV_M3_DPLL_PER, + .clksel_mask = OMAP4430_DPLL_CLKOUTHIF_DIV_MASK, + .clksel = dpll_per_x2mx_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk dpll_per_x2m4_ck = { + .name = "dpll_per_x2m4_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .clksel_reg = OMAP4430_CM_DIV_M4_DPLL_PER, + .clksel_mask = OMAP4430_DPLL_CLKOUTHIF_DIV_MASK, + .clksel = dpll_per_x2mx_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk dpll_per_x2m5_ck = { + .name = "dpll_per_x2m5_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .clksel_reg = OMAP4430_CM_DIV_M5_DPLL_PER, + .clksel_mask = OMAP4430_DPLL_CLKOUTHIF_DIV_MASK, + .clksel = dpll_per_x2mx_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk dpll_per_x2m6_ck = { + .name = "dpll_per_x2m6_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .clksel_reg = OMAP4430_CM_DIV_M6_DPLL_PER, + .clksel_mask = OMAP4430_DPLL_CLKOUTHIF_DIV_MASK, + .clksel = dpll_per_x2mx_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk dpll_per_x2m7_ck = { + .name = "dpll_per_x2m7_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .clksel_reg = OMAP4430_CM_DIV_M7_DPLL_PER, + .clksel_mask = OMAP4430_DPLL_CLKOUTHIF_DIV_MASK, + .clksel = dpll_per_x2mx_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk omap_96m_alwon_ck = { + .name = "omap_96m_alwon_ck", + .ops = &clkops_null, + .parent = &dpll_per_m2_ck, + .recalc = &followparent_recalc, +}; + +static struct clk omap_192m_fck = { + .name = "omap_192m_fck", + .ops = &clkops_null, + .parent = &dpll_per_x2m2_ck, + .recalc = &followparent_recalc, +}; + +static struct clk per_dpll_scrm_ck = { + .name = "per_dpll_scrm_ck", + .ops = &clkops_null, + .parent = &dpll_per_x2m3_ck, + .recalc = &followparent_recalc, +}; + +static struct clk omap_128m_fck = { + .name = "omap_128m_fck", + .ops = &clkops_null, + .parent = &dpll_per_x2m4_ck, + .recalc = &followparent_recalc, +}; + +static struct clk dss_fck = { + .name = "dss_fck", + .ops = &clkops_null, + .parent = &dpll_per_x2m5_ck, + .recalc = &followparent_recalc, +}; + +static struct clk per_mpu_m3 = { + .name = "per_mpu_m3", + .ops = &clkops_null, + .parent = &dpll_per_x2m6_ck, + .recalc = &followparent_recalc, +}; + +static struct clk per_dpll_emu_ck = { + .name = "per_dpll_emu_ck", + .ops = &clkops_null, + .parent = &dpll_per_x2m7_ck, + .recalc = &followparent_recalc, +}; + +/* DPLL CORE */ +static const struct clksel_rate core_dpll_hs_ck_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 0 } +}; + +static const struct clksel core_phy_hsd_byp_ck_clksel[] = { + { .parent = &dpll_sys_ref_ck, .rates = dpll_sys_ref_ck_rates }, + { .parent = &core_dpll_hs_ck, .rates = core_dpll_hs_ck_rates }, + { .parent = NULL } +}; + +static struct clk core_phy_hsd_byp_ck = { + .name = "core_phy_hsd_byp_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .parent = &dpll_sys_ref_ck, + .clksel_reg = OMAP4430_CM_CLKSEL_DPLL_CORE, + .clksel_mask = OMAP4430_DPLL_BYP_CLKSEL_MASK, + .clksel = core_phy_hsd_byp_ck_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct dpll_data dpll_core_dd = { + .mult_div1_reg = OMAP4430_CM_CLKSEL_DPLL_CORE, + .mult_mask = OMAP4430_CM2_DPLL_MULT_MASK, + .div1_mask = OMAP4430_CM2_DPLL_DIV_MASK, + .clk_bypass = &core_dpll_hs_ck, + .clk_ref = &dpll_sys_ref_ck, + .clk_hsd_bypass = &core_phy_hsd_byp_ck, + .control_reg = OMAP4430_CM_CLKMODE_DPLL_CORE, + .enable_mask = OMAP4430_DPLL_EN_MASK, + .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), + .autoidle_reg = OMAP4430_CM_AUTOIDLE_DPLL_CORE, + .autoidle_mask = OMAP4430_AUTO_DPLL_MODE_MASK, + .idlest_reg = OMAP4430_CM_IDLEST_DPLL_CORE, + .idlest_mask = OMAP4430_ST_DPLL_CLK_MASK, +}; + +static struct clk dpll_core_ck = { + .name = "dpll_core_ck", + .ops = &clkops_null, + .parent = &dpll_sys_ref_ck, + .dpll_data = &dpll_core_dd, + .round_rate = &omap2_dpll_round_rate, + .set_rate = &omap4_noncore_dpll_set_rate, + .recalc = &omap4_dpll_recalc, +}; + +static struct clk dpll_core_x2_ck = { + .name = "dpll_core_x2_ck", + .ops = &clkops_null, + .parent = &dpll_core_ck, + .recalc = &omap4_clkoutx2_recalc, +}; + +static const struct clksel dpll_core_m2_clksel[] = { + { .parent = &dpll_core_ck, .rates = div_mx_dpll_rates }, + { .parent = NULL } +}; + +static struct clk dpll_core_m2_ck = { + .name = "dpll_core_m2_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_CORE, + .clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK, + .clksel = dpll_core_m2_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static const struct clksel dpll_core_x2mx_clksel[] = { + { .parent = &dpll_core_x2_ck, .rates = div_mx_dpll_rates }, + { .parent = NULL } +}; + +static struct clk dpll_core_x2m3_ck = { + .name = "dpll_core_x2m3_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .clksel_reg = OMAP4430_CM_DIV_M3_DPLL_CORE, + .clksel_mask = OMAP4430_DPLL_CLKOUTHIF_DIV_MASK, + .clksel = dpll_core_x2mx_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk dpll_core_x2m4_ck = { + .name = "dpll_core_x2m4_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .clksel_reg = OMAP4430_CM_DIV_M4_DPLL_CORE, + .clksel_mask = OMAP4430_DPLL_CLKOUTHIF_DIV_MASK, + .clksel = dpll_core_x2mx_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk dpll_core_x2m5_ck = { + .name = "dpll_core_x2m5_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .clksel_reg = OMAP4430_CM_DIV_M5_DPLL_CORE, + .clksel_mask = OMAP4430_DPLL_CLKOUTHIF_DIV_MASK, + .clksel = dpll_core_x2mx_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk dpll_core_x2m6_ck = { + .name = "dpll_core_x2m6_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .clksel_reg = OMAP4430_CM_DIV_M6_DPLL_CORE, + .clksel_mask = OMAP4430_DPLL_CLKOUTHIF_DIV_MASK, + .clksel = dpll_core_x2mx_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk dpll_core_x2m7_ck = { + .name = "dpll_core_x2m7_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .clksel_reg = OMAP4430_CM_DIV_M7_DPLL_CORE, + .clksel_mask = OMAP4430_DPLL_CLKOUTHIF_DIV_MASK, + .clksel = dpll_core_x2mx_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk phy_root_ck = { + .name = "phy_root_ck", + .ops = &clkops_null, + .parent = &dpll_core_m2_ck, + .recalc = &followparent_recalc, +}; + +static struct clk core_dpll_scrm_ck = { + .name = "core_dpll_scrm_ck", + .ops = &clkops_null, + .parent = &dpll_core_x2m3_ck, + .recalc = &followparent_recalc, +}; + +static struct clk dpll_x2_ck = { + .name = "dpll_x2_ck", + .ops = &clkops_null, + .parent = &dpll_core_x2m4_ck, + .recalc = &followparent_recalc, +}; + +static struct clk core_x2_ck = { + .name = "core_x2_ck", + .ops = &clkops_null, + .parent = &dpll_core_x2m5_ck, + .recalc = &followparent_recalc, +}; + +static struct clk core_dpll_emu_ck = { + .name = "core_dpll_emu_ck", + .ops = &clkops_null, + .parent = &dpll_core_x2m6_ck, + .recalc = &followparent_recalc, +}; + +static struct clk core_sgx_fck = { + .name = "core_sgx_fck", + .ops = &clkops_null, + .parent = &dpll_core_x2m7_ck, + .recalc = &followparent_recalc, +}; + +/* MPU DPLL */ + +static const struct clksel_rate div4_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 2, .val = 1, .flags = RATE_IN_443X }, + { .div = 4, .val = 2, .flags = RATE_IN_443X }, + { .div = 8, .val = 3, .flags = RATE_IN_443X }, + { .div = 0 } +}; + +static const struct clksel mpu_dpll_hs_ck_clksel[] = { + { .parent = &core_x2_ck, .rates = div4_rates }, + { .parent = NULL } +}; + +static struct clk mpu_dpll_hs_ck = { + .name = "mpu_dpll_hs_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .parent = &core_x2_ck, + .clksel_reg = OMAP4430_CM_BYPCLK_DPLL_MPU, + .clksel_mask = OMAP4430_CLKSEL_MASK, + .clksel = mpu_dpll_hs_ck_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct dpll_data dpll_mpu_dd = { + .mult_div1_reg = OMAP4430_CM_CLKSEL_DPLL_MPU, + .mult_mask = OMAP4430_CM2_DPLL_MULT_MASK, + .div1_mask = OMAP4430_CM2_DPLL_DIV_MASK, + .clk_bypass = &mpu_dpll_hs_ck, + .clk_ref = &dpll_sys_ref_ck, + .control_reg = OMAP4430_CM_CLKMODE_DPLL_MPU, + .enable_mask = OMAP4430_DPLL_EN_MASK, + .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), + .autoidle_reg = OMAP4430_CM_AUTOIDLE_DPLL_MPU, + .autoidle_mask = OMAP4430_AUTO_DPLL_MODE_MASK, + .idlest_reg = OMAP4430_CM_IDLEST_DPLL_MPU, + .idlest_mask = OMAP4430_ST_DPLL_CLK_MASK, +}; + +static struct clk dpll_mpu_ck = { + .name = "dpll_mpu_ck", + .ops = &clkops_null, + .parent = &dpll_sys_ref_ck, + .dpll_data = &dpll_mpu_dd, + .round_rate = &omap2_dpll_round_rate, + .set_rate = &omap4_noncore_dpll_set_rate, + .recalc = &omap4_dpll_recalc, +}; + +static const struct clksel dpll_mpu_m2_clksel[] = { + { .parent = &dpll_mpu_ck, .rates = div_mx_dpll_rates }, + { .parent = NULL } +}; + +static struct clk dpll_mpu_m2_ck = { + .name = "dpll_mpu_m2_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_MPU, + .clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK, + .clksel = dpll_mpu_m2_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk mpu_dpll_ck = { + .name = "mpu_dpll_ck", + .ops = &clkops_null, + .parent = &dpll_mpu_m2_ck, + .recalc = &followparent_recalc, +}; + +/* IVA DPLL */ + +static const struct clksel iva_dpll_hs_ck_clksel[] = { + { .parent = &core_x2_ck, .rates = div4_rates }, + { .parent = NULL } +}; + +static struct clk iva_dpll_hs_ck = { + .name = "iva_dpll_hs_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .parent = &core_x2_ck, + .clksel_reg = OMAP4430_CM_BYPCLK_DPLL_IVA, + .clksel_mask = OMAP4430_CLKSEL_MASK, + .clksel = iva_dpll_hs_ck_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct dpll_data dpll_iva_dd = { + .mult_div1_reg = OMAP4430_CM_CLKSEL_DPLL_IVA, + .mult_mask = OMAP4430_CM2_DPLL_MULT_MASK, + .div1_mask = OMAP4430_CM2_DPLL_DIV_MASK, + .clk_bypass = &iva_dpll_hs_ck, + .clk_ref = &dpll_sys_ref_ck, + .control_reg = OMAP4430_CM_CLKMODE_DPLL_IVA, + .enable_mask = OMAP4430_DPLL_EN_MASK, + .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), + .autoidle_reg = OMAP4430_CM_AUTOIDLE_DPLL_IVA, + .autoidle_mask = OMAP4430_AUTO_DPLL_MODE_MASK, + .idlest_reg = OMAP4430_CM_IDLEST_DPLL_IVA, + .idlest_mask = OMAP4430_ST_DPLL_CLK_MASK, +}; + +static struct clk dpll_iva_ck = { + .name = "dpll_iva_ck", + .ops = &clkops_null, + .parent = &dpll_sys_ref_ck, + .dpll_data = &dpll_iva_dd, + .round_rate = &omap2_dpll_round_rate, + .set_rate = &omap4_noncore_dpll_set_rate, + .recalc = &omap4_dpll_recalc, +}; + +static struct clk dpll_iva_x2_ck = { + .name = "dpll_iva_x2_ck", + .ops = &clkops_null, + .parent = &dpll_iva_ck, + .recalc = &omap4_clkoutx2_recalc, +}; + +static const struct clksel dpll_iva_x2mx_clksel[] = { + { .parent = &dpll_iva_x2_ck, .rates = div_mx_dpll_rates }, + { .parent = NULL } +}; + +static struct clk dpll_iva_x2m4_ck = { + .name = "dpll_iva_x2m4_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .clksel_reg = OMAP4430_CM_DIV_M4_DPLL_IVA, + .clksel_mask = OMAP4430_DPLL_CLKOUTHIF_DIV_MASK, + .clksel = dpll_iva_x2mx_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk dpll_iva_x2m5_ck = { + .name = "dpll_iva_x2m5_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .clksel_reg = OMAP4430_CM_DIV_M5_DPLL_IVA, + .clksel_mask = OMAP4430_DPLL_CLKOUTHIF_DIV_MASK, + .clksel = dpll_iva_x2mx_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk dsp_root_ck = { + .name = "dsp_root_ck", + .ops = &clkops_null, + .parent = &dpll_iva_x2m4_ck, + .recalc = &followparent_recalc, +}; + +static struct clk ivahd_ck = { + .name = "ivahd_ck", + .ops = &clkops_null, + .parent = &dpll_iva_x2m5_ck, + .recalc = &followparent_recalc, +}; + +/* UNIPRO DPLL */ + +static struct dpll_data dpll_unipro_dd = { + .mult_div1_reg = OMAP4430_CM_CLKSEL_DPLL_UNIPRO, + .mult_mask = OMAP4430_CM2_DPLL_MULT_MASK, + .div1_mask = OMAP4430_CM2_DPLL_DIV_MASK, + .clk_ref = &dpll_sys_ref_ck, + .control_reg = OMAP4430_CM_CLKMODE_DPLL_UNIPRO, + .enable_mask = OMAP4430_DPLL_EN_MASK, + .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), + .autoidle_reg = OMAP4430_CM_AUTOIDLE_DPLL_UNIPRO, + .autoidle_mask = OMAP4430_AUTO_DPLL_MODE_MASK, + .idlest_reg = OMAP4430_CM_IDLEST_DPLL_UNIPRO, + .idlest_mask = OMAP4430_ST_DPLL_CLK_MASK, +}; + +static struct clk dpll_unipro_ck = { + .name = "dpll_unipro_ck", + .ops = &clkops_null, + .parent = &dpll_sys_ref_ck, + .dpll_data = &dpll_unipro_dd, + .round_rate = &omap2_dpll_round_rate, + .set_rate = &omap4_noncore_dpll_set_rate, + .recalc = &omap4_dpll_recalc, +}; + +static struct clk dpll_unipro_x2_ck = { + .name = "dpll_unipro_x2_ck", + .ops = &clkops_null, + .parent = &dpll_unipro_ck, + .recalc = &omap4_clkoutx2_recalc, +}; + +static const struct clksel dpll_unipro_x2mx_clksel[] = { + { .parent = &dpll_unipro_x2_ck, .rates = div_mx_dpll_rates }, + { .parent = NULL } +}; + +static struct clk dpll_unipro_x2m2_ck = { + .name = "dpll_unipro_x2m2_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_UNIPRO, + .clksel_mask = OMAP4430_DPLL_CLKOUTHIF_DIV_MASK, + .clksel = dpll_unipro_x2mx_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk unipro1_phy_fck = { + .name = "unipro1_phy_fck", + .ops = &clkops_null, + .parent = &dpll_unipro_x2m2_ck, + .recalc = &followparent_recalc, +}; + +/* USB DPLL */ + +static struct dpll_data dpll_usb_dd = { + .mult_div1_reg = OMAP4430_CM_CLKSEL_DPLL_USB, + .mult_mask = OMAP4430_CM2_USB_DPLL_MULT_MASK, + .div1_mask = OMAP4430_CM2_USB_DPLL_DIV_MASK, + .clk_bypass = &usb_dpll_hs_ck, + .clk_ref = &dpll_sys_ref_ck, + .control_reg = OMAP4430_CM_CLKMODE_DPLL_USB, + .enable_mask = OMAP4430_DPLL_EN_MASK, + .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), + .autoidle_reg = OMAP4430_CM_AUTOIDLE_DPLL_USB, + .autoidle_mask = OMAP4430_AUTO_DPLL_MODE_MASK, + .idlest_reg = OMAP4430_CM_IDLEST_DPLL_USB, + .idlest_mask = OMAP4430_ST_DPLL_CLK_MASK, +}; + +static struct clk dpll_usb_ck = { + .name = "dpll_usb_ck", + .ops = &clkops_null, + .parent = &dpll_sys_ref_ck, + .dpll_data = &dpll_usb_dd, + .round_rate = &omap2_dpll_round_rate, + .set_rate = &omap4_noncore_dpll_set_rate, + .recalc = &omap4_dpll_recalc, +}; + +static const struct clksel dpll_usb_m2_clksel[] = { + { .parent = &dpll_usb_ck, .rates = div_mx_dpll_rates }, + { .parent = NULL } +}; + +static struct clk dpll_usb_m2_ck = { + .name = "dpll_usb_m2_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_USB, + .clksel_mask = OMAP4430_USB_DPLL_CLKOUT_DIV_MASK, + .clksel = dpll_usb_m2_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk init_480m_fck = { + .name = "init_480m_fck", + .ops = &clkops_null, + .parent = &dpll_usb_m2_ck, + .recalc = &followparent_recalc, +}; + +static struct clk dpll_usb_clkdcoldo = { + .name = "dpll_usb_clkdcoldo", + .ops = &clkops_null, + .parent = &dpll_usb_ck, + .recalc = &followparent_recalc, +}; + +static struct clk init_960m_fck = { + .name = "init_960m_fck", + .ops = &clkops_null, + .parent = &dpll_usb_clkdcoldo, + .recalc = &followparent_recalc, +}; + +/* CM1_USB nodes */ + +static const struct clksel_rate init_480m_fck_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_443X }, + { .div = 8, .val = 1, .flags = RATE_IN_443X | DEFAULT_RATE}, + { .div = 0 } +}; + +static const struct clksel init_60m_fck_clksel[] = { + { .parent = &init_480m_fck, .rates = init_480m_fck_rates }, + { .parent = NULL } +}; + +static struct clk init_60m_fck = { + .name = "init_60m_fck", + .ops = &clkops_null, + .parent = &init_480m_fck, + .clksel_reg = OMAP4430_CM_CLKSEL_USB_60MHZ, + .clksel_mask = OMAP4430_USB_60MHZ_CLKSEL_MASK, + .clksel = init_60m_fck_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk utmi_p3_fck = { + .name = "utmi_p3_fck", + .ops = &clkops_null, + .parent = &init_480m_fck, + .recalc = &followparent_recalc, +}; + +static struct clk init_60m_p1_fck = { + .name = "init_60m_p1_fck", + .ops = &clkops_null, + .parent = &init_480m_fck, + .recalc = &followparent_recalc, +}; + +static struct clk init_60m_p2_fck = { + .name = "init_60m_p2_fck", + .ops = &clkops_null, + .parent = &init_480m_fck, + .recalc = &followparent_recalc, +}; + +static struct clk utmi_root_gfck = { + .name = "utmi_root_gfck", + .ops = &clkops_null, + .parent = &init_480m_fck, + .recalc = &followparent_recalc, +}; + +static struct clk tll_ch0_fck = { + .name = "tll_ch0_fck", + .ops = &clkops_null, + .parent = &init_480m_fck, + .recalc = &followparent_recalc, +}; + +static struct clk tll_ch1_fck = { + .name = "tll_ch1_fck", + .ops = &clkops_null, + .parent = &init_480m_fck, + .recalc = &followparent_recalc, +}; + +static struct clk tll_ch2_fck = { + .name = "tll_ch2_fck", + .ops = &clkops_null, + .parent = &init_480m_fck, + .recalc = &followparent_recalc, +}; + +static struct clk hsic_p1_480m_fck = { + .name = "hsic_p1_480m_fck", + .ops = &clkops_null, + .parent = &init_480m_fck, + .recalc = &followparent_recalc, +}; + +static struct clk hsic_p2_480m_fck = { + .name = "hsic_p2_480m_fck", + .ops = &clkops_null, + .parent = &init_480m_fck, + .recalc = &followparent_recalc, +}; + +static const struct clksel_rate phy_clkout_ck_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 0 } +}; + +static const struct clksel_rate xclk_60m_otg_ck_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 0 } +}; + +static const struct clksel otg_60m_fck_clksel[] = { + { .parent = &phy_clkout_ck, .rates = phy_clkout_ck_rates }, + { .parent = &xclk_60m_otg_ck, .rates = xclk_60m_otg_ck_rates }, + { .parent = NULL } +}; + +static struct clk otg_60m_fck = { + .name = "otg_60m_fck", + .ops = &clkops_null, + .parent = &phy_clkout_ck, + .clksel_reg = OMAP4430_CM_L3INIT_USB_OTG_CLKCTRL, + .clksel_mask = OMAP4430_CLKSEL_60M_MASK, + .clksel = otg_60m_fck_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static const struct clksel_rate init_60m_p1_fck_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 0 } +}; + +static const struct clksel_rate xclk_60m_hsp1_ck_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 0 } +}; + +static const struct clksel utmi_p1_fck_clksel[] = { + { .parent = &init_60m_p1_fck, .rates = init_60m_p1_fck_rates }, + { .parent = &xclk_60m_hsp1_ck, .rates = xclk_60m_hsp1_ck_rates }, + { .parent = NULL } +}; + +static struct clk utmi_p1_fck = { + .name = "utmi_p1_fck", + .ops = &clkops_null, + .parent = &init_60m_p1_fck, + .clksel_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL, + .clksel_mask = OMAP4430_CLKSEL_UTMI_P1_MASK, + .clksel = utmi_p1_fck_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static const struct clksel_rate init_60m_p2_fck_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 0 } +}; + +static const struct clksel_rate xclk_60m_hsp2_ck_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 0 } +}; + +static const struct clksel utmi_p2_fck_clksel[] = { + { .parent = &init_60m_p2_fck, .rates = init_60m_p2_fck_rates }, + { .parent = &xclk_60m_hsp2_ck, .rates = xclk_60m_hsp2_ck_rates }, + { .parent = NULL } +}; + +static struct clk utmi_p2_fck = { + .name = "utmi_p2_fck", + .ops = &clkops_null, + .parent = &init_60m_p2_fck, + .clksel_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL, + .clksel_mask = OMAP4430_CLKSEL_UTMI_P2_MASK, + .clksel = utmi_p2_fck_clksel, + .recalc = &omap2_clksel_recalc, +}; + +/* CM1 nodes */ + +static const struct clksel core_ck_clksel[] = { + { .parent = &core_x2_ck, .rates = div2_rates }, + { .parent = NULL } +}; + +static struct clk core_ck = { + .name = "core_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .clksel_reg = OMAP4430_CM_CLKSEL_CORE, + .clksel_mask = OMAP4430_CLKSEL_CORE_MASK, + .clksel = core_ck_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static const struct clksel l3_ick_clksel[] = { + { .parent = &core_ck, .rates = div2_rates }, + { .parent = NULL } +}; + +static struct clk l3_ick = { + .name = "l3_ick", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .clksel_reg = OMAP4430_CM_CLKSEL_CORE, + .clksel_mask = OMAP4430_CM_CLKSEL_CORE_RESTORE_CLKSEL_L3_MASK, + .clksel = l3_ick_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static const struct clksel l4_root_ck_clksel[] = { + { .parent = &core_ck, .rates = div2_rates }, + { .parent = NULL } +}; + +static struct clk l4_root_ck = { + .name = "l4_root_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .clksel_reg = OMAP4430_CM_CLKSEL_CORE, + .clksel_mask = OMAP4430_CLKSEL_L4_MASK, + .clksel = l4_root_ck_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static struct clk per_24m_fck = { + .name = "per_24m_fck", + .ops = &clkops_null, + .parent = &omap_96m_alwon_ck, + .fixed_div = 4, + .recalc = &omap2_fixed_divisor_recalc, +}; + +/* CM2 nodes */ + +static const struct clksel_rate div124_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 2, .val = 1, .flags = RATE_IN_443X }, + { .div = 4, .val = 2, .flags = RATE_IN_443X }, + { .div = 0 } +}; + +static const struct clksel fdif_fck_clksel[] = { + { .parent = &omap_128m_fck, .rates = div124_rates }, + { .parent = NULL } +}; + +static struct clk fdif_fck = { + .name = "fdif_fck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .clksel_reg = OMAP4430_CM_CAM_FDIF_CLKCTRL, + .clksel_mask = OMAP4430_CLKSEL_FCLK_MASK, + .clksel = fdif_fck_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static const struct clksel hsi_fck_clksel[] = { + { .parent = &omap_192m_fck, .rates = div124_rates }, + { .parent = NULL } +}; + +static struct clk hsi_fck = { + .name = "hsi_fck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .clksel_reg = OMAP4430_CM_L3INIT_HSI_CLKCTRL, + .clksel_mask = OMAP4430_HSI_CLKSEL_MASK, + .clksel = hsi_fck_clksel, + .recalc = &omap2_clksel_recalc, +}; + +static const struct clksel_rate core_ck_rates[] = { + { .div = 1, .val = 0, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 0 } +}; + +static const struct clksel_rate per_mpu_m3_rates[] = { + { .div = 1, .val = 1, .flags = RATE_IN_443X | DEFAULT_RATE }, + { .div = 0 } +}; + +static const struct clksel mpu_m3_iss_ck_clksel[] = { + { .parent = &core_ck, .rates = core_ck_rates }, + { .parent = &per_mpu_m3, .rates = per_mpu_m3_rates }, + { .parent = NULL } +}; + +static struct clk mpu_m3_iss_ck = { + .name = "mpu_m3_iss_ck", + .ops = &clkops_null, + .init = &omap2_init_clksel_parent, + .parent = &core_ck, + .clksel_reg = OMAP4430_CM_CLKSEL_DUCATI_ISS_ROOT, + .clksel_mask = OMAP4430_MPU_M3_ISS_ROOT_CLKSEL_MASK, + .clksel = mpu_m3_iss_ck_clksel, + .recalc = &omap2_clksel_recalc, +}; + +#endif diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h index 1d3c93bf86d3..5e6d255a34db 100644 --- a/arch/arm/mach-omap2/cm.h +++ b/arch/arm/mach-omap2/cm.h @@ -4,10 +4,11 @@ /* * OMAP2/3 Clock Management (CM) register definitions * - * Copyright (C) 2007-2008 Texas Instruments, Inc. + * Copyright (C) 2007-2009 Texas Instruments, Inc. * Copyright (C) 2007-2008 Nokia Corporation * * Written by Paul Walmsley + * Updated for OMAP4 by 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 version 2 as @@ -22,6 +23,10 @@ IO_ADDRESS(OMAP2430_CM_BASE + (module) + (reg)) #define OMAP34XX_CM_REGADDR(module, reg) \ IO_ADDRESS(OMAP3430_CM_BASE + (module) + (reg)) +#define OMAP44XX_CM1_REGADDR(module, reg) \ + IO_ADDRESS(OMAP4430_CM1_BASE + (module) + (reg)) +#define OMAP44XX_CM2_REGADDR(module, reg) \ + IO_ADDRESS(OMAP4430_CM2_BASE + (module) + (reg)) /* * Architecture-specific global CM registers @@ -89,6 +94,264 @@ #define OMAP3430_CM_CLKSEL2_EMU 0x0050 #define OMAP3430_CM_CLKSEL3_EMU 0x0054 +#define OMAP4430_CM_CLKSEL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x0) +#define OMAP4430_CM_CLKSEL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x8) +#define OMAP4430_CM_DLL_CTRL OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x10) +#define OMAP4430_CM_CLKMODE_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x20) +#define OMAP4430_CM_IDLEST_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x24) +#define OMAP4430_CM_AUTOIDLE_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x28) +#define OMAP4430_CM_CLKSEL_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x2C) +#define OMAP4430_CM_DIV_M2_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x30) +#define OMAP4430_CM_DIV_M3_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x34) +#define OMAP4430_CM_DIV_M4_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x38) +#define OMAP4430_CM_DIV_M5_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x3C) +#define OMAP4430_CM_DIV_M6_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x40) +#define OMAP4430_CM_DIV_M7_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x44) +#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x48) +#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x4C) +#define OMAP4430_CM_EMU_OVERRIDE_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x50) +#define OMAP4430_CM_CLKMODE_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x60) +#define OMAP4430_CM_IDLEST_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x64) +#define OMAP4430_CM_AUTOIDLE_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x68) +#define OMAP4430_CM_CLKSEL_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x6C) +#define OMAP4430_CM_DIV_M2_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x70) +#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x88) +#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x8C) +#define OMAP4430_CM_BYPCLK_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x9C) +#define OMAP4430_CM_CLKMODE_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0xA0) +#define OMAP4430_CM_IDLEST_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0xA4) +#define OMAP4430_CM_AUTOIDLE_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0xA8) +#define OMAP4430_CM_CLKSEL_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0xAC) +#define OMAP4430_CM_DIV_M4_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0xB8) +#define OMAP4430_CM_DIV_M5_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0xBC) +#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0xC8) +#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0xCC) +#define OMAP4430_CM_BYPCLK_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0xDC) +#define OMAP4430_CM_CLKMODE_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0xE0) +#define OMAP4430_CM_IDLEST_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0xE4) +#define OMAP4430_CM_AUTOIDLE_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0xE8) +#define OMAP4430_CM_CLKSEL_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0xEC) +#define OMAP4430_CM_DIV_M2_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0xF0) +#define OMAP4430_CM_DIV_M3_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0xF4) +#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x108) +#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x10C) +#define OMAP4430_CM_CLKMODE_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x120) +#define OMAP4430_CM_IDLEST_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x124) +#define OMAP4430_CM_AUTOIDLE_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x128) +#define OMAP4430_CM_CLKSEL_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x12C) +#define OMAP4430_CM_DIV_M2_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x130) +#define OMAP4430_CM_DIV_M4_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x138) +#define OMAP4430_CM_DIV_M5_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x13C) +#define OMAP4430_CM_DIV_M6_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x140) +#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x148) +#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x14C) +#define OMAP4430_CM_SHADOW_FREQ_CONFIG1 OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x160) +#define OMAP4430_CM_SHADOW_FREQ_CONFIG2 OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x164) +#define OMAP4430_CM_DYN_DEP_PRESCAL OMAP44XX_CM1_REGADDR(OMAP4430_CKGEN_MOD, 0x170) +#define OMAP4430_CM1_ABE_CLKSTCTRL OMAP44XX_CM1_REGADDR(OMAP4430_ABE_MOD, 0x0) +#define OMAP4430_CM1_ABE_L4ABE_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_ABE_MOD, 0x20) +#define OMAP4430_CM1_ABE_AESS_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_ABE_MOD, 0x28) +#define OMAP4430_CM1_ABE_PDM_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_ABE_MOD, 0x30) +#define OMAP4430_CM1_ABE_DMIC_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_ABE_MOD, 0x38) +#define OMAP4430_CM1_ABE_MCASP_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_ABE_MOD, 0x40) +#define OMAP4430_CM1_ABE_MCBSP1_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_ABE_MOD, 0x48) +#define OMAP4430_CM1_ABE_MCBSP2_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_ABE_MOD, 0x50) +#define OMAP4430_CM1_ABE_MCBSP3_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_ABE_MOD, 0x58) +#define OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_ABE_MOD, 0x60) +#define OMAP4430_CM1_ABE_TIMER5_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_ABE_MOD, 0x68) +#define OMAP4430_CM1_ABE_TIMER6_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_ABE_MOD, 0x70) +#define OMAP4430_CM1_ABE_TIMER7_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_ABE_MOD, 0x78) +#define OMAP4430_CM1_ABE_TIMER8_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_ABE_MOD, 0x80) +#define OMAP4430_CM1_ABE_WDT3_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_ABE_MOD, 0x88) +#define OMAP4430_CM_MPU_CLKSTCTRL OMAP44XX_CM1_REGADDR(OMAP4430_MPU_MOD, 0x0) +#define OMAP4430_CM_MPU_STATICDEP OMAP44XX_CM1_REGADDR(OMAP4430_MPU_MOD, 0x4) +#define OMAP4430_CM_MPU_DYNAMICDEP OMAP44XX_CM1_REGADDR(OMAP4430_MPU_MOD, 0x8) +#define OMAP4430_CM_MPU_MPU_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_MPU_MOD, 0x20) +#define OMAP4430_CM_TESLA_CLKSTCTRL OMAP44XX_CM1_REGADDR(OMAP4430_DSP_MOD, 0x0) +#define OMAP4430_CM_TESLA_STATICDEP OMAP44XX_CM1_REGADDR(OMAP4430_DSP_MOD, 0x4) +#define OMAP4430_CM_TESLA_DYNAMICDEP OMAP44XX_CM1_REGADDR(OMAP4430_DSP_MOD, 0x8) +#define OMAP4430_CM_TESLA_TESLA_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_DSP_MOD, 0x20) +#define OMAP4430_REVISION_CM1 OMAP44XX_CM1_REGADDR(OMAP4430_OCP_SOCKET_MOD, 0x0) +#define OMAP4430_CM_CM1_PROFILING_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_OCP_SOCKET_MOD, 0x40) + +#define OMAP4430_CM_CAM_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CAM_MOD, 0x0) +#define OMAP4430_CM_CAM_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CAM_MOD, 0x4) +#define OMAP4430_CM_CAM_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CAM_MOD, 0x8) +#define OMAP4430_CM_CAM_ISS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CAM_MOD, 0x20) +#define OMAP4430_CM_CAM_FDIF_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CAM_MOD, 0x28) +#define OMAP4430_CM_L3INIT_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L3INIT_MOD, 0x0) +#define OMAP4430_CM_L3INIT_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_L3INIT_MOD, 0x4) +#define OMAP4430_CM_L3INIT_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_L3INIT_MOD, 0x8) +#define OMAP4430_CM_L3INIT_MMC1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L3INIT_MOD, 0x28) +#define OMAP4430_CM_L3INIT_MMC2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L3INIT_MOD, 0x30) +#define OMAP4430_CM_L3INIT_HSI_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L3INIT_MOD, 0x38) +#define OMAP4430_CM_L3INIT_UNIPRO1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L3INIT_MOD, 0x40) +#define OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L3INIT_MOD, 0x58) +#define OMAP4430_CM_L3INIT_USB_OTG_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L3INIT_MOD, 0x60) +#define OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L3INIT_MOD, 0x68) +#define OMAP4430_CM_L3INIT_P1500_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L3INIT_MOD, 0x78) +#define OMAP4430_CM_L3INIT_EMAC_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L3INIT_MOD, 0x80) +#define OMAP4430_CM_L3INIT_SATA_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L3INIT_MOD, 0x88) +#define OMAP4430_CM_L3INIT_TPPSS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L3INIT_MOD, 0x90) +#define OMAP4430_CM_L3INIT_PCIESS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L3INIT_MOD, 0x98) +#define OMAP4430_CM_L3INIT_CCPTX_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L3INIT_MOD, 0xA8) +#define OMAP4430_CM_L3INIT_XHPI_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L3INIT_MOD, 0xC0) +#define OMAP4430_CM_L3INIT_MMC6_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L3INIT_MOD, 0xC8) +#define OMAP4430_CM_L3INIT_USB_HOST_FS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L3INIT_MOD, 0xD0) +#define OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L3INIT_MOD, 0xE0) +#define OMAP4430_CM_IVAHD_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_IVAHD_MOD, 0x0) +#define OMAP4430_CM_IVAHD_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_IVAHD_MOD, 0x4) +#define OMAP4430_CM_IVAHD_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_IVAHD_MOD, 0x8) +#define OMAP4430_CM_IVAHD_IVAHD_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_IVAHD_MOD, 0x20) +#define OMAP4430_CM_IVAHD_SL2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_IVAHD_MOD, 0x28) +#define OMAP4430_CM_DSS_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_DSS_MOD, 0x0) +#define OMAP4430_CM_DSS_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_DSS_MOD, 0x4) +#define OMAP4430_CM_DSS_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_DSS_MOD, 0x8) +#define OMAP4430_CM_DSS_DSS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_DSS_MOD, 0x20) +#define OMAP4430_CM_DSS_DEISS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_DSS_MOD, 0x28) +#define OMAP4430_CM_L4PER_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x0) +#define OMAP4430_CM_L4PER_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x8) +#define OMAP4430_CM_L4PER_ADC_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x20) +#define OMAP4430_CM_L4PER_GPTIMER10_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x28) +#define OMAP4430_CM_L4PER_GPTIMER11_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x30) +#define OMAP4430_CM_L4PER_GPTIMER2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x38) +#define OMAP4430_CM_L4PER_GPTIMER3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x40) +#define OMAP4430_CM_L4PER_GPTIMER4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x48) +#define OMAP4430_CM_L4PER_GPTIMER9_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x50) +#define OMAP4430_CM_L4PER_ELM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x58) +#define OMAP4430_CM_L4PER_GPIO2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x60) +#define OMAP4430_CM_L4PER_GPIO3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x68) +#define OMAP4430_CM_L4PER_GPIO4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x70) +#define OMAP4430_CM_L4PER_GPIO5_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x78) +#define OMAP4430_CM_L4PER_GPIO6_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x80) +#define OMAP4430_CM_L4PER_HDQ1W_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x88) +#define OMAP4430_CM_L4PER_HECC1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x90) +#define OMAP4430_CM_L4PER_HECC2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x98) +#define OMAP4430_CM_L4PER_I2C1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0xA0) +#define OMAP4430_CM_L4PER_I2C2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0xA8) +#define OMAP4430_CM_L4PER_I2C3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0xB0) +#define OMAP4430_CM_L4PER_I2C4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0xB8) +#define OMAP4430_CM_L4PER_L4PER_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0xC0) +#define OMAP4430_CM_L4PER_MCASP2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0xD0) +#define OMAP4430_CM_L4PER_MCASP3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0xD8) +#define OMAP4430_CM_L4PER_MCBSP4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0xE0) +#define OMAP4430_CM_L4PER_MGATE_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0xE8) +#define OMAP4430_CM_L4PER_MCSPI1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0xF0) +#define OMAP4430_CM_L4PER_MCSPI2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0xF8) +#define OMAP4430_CM_L4PER_MCSPI3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x100) +#define OMAP4430_CM_L4PER_MCSPI4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x108) +#define OMAP4430_CM_L4PER_MMCSD3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x120) +#define OMAP4430_CM_L4PER_MMCSD4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x128) +#define OMAP4430_CM_L4PER_MSPROHG_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x130) +#define OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x138) +#define OMAP4430_CM_L4PER_UART1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x140) +#define OMAP4430_CM_L4PER_UART2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x148) +#define OMAP4430_CM_L4PER_UART3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x150) +#define OMAP4430_CM_L4PER_UART4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x158) +#define OMAP4430_CM_L4PER_MMCSD5_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x160) +#define OMAP4430_CM_L4SEC_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x180) +#define OMAP4430_CM_L4SEC_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x184) +#define OMAP4430_CM_L4SEC_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x188) +#define OMAP4430_CM_L4SEC_AES1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x1A0) +#define OMAP4430_CM_L4SEC_AES2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x1A8) +#define OMAP4430_CM_L4SEC_DES3DES_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x1B0) +#define OMAP4430_CM_L4SEC_PKAEIP29_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x1B8) +#define OMAP4430_CM_L4SEC_RNG_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x1C0) +#define OMAP4430_CM_L4SEC_SHA2MD51_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x1C8) +#define OMAP4430_CM_L4SEC_CRYPTODMA_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_L4PER_MOD, 0x1D8) +#define OMAP4430_CM_GFX_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_GFX_MOD, 0x0) +#define OMAP4430_CM_GFX_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_GFX_MOD, 0x4) +#define OMAP4430_CM_GFX_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_GFX_MOD, 0x8) +#define OMAP4430_CM_GFX_GFX_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_GFX_MOD, 0x20) +#define OMAP4430_CM_L3_1_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x0) +#define OMAP4430_CM_L3_1_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x8) +#define OMAP4430_CM_L3_1_L3_1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x20) +#define OMAP4430_CM_L3_2_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x100) +#define OMAP4430_CM_L3_2_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x108) +#define OMAP4430_CM_L3_2_L3_2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x120) +#define OMAP4430_CM_L3_2_GPMC_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x128) +#define OMAP4430_CM_L3_2_OCMC_RAM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x130) +#define OMAP4430_CM_DUCATI_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x200) +#define OMAP4430_CM_DUCATI_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x204) +#define OMAP4430_CM_DUCATI_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x208) +#define OMAP4430_CM_DUCATI_DUCATI_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x220) +#define OMAP4430_CM_SDMA_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x300) +#define OMAP4430_CM_SDMA_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x304) +#define OMAP4430_CM_SDMA_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x308) +#define OMAP4430_CM_SDMA_SDMA_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x320) +#define OMAP4430_CM_MEMIF_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x400) +#define OMAP4430_CM_MEMIF_DMM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x420) +#define OMAP4430_CM_MEMIF_EMIF_FW_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x428) +#define OMAP4430_CM_MEMIF_EMIF_1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x430) +#define OMAP4430_CM_MEMIF_EMIF_2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x438) +#define OMAP4430_CM_MEMIF_DLL_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x440) +#define OMAP4430_CM_MEMIF_EMIF_H1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x450) +#define OMAP4430_CM_MEMIF_EMIF_H2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x458) +#define OMAP4430_CM_MEMIF_DLL_H_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x460) +#define OMAP4430_CM_D2D_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x500) +#define OMAP4430_CM_D2D_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x504) +#define OMAP4430_CM_D2D_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x508) +#define OMAP4430_CM_D2D_SAD2D_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x520) +#define OMAP4430_CM_D2D_MODEM_ICR_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x528) +#define OMAP4430_CM_L4CFG_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x600) +#define OMAP4430_CM_L4CFG_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x608) +#define OMAP4430_CM_L4CFG_L4_CFG_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x620) +#define OMAP4430_CM_L4CFG_HW_SEM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x628) +#define OMAP4430_CM_L4CFG_MAILBOX_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x630) +#define OMAP4430_CM_L4CFG_SAR_ROM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x638) +#define OMAP4430_CM_L3INSTR_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x700) +#define OMAP4430_CM_L3INSTR_L3_3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x720) +#define OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x728) +#define OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CORE_MOD, 0x740) +#define OMAP4430_CM_CEFUSE_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CEFUSE_MOD, 0x0) +#define OMAP4430_CM_CEFUSE_CEFUSE_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CEFUSE_MOD, 0x20) +#define OMAP4430_REVISION_CM2 OMAP44XX_CM2_REGADDR(OMAP4430_OCP_SOCKET_MOD, 0x0) +#define OMAP4430_CM_CM2_PROFILING_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_OCP_SOCKET_MOD, 0x40) +#define OMAP4430_CM_CLKSEL_DUCATI_ISS_ROOT OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x0) +#define OMAP4430_CM_CLKSEL_USB_60MHZ OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x4) +#define OMAP4430_CM_SCALE_FCLK OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x8) +#define OMAP4430_CM_CORE_DVFS_PERF1 OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x10) +#define OMAP4430_CM_CORE_DVFS_PERF2 OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x14) +#define OMAP4430_CM_CORE_DVFS_PERF3 OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x18) +#define OMAP4430_CM_CORE_DVFS_PERF4 OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x1C) +#define OMAP4430_CM_CORE_DVFS_CURRENT OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x24) +#define OMAP4430_CM_IVA_DVFS_PERF_TESLA OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x28) +#define OMAP4430_CM_IVA_DVFS_PERF_IVAHD OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x2C) +#define OMAP4430_CM_IVA_DVFS_PERF_ABE OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x30) +#define OMAP4430_CM_IVA_DVFS_CURRENT OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x38) +#define OMAP4430_CM_CLKMODE_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x40) +#define OMAP4430_CM_IDLEST_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x44) +#define OMAP4430_CM_AUTOIDLE_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x48) +#define OMAP4430_CM_CLKSEL_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x4C) +#define OMAP4430_CM_DIV_M2_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x50) +#define OMAP4430_CM_DIV_M3_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x54) +#define OMAP4430_CM_DIV_M4_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x58) +#define OMAP4430_CM_DIV_M5_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x5C) +#define OMAP4430_CM_DIV_M6_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x60) +#define OMAP4430_CM_DIV_M7_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x64) +#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x68) +#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x6C) +#define OMAP4430_CM_EMU_OVERRIDE_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x70) +#define OMAP4430_CM_CLKMODE_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x80) +#define OMAP4430_CM_IDLEST_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x84) +#define OMAP4430_CM_AUTOIDLE_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x88) +#define OMAP4430_CM_CLKSEL_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x8C) +#define OMAP4430_CM_DIV_M2_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0x90) +#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0xA8) +#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0xAC) +#define OMAP4430_CM_CLKDCOLDO_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0xB4) +#define OMAP4430_CM_CLKMODE_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0xC0) +#define OMAP4430_CM_IDLEST_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0xC4) +#define OMAP4430_CM_AUTOIDLE_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0xC8) +#define OMAP4430_CM_CLKSEL_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0xCC) +#define OMAP4430_CM_DIV_M2_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0xD0) +#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0xE8) +#define OMAP4430_CM_SSC_MODFREQDIV_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CKGEN_MOD, 0xEC) +#define OMAP4430_CM_ALWON_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_ALWAYS_ON_MOD, 0x0) +#define OMAP4430_CM_ALWON_MDMINTC_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_ALWAYS_ON_MOD, 0x20) +#define OMAP4430_CM_ALWON_SR_MPU_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_ALWAYS_ON_MOD, 0x28) +#define OMAP4430_CM_ALWON_SR_IVA_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_ALWAYS_ON_MOD, 0x30) +#define OMAP4430_CM_ALWON_SR_CORE_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_ALWAYS_ON_MOD, 0x38) /* Clock management domain register get/set */ diff --git a/arch/arm/mach-omap2/cm1-regbits-44xx.h b/arch/arm/mach-omap2/cm1-regbits-44xx.h new file mode 100644 index 000000000000..c2081851dd13 --- /dev/null +++ b/arch/arm/mach-omap2/cm1-regbits-44xx.h @@ -0,0 +1,325 @@ +#ifndef __ARCH_ARM_MACH_OMAP2_CM1_REGBITS_44XX_H +#define __ARCH_ARM_MACH_OMAP2_CM1_REGBITS_44XX_H + +/* + * OMAP4430 Clock Management Module1 register bits + * + * Copyright (C) 2009 Texas Instruments, Inc. + * + * Written by 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 version 2 as + * published by the Free Software Foundation. + */ + +#include "cm.h" + +#define OMAP4430_CLKSEL_L4 (1 << 8) +#define OMAP4430_CM_CLKSEL_CORE_CLKSEL_L3 (1 << 4) +#define OMAP4430_CLKSEL_CORE (1 << 0) +#define OMAP4430_SLIMBUS_CLK_GATE (1 << 10) +#define OMAP4430_PAD_CLKS_GATE (1 << 8) +#define OMAP4430_CLKSEL_OPP (1 << 0) +#define OMAP4430_CM_DLL_CTRL_DLL_OVERRIDE (1 << 0) +#define OMAP4430_DPLL_SSC_TYPE (1 << 15) +#define OMAP4430_DPLL_SSC_DOWNSPREAD (1 << 14) +#define OMAP4430_DPLL_SSC_ACK (1 << 13) +#define OMAP4430_DPLL_SSC_EN (1 << 12) +#define OMAP4430_DPLL_REGM4XEN (1 << 11) +#define OMAP4430_DPLL_LPMODE_EN (1 << 10) +#define OMAP4430_DPLL_RELOCK_RAMP_EN (1 << 9) +#define OMAP4430_DPLL_RAMP_RATE (1 << 6) +#define OMAP4430_DPLL_RAMP_LEVEL (1 << 4) +#define OMAP4430_DPLL_DRIFTGUARD_EN (1 << 3) +#define OMAP4430_DPLL_EN (1 << 0) +#define OMAP4430_DPLL_DCOCLKLDO_PWDN (1 << 4) +#define OMAP4430_AUTO_DPLL_MODE (1 << 0) +#define OMAP4430_DPLL_BYP_CLKSEL (1 << 23) +#define OMAP4430_DPLL_CLKOUTHIF_CLKSEL (1 << 20) +#define OMAP4430_DPLL_MULT (1 << 8) +#define OMAP4430_DPLL_DIV (1 << 0) +#define OMAP4430_DPLL_M2_PWDN (1 << 12) +#define OMAP4430_ST_DPLL_CLKOUT (1 << 9) +#define OMAP4430_DPLL_CLKOUT_GATE_CTRL (1 << 8) +#define OMAP4430_DPLL_CLKOUT_DIVCHACK (1 << 5) +#define OMAP4430_DPLL_CLKOUT_DIV (1 << 0) +#define OMAP4430_DPLL_M3_PWDN (1 << 12) +#define OMAP4430_ST_DPLL_CLKOUTHIF (1 << 9) +#define OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL (1 << 8) +#define OMAP4430_DPLL_CLKOUTHIF_DIVCHACK (1 << 5) +#define OMAP4430_DPLL_CLKOUTHIF_DIV (1 << 0) +#define OMAP4430_HSDIVIDER_CLKOUT1_PWDN (1 << 12) +#define OMAP4430_ST_HSDIVIDER_CLKOUT1 (1 << 9) +#define OMAP4430_HSDIVIDER_CLKOUT1_GATE_CTRL (1 << 8) +#define OMAP4430_HSDIVIDER_CLKOUT1_DIVCHACK (1 << 5) +#define OMAP4430_HSDIVIDER_CLKOUT1_DIV (1 << 0) +#define OMAP4430_HSDIVIDER_CLKOUT2_PWDN (1 << 12) +#define OMAP4430_ST_HSDIVIDER_CLKOUT2 (1 << 9) +#define OMAP4430_HSDIVIDER_CLKOUT2_GATE_CTRL (1 << 8) +#define OMAP4430_HSDIVIDER_CLKOUT2_DIVCHACK (1 << 5) +#define OMAP4430_HSDIVIDER_CLKOUT2_DIV (1 << 0) +#define OMAP4430_HSDIVIDER_CLKOUT3_PWDN (1 << 12) +#define OMAP4430_ST_HSDIVIDER_CLKOUT3 (1 << 9) +#define OMAP4430_HSDIVIDER_CLKOUT3_GATE_CTRL (1 << 8) +#define OMAP4430_HSDIVIDER_CLKOUT3_DIVCHACK (1 << 5) +#define OMAP4430_HSDIVIDER_CLKOUT3_DIV (1 << 0) +#define OMAP4430_HSDIVIDER_CLKOUT4_PWDN (1 << 12) +#define OMAP4430_ST_HSDIVIDER_CLKOUT4 (1 << 9) +#define OMAP4430_HSDIVIDER_CLKOUT4_GATE_CTRL (1 << 8) +#define OMAP4430_HSDIVIDER_CLKOUT4_DIVCHACK (1 << 5) +#define OMAP4430_HSDIVIDER_CLKOUT4_DIV (1 << 0) +#define OMAP4430_DELTAMSTEP (1 << 0) +#define OMAP4430_MODFREQDIV_EXPONENT (1 << 8) +#define OMAP4430_MODFREQDIV_MANTISSA (1 << 0) +#define OMAP4430_OVERRIDE_ENABLE (1 << 19) +#define OMAP4430_CORE_DPLL_EMU_MULT (1 << 8) +#define OMAP4430_RESERVED (1 << 7) +#define OMAP4430_CORE_DPLL_EMU_DIV (1 << 0) +#define OMAP4430_ST_DPLL_CLK (1 << 0) +#define OMAP4430_BYPCLK_DPLL_CLKSEL (1 << 0) +#define OMAP4430_DPLL_DCOCLKLDO_PWDN (1 << 4) +#define OMAP4430_ST_DPLL_CLKOUTX2 (1 << 11) +#define OMAP4430_DPLL_CLKOUTX2_GATE_CTRL (1 << 10) +#define OMAP4430_DPLL_DCOCLKLDO_PWDN (1 << 4) +#define OMAP4430_DPLL_DDRPHY_M6_DIV (1 << 24) +#define OMAP4430_DPLL_DDRPHY_M5_DIV (1 << 19) +#define OMAP4430_DPLL_DDRPHY_DPLL_EN (1 << 16) +#define OMAP4430_DPLL_CORE_M2_DIV (1 << 11) +#define OMAP4430_DPLL_CORE_DPLL_EN (1 << 8) +#define OMAP4430_DLL_RESET (1 << 3) +#define OMAP4430_CM_SHADOW_FREQ_CONFIG1_DLL_OVERRIDE (1 << 2) +#define OMAP4430_DPLL_CORE_SYS_REF_CLKSEL (1 << 1) +#define OMAP4430_FREQ_UPDATE (1 << 0) +#define OMAP4430_DPLL_CORE_M5_DIV (1 << 3) +#define OMAP4430_CM_SHADOW_FREQ_CONFIG2_CLKSEL_L3 (1 << 2) +#define OMAP4430_CM_SHADOW_FREQ_CONFIG2_CLKSEL_CORE (1 << 1) +#define OMAP4430_GPMC_FREQ_UPDATE (1 << 0) +#define OMAP4430_PRESCAL (1 << 0) +#define OMAP4430_CLKACTIVITY_ABE_24M_GFCLK (1 << 13) +#define OMAP4430_CLKACTIVITY_ABE_ALWON_32K_CLK (1 << 12) +#define OMAP4430_CLKACTIVITY_ABE_SYSCLK (1 << 11) +#define OMAP4430_CLKACTIVITY_FUNC_24M_GFCLK (1 << 10) +#define OMAP4430_CLKACTIVITY_OCP_ABE_GICLK (1 << 9) +#define OMAP4430_CLKACTIVITY_ABE_X2_CLK (1 << 8) +#define OMAP4430_CLKTRCTRL (1 << 0) +#define OMAP4430_IDLEST (1 << 16) +#define OMAP4430_MODULEMODE (1 << 0) +#define OMAP4430_CLKSEL_AESS_FCLK (1 << 24) +#define OMAP4430_STBYST (1 << 18) +#define OMAP4430_ABE_CLKSEL_INTERNAL_SOURCE (1 << 26) +#define OMAP4430_CLKSEL_SOURCE (1 << 24) +#define OMAP4430_ABE_OPTFCLKEN_SLIMBUS_CLK (1 << 11) +#define OMAP4430_OPTFCLKEN_FCLK2 (1 << 10) +#define OMAP4430_OPTFCLKEN_FCLK1 (1 << 9) +#define OMAP4430_OPTFCLKEN_FCLK0 (1 << 8) +#define OMAP4430_ABE_GPTIMER_CLKCTRL_CLKSEL (1 << 24) +#define OMAP4430_CLKACTIVITY_MPU_DPLL_CLK (1 << 8) +#define OMAP4430_D2D_STATDEP (1 << 18) +#define OMAP4430_CEFUSE_STATDEP (1 << 17) +#define OMAP4430_ALWONCORE_STATDEP (1 << 16) +#define OMAP4430_L4WKUP_STATDEP (1 << 15) +#define OMAP4430_L4SEC_STATDEP (1 << 14) +#define OMAP4430_L4PER_STATDEP (1 << 13) +#define OMAP4430_L4CFG_STATDEP (1 << 12) +#define OMAP4430_SDMA_STATDEP (1 << 11) +#define OMAP4430_GFX_STATDEP (1 << 10) +#define OMAP4430_ISS_STATDEP (1 << 9) +#define OMAP4430_DSS_STATDEP (1 << 8) +#define OMAP4430_L3INIT_STATDEP (1 << 7) +#define OMAP4430_L3_2_STATDEP (1 << 6) +#define OMAP4430_L3_1_STATDEP (1 << 5) +#define OMAP4430_MEMIF_STATDEP (1 << 4) +#define OMAP4430_ABE_STATDEP (1 << 3) +#define OMAP4430_IVAHD_STATDEP (1 << 2) +#define OMAP4430_TESLA_STATDEP (1 << 1) +#define OMAP4430_DUCATI_STATDEP (1 << 0) +#define OMAP4430_WINDOWSIZE (1 << 24) +#define OMAP4430_L3_1_DYNDEP (1 << 5) +#define OMAP4430_MEMIF_DYNDEP (1 << 4) +#define OMAP4430_ABE_DYNDEP (1 << 3) +#define OMAP4430_CLKACTIVITY_TESLA_ROOT_CLK (1 << 8) +#define OMAP4430_CEFUSE_STATDEP (1 << 17) +#define OMAP4430_ALWONCORE_STATDEP (1 << 16) +#define OMAP4430_L4WKUP_STATDEP (1 << 15) +#define OMAP4430_L4PER_STATDEP (1 << 13) +#define OMAP4430_L4CFG_STATDEP (1 << 12) +#define OMAP4430_ISS_STATDEP (1 << 9) +#define OMAP4430_L3INIT_STATDEP (1 << 7) +#define OMAP4430_L3_2_STATDEP (1 << 6) +#define OMAP4430_L3_1_STATDEP (1 << 5) +#define OMAP4430_MEMIF_STATDEP (1 << 4) +#define OMAP4430_ABE_STATDEP (1 << 3) +#define OMAP4430_IVAHD_STATDEP (1 << 2) +#define OMAP4430_WINDOWSIZE (1 << 24) +#define OMAP4430_L3_1_DYNDEP (1 << 5) +#define OMAP4430_ABE_DYNDEP (1 << 3) +#define OMAP4430_IVAHD_DYNDEP (1 << 2) +#define OMAP4430_CLKACTIVITY_BGAP_32K_GFCLK (1 << 12) +#define OMAP4430_CLKACTIVITY_SR_CORE_SYSCLK (1 << 11) +#define OMAP4430_CLKACTIVITY_SR_IVA_SYSCLK (1 << 10) +#define OMAP4430_CLKACTIVITY_SR_MPU_SYSCLK (1 << 9) +#define OMAP4430_CLKACTIVITY_L4_AO_ICLK (1 << 8) +#define OMAP4430_OPTFCLKEN_BGAP_32K (1 << 8) +#define OMAP4430_REV (1 << 0) + + +#define OMAP4430_CLKSEL_L4_MASK BITFIELD(8, 8) +#define OMAP4430_CM_CLKSEL_CORE_RESTORE_CLKSEL_L3_MASK BITFIELD(4, 4) +#define OMAP4430_CLKSEL_CORE_MASK BITFIELD(0, 0) +#define OMAP4430_SLIMBUS_CLK_GATE_MASK BITFIELD(10, 10) +#define OMAP4430_PAD_CLKS_GATE_MASK BITFIELD(8, 8) +#define OMAP4430_CLKSEL_OPP_MASK BITFIELD(1, 0) +#define OMAP4430_CM_DLL_CTRL_DLL_OVERRIDE_MASK BITFIELD(0, 0) +#define OMAP4430_DPLL_SSC_TYPE_MASK BITFIELD(15, 15) +#define OMAP4430_DPLL_SSC_DOWNSPREAD_MASK BITFIELD(14, 14) +#define OMAP4430_DPLL_SSC_ACK_MASK BITFIELD(13, 13) +#define OMAP4430_DPLL_SSC_EN_MASK BITFIELD(12, 12) +#define OMAP4430_DPLL_REGM4XEN_MASK BITFIELD(11, 11) +#define OMAP4430_DPLL_LPMODE_EN_MASK BITFIELD(10, 10) +#define OMAP4430_DPLL_RELOCK_RAMP_EN_MASK BITFIELD(9, 9) +#define OMAP4430_DPLL_RAMP_RATE_MASK BITFIELD(8, 6) +#define OMAP4430_DPLL_RAMP_LEVEL_MASK BITFIELD(5, 4) +#define OMAP4430_DPLL_DRIFTGUARD_EN_MASK BITFIELD(3, 3) +#define OMAP4430_DPLL_EN_MASK BITFIELD(2, 0) +#define OMAP4430_ST_DPLL_CLK_MASK BITFIELD(0, 0) +#define OMAP4430_DPLL_DCOCLKLDO_PWDN_MASK BITFIELD(4, 4) +#define OMAP4430_AUTO_DPLL_MODE_MASK BITFIELD(2, 0) +#define OMAP4430_DPLL_BYP_CLKSEL_MASK BITFIELD(23, 23) +#define OMAP4430_DPLL_CLKOUTHIF_CLKSEL_MASK BITFIELD(20, 20) +#define OMAP4430_CM1_DPLL_MULT_MASK BITFIELD(18, 8) +#define OMAP4430_CM1_DPLL_DIV_MASK BITFIELD(6, 0) +#define OMAP4430_DPLL_M2_PWDN_MASK BITFIELD(12, 12) +#define OMAP4430_ST_DPLL_CLKOUT_MASK BITFIELD(9, 9) +#define OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK BITFIELD(8, 8) +#define OMAP4430_DPLL_CLKOUT_DIVCHACK_MASK BITFIELD(5, 5) +#define OMAP4430_DPLL_CLKOUT_DIV_MASK BITFIELD(4, 0) +#define OMAP4430_DPLL_M3_PWDN_MASK BITFIELD(12, 12) +#define OMAP4430_ST_DPLL_CLKOUTHIF_MASK BITFIELD(9, 9) +#define OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_MASK BITFIELD(8, 8) +#define OMAP4430_DPLL_CLKOUTHIF_DIVCHACK_MASK BITFIELD(5, 5) +#define OMAP4430_DPLL_CLKOUTHIF_DIV_MASK BITFIELD(4, 0) +#define OMAP4430_HSDIVIDER_CLKOUT1_PWDN_MASK BITFIELD(12, 12) +#define OMAP4430_ST_HSDIVIDER_CLKOUT1_MASK BITFIELD(9, 9) +#define OMAP4430_HSDIVIDER_CLKOUT1_GATE_CTRL_MASK BITFIELD(8, 8) +#define OMAP4430_HSDIVIDER_CLKOUT1_DIVCHACK_MASK BITFIELD(5, 5) +#define OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK BITFIELD(4, 0) +#define OMAP4430_HSDIVIDER_CLKOUT2_PWDN_MASK BITFIELD(12, 12) +#define OMAP4430_ST_HSDIVIDER_CLKOUT2_MASK BITFIELD(9, 9) +#define OMAP4430_HSDIVIDER_CLKOUT2_GATE_CTRL_MASK BITFIELD(8, 8) +#define OMAP4430_HSDIVIDER_CLKOUT2_DIVCHACK_MASK BITFIELD(5, 5) +#define OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK BITFIELD(4, 0) +#define OMAP4430_HSDIVIDER_CLKOUT3_PWDN_MASK BITFIELD(12, 12) +#define OMAP4430_ST_HSDIVIDER_CLKOUT3_MASK BITFIELD(9, 9) +#define OMAP4430_HSDIVIDER_CLKOUT3_GATE_CTRL_MASK BITFIELD(8, 8) +#define OMAP4430_HSDIVIDER_CLKOUT3_DIVCHACK_MASK BITFIELD(5, 5) +#define OMAP4430_HSDIVIDER_CLKOUT3_DIV_MASK BITFIELD(4, 0) +#define OMAP4430_HSDIVIDER_CLKOUT4_PWDN_MASK BITFIELD(12, 12) +#define OMAP4430_ST_HSDIVIDER_CLKOUT4_MASK BITFIELD(9, 9) +#define OMAP4430_HSDIVIDER_CLKOUT4_GATE_CTRL_MASK BITFIELD(8, 8) +#define OMAP4430_HSDIVIDER_CLKOUT4_DIVCHACK_MASK BITFIELD(5, 5) +#define OMAP4430_HSDIVIDER_CLKOUT4_DIV_MASK BITFIELD(4, 0) +#define OMAP4430_DELTAMSTEP_MASK BITFIELD(19, 0) +#define OMAP4430_MODFREQDIV_EXPONENT_MASK BITFIELD(10, 8) +#define OMAP4430_MODFREQDIV_MANTISSA_MASK BITFIELD(6, 0) +#define OMAP4430_OVERRIDE_ENABLE_MASK BITFIELD(19, 19) +#define OMAP4430_CORE_DPLL_EMU_MULT_MASK BITFIELD(18, 8) +#define OMAP4430_RESERVED_MASK BITFIELD(7, 7) +#define OMAP4430_CORE_DPLL_EMU_DIV_MASK BITFIELD(6, 0) +#define OMAP4430_DPLL_SSC_TYPE_MASK BITFIELD(15, 15) +#define OMAP4430_DPLL_SSC_DOWNSPREAD_MASK BITFIELD(14, 14) +#define OMAP4430_DPLL_SSC_ACK_MASK BITFIELD(13, 13) +#define OMAP4430_DPLL_SSC_EN_MASK BITFIELD(12, 12) +#define OMAP4430_DPLL_CLKSEL_MASK BITFIELD(1, 0) +#define OMAP4430_DPLL_SSC_TYPE_MASK BITFIELD(15, 15) +#define OMAP4430_DPLL_SSC_DOWNSPREAD_MASK BITFIELD(14, 14) +#define OMAP4430_DPLL_SSC_ACK_MASK BITFIELD(13, 13) +#define OMAP4430_DPLL_SSC_EN_MASK BITFIELD(12, 12) +#define OMAP4430_DPLL_SSC_TYPE_MASK BITFIELD(15, 15) +#define OMAP4430_DPLL_SSC_DOWNSPREAD_MASK BITFIELD(14, 14) +#define OMAP4430_DPLL_SSC_ACK_MASK BITFIELD(13, 13) +#define OMAP4430_DPLL_SSC_EN_MASK BITFIELD(12, 12) +#define OMAP4430_ST_DPLL_CLKOUTX2_MASK BITFIELD(11, 11) +#define OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK BITFIELD(10, 10) +#define OMAP4430_DPLL_SSC_TYPE_MASK BITFIELD(15, 15) +#define OMAP4430_DPLL_SSC_DOWNSPREAD_MASK BITFIELD(14, 14) +#define OMAP4430_DPLL_SSC_ACK_MASK BITFIELD(13, 13) +#define OMAP4430_DPLL_SSC_EN_MASK BITFIELD(12, 12) +#define OMAP4430_DPLL_DDRPHY_M6_DIV_MASK BITFIELD(28, 24) +#define OMAP4430_DPLL_DDRPHY_M5_DIV_MASK BITFIELD(23, 19) +#define OMAP4430_DPLL_DDRPHY_DPLL_EN_MASK BITFIELD(18, 16) +#define OMAP4430_DPLL_CORE_M2_DIV_MASK BITFIELD(15, 11) +#define OMAP4430_DPLL_CORE_DPLL_EN_MASK BITFIELD(10, 8) +#define OMAP4430_DLL_RESET_MASK BITFIELD(3, 3) +#define OMAP4430_SHADOW_FREQ_DLL_OVERRIDE_MASK BITFIELD(2, 2) +#define OMAP4430_DPLL_CORE_SYS_REF_CLKSEL_MASK BITFIELD(1, 1) +#define OMAP4430_FREQ_UPDATE_MASK BITFIELD(0, 0) +#define OMAP4430_DPLL_CORE_M5_DIV_MASK BITFIELD(7, 3) +#define OMAP4430_CM_SHADOW_FREQ_CONFIG2_CLKSEL_L3_MASK BITFIELD(2, 2) +#define OMAP4430_CM_SHADOW_FREQ_CONFIG2_CLKSEL_CORE_MASK BITFIELD(1, 1) +#define OMAP4430_GPMC_FREQ_UPDATE_MASK BITFIELD(0, 0) +#define OMAP4430_PRESCAL_MASK BITFIELD(5, 0) +#define OMAP4430_CLKACTIVITY_ABE_24M_GFCLK_MASK BITFIELD(13, 13) +#define OMAP4430_CLKACTIVITY_ABE_ALWON_32K_CLK_MASK BITFIELD(12, 12) +#define OMAP4430_CLKACTIVITY_ABE_SYSCLK_MASK BITFIELD(11, 11) +#define OMAP4430_CLKACTIVITY_FUNC_24M_GFCLK_MASK BITFIELD(10, 10) +#define OMAP4430_CLKACTIVITY_OCP_ABE_GICLK_MASK BITFIELD(9, 9) +#define OMAP4430_CLKACTIVITY_ABE_X2_CLK_MASK BITFIELD(8, 8) +#define OMAP4430_CLKTRCTRL_MASK BITFIELD(1, 0) +#define OMAP4430_IDLEST_MASK BITFIELD(17, 16) +#define OMAP4430_MODULEMODE_MASK BITFIELD(1, 0) +#define OMAP4430_CLKSEL_AESS_FCLK_MASK BITFIELD(24, 24) +#define OMAP4430_STBYST_MASK BITFIELD(18, 18) +#define OMAP4430_CM1_CLKSEL_INTERNAL_SOURCE_MASK BITFIELD(27, 26) +#define OMAP4430_CM1_CLKSEL_SOURCE_MASK BITFIELD(25, 24) +#define OMAP4430_CM1_OPTFCLKEN_SLIMBUS_CLK_MASK BITFIELD(11, 11) +#define OMAP4430_OPTFCLKEN_FCLK2_MASK BITFIELD(10, 10) +#define OMAP4430_OPTFCLKEN_FCLK1_MASK BITFIELD(9, 9) +#define OMAP4430_OPTFCLKEN_FCLK0_MASK BITFIELD(8, 8) +#define OMAP4430_GPTIMER_CLKSEL_MASK BITFIELD(24, 24) +#define OMAP4430_CLKACTIVITY_MPU_DPLL_CLK_MASK BITFIELD(8, 8) +#define OMAP4430_D2D_STATDEP_MASK BITFIELD(18, 18) +#define OMAP4430_CEFUSE_STATDEP_MASK BITFIELD(17, 17) +#define OMAP4430_ALWONCORE_STATDEP_MASK BITFIELD(16, 16) +#define OMAP4430_L4WKUP_STATDEP_MASK BITFIELD(15, 15) +#define OMAP4430_L4SEC_STATDEP_MASK BITFIELD(14, 14) +#define OMAP4430_L4PER_STATDEP_MASK BITFIELD(13, 13) +#define OMAP4430_L4CFG_STATDEP_MASK BITFIELD(12, 12) +#define OMAP4430_SDMA_STATDEP_MASK BITFIELD(11, 11) +#define OMAP4430_GFX_STATDEP_MASK BITFIELD(10, 10) +#define OMAP4430_ISS_STATDEP_MASK BITFIELD(9, 9) +#define OMAP4430_DSS_STATDEP_MASK BITFIELD(8, 8) +#define OMAP4430_L3INIT_STATDEP_MASK BITFIELD(7, 7) +#define OMAP4430_L3_2_STATDEP_MASK BITFIELD(6, 6) +#define OMAP4430_L3_1_STATDEP_MASK BITFIELD(5, 5) +#define OMAP4430_MEMIF_STATDEP_MASK BITFIELD(4, 4) +#define OMAP4430_ABE_STATDEP_MASK BITFIELD(3, 3) +#define OMAP4430_IVAHD_STATDEP_MASK BITFIELD(2, 2) +#define OMAP4430_TESLA_STATDEP_MASK BITFIELD(1, 1) +#define OMAP4430_DUCATI_STATDEP_MASK BITFIELD(0, 0) +#define OMAP4430_WINDOWSIZE_MASK BITFIELD(27, 24) +#define OMAP4430_L3_1_DYNDEP_MASK BITFIELD(5, 5) +#define OMAP4430_MEMIF_DYNDEP_MASK BITFIELD(4, 4) +#define OMAP4430_ABE_DYNDEP_MASK BITFIELD(3, 3) +#define OMAP4430_CLKACTIVITY_TESLA_ROOT_CLK_MASK BITFIELD(8, 8) +#define OMAP4430_CEFUSE_STATDEP_MASK BITFIELD(17, 17) +#define OMAP4430_ALWONCORE_STATDEP_MASK BITFIELD(16, 16) +#define OMAP4430_L4PER_STATDEP_MASK BITFIELD(13, 13) +#define OMAP4430_L4CFG_STATDEP_MASK BITFIELD(12, 12) +#define OMAP4430_ISS_STATDEP_MASK BITFIELD(9, 9) +#define OMAP4430_L3INIT_STATDEP_MASK BITFIELD(7, 7) +#define OMAP4430_L3_1_STATDEP_MASK BITFIELD(5, 5) +#define OMAP4430_MEMIF_STATDEP_MASK BITFIELD(4, 4) +#define OMAP4430_ABE_STATDEP_MASK BITFIELD(3, 3) +#define OMAP4430_IVAHD_STATDEP_MASK BITFIELD(2, 2) +#define OMAP4430_WINDOWSIZE_MASK BITFIELD(27, 24) +#define OMAP4430_ABE_DYNDEP_MASK BITFIELD(3, 3) +#define OMAP4430_IVAHD_DYNDEP_MASK BITFIELD(2, 2) +#define OMAP4430_CLKACTIVITY_BGAP_32K_GFCLK_MASK BITFIELD(12, 12) +#define OMAP4430_CLKACTIVITY_SR_CORE_SYSCLK_MASK BITFIELD(11, 11) +#define OMAP4430_CLKACTIVITY_SR_IVA_SYSCLK_MASK BITFIELD(10, 10) +#define OMAP4430_CLKACTIVITY_SR_MPU_SYSCLK_MASK BITFIELD(9, 9) +#define OMAP4430_CLKACTIVITY_L4_AO_ICLK_MASK BITFIELD(8, 8) +#define OMAP4430_OPTFCLKEN_BGAP_32K_MASK BITFIELD(8, 8) +#define OMAP4430_REV_MASK BITFIELD(7, 0) +#endif /* __ARCH_ARM_MACH_OMAP2_CM1_REGBITS_44XX_H */ diff --git a/arch/arm/mach-omap2/cm2-regbits-44xx.h b/arch/arm/mach-omap2/cm2-regbits-44xx.h new file mode 100644 index 000000000000..ac8b151f456f --- /dev/null +++ b/arch/arm/mach-omap2/cm2-regbits-44xx.h @@ -0,0 +1,584 @@ +#ifndef __ARCH_ARM_MACH_OMAP2_CM2_REGBITS_44XX_H +#define __ARCH_ARM_MACH_OMAP2_CM2_REGBITS_44XX_H + +/* + * OMAP4430 Clock Management Module2 register bits + * + * Copyright (C) 2009 Texas Instruments, Inc. + * + * Written by 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 version 2 as + * published by the Free Software Foundation. + */ + +#include "cm.h" + +#define OMAP4430_EN_GPT_SHIFT 1 + +#define OMAP4430_CLKACTIVITY_FDIF_GFCLK (1 << 10) +#define OMAP4430_CLKACTIVITY_ISS_GCLK (1 << 9) +#define OMAP4430_CLKACTIVITY_CAM_PHY_CTRL_GCLK (1 << 8) +#define OMAP4430_CLKTRCTRL (1 << 0) +#define OMAP4430_L3_2_STATDEP (1 << 6) +#define OMAP4430_L3_1_STATDEP (1 << 5) +#define OMAP4430_MEMIF_STATDEP (1 << 4) +#define OMAP4430_IVAHD_STATDEP (1 << 2) +#define OMAP4430_L3_2_DYNDEP (1 << 6) +#define OMAP4430_STBYST (1 << 18) +#define OMAP4430_IDLEST (1 << 16) +#define OMAP4430_OPTFCLKEN_CTRLCLK (1 << 8) +#define OMAP4430_MODULEMODE (1 << 0) +#define OMAP4430_CLKSEL_FCLK (1 << 24) +#define OMAP4430_CLKACTIVITY_UTMI_P3_GFCLK (1 << 30) +#define OMAP4430_CLKACTIVITY_INIT_60M_P2_GFCLK (1 << 29) +#define OMAP4430_CLKACTIVITY_INIT_60M_P1_GFCLK (1 << 28) +#define OMAP4430_CLKACTIVITY_HSIC_P2_GFCLK (1 << 27) +#define OMAP4430_CLKACTIVITY_HSIC_P1_GFCLK (1 << 26) +#define OMAP4430_CLKACTIVITY_UTMI_ROOT_GFCLK (1 << 25) +#define OMAP4430_CLKACTIVITY_TLL_CH2_GFCLK (1 << 24) +#define OMAP4430_CLKACTIVITY_TLL_CH1_GFCLK (1 << 23) +#define OMAP4430_CLKACTIVITY_TLL_CH0_GFCLK (1 << 22) +#define OMAP4430_CLKACTIVITY_HSIC_P2_480M_GFCLK (1 << 21) +#define OMAP4430_CLKACTIVITY_HSIC_P1_480M_GFCLK (1 << 20) +#define OMAP4430_CLKACTIVITY_INIT_HSMMC6_GFCLK (1 << 19) +#define OMAP4430_CLKACTIVITY_INIT_HSMMC2_GFCLK (1 << 18) +#define OMAP4430_CLKACTIVITY_INIT_HSMMC1_GFCLK (1 << 17) +#define OMAP4430_CLKACTIVITY_INIT_HSI_GFCLK (1 << 16) +#define OMAP4430_CLKACTIVITY_USB_DPLL_HS_CLK (1 << 15) +#define OMAP4430_CLKACTIVITY_L3INIT_DPLL_ALWON_CLK (1 << 14) +#define OMAP4430_CLKACTIVITY_INIT_48MC_GFCLK (1 << 13) +#define OMAP4430_CLKACTIVITY_INIT_48M_GFCLK (1 << 12) +#define OMAP4430_CLKACTIVITY_INIT_96M_GFCLK (1 << 11) +#define OMAP4430_CLKACTIVITY_EMAC_50MHZ_CLK (1 << 10) +#define OMAP4430_CLKACTIVITY_L4_INIT_GICLK (1 << 9) +#define OMAP4430_CLKACTIVITY_L3_INIT_GICLK (1 << 8) +#define OMAP4430_L4WKUP_STATDEP (1 << 15) +#define OMAP4430_L4SEC_STATDEP (1 << 14) +#define OMAP4430_L4PER_STATDEP (1 << 13) +#define OMAP4430_L4CFG_STATDEP (1 << 12) +#define OMAP4430_ABE_STATDEP (1 << 3) +#define OMAP4430_L3_1_DYNDEP (1 << 5) +#define OMAP4430_HSMMC1_CLKSEL (1 << 24) +#define OMAP4430_HSMMC2_CLKSEL (1 << 24) +#define OMAP4430_HSI_CLKSEL (1 << 24) +#define OMAP4430_OPTFCLKEN_TXPHYCLK (1 << 8) +#define OMAP4430_CLKSEL_UTMI_P2 (1 << 25) +#define OMAP4430_CLKSEL_UTMI_P1 (1 << 24) +#define OMAP4430_OPTFCLKEN_FUNC48MCLK (1 << 15) +#define OMAP4430_OPTFCLKEN_HSIC480M_P2_CLK (1 << 14) +#define OMAP4430_OPTFCLKEN_HSIC480M_P1_CLK (1 << 13) +#define OMAP4430_OPTFCLKEN_HSIC60M_P2_CLK (1 << 12) +#define OMAP4430_OPTFCLKEN_HSIC60M_P1_CLK (1 << 11) +#define OMAP4430_OPTFCLKEN_UTMI_P3_CLK (1 << 10) +#define OMAP4430_OPTFCLKEN_UTMI_P2_CLK (1 << 9) +#define OMAP4430_OPTFCLKEN_UTMI_P1_CLK (1 << 8) +#define OMAP4430_SAR_MODE (1 << 4) +#define OMAP4430_CLKSEL_60M (1 << 24) +#define OMAP4430_OPTFCLKEN_XCLK (1 << 8) +#define OMAP4430_OPTFCLKEN_USB_CH2_CLK (1 << 10) +#define OMAP4430_OPTFCLKEN_USB_CH1_CLK (1 << 9) +#define OMAP4430_OPTFCLKEN_USB_CH0_CLK (1 << 8) +#define OMAP4430_GPTIMER10_CLKSEL (1 << 24) +#define OMAP4430_OPTFCLKEN_PHY_48M (1 << 8) +#define OMAP4430_CLKACTIVITY_IVAHD_ROOT_CLK (1 << 8) +#define OMAP4430_CLKACTIVITY_HDMI_PHY_48MHZ_GFCLK (1 << 11) +#define OMAP4430_CLKACTIVITY_DSS_ALWON_SYS_CLK (1 << 10) +#define OMAP4430_CLKACTIVITY_DSS_FCLK (1 << 9) +#define OMAP4430_CLKACTIVITY_L3_DSS_GICLK (1 << 8) +#define OMAP4430_IVAHD_STATDEP (1 << 2) +#define OMAP4430_OPTFCLKEN_TV_CLK (1 << 11) +#define OMAP4430_OPTFCLKEN_SYS_CLK (1 << 10) +#define OMAP4430_OPTFCLKEN_48MHZ_CLK (1 << 9) +#define OMAP4430_OPTFCLKEN_DSSCLK (1 << 8) +#define OMAP4430_CLKACTIVITY_PER_ABE_24M_GFCLK (1 << 25) +#define OMAP4430_CLKACTIVITY_PER_SYS_GFCLK (1 << 24) +#define OMAP4430_CLKACTIVITY_PER_MCBSP4_GFCLK (1 << 22) +#define OMAP4430_CLKACTIVITY_PER_MCASP3_GFCLK (1 << 21) +#define OMAP4430_CLKACTIVITY_PER_MCASP2_GFCLK (1 << 20) +#define OMAP4430_CLKACTIVITY_PER_96M_GFCLK (1 << 19) +#define OMAP4430_CLKACTIVITY_PER_48M_GFCLK (1 << 18) +#define OMAP4430_CLKACTIVITY_PER_32K_GFCLK (1 << 17) +#define OMAP4430_CLKACTIVITY_PER_24MC_GFCLK (1 << 16) +#define OMAP4430_CLKACTIVITY_FUNC_12M_GFCLK (1 << 15) +#define OMAP4430_CLKACTIVITY_DMT9_GFCLK (1 << 14) +#define OMAP4430_CLKACTIVITY_DMT4_GFCLK (1 << 13) +#define OMAP4430_CLKACTIVITY_DMT3_GFCLK (1 << 12) +#define OMAP4430_CLKACTIVITY_DMT2_GFCLK (1 << 11) +#define OMAP4430_CLKACTIVITY_DMT11_GFCLK (1 << 10) +#define OMAP4430_CLKACTIVITY_DMT10_GFCLK (1 << 9) +#define OMAP4430_CLKACTIVITY_L4_PER_GICLK (1 << 8) +#define OMAP4430_WINDOWSIZE (1 << 24) +#define OMAP4430_L4SEC_DYNDEP (1 << 14) +#define OMAP4430_DSS_DYNDEP (1 << 8) +#define OMAP4430_L3INIT_DYNDEP (1 << 7) +#define OMAP4430_GPTIMER11_CLKSEL (1 << 24) +#define OMAP4430_GPTIMER2_CLKSEL (1 << 24) +#define OMAP4430_GPTIMER3_CLKSEL (1 << 24) +#define OMAP4430_GPTIMER4_CLKSEL (1 << 24) +#define OMAP4430_GPTIMER9_CLKSEL (1 << 24) +#define OMAP4430_OPTFCLKEN_DBCLK (1 << 8) +#define OMAP4430_OPTFCLKEN_DBCLK (1 << 8) +#define OMAP4430_OPTFCLKEN_DBCLK (1 << 8) +#define OMAP4430_OPTFCLKEN_DBCLK (1 << 8) +#define OMAP4430_OPTFCLKEN_DBCLK (1 << 8) +#define OMAP4430_L4PER_CLKSEL_INTERNAL_SOURCE (1 << 25) +#define OMAP4430_CLKSEL_SOURCE (1 << 24) +#define OMAP4430_L4PER_OPTFCLKEN_SLIMBUS_CLK (1 << 10) +#define OMAP4430_OPTFCLKEN_PERABE24M_GFCLK (1 << 9) +#define OMAP4430_OPTFCLKEN_PER24MC_GFCLK (1 << 8) +#define OMAP4430_CLKACTIVITY_L4_SECURE_GICLK (1 << 9) +#define OMAP4430_CLKACTIVITY_L3_SECURE_GICLK (1 << 8) +#define OMAP4430_CLKACTIVITY_SGX_GFCLK (1 << 9) +#define OMAP4430_CLKACTIVITY_L3_GFX_GICLK (1 << 8) +#define OMAP4430_IVAHD_STATDEP (1 << 2) +#define OMAP4430_CLKSEL_PER_192M (1 << 25) +#define OMAP4430_CLKSEL_SGX_FCLK (1 << 24) +#define OMAP4430_CLKACTIVITY_L3_1_GICLK (1 << 8) +#define OMAP4430_L4CFG_DYNDEP (1 << 12) +#define OMAP4430_MEMIF_DYNDEP (1 << 4) +#define OMAP4430_ABE_DYNDEP (1 << 3) +#define OMAP4430_CLKACTIVITY_L3_2_GICLK (1 << 8) +#define OMAP4430_L4PER_DYNDEP (1 << 13) +#define OMAP4430_GFX_DYNDEP (1 << 10) +#define OMAP4430_ISS_DYNDEP (1 << 9) +#define OMAP4430_IVAHD_DYNDEP (1 << 2) +#define OMAP4430_DUCATI_DYNDEP (1 << 0) +#define OMAP4430_CLKACTIVITY_DUCATI_GCLK (1 << 8) +#define OMAP4430_CEFUSE_STATDEP (1 << 17) +#define OMAP4430_ALWONCORE_STATDEP (1 << 16) +#define OMAP4430_L4SEC_STATDEP (1 << 14) +#define OMAP4430_L4CFG_STATDEP (1 << 12) +#define OMAP4430_SDMA_STATDEP (1 << 11) +#define OMAP4430_GFX_STATDEP (1 << 10) +#define OMAP4430_ISS_STATDEP (1 << 9) +#define OMAP4430_DSS_STATDEP (1 << 8) +#define OMAP4430_L3INIT_STATDEP (1 << 7) +#define OMAP4430_ABE_STATDEP (1 << 3) +#define OMAP4430_IVAHD_STATDEP (1 << 2) +#define OMAP4430_TESLA_STATDEP (1 << 1) +#define OMAP4430_CLKACTIVITY_L3_DMA_GICLK (1 << 8) +#define OMAP4430_L4SEC_STATDEP (1 << 14) +#define OMAP4430_L4CFG_STATDEP (1 << 12) +#define OMAP4430_ISS_STATDEP (1 << 9) +#define OMAP4430_L3INIT_STATDEP (1 << 7) +#define OMAP4430_ABE_STATDEP (1 << 3) +#define OMAP4430_DUCATI_STATDEP (1 << 0) +#define OMAP4430_CLKACTIVITY_ASYNC_PHY2_CLK (1 << 13) +#define OMAP4430_CLKACTIVITY_ASYNC_PHY1_CLK (1 << 12) +#define OMAP4430_CLKACTIVITY_ASYNC_DLL_CLK (1 << 11) +#define OMAP4430_CLKACTIVITY_PHY_ROOT_CLK (1 << 10) +#define OMAP4430_CLKACTIVITY_DLL_CLK (1 << 9) +#define OMAP4430_CLKACTIVITY_L3_EMIF_GICLK (1 << 8) +#define OMAP4430_OPTFCLKEN_DLL_CLK (1 << 8) +#define OMAP4430_OPTFCLKEN_DLL_CLK (1 << 8) +#define OMAP4430_CLKACTIVITY_L4_D2D_GICLK (1 << 9) +#define OMAP4430_CLKACTIVITY_L3_D2D_GICLK (1 << 8) +#define OMAP4430_L4CFG_STATDEP (1 << 12) +#define OMAP4430_L3INIT_STATDEP (1 << 7) +#define OMAP4430_ABE_STATDEP (1 << 3) +#define OMAP4430_MEMIF_DYNDEP (1 << 4) +#define OMAP4430_CLKACTIVITY_L4_CFG_GICLK (1 << 8) +#define OMAP4430_D2D_DYNDEP (1 << 18) +#define OMAP4430_CEFUSE_DYNDEP (1 << 17) +#define OMAP4430_ALWONCORE_DYNDEP (1 << 16) +#define OMAP4430_L4WKUP_DYNDEP (1 << 15) +#define OMAP4430_SDMA_DYNDEP (1 << 11) +#define OMAP4430_MEMIF_DYNDEP (1 << 4) +#define OMAP4430_TESLA_DYNDEP (1 << 1) +#define OMAP4430_CLKACTIVITY_L3_INSTR_GICLK (1 << 8) +#define OMAP4430_CLKACTIVITY_CUST_EFUSE_SYS_CLK (1 << 9) +#define OMAP4430_CLKACTIVITY_L4_CEFUSE_GICLK (1 << 8) +#define OMAP4430_REV (1 << 0) +#define OMAP4430_CLKSEL_MPU (1 << 0) +#define OMAP4430_CLKSEL_USB (1 << 0) +#define OMAP4430_SCALE_FCLK (1 << 0) +#define OMAP4430_PERF_REQ (1 << 0) +#define OMAP4430_PERF_CURRENT (1 << 0) +#define OMAP4430_DPLL_SSC_TYPE (1 << 15) +#define OMAP4430_DPLL_SSC_DOWNSPREAD (1 << 14) +#define OMAP4430_DPLL_SSC_ACK (1 << 13) +#define OMAP4430_DPLL_SSC_EN (1 << 12) +#define OMAP4430_DPLL_REGM4XEN (1 << 11) +#define OMAP4430_DPLL_LPMODE_EN (1 << 10) +#define OMAP4430_DPLL_RELOCK_RAMP_EN (1 << 9) +#define OMAP4430_DPLL_RAMP_RATE (1 << 6) +#define OMAP4430_DPLL_RAMP_LEVEL (1 << 4) +#define OMAP4430_DPLL_DRIFTGUARD_EN (1 << 3) +#define OMAP4430_DPLL_EN (1 << 0) +#define OMAP4430_ST_DPLL_CLK (1 << 0) +#define OMAP4430_DPLL_DCOCLKLDO_PWDN (1 << 4) +#define OMAP4430_AUTO_DPLL_MODE (1 << 0) +#define OMAP4430_DPLL_BYP_CLKSEL (1 << 23) +#define OMAP4430_DPLL_MULT (1 << 8) +#define OMAP4430_DPLL_DIV (1 << 0) +#define OMAP4430_DPLL_M2_PWDN (1 << 12) +#define OMAP4430_ST_DPLL_CLKOUTX2 (1 << 11) +#define OMAP4430_DPLL_CLKOUTX2_GATE_CTRL (1 << 10) +#define OMAP4430_ST_DPLL_CLKOUT (1 << 9) +#define OMAP4430_DPLL_CLKOUT_GATE_CTRL (1 << 8) +#define OMAP4430_DPLL_PER_CLKOUT_DIVCHACK (1 << 5) +#define OMAP4430_DPLL_CLKOUT_DIV (1 << 0) +#define OMAP4430_DPLL_M3_PWDN (1 << 12) +#define OMAP4430_ST_DPLL_CLKOUTHIF (1 << 9) +#define OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL (1 << 8) +#define OMAP4430_DPLL_CLKOUTHIF_DIVCHACK (1 << 5) +#define OMAP4430_DPLL_CLKOUTHIF_DIV (1 << 0) +#define OMAP4430_HSDIVIDER_CLKOUT1_PWDN (1 << 12) +#define OMAP4430_ST_HSDIVIDER_CLKOUT1 (1 << 9) +#define OMAP4430_HSDIVIDER_CLKOUT1_GATE_CTRL (1 << 8) +#define OMAP4430_HSDIVIDER_CLKOUT1_DIVCHACK (1 << 5) +#define OMAP4430_HSDIVIDER_CLKOUT1_DIV (1 << 0) +#define OMAP4430_HSDIVIDER_CLKOUT2_PWDN (1 << 12) +#define OMAP4430_ST_HSDIVIDER_CLKOUT2 (1 << 9) +#define OMAP4430_HSDIVIDER_CLKOUT2_GATE_CTRL (1 << 8) +#define OMAP4430_HSDIVIDER_CLKOUT2_DIVCHACK (1 << 5) +#define OMAP4430_HSDIVIDER_CLKOUT2_DIV (1 << 0) +#define OMAP4430_HSDIVIDER_CLKOUT3_PWDN (1 << 12) +#define OMAP4430_ST_HSDIVIDER_CLKOUT3 (1 << 9) +#define OMAP4430_HSDIVIDER_CLKOUT3_GATE_CTRL (1 << 8) +#define OMAP4430_HSDIVIDER_CLKOUT3_DIVCHACK (1 << 5) +#define OMAP4430_HSDIVIDER_CLKOUT3_DIV (1 << 0) +#define OMAP4430_HSDIVIDER_CLKOUT4_PWDN (1 << 12) +#define OMAP4430_ST_HSDIVIDER_CLKOUT4 (1 << 9) +#define OMAP4430_HSDIVIDER_CLKOUT4_GATE_CTRL (1 << 8) +#define OMAP4430_HSDIVIDER_CLKOUT4_DIVCHACK (1 << 5) +#define OMAP4430_HSDIVIDER_CLKOUT4_DIV (1 << 0) +#define OMAP4430_DELTAMSTEP (1 << 0) +#define OMAP4430_MODFREQDIV_EXPONENT (1 << 8) +#define OMAP4430_MODFREQDIV_MANTISSA (1 << 0) +#define OMAP4430_OVERRIDE_ENABLE (1 << 19) +#define OMAP4430_PER_DPLL_EMU_MULT (1 << 8) +#define OMAP4430_RESERVED (1 << 7) +#define OMAP4430_PER_DPLL_EMU_DIV (1 << 0) +#define OMAP4430_DPLL_SSC_TYPE (1 << 15) +#define OMAP4430_DPLL_SSC_DOWNSPREAD (1 << 14) +#define OMAP4430_DPLL_SSC_ACK (1 << 13) +#define OMAP4430_DPLL_SSC_EN (1 << 12) +#define OMAP4430_DPLL_DRIFTGUARD_EN (1 << 3) +#define OMAP4430_AUTO_DPLL_MODE (1 << 0) +#define OMAP4430_DPLL_SD_DIV (1 << 24) +#define OMAP4430_DPLL_CLKOUT_GATE_CTRL (1 << 8) +#define OMAP4430_DPLL_USB_CLKOUT_DIVCHACK (1 << 7) +#define OMAP4430_DPLL_CLKOUT_DIV (1 << 0) +#define OMAP4430_DELTAMSTEP (1 << 0) +#define OMAP4430_MODFREQDIV_EXPONENT (1 << 8) +#define OMAP4430_MODFREQDIV_MANTISSA (1 << 0) +#define OMAP4430_DPLL_CLKDCOLDO_PWDN (1 << 12) +#define OMAP4430_ST_DPLL_CLKDCOLDO (1 << 9) +#define OMAP4430_DPLL_CLKDCOLDO_GATE_CTRL (1 << 8) +#define OMAP4430_DPLL_SSC_TYPE (1 << 15) +#define OMAP4430_DPLL_SSC_DOWNSPREAD (1 << 14) +#define OMAP4430_DPLL_SSC_ACK (1 << 13) +#define OMAP4430_DPLL_SSC_EN (1 << 12) +#define OMAP4430_DPLL_REGM4XEN (1 << 11) +#define OMAP4430_DPLL_LPMODE_EN (1 << 10) +#define OMAP4430_DPLL_RELOCK_RAMP_EN (1 << 9) +#define OMAP4430_DPLL_RAMP_RATE (1 << 6) +#define OMAP4430_DPLL_RAMP_LEVEL (1 << 4) +#define OMAP4430_DPLL_DRIFTGUARD_EN (1 << 3) +#define OMAP4430_AUTO_DPLL_MODE (1 << 0) +#define OMAP4430_DPLL_UNIPRO_CLKOUT_DIVCHACK (1 << 5) +#define OMAP4430_DPLL_CLKOUT_DIV (1 << 0) +#define OMAP4430_DELTAMSTEP (1 << 0) +#define OMAP4430_MODFREQDIV_EXPONENT (1 << 8) +#define OMAP4430_MODFREQDIV_MANTISSA (1 << 0) +#define OMAP4430_CLKACTIVITY_SR_CORE_SYSCLK (1 << 11) +#define OMAP4430_CLKACTIVITY_SR_IVA_SYSCLK (1 << 10) +#define OMAP4430_CLKACTIVITY_SR_MPU_SYSCLK (1 << 9) +#define OMAP4430_CLKACTIVITY_L4_AO_ICLK (1 << 8) + +#define OMAP4430_CLKACTIVITY_FDIF_GFCLK_MASK BITFIELD(10, 10) +#define OMAP4430_CLKACTIVITY_ISS_GCLK_MASK BITFIELD(9, 9) +#define OMAP4430_CLKACTIVITY_CAM_PHY_CTRL_GCLK_MASK BITFIELD(8, 8) +#define OMAP4430_CLKTRCTRL_MASK BITFIELD(1, 0) +#define OMAP4430_L3_2_STATDEP_MASK BITFIELD(6, 6) +#define OMAP4430_L3_1_STATDEP_MASK BITFIELD(5, 5) +#define OMAP4430_MEMIF_STATDEP_MASK BITFIELD(4, 4) +#define OMAP4430_IVAHD_STATDEP_MASK BITFIELD(2, 2) +#define OMAP4430_L3_2_DYNDEP_MASK BITFIELD(6, 6) +#define OMAP4430_STBYST_MASK BITFIELD(18, 18) +#define OMAP4430_IDLEST_MASK BITFIELD(17, 16) +#define OMAP4430_OPTFCLKEN_CTRLCLK_MASK BITFIELD(8, 8) +#define OMAP4430_MODULEMODE_MASK BITFIELD(1, 0) +#define OMAP4430_CLKSEL_FCLK_MASK BITFIELD(25, 24) +#define OMAP4430_CLKACTIVITY_UTMI_P3_GFCLK_MASK BITFIELD(30, 30) +#define OMAP4430_CLKACTIVITY_INIT_60M_P2_GFCLK_MASK BITFIELD(29, 29) +#define OMAP4430_CLKACTIVITY_INIT_60M_P1_GFCLK_MASK BITFIELD(28, 28) +#define OMAP4430_CLKACTIVITY_HSIC_P2_GFCLK_MASK BITFIELD(27, 27) +#define OMAP4430_CLKACTIVITY_HSIC_P1_GFCLK_MASK BITFIELD(26, 26) +#define OMAP4430_CLKACTIVITY_UTMI_ROOT_GFCLK_MASK BITFIELD(25, 25) +#define OMAP4430_CLKACTIVITY_TLL_CH2_GFCLK_MASK BITFIELD(24, 24) +#define OMAP4430_CLKACTIVITY_TLL_CH1_GFCLK_MASK BITFIELD(23, 23) +#define OMAP4430_CLKACTIVITY_TLL_CH0_GFCLK_MASK BITFIELD(22, 22) +#define OMAP4430_CLKACTIVITY_HSIC_P2_480M_GFCLK_MASK BITFIELD(21, 21) +#define OMAP4430_CLKACTIVITY_HSIC_P1_480M_GFCLK_MASK BITFIELD(20, 20) +#define OMAP4430_CLKACTIVITY_INIT_HSMMC6_GFCLK_MASK BITFIELD(19, 19) +#define OMAP4430_CLKACTIVITY_INIT_HSMMC2_GFCLK_MASK BITFIELD(18, 18) +#define OMAP4430_CLKACTIVITY_INIT_HSMMC1_GFCLK_MASK BITFIELD(17, 17) +#define OMAP4430_CLKACTIVITY_INIT_HSI_GFCLK_MASK BITFIELD(16, 16) +#define OMAP4430_CLKACTIVITY_USB_DPLL_HS_CLK_MASK BITFIELD(15, 15) +#define OMAP4430_CLKACTIVITY_L3INIT_DPLL_ALWON_CLK_MASK BITFIELD(14, 14) +#define OMAP4430_CLKACTIVITY_INIT_48MC_GFCLK_MASK BITFIELD(13, 13) +#define OMAP4430_CLKACTIVITY_INIT_48M_GFCLK_MASK BITFIELD(12, 12) +#define OMAP4430_CLKACTIVITY_INIT_96M_GFCLK_MASK BITFIELD(11, 11) +#define OMAP4430_CLKACTIVITY_EMAC_50MHZ_CLK_MASK BITFIELD(10, 10) +#define OMAP4430_CLKACTIVITY_L4_INIT_GICLK_MASK BITFIELD(9, 9) +#define OMAP4430_CLKACTIVITY_L3_INIT_GICLK_MASK BITFIELD(8, 8) +#define OMAP4430_L4WKUP_STATDEP_MASK BITFIELD(15, 15) +#define OMAP4430_L4SEC_STATDEP_MASK BITFIELD(14, 14) +#define OMAP4430_L4PER_STATDEP_MASK BITFIELD(13, 13) +#define OMAP4430_L4CFG_STATDEP_MASK BITFIELD(12, 12) +#define OMAP4430_MEMIF_STATDEP_MASK BITFIELD(4, 4) +#define OMAP4430_ABE_STATDEP_MASK BITFIELD(3, 3) +#define OMAP4430_IVAHD_STATDEP_MASK BITFIELD(2, 2) +#define OMAP4430_L3_1_DYNDEP_MASK BITFIELD(5, 5) +#define OMAP4430_CLKSEL_MASK BITFIELD(24, 24) +#define OMAP4430_HSI_CLKSEL_MASK BITFIELD(25, 24) +#define OMAP4430_OPTFCLKEN_TXPHYCLK_MASK BITFIELD(8, 8) +#define OMAP4430_CLKSEL_UTMI_P2_MASK BITFIELD(25, 25) +#define OMAP4430_CLKSEL_UTMI_P1_MASK BITFIELD(24, 24) +#define OMAP4430_OPTFCLKEN_FUNC48MCLK_MASK BITFIELD(15, 15) +#define OMAP4430_OPTFCLKEN_HSIC480M_P2_CLK_MASK BITFIELD(14, 14) +#define OMAP4430_OPTFCLKEN_HSIC480M_P1_CLK_MASK BITFIELD(13, 13) +#define OMAP4430_OPTFCLKEN_HSIC60M_P2_CLK_MASK BITFIELD(12, 12) +#define OMAP4430_OPTFCLKEN_HSIC60M_P1_CLK_MASK BITFIELD(11, 11) +#define OMAP4430_OPTFCLKEN_UTMI_P3_CLK_MASK BITFIELD(10, 10) +#define OMAP4430_OPTFCLKEN_UTMI_P2_CLK_MASK BITFIELD(9, 9) +#define OMAP4430_OPTFCLKEN_UTMI_P1_CLK_MASK BITFIELD(8, 8) +#define OMAP4430_SAR_MODE_MASK BITFIELD(4, 4) +#define OMAP4430_CLKSEL_60M_MASK BITFIELD(24, 24) +#define OMAP4430_OPTFCLKEN_XCLK_MASK BITFIELD(8, 8) +#define OMAP4430_OPTFCLKEN_USB_CH2_CLK_MASK BITFIELD(10, 10) +#define OMAP4430_OPTFCLKEN_USB_CH1_CLK_MASK BITFIELD(9, 9) +#define OMAP4430_OPTFCLKEN_USB_CH0_CLK_MASK BITFIELD(8, 8) +#define OMAP4430_SAR_MODE_MASK BITFIELD(4, 4) +#define OMAP4430_OPTFCLKEN_PHY_48M_MASK BITFIELD(8, 8) +#define OMAP4430_CLKACTIVITY_IVAHD_ROOT_CLK_MASK BITFIELD(8, 8) +#define OMAP4430_MEMIF_STATDEP_MASK BITFIELD(4, 4) +#define OMAP4430_CLKACTIVITY_HDMI_PHY_48MHZ_GFCLK_MASK BITFIELD(11, 11) +#define OMAP4430_CLKACTIVITY_DSS_ALWON_SYS_CLK_MASK BITFIELD(10, 10) +#define OMAP4430_CLKACTIVITY_DSS_FCLK_MASK BITFIELD(9, 9) +#define OMAP4430_CLKACTIVITY_L3_DSS_GICLK_MASK BITFIELD(8, 8) +#define OMAP4430_MEMIF_STATDEP_MASK BITFIELD(4, 4) +#define OMAP4430_IVAHD_STATDEP_MASK BITFIELD(2, 2) +#define OMAP4430_OPTFCLKEN_TV_CLK_MASK BITFIELD(11, 11) +#define OMAP4430_OPTFCLKEN_SYS_CLK_MASK BITFIELD(10, 10) +#define OMAP4430_OPTFCLKEN_48MHZ_CLK_MASK BITFIELD(9, 9) +#define OMAP4430_OPTFCLKEN_DSSCLK_MASK BITFIELD(8, 8) +#define OMAP4430_CLKACTIVITY_PER_ABE_24M_GFCLK_MASK BITFIELD(25, 25) +#define OMAP4430_CLKACTIVITY_PER_SYS_GFCLK_MASK BITFIELD(24, 24) +#define OMAP4430_CLKACTIVITY_PER_MCBSP4_GFCLK_MASK BITFIELD(22, 22) +#define OMAP4430_CLKACTIVITY_PER_MCASP3_GFCLK_MASK BITFIELD(21, 21) +#define OMAP4430_CLKACTIVITY_PER_MCASP2_GFCLK_MASK BITFIELD(20, 20) +#define OMAP4430_CLKACTIVITY_PER_96M_GFCLK_MASK BITFIELD(19, 19) +#define OMAP4430_CLKACTIVITY_PER_48M_GFCLK_MASK BITFIELD(18, 18) +#define OMAP4430_CLKACTIVITY_PER_32K_GFCLK_MASK BITFIELD(17, 17) +#define OMAP4430_CLKACTIVITY_PER_24MC_GFCLK_MASK BITFIELD(16, 16) +#define OMAP4430_CLKACTIVITY_FUNC_12M_GFCLK_MASK BITFIELD(15, 15) +#define OMAP4430_CLKACTIVITY_DMT9_GFCLK_MASK BITFIELD(14, 14) +#define OMAP4430_CLKACTIVITY_DMT4_GFCLK_MASK BITFIELD(13, 13) +#define OMAP4430_CLKACTIVITY_DMT3_GFCLK_MASK BITFIELD(12, 12) +#define OMAP4430_CLKACTIVITY_DMT2_GFCLK_MASK BITFIELD(11, 11) +#define OMAP4430_CLKACTIVITY_DMT11_GFCLK_MASK BITFIELD(10, 10) +#define OMAP4430_CLKACTIVITY_DMT10_GFCLK_MASK BITFIELD(9, 9) +#define OMAP4430_CLKACTIVITY_L4_PER_GICLK_MASK BITFIELD(8, 8) +#define OMAP4430_WINDOWSIZE_MASK BITFIELD(27, 24) +#define OMAP4430_L4SEC_DYNDEP_MASK BITFIELD(14, 14) +#define OMAP4430_DSS_DYNDEP_MASK BITFIELD(8, 8) +#define OMAP4430_L3INIT_DYNDEP_MASK BITFIELD(7, 7) +#define OMAP4430_OPTFCLKEN_DBCLK_MASK BITFIELD(8, 8) +#define OMAP4430_OPTFCLKEN_DBCLK_MASK BITFIELD(8, 8) +#define OMAP4430_OPTFCLKEN_DBCLK_MASK BITFIELD(8, 8) +#define OMAP4430_OPTFCLKEN_DBCLK_MASK BITFIELD(8, 8) +#define OMAP4430_OPTFCLKEN_DBCLK_MASK BITFIELD(8, 8) +#define OMAP4430_CM2_CLKSEL_INTERNAL_SOURCE_MASK BITFIELD(25, 25) +#define OMAP4430_CM2_CLKSEL_SOURCE_MASK BITFIELD(24, 24) +#define OMAP4430_CM2_OPTFCLKEN_SLIMBUS_CLK_MASK BITFIELD(10, 10) +#define OMAP4430_OPTFCLKEN_PERABE24M_GFCLK_MASK BITFIELD(9, 9) +#define OMAP4430_OPTFCLKEN_PER24MC_GFCLK_MASK BITFIELD(8, 8) +#define OMAP4430_CLKACTIVITY_L4_SECURE_GICLK_MASK BITFIELD(9, 9) +#define OMAP4430_CLKACTIVITY_L3_SECURE_GICLK_MASK BITFIELD(8, 8) +#define OMAP4430_L4PER_STATDEP_MASK BITFIELD(13, 13) +#define OMAP4430_MEMIF_STATDEP_MASK BITFIELD(4, 4) +#define OMAP4430_CLKACTIVITY_SGX_GFCLK_MASK BITFIELD(9, 9) +#define OMAP4430_CLKACTIVITY_L3_GFX_GICLK_MASK BITFIELD(8, 8) +#define OMAP4430_MEMIF_STATDEP_MASK BITFIELD(4, 4) +#define OMAP4430_IVAHD_STATDEP_MASK BITFIELD(2, 2) +#define OMAP4430_CLKSEL_PER_192M_MASK BITFIELD(26, 25) +#define OMAP4430_CLKSEL_SGX_FCLK_MASK BITFIELD(24, 24) +#define OMAP4430_CLKACTIVITY_L3_1_GICLK_MASK BITFIELD(8, 8) +#define OMAP4430_WINDOWSIZE_MASK BITFIELD(27, 24) +#define OMAP4430_L4CFG_DYNDEP_MASK BITFIELD(12, 12) +#define OMAP4430_MEMIF_DYNDEP_MASK BITFIELD(4, 4) +#define OMAP4430_ABE_DYNDEP_MASK BITFIELD(3, 3) +#define OMAP4430_CLKACTIVITY_L3_2_GICLK_MASK BITFIELD(8, 8) +#define OMAP4430_WINDOWSIZE_MASK BITFIELD(27, 24) +#define OMAP4430_L4SEC_DYNDEP_MASK BITFIELD(14, 14) +#define OMAP4430_L4PER_DYNDEP_MASK BITFIELD(13, 13) +#define OMAP4430_GFX_DYNDEP_MASK BITFIELD(10, 10) +#define OMAP4430_ISS_DYNDEP_MASK BITFIELD(9, 9) +#define OMAP4430_L3INIT_DYNDEP_MASK BITFIELD(7, 7) +#define OMAP4430_IVAHD_DYNDEP_MASK BITFIELD(2, 2) +#define OMAP4430_DUCATI_DYNDEP_MASK BITFIELD(0, 0) +#define OMAP4430_CLKACTIVITY_DUCATI_GCLK_MASK BITFIELD(8, 8) +#define OMAP4430_CEFUSE_STATDEP_MASK BITFIELD(17, 17) +#define OMAP4430_ALWONCORE_STATDEP_MASK BITFIELD(16, 16) +#define OMAP4430_L4WKUP_STATDEP_MASK BITFIELD(15, 15) +#define OMAP4430_L4SEC_STATDEP_MASK BITFIELD(14, 14) +#define OMAP4430_L4PER_STATDEP_MASK BITFIELD(13, 13) +#define OMAP4430_L4CFG_STATDEP_MASK BITFIELD(12, 12) +#define OMAP4430_SDMA_STATDEP_MASK BITFIELD(11, 11) +#define OMAP4430_GFX_STATDEP_MASK BITFIELD(10, 10) +#define OMAP4430_ISS_STATDEP_MASK BITFIELD(9, 9) +#define OMAP4430_DSS_STATDEP_MASK BITFIELD(8, 8) +#define OMAP4430_L3INIT_STATDEP_MASK BITFIELD(7, 7) +#define OMAP4430_MEMIF_STATDEP_MASK BITFIELD(4, 4) +#define OMAP4430_ABE_STATDEP_MASK BITFIELD(3, 3) +#define OMAP4430_IVAHD_STATDEP_MASK BITFIELD(2, 2) +#define OMAP4430_TESLA_STATDEP_MASK BITFIELD(1, 1) +#define OMAP4430_WINDOWSIZE_MASK BITFIELD(27, 24) +#define OMAP4430_ISS_DYNDEP_MASK BITFIELD(9, 9) +#define OMAP4430_CLKACTIVITY_L3_DMA_GICLK_MASK BITFIELD(8, 8) +#define OMAP4430_L4WKUP_STATDEP_MASK BITFIELD(15, 15) +#define OMAP4430_L4SEC_STATDEP_MASK BITFIELD(14, 14) +#define OMAP4430_L4PER_STATDEP_MASK BITFIELD(13, 13) +#define OMAP4430_L4CFG_STATDEP_MASK BITFIELD(12, 12) +#define OMAP4430_ISS_STATDEP_MASK BITFIELD(9, 9) +#define OMAP4430_DSS_STATDEP_MASK BITFIELD(8, 8) +#define OMAP4430_L3INIT_STATDEP_MASK BITFIELD(7, 7) +#define OMAP4430_MEMIF_STATDEP_MASK BITFIELD(4, 4) +#define OMAP4430_ABE_STATDEP_MASK BITFIELD(3, 3) +#define OMAP4430_IVAHD_STATDEP_MASK BITFIELD(2, 2) +#define OMAP4430_DUCATI_STATDEP_MASK BITFIELD(0, 0) +#define OMAP4430_CLKACTIVITY_ASYNC_PHY2_CLK_MASK BITFIELD(13, 13) +#define OMAP4430_CLKACTIVITY_ASYNC_PHY1_CLK_MASK BITFIELD(12, 12) +#define OMAP4430_CLKACTIVITY_ASYNC_DLL_CLK_MASK BITFIELD(11, 11) +#define OMAP4430_CLKACTIVITY_PHY_ROOT_CLK_MASK BITFIELD(10, 10) +#define OMAP4430_CLKACTIVITY_DLL_CLK_MASK BITFIELD(9, 9) +#define OMAP4430_CLKACTIVITY_L3_EMIF_GICLK_MASK BITFIELD(8, 8) +#define OMAP4430_OPTFCLKEN_DLL_CLK_MASK BITFIELD(8, 8) +#define OMAP4430_OPTFCLKEN_DLL_CLK_MASK BITFIELD(8, 8) +#define OMAP4430_CLKACTIVITY_L4_D2D_GICLK_MASK BITFIELD(9, 9) +#define OMAP4430_CLKACTIVITY_L3_D2D_GICLK_MASK BITFIELD(8, 8) +#define OMAP4430_L4PER_STATDEP_MASK BITFIELD(13, 13) +#define OMAP4430_L4CFG_STATDEP_MASK BITFIELD(12, 12) +#define OMAP4430_L3INIT_STATDEP_MASK BITFIELD(7, 7) +#define OMAP4430_MEMIF_STATDEP_MASK BITFIELD(4, 4) +#define OMAP4430_ABE_STATDEP_MASK BITFIELD(3, 3) +#define OMAP4430_IVAHD_STATDEP_MASK BITFIELD(2, 2) +#define OMAP4430_WINDOWSIZE_MASK BITFIELD(27, 24) +#define OMAP4430_MEMIF_DYNDEP_MASK BITFIELD(4, 4) +#define OMAP4430_CLKACTIVITY_L4_CFG_GICLK_MASK BITFIELD(8, 8) +#define OMAP4430_WINDOWSIZE_MASK BITFIELD(27, 24) +#define OMAP4430_D2D_DYNDEP_MASK BITFIELD(18, 18) +#define OMAP4430_CEFUSE_DYNDEP_MASK BITFIELD(17, 17) +#define OMAP4430_ALWONCORE_DYNDEP_MASK BITFIELD(16, 16) +#define OMAP4430_L4WKUP_DYNDEP_MASK BITFIELD(15, 15) +#define OMAP4430_SDMA_DYNDEP_MASK BITFIELD(11, 11) +#define OMAP4430_ISS_DYNDEP_MASK BITFIELD(9, 9) +#define OMAP4430_L3INIT_DYNDEP_MASK BITFIELD(7, 7) +#define OMAP4430_MEMIF_DYNDEP_MASK BITFIELD(4, 4) +#define OMAP4430_TESLA_DYNDEP_MASK BITFIELD(1, 1) +#define OMAP4430_CLKACTIVITY_L3_INSTR_GICLK_MASK BITFIELD(8, 8) +#define OMAP4430_CLKACTIVITY_CUST_EFUSE_SYS_CLK_MASK BITFIELD(9, 9) +#define OMAP4430_CLKACTIVITY_L4_CEFUSE_GICLK_MASK BITFIELD(8, 8) +#define OMAP4430_REV_MASK BITFIELD(7, 0) +#define OMAP4430_MPU_M3_ISS_ROOT_CLKSEL_MASK BITFIELD(0, 0) +#define OMAP4430_USB_60MHZ_CLKSEL_MASK BITFIELD(0, 0) +#define OMAP4430_SCALE_FCLK_MASK BITFIELD(0, 0) +#define OMAP4430_PERF_REQ_MASK BITFIELD(7, 0) +#define OMAP4430_PERF_CURRENT_MASK BITFIELD(7, 0) +#define OMAP4430_DPLL_SSC_TYPE_MASK BITFIELD(15, 15) +#define OMAP4430_DPLL_SSC_DOWNSPREAD_MASK BITFIELD(14, 14) +#define OMAP4430_DPLL_SSC_ACK_MASK BITFIELD(13, 13) +#define OMAP4430_DPLL_SSC_EN_MASK BITFIELD(12, 12) +#define OMAP4430_DPLL_REGM4XEN_MASK BITFIELD(11, 11) +#define OMAP4430_DPLL_LPMODE_EN_MASK BITFIELD(10, 10) +#define OMAP4430_DPLL_RELOCK_RAMP_EN_MASK BITFIELD(9, 9) +#define OMAP4430_DPLL_RAMP_RATE_MASK BITFIELD(8, 6) +#define OMAP4430_DPLL_RAMP_LEVEL_MASK BITFIELD(5, 4) +#define OMAP4430_DPLL_DRIFTGUARD_EN_MASK BITFIELD(3, 3) +#define OMAP4430_DPLL_EN_MASK BITFIELD(2, 0) +#define OMAP4430_ST_DPLL_CLK_MASK BITFIELD(0, 0) +#define OMAP4430_DPLL_DCOCLKLDO_PWDN_MASK BITFIELD(4, 4) +#define OMAP4430_AUTO_DPLL_MODE_MASK BITFIELD(2, 0) +#define OMAP4430_DPLL_BYP_CLKSEL_MASK BITFIELD(23, 23) +#define OMAP4430_CM2_DPLL_MULT_MASK BITFIELD(18, 8) +#define OMAP4430_CM2_DPLL_DIV_MASK BITFIELD(6, 0) +#define OMAP4430_DPLL_M2_PWDN_MASK BITFIELD(12, 12) +#define OMAP4430_ST_DPLL_CLKOUTX2_MASK BITFIELD(11, 11) +#define OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK BITFIELD(10, 10) +#define OMAP4430_ST_DPLL_CLKOUT_MASK BITFIELD(9, 9) +#define OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK BITFIELD(8, 8) +#define OMAP4430_DPLL_CLKOUT_DIVCHACK_MASK BITFIELD(5, 5) +#define OMAP4430_DPLL_CLKOUT_DIV_MASK BITFIELD(4, 0) +#define OMAP4430_DPLL_M3_PWDN_MASK BITFIELD(12, 12) +#define OMAP4430_ST_DPLL_CLKOUTHIF_MASK BITFIELD(9, 9) +#define OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_MASK BITFIELD(8, 8) +#define OMAP4430_DPLL_CLKOUTHIF_DIVCHACK_MASK BITFIELD(5, 5) +#define OMAP4430_DPLL_CLKOUTHIF_DIV_MASK BITFIELD(4, 0) +#define OMAP4430_HSDIVIDER_CLKOUT1_PWDN_MASK BITFIELD(12, 12) +#define OMAP4430_ST_HSDIVIDER_CLKOUT1_MASK BITFIELD(9, 9) +#define OMAP4430_HSDIVIDER_CLKOUT1_GATE_CTRL_MASK BITFIELD(8, 8) +#define OMAP4430_HSDIVIDER_CLKOUT1_DIVCHACK_MASK BITFIELD(5, 5) +#define OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK BITFIELD(4, 0) +#define OMAP4430_HSDIVIDER_CLKOUT2_PWDN_MASK BITFIELD(12, 12) +#define OMAP4430_ST_HSDIVIDER_CLKOUT2_MASK BITFIELD(9, 9) +#define OMAP4430_HSDIVIDER_CLKOUT2_GATE_CTRL_MASK BITFIELD(8, 8) +#define OMAP4430_HSDIVIDER_CLKOUT2_DIVCHACK_MASK BITFIELD(5, 5) +#define OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK BITFIELD(4, 0) +#define OMAP4430_HSDIVIDER_CLKOUT3_PWDN_MASK BITFIELD(12, 12) +#define OMAP4430_ST_HSDIVIDER_CLKOUT3_MASK BITFIELD(9, 9) +#define OMAP4430_HSDIVIDER_CLKOUT3_GATE_CTRL_MASK BITFIELD(8, 8) +#define OMAP4430_HSDIVIDER_CLKOUT3_DIVCHACK_MASK BITFIELD(5, 5) +#define OMAP4430_HSDIVIDER_CLKOUT3_DIV_MASK BITFIELD(4, 0) +#define OMAP4430_HSDIVIDER_CLKOUT4_PWDN_MASK BITFIELD(12, 12) +#define OMAP4430_ST_HSDIVIDER_CLKOUT4_MASK BITFIELD(9, 9) +#define OMAP4430_HSDIVIDER_CLKOUT4_GATE_CTRL_MASK BITFIELD(8, 8) +#define OMAP4430_HSDIVIDER_CLKOUT4_DIVCHACK_MASK BITFIELD(5, 5) +#define OMAP4430_HSDIVIDER_CLKOUT4_DIV_MASK BITFIELD(4, 0) +#define OMAP4430_DELTAMSTEP_MASK BITFIELD(19, 0) +#define OMAP4430_MODFREQDIV_EXPONENT_MASK BITFIELD(10, 8) +#define OMAP4430_MODFREQDIV_MANTISSA_MASK BITFIELD(6, 0) +#define OMAP4430_OVERRIDE_ENABLE_MASK BITFIELD(19, 19) +#define OMAP4430_PER_DPLL_EMU_MULT_MASK BITFIELD(18, 8) +#define OMAP4430_RESERVED_MASK BITFIELD(7, 7) +#define OMAP4430_PER_DPLL_EMU_DIV_MASK BITFIELD(6, 0) +#define OMAP4430_DPLL_SSC_TYPE_MASK BITFIELD(15, 15) +#define OMAP4430_DPLL_SSC_DOWNSPREAD_MASK BITFIELD(14, 14) +#define OMAP4430_DPLL_SSC_ACK_MASK BITFIELD(13, 13) +#define OMAP4430_DPLL_SSC_EN_MASK BITFIELD(12, 12) +#define OMAP4430_DPLL_DRIFTGUARD_EN_MASK BITFIELD(3, 3) +#define OMAP4430_DPLL_SD_DIV_MASK BITFIELD(31, 24) +#define OMAP4430_CM2_USB_DPLL_MULT_MASK BITFIELD(19, 8) +#define OMAP4430_CM2_USB_DPLL_DIV_MASK BITFIELD(7, 0) +#define OMAP4430_ST_DPLL_CLKOUT_MASK BITFIELD(9, 9) +#define OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK BITFIELD(8, 8) +#define OMAP4430_USB_DPLL_CLKOUT_DIVCHACK_MASK BITFIELD(7, 7) +#define OMAP4430_USB_DPLL_CLKOUT_DIV_MASK BITFIELD(6, 0) +#define OMAP4430_DELTAMSTEP_MASK BITFIELD(19, 0) +#define OMAP4430_MODFREQDIV_EXPONENT_MASK BITFIELD(10, 8) +#define OMAP4430_MODFREQDIV_MANTISSA_MASK BITFIELD(6, 0) +#define OMAP4430_DPLL_CLKDCOLDO_PWDN_MASK BITFIELD(12, 12) +#define OMAP4430_ST_DPLL_CLKDCOLDO_MASK BITFIELD(9, 9) +#define OMAP4430_DPLL_CLKDCOLDO_GATE_CTRL_MASK BITFIELD(8, 8) +#define OMAP4430_DPLL_SSC_TYPE_MASK BITFIELD(15, 15) +#define OMAP4430_DPLL_SSC_DOWNSPREAD_MASK BITFIELD(14, 14) +#define OMAP4430_DPLL_SSC_ACK_MASK BITFIELD(13, 13) +#define OMAP4430_DPLL_SSC_EN_MASK BITFIELD(12, 12) +#define OMAP4430_DPLL_REGM4XEN_MASK BITFIELD(11, 11) +#define OMAP4430_DPLL_LPMODE_EN_MASK BITFIELD(10, 10) +#define OMAP4430_DPLL_RELOCK_RAMP_EN_MASK BITFIELD(9, 9) +#define OMAP4430_DPLL_DRIFTGUARD_EN_MASK BITFIELD(3, 3) +#define OMAP4430_ST_DPLL_CLKOUTX2_MASK BITFIELD(11, 11) +#define OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK BITFIELD(10, 10) +#define OMAP4430_DELTAMSTEP_MASK BITFIELD(19, 0) +#define OMAP4430_MODFREQDIV_EXPONENT_MASK BITFIELD(10, 8) +#define OMAP4430_MODFREQDIV_MANTISSA_MASK BITFIELD(6, 0) +#define OMAP4430_CLKACTIVITY_SR_CORE_SYSCLK_MASK BITFIELD(11, 11) +#define OMAP4430_CLKACTIVITY_SR_IVA_SYSCLK_MASK BITFIELD(10, 10) +#define OMAP4430_CLKACTIVITY_SR_MPU_SYSCLK_MASK BITFIELD(9, 9) +#define OMAP4430_CLKACTIVITY_L4_AO_ICLK_MASK BITFIELD(8, 8) +#endif /* __ARCH_ARM_MACH_OMAP2_CM2_REGBITS_44XX_H */ diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 711ed6aa3124..4224025700bc 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -319,7 +319,8 @@ static struct platform_device omap2_mcspi2 = { }, }; -#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) +#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ +defined(CONFIG_ARCH_OMAP4) static struct omap2_mcspi_platform_config omap2_mcspi3_config = { .num_cs = 2, }; @@ -343,7 +344,7 @@ static struct platform_device omap2_mcspi3 = { }; #endif -#ifdef CONFIG_ARCH_OMAP3 +#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) static struct omap2_mcspi_platform_config omap2_mcspi4_config = { .num_cs = 1, }; @@ -371,12 +372,13 @@ static void omap_init_mcspi(void) { platform_device_register(&omap2_mcspi1); platform_device_register(&omap2_mcspi2); -#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) - if (cpu_is_omap2430() || cpu_is_omap343x()) +#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ +defined(CONFIG_ARCH_OMAP4) + if (cpu_is_omap2430() || cpu_is_omap343x() || cpu_is_omap44xx()) platform_device_register(&omap2_mcspi3); #endif -#ifdef CONFIG_ARCH_OMAP3 - if (cpu_is_omap343x()) +#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) + if (cpu_is_omap343x() || cpu_is_omap44xx()) platform_device_register(&omap2_mcspi4); #endif } @@ -415,7 +417,7 @@ static inline void omap_init_sha1_md5(void) { } /*-------------------------------------------------------------------------*/ -#ifdef CONFIG_ARCH_OMAP3 +#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) #define MMCHS_SYSCONFIG 0x0010 #define MMCHS_SYSCONFIG_SWRESET (1 << 1) @@ -442,8 +444,8 @@ static struct platform_device dummy_pdev = { **/ static void __init omap_hsmmc_reset(void) { - u32 i, nr_controllers = cpu_is_omap34xx() ? OMAP34XX_NR_MMC : - OMAP24XX_NR_MMC; + u32 i, nr_controllers = cpu_is_omap44xx() ? OMAP44XX_NR_MMC : + (cpu_is_omap34xx() ? OMAP34XX_NR_MMC : OMAP24XX_NR_MMC); for (i = 0; i < nr_controllers; i++) { u32 v, base = 0; @@ -452,13 +454,32 @@ static void __init omap_hsmmc_reset(void) switch (i) { case 0: - base = OMAP2_MMC1_BASE; + if (!cpu_is_omap44xx()) + base = OMAP2_MMC1_BASE; + else + base = OMAP4_MMC1_BASE; break; case 1: - base = OMAP2_MMC2_BASE; + if (!cpu_is_omap44xx()) + base = OMAP2_MMC2_BASE; + else + base = OMAP4_MMC2_BASE; break; case 2: - base = OMAP3_MMC3_BASE; + if (!cpu_is_omap44xx()) + base = OMAP3_MMC3_BASE; + else + base = OMAP4_MMC3_BASE; + break; + case 3: + if (!cpu_is_omap44xx()) + return; + base = OMAP4_MMC4_BASE; + break; + case 4: + if (!cpu_is_omap44xx()) + return; + base = OMAP4_MMC5_BASE; break; } @@ -531,6 +552,63 @@ static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller, omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0); } } + if (cpu_is_omap44xx()) { + switch (controller_nr) { + case 0: + /* MMCC1 MUX configure */ + omap_cfg_reg(A1_4430_MMC1_CLK); + omap_cfg_reg(C1_4430_MMC1_CMD); + omap_cfg_reg(D0_4430_MMC1_DAT0); + omap_cfg_reg(D1_4430_MMC1_DAT1); + omap_cfg_reg(D2_4430_MMC1_DAT2); + omap_cfg_reg(D3_4430_MMC1_DAT3); + omap_cfg_reg(D4_4430_MMC1_DAT4); + omap_cfg_reg(D5_4430_MMC1_DAT5); + omap_cfg_reg(D6_4430_MMC1_DAT6); + omap_cfg_reg(D7_4430_MMC1_DAT7); + break; + case 1: + /*MMC2 MUX configure */ + omap_cfg_reg(A1_4430_MMC2_CLK); + omap_cfg_reg(C1_4430_MMC2_CMD); + omap_cfg_reg(D0_4430_MMC2_DAT0); + omap_cfg_reg(D1_4430_MMC2_DAT1); + omap_cfg_reg(D2_4430_MMC2_DAT2); + omap_cfg_reg(D3_4430_MMC2_DAT3); + omap_cfg_reg(D4_4430_MMC2_DAT4); + omap_cfg_reg(D5_4430_MMC2_DAT5); + omap_cfg_reg(D6_4430_MMC2_DAT6); + omap_cfg_reg(D7_4430_MMC2_DAT7); + break; + case 2: + /*MMC3 MUX configure */ + omap_cfg_reg(A1_4430_MMC3_CLK); + omap_cfg_reg(C1_4430_MMC3_CMD); + omap_cfg_reg(D0_4430_MMC3_DAT0); + omap_cfg_reg(D1_4430_MMC3_DAT1); + omap_cfg_reg(D2_4430_MMC3_DAT2); + omap_cfg_reg(D3_4430_MMC3_DAT3); + break; + case 3: + /*MMC4 MUX configure */ + omap_cfg_reg(A1_4430_MMC4_CLK); + omap_cfg_reg(C1_4430_MMC4_CMD); + omap_cfg_reg(D0_4430_MMC4_DAT0); + omap_cfg_reg(D1_4430_MMC4_DAT1); + omap_cfg_reg(D2_4430_MMC4_DAT2); + omap_cfg_reg(D3_4430_MMC4_DAT3); + break; + case 4: + /*MMC5 MUX configure */ + omap_cfg_reg(A1_4430_MMC5_CLK); + omap_cfg_reg(C1_4430_MMC5_CMD); + omap_cfg_reg(D0_4430_MMC5_DAT0); + omap_cfg_reg(D1_4430_MMC5_DAT1); + omap_cfg_reg(D2_4430_MMC5_DAT2); + omap_cfg_reg(D3_4430_MMC2_DAT3); + break; + } + } } void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, @@ -550,18 +628,45 @@ void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, switch (i) { case 0: - base = OMAP2_MMC1_BASE; - irq = INT_24XX_MMC_IRQ; + if (!cpu_is_omap44xx()) { + base = OMAP2_MMC1_BASE; + irq = INT_24XX_MMC_IRQ; + } else { + base = OMAP4_MMC1_BASE; + irq = INT_44XX_MMC_IRQ; + } break; case 1: - base = OMAP2_MMC2_BASE; - irq = INT_24XX_MMC2_IRQ; + if (!cpu_is_omap44xx()) { + base = OMAP2_MMC2_BASE; + irq = INT_24XX_MMC2_IRQ; + } else { + base = OMAP4_MMC2_BASE; + irq = INT_44XX_MMC2_IRQ; + } break; case 2: - if (!cpu_is_omap34xx()) + if (!cpu_is_omap34xx() || !cpu_is_omap44xx()) + return; + if (!cpu_is_omap44xx()) { + base = OMAP3_MMC3_BASE; + irq = INT_34XX_MMC3_IRQ; + } else { + base = OMAP4_MMC3_BASE; + irq = INT_44XX_MMC3_IRQ; + } + break; + case 3: + if (!cpu_is_omap44xx()) + return; + base = OMAP4_MMC4_BASE; + irq = INT_44XX_MMC4_IRQ; + break; + case 4: + if (!cpu_is_omap44xx()) return; - base = OMAP3_MMC3_BASE; - irq = INT_34XX_MMC3_IRQ; + base = OMAP4_MMC5_BASE; + irq = INT_44XX_MMC5_IRQ; break; default: continue; diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 4e4219d9d2b6..e9764f37961e 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -21,6 +21,7 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/io.h> +#include <linux/omapfb.h> #include <linux/clk.h> #include <asm/tlb.h> @@ -28,12 +29,10 @@ #include <asm/mach/map.h> #include <mach/mux.h> -#include <mach/omapfb.h> #include <mach/sram.h> #include <mach/sdrc.h> #include <mach/gpmc.h> -#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once clkdev is ready */ #include "clock.h" #include <mach/powerdomain.h> @@ -42,8 +41,8 @@ #include <mach/clockdomain.h> #include "clockdomains.h" -#endif #include <dspbridge/host_os.h> + /* * The machine specific code may provide the extra mapping besides the * default mapping provided here. @@ -287,12 +286,12 @@ static int __init _omap2_init_reprogram_sdrc(void) void __init omap2_init_common_hw(struct omap_sdrc_params *sp) { omap2_mux_init(); -#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once the clkdev is ready */ +#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once the clkdm/pwrdm f/w is ready */ pwrdm_init(powerdomains_omap); clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps); - omap2_clk_init(); omap2_sdrc_init(sp); _omap2_init_reprogram_sdrc(); #endif + omap2_clk_init(); gpmc_init(); } diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c index a5c0f0435cd6..550ba1452d67 100644 --- a/arch/arm/mach-omap2/mcbsp.c +++ b/arch/arm/mach-omap2/mcbsp.c @@ -169,6 +169,47 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { #define OMAP34XX_MCBSP_PDATA_SZ 0 #endif +#ifdef CONFIG_ARCH_OMAP4 +static struct omap_mcbsp_platform_data omap44xx_mcbsp_pdata[] = { + { + .phys_base = OMAP44XX_MCBSP1_BASE, + .dma_rx_sync = OMAP44XX_DMA_MCBSP1_RX, + .dma_tx_sync = OMAP44XX_DMA_MCBSP1_TX, + .rx_irq = INT_24XX_MCBSP1_IRQ_RX, + .tx_irq = INT_24XX_MCBSP1_IRQ_TX, + .ops = &omap2_mcbsp_ops, + }, + { + .phys_base = OMAP44XX_MCBSP2_BASE, + .dma_rx_sync = OMAP44XX_DMA_MCBSP2_RX, + .dma_tx_sync = OMAP44XX_DMA_MCBSP2_TX, + .rx_irq = INT_24XX_MCBSP2_IRQ_RX, + .tx_irq = INT_24XX_MCBSP2_IRQ_TX, + .ops = &omap2_mcbsp_ops, + }, + { + .phys_base = OMAP44XX_MCBSP3_BASE, + .dma_rx_sync = OMAP44XX_DMA_MCBSP3_RX, + .dma_tx_sync = OMAP44XX_DMA_MCBSP3_TX, + .rx_irq = INT_24XX_MCBSP3_IRQ_RX, + .tx_irq = INT_24XX_MCBSP3_IRQ_TX, + .ops = &omap2_mcbsp_ops, + }, + { + .phys_base = OMAP44XX_MCBSP4_BASE, + .dma_rx_sync = OMAP44XX_DMA_MCBSP4_RX, + .dma_tx_sync = OMAP44XX_DMA_MCBSP4_TX, + .rx_irq = INT_24XX_MCBSP4_IRQ_RX, + .tx_irq = INT_24XX_MCBSP4_IRQ_TX, + .ops = &omap2_mcbsp_ops, + }, +}; +#define OMAP44XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap44xx_mcbsp_pdata) +#else +#define omap44xx_mcbsp_pdata NULL +#define OMAP44XX_MCBSP_PDATA_SZ 0 +#endif + static int __init omap2_mcbsp_init(void) { if (cpu_is_omap2420()) @@ -177,6 +218,8 @@ static int __init omap2_mcbsp_init(void) omap_mcbsp_count = OMAP2430_MCBSP_PDATA_SZ; if (cpu_is_omap34xx()) omap_mcbsp_count = OMAP34XX_MCBSP_PDATA_SZ; + if (cpu_is_omap44xx()) + omap_mcbsp_count = OMAP44XX_MCBSP_PDATA_SZ; mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *), GFP_KERNEL); @@ -192,6 +235,9 @@ static int __init omap2_mcbsp_init(void) if (cpu_is_omap34xx()) omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata, OMAP34XX_MCBSP_PDATA_SZ); + if (cpu_is_omap44xx()) + omap_mcbsp_register_board_cfg(omap44xx_mcbsp_pdata, + OMAP44XX_MCBSP_PDATA_SZ); return omap_mcbsp_init(); } diff --git a/arch/arm/mach-omap2/mmc-twl4030.c b/arch/arm/mach-omap2/mmc-twl4030.c index 1541fd4c8d0f..eea196700b04 100644 --- a/arch/arm/mach-omap2/mmc-twl4030.c +++ b/arch/arm/mach-omap2/mmc-twl4030.c @@ -25,7 +25,7 @@ #include <mach/board.h> #include "mmc-twl4030.h" - +#include <linux/i2c/twl.h> #if defined(CONFIG_REGULATOR) && \ (defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)) @@ -34,6 +34,7 @@ static u16 control_pbias_offset; static u16 control_devconf1_offset; #define HSMMC_NAME_LEN 9 +#define REG_SIMCTRL 0x09 static struct twl_mmc_controller { struct omap_mmc_platform_data *mmc; @@ -50,19 +51,37 @@ static struct twl_mmc_controller { static int twl_mmc_card_detect(int irq) { - unsigned i; - - for (i = 0; i < ARRAY_SIZE(hsmmc); i++) { - struct omap_mmc_platform_data *mmc; - - mmc = hsmmc[i].mmc; - if (!mmc) - continue; - if (irq != mmc->slots[0].card_detect_irq) - continue; - - /* NOTE: assumes card detect signal is active-low */ - return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); + if (!cpu_is_omap44xx()) { + unsigned i; + for (i = 0; i < ARRAY_SIZE(hsmmc); i++) { + struct omap_mmc_platform_data *mmc; + + mmc = hsmmc[i].mmc; + if (!mmc) + continue; + if (irq != mmc->slots[0].card_detect_irq) + continue; + + /* NOTE: assumes card detect signal is active-low */ + return !gpio_get_value_cansleep + (mmc->slots[0].switch_pin); + } + } else { + /* BIT0 of REG_SIMCTRL + * 0 - Card not present + * 1 - Card present + */ + u8 read_reg; + unsigned res; + res = twl_i2c_read_u8(TWL6030_MODULE_PM_MISC, + &read_reg, REG_SIMCTRL); + if (res < 0) { + printk(KERN_ERR"%s: i2c_read fail at %x \n", + __func__, REG_SIMCTRL); + return -1; + } else { + return !(read_reg & 0x01); + } } return -ENOSYS; } @@ -369,31 +388,50 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) mmc->dma_mask = 0xffffffff; mmc->init = twl_mmc_late_init; - /* note: twl4030 card detect GPIOs can disable VMMCx ... */ - if (gpio_is_valid(c->gpio_cd)) { + if (!cpu_is_omap44xx()) { + /* note: twl4030 card detect GPIOs can disable + * VMMCx ... + */ + if (gpio_is_valid(c->gpio_cd)) { + mmc->cleanup = twl_mmc_cleanup; + mmc->suspend = twl_mmc_suspend; + mmc->resume = twl_mmc_resume; + + mmc->slots[0].switch_pin = c->gpio_cd; + mmc->slots[0].card_detect_irq = + gpio_to_irq(c->gpio_cd); + 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; + } else + mmc->slots[0].switch_pin = -EINVAL; + + /* write protect normally uses an OMAP gpio */ + if (gpio_is_valid(c->gpio_wp)) { + gpio_request(c->gpio_wp, "mmc_wp"); + gpio_direction_input(c->gpio_wp); + + mmc->slots[0].gpio_wp = c->gpio_wp; + mmc->slots[0].get_ro = twl_mmc_get_ro; + } else + mmc->slots[0].gpio_wp = -EINVAL; + } else { + /* Dummy Initialization for OMAP4 */ + mmc->init = twl_mmc_late_init; mmc->cleanup = twl_mmc_cleanup; mmc->suspend = twl_mmc_suspend; mmc->resume = twl_mmc_resume; - + mmc->slots[0].switch_pin = NULL; + mmc->slots[0].get_cover_state = NULL; mmc->slots[0].switch_pin = c->gpio_cd; - mmc->slots[0].card_detect_irq = gpio_to_irq(c->gpio_cd); - 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; - } else - mmc->slots[0].switch_pin = -EINVAL; - - /* write protect normally uses an OMAP gpio */ - if (gpio_is_valid(c->gpio_wp)) { - gpio_request(c->gpio_wp, "mmc_wp"); - gpio_direction_input(c->gpio_wp); - - mmc->slots[0].gpio_wp = c->gpio_wp; - mmc->slots[0].get_ro = twl_mmc_get_ro; - } else - mmc->slots[0].gpio_wp = -EINVAL; - + mmc->slots[0].card_detect_irq = 373; + mmc->slots[0].card_detect = twl_mmc_card_detect; + mmc->slots[0].gpio_wp = NULL; + mmc->slots[0].get_ro = NULL; + } /* NOTE: MMC slots should have a Vcc regulator set up. * This may be from a TWL4030-family chip, another * controllable regulator, or a fixed supply. diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index 026c4fc883a7..84aa99650791 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c @@ -495,6 +495,213 @@ MUX_CFG_34XX("J25_34XX_GPIO170", 0x1c6, #define OMAP34XX_PINS_SZ 0 #endif /* CONFIG_ARCH_OMAP34XX */ +#ifdef CONFIG_ARCH_OMAP4 +static struct pin_config __initdata_or_module omap44xx_pins[] = { +/* + * Name, reg-offset, + * mux-mode | [active-mode | off-mode] + */ +/* 34xx I2C */ +MUX_CFG_34XX("AA3_4430_McSPI1_CLK", 0x130, + OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_OUTPUT) +MUX_CFG_34XX("Y2_4430_McSPI1_SIMO", 0x136, + OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_OUTPUT) +MUX_CFG_34XX("Y3_4430_McSPI1_SOMI", 0x134, + OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_OUTPUT) +MUX_CFG_34XX("Y4_4430_McSPI1_CS0", 0x138, + OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_OUTPUT) +MUX_CFG_34XX("Y4_4430_McSPI1_CS1", 0x13a, + OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_OUTPUT) +MUX_CFG_34XX("Y4_4430_McSPI1_CS2", 0x13c, + OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_OUTPUT) +MUX_CFG_34XX("Y4_4430_McSPI1_CS3", 0x13e, + OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) + +MUX_CFG_34XX("AA3_4430_McBSP1_CLK", 0x00fe, + OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT) +MUX_CFG_34XX("Y3_4430_McBSP1_DR", 0x100, + OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT) +MUX_CFG_34XX("Y2_4430_McBSP1_DX", 0x102, + OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_OUTPUT) +MUX_CFG_34XX("Y4_4430_McBSP1_FSX", 0x104, + OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT) + +MUX_CFG_34XX("PAD0_4430_UNIPRO_TX0", 0x07c, + OMAP34XX_MUX_MODE1 | OMAP34XX_PIN_OUTPUT) +MUX_CFG_34XX("PAD1_4430_UNIPRO_TY0", 0x07e, + OMAP34XX_MUX_MODE1 | OMAP34XX_PIN_OUTPUT) +MUX_CFG_34XX("PAD0_4430_UNIPRO_TX1", 0x180, + OMAP34XX_MUX_MODE1 | OMAP34XX_PIN_OUTPUT) +MUX_CFG_34XX("PAD1_4430_UNIPRO_TY1", 0x182, + OMAP34XX_MUX_MODE1 | OMAP34XX_PIN_OUTPUT) +MUX_CFG_34XX("PAD0_4430_UNIPRO_TX2", 0x184, + OMAP34XX_MUX_MODE1 | OMAP34XX_PIN_OUTPUT) +MUX_CFG_34XX("PAD1_4430_UNIPRO_TY2", 0x186, + OMAP34XX_MUX_MODE1 | OMAP34XX_PIN_OUTPUT) +MUX_CFG_34XX("PAD0_4430_UNIPRO_RX0", 0x188, + OMAP34XX_MUX_MODE1 | OMAP34XX_PIN_OUTPUT) +MUX_CFG_34XX("PAD0_4430_UNIPRO_RX1", 0x18c, + OMAP34XX_MUX_MODE1 | OMAP34XX_PIN_OUTPUT) +MUX_CFG_34XX("PAD1_4430_UNIPRO_RY1", 0x18e, + OMAP34XX_MUX_MODE1 | OMAP34XX_PIN_OUTPUT) +MUX_CFG_34XX("PAD1_4430_UNIPRO_RY0", 0x18a, + OMAP34XX_MUX_MODE1 | OMAP34XX_PIN_OUTPUT) +MUX_CFG_34XX("PAD0_4430_UNIPRO_RX2", 0x190, + OMAP34XX_MUX_MODE1 | OMAP34XX_PIN_OUTPUT) +MUX_CFG_34XX("PAD1_4430_UNIPRO_RY2", 0x192, + OMAP34XX_MUX_MODE1 | OMAP34XX_PIN_OUTPUT) + +/* SYS_nIRQ MUX Config */ +MUX_CFG_34XX("PAD1_4430_SYS_NIRQ1", 0x019E, OMAP34XX_MUX_MODE0 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN) +MUX_CFG_34XX("PAD0_4430_SYS_NIRQ2", 0x01A0, OMAP34XX_MUX_MODE0 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN) + +/* MMC1 MUX Config */ +MUX_CFG_34XX("A1_4430_MMC1_CLK", 0x00e2, OMAP34XX_MUX_MODE0 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_OFF_EN) +MUX_CFG_34XX("C1_4430_MMC1_CMD", 0x00e4, OMAP34XX_MUX_MODE0 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + |OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("D0_4430_MMC1_DAT0", 0x00e6, OMAP34XX_MUX_MODE0 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("D1_4430_MMC1_DAT1", 0x00e8, OMAP34XX_MUX_MODE0 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("D2_4430_MMC1_DAT2", 0x00ea, OMAP34XX_MUX_MODE0 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("D3_4430_MMC1_DAT3", 0x00ec, OMAP34XX_MUX_MODE0 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("D4_4430_MMC1_DAT4", 0x00ee, OMAP34XX_MUX_MODE0 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("D5_4430_MMC1_DAT5", 0x00f0, OMAP34XX_MUX_MODE0 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("D6_4430_MMC1_DAT6", 0x00f2, OMAP34XX_MUX_MODE0 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("D7_4430_MMC1_DAT7", 0x00f4, OMAP34XX_MUX_MODE0 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) + +/* MMC2 MUX Config */ +MUX_CFG_34XX("A1_4430_MMC2_CLK", 0x0082, OMAP34XX_MUX_MODE1 + |OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("C1_4430_MMC2_CMD", 0x0080, OMAP34XX_MUX_MODE1 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("D0_4430_MMC2_DAT0", 0x0040, OMAP34XX_MUX_MODE1 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("D1_4430_MMC2_DAT1", 0x0042, OMAP34XX_MUX_MODE1 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("D2_4430_MMC2_DAT2", 0x0044, OMAP34XX_MUX_MODE1 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("D3_4430_MMC2_DAT3", 0x0046, OMAP34XX_MUX_MODE1 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("D4_4430_MMC2_DAT4", 0x0048, OMAP34XX_MUX_MODE1 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("D5_4430_MMC2_DAT5", 0x004a, OMAP34XX_MUX_MODE1 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("D6_4430_MMC2_DAT6", 0x004c, OMAP34XX_MUX_MODE1 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("D7_4430_MMC2_DAT7", 0x004e, OMAP34XX_MUX_MODE1 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) + +/* MMC3 MUX Config*/ +MUX_CFG_34XX("A1_4430_MMC3_CLK", 0x0176, OMAP34XX_MUX_MODE2 + | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("C1_4430_MMC3_CMD", 0x0174, OMAP34XX_MUX_MODE2 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("D0_4430_MMC3_DAT0", 0x0170, OMAP34XX_MUX_MODE2 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("D1_4430_MMC3_DAT1", 0x016e, OMAP34XX_MUX_MODE2 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("D2_4430_MMC3_DAT2", 0x016c, OMAP34XX_MUX_MODE2 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("D3_4430_MMC3_DAT3", 0x0172, OMAP34XX_MUX_MODE2 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) + +/* MMC4 MUX Config*/ +MUX_CFG_34XX("A1_4430_MMC4_CLK", 0x0162, OMAP34XX_MUX_MODE2 + | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("C1_4430_MMC4_CMD", 0x0160, OMAP34XX_MUX_MODE2 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("D0_4430_MMC4_DAT0", 0x0164, OMAP34XX_MUX_MODE2 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("D1_4430_MMC4_DAT1", 0x0166, OMAP34XX_MUX_MODE2 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("D2_4430_MMC4_DAT2", 0x0168, OMAP34XX_MUX_MODE2 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("D3_4430_MMC4_DAT3", 0x016a, OMAP34XX_MUX_MODE2 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) + +/* MMC5 MUX Config*/ +MUX_CFG_34XX("A1_4430_MMC5_CLK", 0x0148, OMAP34XX_MUX_MODE0 + | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("C1_4430_MMC5_CMD", 0x014a, OMAP34XX_MUX_MODE0 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("D0_4430_MMC5_DAT0", 0x014c, OMAP34XX_MUX_MODE0 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("D1_4430_MMC5_DAT1", 0x014e, OMAP34XX_MUX_MODE0 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("D2_4430_MMC5_DAT2", 0x0150, OMAP34XX_MUX_MODE0 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) +MUX_CFG_34XX("D3_4430_MMC5_DAT3", 0x0152, OMAP34XX_MUX_MODE0 | OMAP2_PULL_ENA + | OMAP2_PULL_UP | OMAP3_INPUT_EN | OMAP3_OFF_EN + | OMAP3_OFFOUT_EN | OMAP3_OFF_PULL_EN) + +/* Audio */ +MUX_CFG_34XX("AG25_4430_ABE_PDM_UL_DATA", 0x0106, + OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT) +MUX_CFG_34XX("AF25_4430_ABE_PDM_DL_DATA", 0x0108, + OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_OUTPUT) +MUX_CFG_34XX("AE25_4430_ABE_PDM_FRAME", 0x010a, + OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT) +MUX_CFG_34XX("AF26_4430_ABE_PDM_LB_CLK", 0x010c, + OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_OUTPUT) +MUX_CFG_34XX("AH26_4430_ABE_PDM_CLKS", 0x010e, + OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT) + +MUX_CFG_34XX("AA27_4430_GPIO_127", 0x0120, + OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT) +}; +#define OMAP44XX_PINS_SZ ARRAY_SIZE(omap44xx_pins) + +#else +#define omap44xx_pins NULL +#define OMAP44XX_PINS_SZ 0 +#endif /* CONFIG_ARCH_OMAP34XX */ + #if defined(CONFIG_OMAP_MUX_DEBUG) || defined(CONFIG_OMAP_MUX_WARNINGS) static void __init_or_module omap2_cfg_debug(const struct pin_config *cfg, u16 reg) { @@ -543,7 +750,7 @@ static int __init_or_module omap24xx_cfg_reg(const struct pin_config *cfg) #define omap24xx_cfg_reg NULL #endif -#ifdef CONFIG_ARCH_OMAP34XX +#if defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP4) static int __init_or_module omap34xx_cfg_reg(const struct pin_config *cfg) { static DEFINE_SPINLOCK(mux_spin_lock); @@ -573,7 +780,11 @@ int __init omap2_mux_init(void) arch_mux_cfg.size = OMAP34XX_PINS_SZ; arch_mux_cfg.cfg_reg = omap34xx_cfg_reg; } - + if (cpu_is_omap44xx()) { + arch_mux_cfg.pins = omap44xx_pins; + arch_mux_cfg.size = OMAP44XX_PINS_SZ; + arch_mux_cfg.cfg_reg = omap34xx_cfg_reg; + } return omap_mux_register(&arch_mux_cfg); } diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h index cb1ae84e0925..a3bcdd2d021d 100644 --- a/arch/arm/mach-omap2/prcm-common.h +++ b/arch/arm/mach-omap2/prcm-common.h @@ -49,6 +49,34 @@ #define OMAP3430_NEON_MOD 0xb00 #define OMAP3430ES2_USBHOST_MOD 0xc00 +#define BITS(n_bit) \ + (((1 << n_bit) - 1) | (1 << n_bit)) + +#define BITFIELD(u_bit, l_bit) \ + (BITS(u_bit) & ~((BITS(l_bit)) >> 1)) + +/* OMAP44XX specific module offsets */ +#define OMAP4430_OCP_SOCKET_MOD 0x0000 +#define OMAP4430_CKGEN_MOD 0x0100 +#define OMAP4430_MPU_MOD 0x0300 +#define OMAP4430_DSP_MOD 0x0400 +#define OMAP4430_ABE_MOD 0x0500 +#define OMAP4430_ALWAYS_ON_MOD 0x0600 +#define OMAP4430_CORE_MOD 0x0700 +#define OMAP4430_IVAHD_MOD 0x0F00 +#define OMAP4430_CAM_MOD 0x1000 +#define OMAP4430_DSS_MOD 0x1100 +#define OMAP4430_GFX_MOD 0x1200 +#define OMAP4430_L3INIT_MOD 0x1300 +#define OMAP4430_L4PER_MOD 0x1400 +#define OMAP4430_CEFUSE_MOD 0x1600 +#define OMAP4430_WKUP_MOD 0x1700 +#define OMAP4430_WKUP_CM_MOD 0x1800 +#define OMAP4430_EMU_MOD 0x1900 +#define OMAP4430_EMU_CM_MOD 0x1A00 +#define OMAP4430_DEVICE_MOD 0x1B00 +#define OMAP4430_RESTORE_MOD 0x1E00 +#define OMAP4430_INSTR_MOD 0x1F00 /* 24XX register bits shared between CM & PRM registers */ diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c index f945156d5585..de307fa98933 100644 --- a/arch/arm/mach-omap2/prcm.c +++ b/arch/arm/mach-omap2/prcm.c @@ -27,6 +27,7 @@ static void __iomem *prm_base; static void __iomem *cm_base; +static void __iomem *cm2_base; u32 omap_prcm_get_reset_sources(void) { @@ -124,4 +125,5 @@ void __init omap2_set_globals_prcm(struct omap_globals *omap2_globals) { prm_base = omap2_globals->prm; cm_base = omap2_globals->cm; + cm2_base = omap2_globals->cm2; } diff --git a/arch/arm/mach-omap2/prm-regbits-44xx.h b/arch/arm/mach-omap2/prm-regbits-44xx.h new file mode 100644 index 000000000000..13c1dcbfbe0a --- /dev/null +++ b/arch/arm/mach-omap2/prm-regbits-44xx.h @@ -0,0 +1,1141 @@ +#ifndef __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_44XX_H +#define __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_44XX_H + +/* + * OMAP4430 Power/Reset Management register bits + * + * Copyright (C) 2009 Texas Instruments, Inc. + * + * Written by 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 version 2 as + * published by the Free Software Foundation. + */ + +#include "prm.h" + +#define OMAP4430_CLKSEL (1 << 0) +#define OMAP4430_SYS_CLKSEL (1 << 0) +#define OMAP4430_PERIPHMEM_ONSTATE (1 << 20) +#define OMAP4430_AESSMEM_ONSTATE (1 << 16) +#define OMAP4430_PERIPHMEM_RETSTATE (1 << 10) +#define OMAP4430_AESSMEM_RETSTATE (1 << 8) +#define OMAP4430_LOWPOWERSTATECHANGE (1 << 4) +#define OMAP4430_LOGICRETSTATE (1 << 2) +#define OMAP4430_POWERSTATE (1 << 0) +#define OMAP4430_INTRANSITION (1 << 20) +#define OMAP4430_PERIPHMEM_STATEST (1 << 8) +#define OMAP4430_AESSMEM_STATEST (1 << 4) +#define OMAP4430_LOGICSTATEST (1 << 2) +#define OMAP4430_POWERSTATEST (1 << 0) +#define OMAP4430_LOSTMEM_AESSMEM (1 << 8) +#define OMAP4430_LOSTCONTEXT_DFF (1 << 0) +#define OMAP4430_WKUPDEP_PDM_DMA_SDMA (1 << 7) +#define OMAP4430_WKUPDEP_PDM_DMA_TESLA (1 << 6) +#define OMAP4430_WKUPDEP_PDM_IRQ_TESLA (1 << 2) +#define OMAP4430_WKUPDEP_PDM_IRQ_MPU (1 << 0) +#define OMAP4430_LOSTMEM_PERIHPMEM (1 << 8) +#define OMAP4430_WKUPDEP_DMIC_DMA_SDMA (1 << 7) +#define OMAP4430_WKUPDEP_DMIC_DMA_TESLA (1 << 6) +#define OMAP4430_WKUPDEP_DMIC_IRQ_TESLA (1 << 2) +#define OMAP4430_WKUPDEP_DMIC_IRQ_MPU (1 << 0) +#define OMAP4430_WKUPDEP_MCASP1_DMA_SDMA (1 << 7) +#define OMAP4430_WKUPDEP_MCASP1_DMA_TESLA (1 << 6) +#define OMAP4430_WKUPDEP_MCASP1_IRQ_TESLA (1 << 2) +#define OMAP4430_WKUPDEP_MCASP1_IRQ_MPU (1 << 0) +#define OMAP4430_WKUPDEP_MCBSP1_SDMA (1 << 3) +#define OMAP4430_WKUPDEP_MCBSP1_TESLA (1 << 2) +#define OMAP4430_WKUPDEP_MCBSP1_MPU (1 << 0) +#define OMAP4430_WKUPDEP_MCBSP2_SDMA (1 << 3) +#define OMAP4430_WKUPDEP_MCBSP2_TESLA (1 << 2) +#define OMAP4430_WKUPDEP_MCBSP2_MPU (1 << 0) +#define OMAP4430_WKUPDEP_MCBSP3_SDMA (1 << 3) +#define OMAP4430_WKUPDEP_MCBSP3_TESLA (1 << 2) +#define OMAP4430_WKUPDEP_MCBSP3_MPU (1 << 0) +#define OMAP4430_WKUPDEP_SLIMBUS1_DMA_SDMA (1 << 7) +#define OMAP4430_WKUPDEP_SLIMBUS1_DMA_TESLA (1 << 6) +#define OMAP4430_WKUPDEP_SLIMBUS1_IRQ_TESLA (1 << 2) +#define OMAP4430_WKUPDEP_SLIMBUS1_IRQ_MPU (1 << 0) +#define OMAP4430_WKUPDEP_TIMER5_TESLA (1 << 2) +#define OMAP4430_WKUPDEP_TIMER5_MPU (1 << 0) +#define OMAP4430_WKUPDEP_TIMER6_TESLA (1 << 2) +#define OMAP4430_WKUPDEP_TIMER6_MPU (1 << 0) +#define OMAP4430_WKUPDEP_TIMER7_TESLA (1 << 2) +#define OMAP4430_WKUPDEP_TIMER7_MPU (1 << 0) +#define OMAP4430_WKUPDEP_TIMER8_TESLA (1 << 2) +#define OMAP4430_WKUPDEP_TIMER8_MPU (1 << 0) +#define OMAP4430_WKUPDEP_WDT3_MPU (1 << 0) +#define OMAP4430_DSS_MEM_ONSTATE (1 << 16) +#define OMAP4430_DSS_MEM_RETSTATE (1 << 8) +#define OMAP4430_DSS_MEM_STATEST (1 << 4) +#define OMAP4430_WKUPDEP_HDMIDMA_SDMA (1 << 19) +#define OMAP4430_WKUPDEP_HDMIIRQ_TESLA (1 << 14) +#define OMAP4430_WKUPDEP_HDMIIRQ_DUCATI (1 << 13) +#define OMAP4430_WKUPDEP_HDMIIRQ_MPU (1 << 12) +#define OMAP4430_WKUPDEP_DSI2_SDMA (1 << 11) +#define OMAP4430_WKUPDEP_DSI2_TESLA (1 << 10) +#define OMAP4430_WKUPDEP_DSI2_DUCATI (1 << 9) +#define OMAP4430_WKUPDEP_DSI2_MPU (1 << 8) +#define OMAP4430_WKUPDEP_DSI1_SDMA (1 << 7) +#define OMAP4430_WKUPDEP_DSI1_TESLA (1 << 6) +#define OMAP4430_WKUPDEP_DSI1_DUCATI (1 << 5) +#define OMAP4430_WKUPDEP_DSI1_MPU (1 << 4) +#define OMAP4430_WKUPDEP_DISPC_SDMA (1 << 3) +#define OMAP4430_WKUPDEP_DISPC_TESLA (1 << 2) +#define OMAP4430_WKUPDEP_DISPC_DUCATI (1 << 1) +#define OMAP4430_WKUPDEP_DISPC_MPU (1 << 0) +#define OMAP4430_LOSTMEM_DSS_MEM (1 << 8) +#define OMAP4430_LOSTCONTEXT_RFF (1 << 1) +#define OMAP4430_L3INIT_BANK1_ONSTATE (1 << 16) +#define OMAP4430_L3INIT_BANK1_RETSTATE (1 << 8) +#define OMAP4430_L3INIT_BANK1_STATEST (1 << 4) +#define OMAP4430_WKUPDEP_MMC1_SDMA (1 << 3) +#define OMAP4430_WKUPDEP_MMC1_TESLA (1 << 2) +#define OMAP4430_WKUPDEP_MMC1_DUCATI (1 << 1) +#define OMAP4430_WKUPDEP_MMC1_MPU (1 << 0) +#define OMAP4430_LOSTMEM_L3INIT_BANK1 (1 << 8) +#define OMAP4430_WKUPDEP_MMC2_SDMA (1 << 3) +#define OMAP4430_WKUPDEP_MMC2_TESLA (1 << 2) +#define OMAP4430_WKUPDEP_MMC2_DUCATI (1 << 1) +#define OMAP4430_WKUPDEP_MMC2_MPU (1 << 0) +#define OMAP4430_LOSTMEM_L3INIT_BANK1 (1 << 8) +#define OMAP4430_WKUPDEP_WGM_HSI_WAKE_MPU (1 << 8) +#define OMAP4430_WKUPDEP_HSI_DSP_TESLA (1 << 6) +#define OMAP4430_WKUPDEP_HSI_MCU_DUCATI (1 << 1) +#define OMAP4430_WKUPDEP_HSI_MCU_MPU (1 << 0) +#define OMAP4430_LOSTMEM_L3INIT_BANK1 (1 << 8) +#define OMAP4430_WKUPDEP_UNIPRO1_DUCATI (1 << 1) +#define OMAP4430_WKUPDEP_UNIPRO1_MPU (1 << 0) +#define OMAP4430_LOSTMEM_L3INIT_BANK1 (1 << 8) +#define OMAP4430_WKUPDEP_USB_HOST_DUCATI (1 << 1) +#define OMAP4430_WKUPDEP_USB_HOST_MPU (1 << 0) +#define OMAP4430_WKUPDEP_USB_OTG_DUCATI (1 << 1) +#define OMAP4430_WKUPDEP_USB_OTG_MPU (1 << 0) +#define OMAP4430_LOSTMEM_L3INIT_BANK1 (1 << 8) +#define OMAP4430_WKUPDEP_USB_TLL_DUCATI (1 << 1) +#define OMAP4430_WKUPDEP_USB_TLL_MPU (1 << 0) +#define OMAP4430_LOSTMEM_L3INIT_BANK1 (1 << 8) +#define OMAP4430_WKUPDEP_SATA_TESLA (1 << 2) +#define OMAP4430_WKUPDEP_SATA_MPU (1 << 0) +#define OMAP4430_LOSTMEM_L3INIT_BANK1 (1 << 8) +#define OMAP4430_LOSTMEM_L3INIT_BANK1 (1 << 8) +#define OMAP4430_WKUPDEP_PCIESS_TESLA (1 << 2) +#define OMAP4430_WKUPDEP_PCIESS_MPU (1 << 0) +#define OMAP4430_LOSTMEM_L3INIT_BANK1 (1 << 8) +#define OMAP4430_LOSTMEM_L3INIT_BANK1 (1 << 8) +#define OMAP4430_WKUPDEP_XHPI_DUCATI (1 << 1) +#define OMAP4430_LOSTMEM_L3INIT_BANK1 (1 << 8) +#define OMAP4430_WKUPDEP_MMC6_TESLA (1 << 2) +#define OMAP4430_WKUPDEP_MMC6_DUCATI (1 << 1) +#define OMAP4430_WKUPDEP_MMC6_MPU (1 << 0) +#define OMAP4430_LOSTMEM_L3INIT_BANK1 (1 << 8) +#define OMAP4430_WKUPDEP_USB_HOST_FS_DUCATI (1 << 1) +#define OMAP4430_WKUPDEP_USB_HOST_FS_MPU (1 << 0) +#define OMAP4430_NONRETAINED_BANK_ONSTATE (1 << 18) +#define OMAP4430_RETAINED_BANK_ONSTATE (1 << 16) +#define OMAP4430_NONRETAINED_BANK_RETSTATE (1 << 9) +#define OMAP4430_RETAINED_BANK_RETSTATE (1 << 8) +#define OMAP4430_NONRETAINED_BANK_STATEST (1 << 6) +#define OMAP4430_RETAINED_BANK_STATEST (1 << 4) +#define OMAP4430_WKUPDEP_DMTIMER10_MPU (1 << 0) +#define OMAP4430_WKUPDEP_DMTIMER11_DUCATI (1 << 1) +#define OMAP4430_WKUPDEP_DMTIMER11_MPU (1 << 0) +#define OMAP4430_WKUPDEP_DMTIMER2_MPU (1 << 0) +#define OMAP4430_WKUPDEP_DMTIMER3_DUCATI (1 << 1) +#define OMAP4430_WKUPDEP_DMTIMER3_MPU (1 << 0) +#define OMAP4430_WKUPDEP_DMTIMER4_DUCATI (1 << 1) +#define OMAP4430_WKUPDEP_DMTIMER4_MPU (1 << 0) +#define OMAP4430_WKUPDEP_DMTIMER9_DUCATI (1 << 1) +#define OMAP4430_WKUPDEP_DMTIMER9_MPU (1 << 0) +#define OMAP4430_WKUPDEP_GPIO2_IRQ2_TESLA (1 << 6) +#define OMAP4430_WKUPDEP_GPIO2_IRQ1_DUCATI (1 << 1) +#define OMAP4430_WKUPDEP_GPIO2_IRQ1_MPU (1 << 0) +#define OMAP4430_WKUPDEP_GPIO3_IRQ2_TESLA (1 << 6) +#define OMAP4430_WKUPDEP_GPIO3_IRQ1_MPU (1 << 0) +#define OMAP4430_WKUPDEP_GPIO4_IRQ2_TESLA (1 << 6) +#define OMAP4430_WKUPDEP_GPIO4_IRQ1_MPU (1 << 0) +#define OMAP4430_WKUPDEP_GPIO5_IRQ2_TESLA (1 << 6) +#define OMAP4430_WKUPDEP_GPIO5_IRQ1_MPU (1 << 0) +#define OMAP4430_WKUPDEP_GPIO6_IRQ2_TESLA (1 << 6) +#define OMAP4430_WKUPDEP_GPIO6_IRQ1_MPU (1 << 0) +#define OMAP4430_WKUPDEP_HECC1_MPU (1 << 0) +#define OMAP4430_LOSTMEM_NONRETAINED_BANK (1 << 8) +#define OMAP4430_WKUPDEP_HECC2_MPU (1 << 0) +#define OMAP4430_WKUPDEP_I2C1_DMA_SDMA (1 << 7) +#define OMAP4430_WKUPDEP_I2C1_IRQ_DUCATI (1 << 1) +#define OMAP4430_WKUPDEP_I2C1_IRQ_MPU (1 << 0) +#define OMAP4430_LOSTMEM_RETAINED_BANK (1 << 8) +#define OMAP4430_WKUPDEP_I2C2_DMA_SDMA (1 << 7) +#define OMAP4430_WKUPDEP_I2C2_IRQ_DUCATI (1 << 1) +#define OMAP4430_WKUPDEP_I2C2_IRQ_MPU (1 << 0) +#define OMAP4430_LOSTMEM_RETAINED_BANK (1 << 8) +#define OMAP4430_WKUPDEP_I2C3_DMA_SDMA (1 << 7) +#define OMAP4430_WKUPDEP_I2C3_IRQ_DUCATI (1 << 1) +#define OMAP4430_WKUPDEP_I2C3_IRQ_MPU (1 << 0) +#define OMAP4430_LOSTMEM_RETAINED_BANK (1 << 8) +#define OMAP4430_WKUPDEP_I2C4_DMA_SDMA (1 << 7) +#define OMAP4430_WKUPDEP_I2C4_IRQ_DUCATI (1 << 1) +#define OMAP4430_WKUPDEP_I2C4_IRQ_MPU (1 << 0) +#define OMAP4430_LOSTMEM_RETAINED_BANK (1 << 8) +#define OMAP4430_WKUPDEP_MCASP2_DMA_SDMA (1 << 7) +#define OMAP4430_WKUPDEP_MCASP2_DMA_TESLA (1 << 6) +#define OMAP4430_WKUPDEP_MCASP2_IRQ_TESLA (1 << 2) +#define OMAP4430_WKUPDEP_MCASP2_IRQ_MPU (1 << 0) +#define OMAP4430_WKUPDEP_MCASP3_DMA_SDMA (1 << 7) +#define OMAP4430_WKUPDEP_MCASP3_DMA_TESLA (1 << 6) +#define OMAP4430_WKUPDEP_MCASP3_IRQ_TESLA (1 << 2) +#define OMAP4430_WKUPDEP_MCASP3_IRQ_MPU (1 << 0) +#define OMAP4430_WKUPDEP_MCBSP4_SDMA (1 << 3) +#define OMAP4430_WKUPDEP_MCBSP4_TESLA (1 << 2) +#define OMAP4430_WKUPDEP_MCBSP4_MPU (1 << 0) +#define OMAP4430_WKUPDEP_MCSPI1_SDMA (1 << 3) +#define OMAP4430_WKUPDEP_MCSPI1_TESLA (1 << 2) +#define OMAP4430_WKUPDEP_MCSPI1_DUCATI (1 << 1) +#define OMAP4430_WKUPDEP_MCSPI1_MPU (1 << 0) +#define OMAP4430_WKUPDEP_MCSPI2_SDMA (1 << 3) +#define OMAP4430_WKUPDEP_MCSPI2_DUCATI (1 << 1) +#define OMAP4430_WKUPDEP_MCSPI2_MPU (1 << 0) +#define OMAP4430_WKUPDEP_MCSPI3_SDMA (1 << 3) +#define OMAP4430_WKUPDEP_MCSPI3_MPU (1 << 0) +#define OMAP4430_WKUPDEP_MCSPI4_SDMA (1 << 3) +#define OMAP4430_WKUPDEP_MCSPI4_MPU (1 << 0) +#define OMAP4430_WKUPDEP_MMCSD3_SDMA (1 << 3) +#define OMAP4430_WKUPDEP_MMCSD3_DUCATI (1 << 1) +#define OMAP4430_WKUPDEP_MMCSD3_MPU (1 << 0) +#define OMAP4430_WKUPDEP_MMCSD4_SDMA (1 << 3) +#define OMAP4430_WKUPDEP_MMCSD4_DUCATI (1 << 1) +#define OMAP4430_WKUPDEP_MMCSD4_MPU (1 << 0) +#define OMAP4430_WKUPDEP_SLIMBUS2_DMA_SDMA (1 << 7) +#define OMAP4430_WKUPDEP_SLIMBUS2_DMA_TESLA (1 << 6) +#define OMAP4430_WKUPDEP_SLIMBUS2_IRQ_TESLA (1 << 2) +#define OMAP4430_WKUPDEP_SLIMBUS2_IRQ_MPU (1 << 0) +#define OMAP4430_WKUPDEP_UART1_SDMA (1 << 3) +#define OMAP4430_WKUPDEP_UART1_MPU (1 << 0) +#define OMAP4430_WKUPDEP_UART2_SDMA (1 << 3) +#define OMAP4430_WKUPDEP_UART2_MPU (1 << 0) +#define OMAP4430_WKUPDEP_UART3_SDMA (1 << 3) +#define OMAP4430_WKUPDEP_UART3_TESLA (1 << 2) +#define OMAP4430_WKUPDEP_UART3_DUCATI (1 << 1) +#define OMAP4430_WKUPDEP_UART3_MPU (1 << 0) +#define OMAP4430_WKUPDEP_UART4_SDMA (1 << 3) +#define OMAP4430_WKUPDEP_UART4_MPU (1 << 0) +#define OMAP4430_WKUPDEP_MMCSD5_SDMA (1 << 3) +#define OMAP4430_WKUPDEP_MMCSD5_DUCATI (1 << 1) +#define OMAP4430_WKUPDEP_MMCSD5_MPU (1 << 0) +#define OMAP4430_LOSTMEM_RETAINED_BANK (1 << 8) +#define OMAP4430_WKUPDEP_WDT2_DUCATI (1 << 1) +#define OMAP4430_WKUPDEP_WDT2_MPU (1 << 0) +#define OMAP4430_WKUPDEP_GPIO1_IRQ2_TESLA (1 << 6) +#define OMAP4430_WKUPDEP_GPIO1_IRQ1_DUCATI (1 << 1) +#define OMAP4430_WKUPDEP_GPIO1_IRQ1_MPU (1 << 0) +#define OMAP4430_WKUPDEP_TIMER1_MPU (1 << 0) +#define OMAP4430_WKUPDEP_TIMER12_MPU (1 << 0) +#define OMAP4430_WKUPDEP_USIM_SDMA (1 << 3) +#define OMAP4430_WKUPDEP_USIM_MPU (1 << 0) +#define OMAP4430_LOSTMEM_WKUP_BANK (1 << 8) +#define OMAP4430_WKUPDEP_KEYBOARD_MPU (1 << 0) +#define OMAP4430_WKUPDEP_RTC_MPU (1 << 0) +#define OMAP4430_MPU_RAM_ONSTATE (1 << 20) +#define OMAP4430_MPU_L2_ONSTATE (1 << 18) +#define OMAP4430_MPU_L1_ONSTATE (1 << 16) +#define OMAP4430_MPU_RAM_RETSTATE (1 << 10) +#define OMAP4430_MPU_L2_RETSTATE (1 << 9) +#define OMAP4430_MPU_L1_RETSTATE (1 << 8) +#define OMAP4430_MPU_RAM_STATEST (1 << 8) +#define OMAP4430_MPU_L2_STATEST (1 << 6) +#define OMAP4430_MPU_L1_STATEST (1 << 4) +#define OMAP4430_ICECRUSHER_MPU_RST (1 << 1) +#define OMAP4430_EMULATION_RST (1 << 0) +#define OMAP4430_LOSTMEM_MPU_RAM (1 << 10) +#define OMAP4430_LOSTMEM_MPU_L2 (1 << 9) +#define OMAP4430_LOSTMEM_MPU_L1 (1 << 8) +#define OMAP4430_TESLA_EDMA_ONSTATE (1 << 20) +#define OMAP4430_TESLA_L2_ONSTATE (1 << 18) +#define OMAP4430_TESLA_L1_ONSTATE (1 << 16) +#define OMAP4430_TESLA_EDMA_RETSTATE (1 << 10) +#define OMAP4430_TESLA_L2_RETSTATE (1 << 9) +#define OMAP4430_TESLA_L1_RETSTATE (1 << 8) +#define OMAP4430_TESLA_EDMA_STATEST (1 << 8) +#define OMAP4430_TESLA_L2_STATEST (1 << 6) +#define OMAP4430_TESLA_L1_STATEST (1 << 4) +#define OMAP4430_RST2 (1 << 1) +#define OMAP4430_RST1 (1 << 0) +#define OMAP4430_TESLA_DSP_EMU_REQ_RSTST (1 << 3) +#define OMAP4430_TESLASS_EMU_RSTST (1 << 2) +#define OMAP4430_RST2ST (1 << 1) +#define OMAP4430_RST1ST (1 << 0) +#define OMAP4430_LOSTMEM_TESLA_EDMA (1 << 10) +#define OMAP4430_LOSTMEM_TESLA_L2 (1 << 9) +#define OMAP4430_LOSTMEM_TESLA_L1 (1 << 8) +#define OMAP4430_TCM2_MEM_ONSTATE (1 << 22) +#define OMAP4430_TCM1_MEM_ONSTATE (1 << 20) +#define OMAP4430_SL2_MEM_ONSTATE (1 << 18) +#define OMAP4430_HWA_MEM_ONSTATE (1 << 16) +#define OMAP4430_TCM2_MEM_RETSTATE (1 << 11) +#define OMAP4430_TCM1_MEM_RETSTATE (1 << 10) +#define OMAP4430_SL2_MEM_RETSTATE (1 << 9) +#define OMAP4430_HWA_MEM_RETSTATE (1 << 8) +#define OMAP4430_TCM2_MEM_STATEST (1 << 10) +#define OMAP4430_TCM1_MEM_STATEST (1 << 8) +#define OMAP4430_SL2_MEM_STATEST (1 << 6) +#define OMAP4430_HWA_MEM_STATEST (1 << 4) +#define OMAP4430_RST3 (1 << 2) +#define OMAP4430_ICECRUSHER_SEQ2_RST2ST (1 << 6) +#define OMAP4430_ICECRUSHER_SEQ1_RST1ST (1 << 5) +#define OMAP4430_EMULATION_SEQ2_RST2ST (1 << 4) +#define OMAP4430_EMULATION_SEQ1_RST1ST (1 << 3) +#define OMAP4430_RST3ST (1 << 2) +#define OMAP4430_LOSTMEM_HWA_MEM (1 << 10) +#define OMAP4430_LOSTMEM_TCM2_MEM (1 << 9) +#define OMAP4430_LOSTMEM_TCM1_MEM (1 << 8) +#define OMAP4430_LOSTMEM_SL2_MEM (1 << 8) +#define OMAP4430_OCP_NRET_BANK_ONSTATE (1 << 24) +#define OMAP4430_DUCATI_UNICACHE_ONSTATE (1 << 22) +#define OMAP4430_DUCATI_L2RAM_ONSTATE (1 << 20) +#define OMAP4430_CORE_OCMRAM_ONSTATE (1 << 18) +#define OMAP4430_CORE_OTHER_BANK_ONSTATE (1 << 16) +#define OMAP4430_OCP_NRET_BANK_RETSTATE (1 << 12) +#define OMAP4430_DUCATI_UNICACHE_RETSTATE (1 << 11) +#define OMAP4430_DUCATI_L2RAM_RETSTATE (1 << 10) +#define OMAP4430_CORE_OCMRAM_RETSTATE (1 << 9) +#define OMAP4430_CORE_OTHER_BANK_RETSTATE (1 << 8) +#define OMAP4430_MEMORYCHANGE (1 << 3) +#define OMAP4430_OCP_NRET_BANK_STATEST (1 << 12) +#define OMAP4430_DUCATI_UNICACHE_STATEST (1 << 10) +#define OMAP4430_DUCATI_L2RAM_STATEST (1 << 8) +#define OMAP4430_CORE_OCMRAM_STATEST (1 << 6) +#define OMAP4430_CORE_OTHER_BANK_STATEST (1 << 4) +#define OMAP4430_LOSTMEM_CORE_OCMRAM (1 << 8) +#define OMAP4430_ICECRUSHER_RST2ST (1 << 6) +#define OMAP4430_ICECRUSHER_RST1ST (1 << 5) +#define OMAP4430_EMULATION_RST2ST (1 << 4) +#define OMAP4430_EMULATION_RST1ST (1 << 3) +#define OMAP4430_LOSTMEM_DUCATI_L2RAM (1 << 9) +#define OMAP4430_LOSTMEM_DUCATI_UNICACHE (1 << 8) +#define OMAP4430_LOSTMEM_CORE_OTHER_BANK (1 << 8) +#define OMAP4430_LOSTMEM_CORE_NRET_BANK (1 << 9) +#define OMAP4430_LOSTMEM_CORE_OTHER_BANK (1 << 8) +#define OMAP4430_OCP_SOCKET_REVISION_REV (1 << 0) +#define OMAP4430_VC_TOERR_ST (1 << 31) +#define OMAP4430_VC_RAERR_ST (1 << 30) +#define OMAP4430_VC_SAERR_ST (1 << 29) +#define OMAP4430_VP_CORE_TRANXDONE_ST (1 << 28) +#define OMAP4430_VP_CORE_EQVALUE_ST (1 << 27) +#define OMAP4430_VP_CORE_NOSMPSACK_ST (1 << 26) +#define OMAP4430_VP_CORE_MAXVDD_ST (1 << 25) +#define OMAP4430_VP_CORE_MINVDD_ST (1 << 24) +#define OMAP4430_VP_CORE_OPPCHANGEDONE_ST (1 << 23) +#define OMAP4430_VP_IVA_TRANXDONE_ST (1 << 22) +#define OMAP4430_VP_IVA_EQVALUE_ST (1 << 21) +#define OMAP4430_VP_IVA_NOSMPSACK_ST (1 << 20) +#define OMAP4430_VP_IVA_MAXVDD_ST (1 << 19) +#define OMAP4430_VP_IVA_MINVDD_ST (1 << 18) +#define OMAP4430_VP_IVA_OPPCHANGEDONE_ST (1 << 17) +#define OMAP4430_VP_MPU_TRANXDONE_ST (1 << 16) +#define OMAP4430_VP_MPU_EQVALUE_ST (1 << 15) +#define OMAP4430_VP_MPU_NOSMPSACK_ST (1 << 14) +#define OMAP4430_VP_MPU_MAXVDD_ST (1 << 13) +#define OMAP4430_VP_MPU_MINVDD_ST (1 << 12) +#define OMAP4430_VP_MPU_OPPCHANGEDONE_ST (1 << 11) +#define OMAP4430_IO_ST (1 << 9) +#define OMAP4430_TRANSITION_ST (1 << 8) +#define OMAP4430_DPLL_UNIPRO_RECAL_ST (1 << 7) +#define OMAP4430_DPLL_DDRPHY_RECAL_ST (1 << 6) +#define OMAP4430_DPLL_USB_RECAL_ST (1 << 5) +#define OMAP4430_DPLL_ABE_RECAL_ST (1 << 4) +#define OMAP4430_DPLL_PER_RECAL_ST (1 << 3) +#define OMAP4430_DPLL_IVA_RECAL_ST (1 << 2) +#define OMAP4430_DPLL_MPU_RECAL_ST (1 << 1) +#define OMAP4430_DPLL_CORE_RECAL_ST (1 << 0) +#define OMAP4430_VC_TOERR_EN (1 << 31) +#define OMAP4430_VC_RAERR_EN (1 << 30) +#define OMAP4430_VC_SAERR_EN (1 << 29) +#define OMAP4430_VP_CORE_TRANXDONE_EN (1 << 28) +#define OMAP4430_VP_CORE_EQVALUE_EN (1 << 27) +#define OMAP4430_VP_CORE_NOSMPSACK_EN (1 << 26) +#define OMAP4430_VP_CORE_MAXVDD_EN (1 << 25) +#define OMAP4430_VP_CORE_MINVDD_EN (1 << 24) +#define OMAP4430_VP_CORE_OPPCHANGEDONE_EN (1 << 23) +#define OMAP4430_VP_IVA_TRANXDONE_EN (1 << 22) +#define OMAP4430_VP_IVA_EQVALUE_EN (1 << 21) +#define OMAP4430_VP_IVA_NOSMPSACK_EN (1 << 20) +#define OMAP4430_VP_IVA_MAXVDD_EN (1 << 19) +#define OMAP4430_VP_IVA_MINVDD_EN (1 << 18) +#define OMAP4430_VP_IVA_OPPCHANGEDONE_EN (1 << 17) +#define OMAP4430_VP_MPU_TRANXDONE_EN (1 << 16) +#define OMAP4430_VP_MPU_EQVALUE_EN (1 << 15) +#define OMAP4430_VP_MPU_NOSMPSACK_EN (1 << 14) +#define OMAP4430_VP_MPU_MAXVDD_EN (1 << 13) +#define OMAP4430_VP_MPU_MINVDD_EN (1 << 12) +#define OMAP4430_VP_MPU_OPPCHANGEDONE_EN (1 << 11) +#define OMAP4430_IO_EN (1 << 9) +#define OMAP4430_TRANSITION_EN (1 << 8) +#define OMAP4430_DPLL_UNIPRO_RECAL_EN (1 << 7) +#define OMAP4430_DPLL_DDRPHY_RECAL_EN (1 << 6) +#define OMAP4430_DPLL_USB_RECAL_EN (1 << 5) +#define OMAP4430_DPLL_ABE_RECAL_EN (1 << 4) +#define OMAP4430_DPLL_PER_RECAL_EN (1 << 3) +#define OMAP4430_DPLL_IVA_RECAL_EN (1 << 2) +#define OMAP4430_DPLL_MPU_RECAL_EN (1 << 1) +#define OMAP4430_DPLL_CORE_RECAL_EN (1 << 0) +#define OMAP4430_VC_TOERR_ST (1 << 31) +#define OMAP4430_VC_RAERR_ST (1 << 30) +#define OMAP4430_VC_SAERR_ST (1 << 29) +#define OMAP4430_VP_CORE_TRANXDONE_ST (1 << 28) +#define OMAP4430_VP_CORE_EQVALUE_ST (1 << 27) +#define OMAP4430_VP_CORE_NOSMPSACK_ST (1 << 26) +#define OMAP4430_VP_CORE_MAXVDD_ST (1 << 25) +#define OMAP4430_VP_CORE_MINVDD_ST (1 << 24) +#define OMAP4430_VP_CORE_OPPCHANGEDONE_ST (1 << 23) +#define OMAP4430_VP_IVA_TRANXDONE_ST (1 << 22) +#define OMAP4430_VP_IVA_EQVALUE_ST (1 << 21) +#define OMAP4430_VP_IVA_NOSMPSACK_ST (1 << 20) +#define OMAP4430_VP_IVA_MAXVDD_ST (1 << 19) +#define OMAP4430_VP_IVA_MINVDD_ST (1 << 18) +#define OMAP4430_VP_IVA_OPPCHANGEDONE_ST (1 << 17) +#define OMAP4430_FORCEWKUP_ST (1 << 10) +#define OMAP4430_DPLL_UNIPRO_RECAL_ST (1 << 7) +#define OMAP4430_DPLL_PER_RECAL_ST (1 << 3) +#define OMAP4430_DPLL_IVA_RECAL_ST (1 << 2) +#define OMAP4430_DPLL_CORE_RECAL_ST (1 << 0) +#define OMAP4430_VC_TOERR_EN (1 << 31) +#define OMAP4430_VC_RAERR_EN (1 << 30) +#define OMAP4430_VC_SAERR_EN (1 << 29) +#define OMAP4430_VP_CORE_TRANXDONE_EN (1 << 28) +#define OMAP4430_VP_CORE_EQVALUE_EN (1 << 27) +#define OMAP4430_VP_CORE_NOSMPSACK_EN (1 << 26) +#define OMAP4430_VP_CORE_MAXVDD_EN (1 << 25) +#define OMAP4430_VP_CORE_MINVDD_EN (1 << 24) +#define OMAP4430_VP_CORE_OPPCHANGEDONE_EN (1 << 23) +#define OMAP4430_VP_IVA_TRANXDONE_EN (1 << 22) +#define OMAP4430_VP_IVA_EQVALUE_EN (1 << 21) +#define OMAP4430_VP_IVA_NOSMPSACK_EN (1 << 20) +#define OMAP4430_VP_IVA_MAXVDD_EN (1 << 19) +#define OMAP4430_VP_IVA_MINVDD_EN (1 << 18) +#define OMAP4430_VP_IVA_OPPCHANGEDONE_EN (1 << 17) +#define OMAP4430_FORCEWKUP_EN (1 << 10) +#define OMAP4430_DPLL_UNIPRO_RECAL_EN (1 << 7) +#define OMAP4430_DPLL_PER_RECAL_EN (1 << 3) +#define OMAP4430_DPLL_IVA_RECAL_EN (1 << 2) +#define OMAP4430_DPLL_CORE_RECAL_EN (1 << 0) +#define OMAP4430_DPLL_ABE_RECAL_ST (1 << 4) +#define OMAP4430_DPLL_IVA_RECAL_ST (1 << 2) +#define OMAP4430_DPLL_ABE_RECAL_EN (1 << 4) +#define OMAP4430_DPLL_IVA_RECAL_EN (1 << 2) +#define OMAP4430_MODULEMODE (1 << 0) +#define OMAP4430_WKUPDEP_SR_MPU_MPU (1 << 0) +#define OMAP4430_WKUPDEP_SR_IVA_DUCATI (1 << 1) +#define OMAP4430_WKUPDEP_SR_IVA_MPU (1 << 0) +#define OMAP4430_WKUPDEP_SR_CORE_DUCATI (1 << 1) +#define OMAP4430_WKUPDEP_SR_CORE_MPU (1 << 0) +#define OMAP4430_CAM_MEM_ONSTATE (1 << 16) +#define OMAP4430_CAM_MEM_STATEST (1 << 4) +#define OMAP4430_LOSTMEM_CAM_MEM (1 << 8) +#define OMAP4430_LOSTMEM_CAM_MEM (1 << 8) +#define OMAP4430_GFX_MEM_ONSTATE (1 << 16) +#define OMAP4430_GFX_MEM_STATEST (1 << 4) +#define OMAP4430_LOSTMEM_GFX_MEM (1 << 8) +#define OMAP4430_EMU_BANK_ONSTATE (1 << 16) +#define OMAP4430_EMU_BANK_STATEST (1 << 4) +#define OMAP4430_LOSTMEM_EMU_BANK (1 << 8) +#define OMAP4430_RST_GLOBAL_COLD_SW (1 << 1) +#define OMAP4430_RST_GLOBAL_WARM_SW (1 << 0) +#define OMAP4430_ICEPICK_RST (1 << 9) +#define OMAP4430_VDD_CORE_VOLT_MGR_RST (1 << 8) +#define OMAP4430_VDD_IVA_VOLT_MGR_RST (1 << 7) +#define OMAP4430_VDD_MPU_VOLT_MGR_RST (1 << 6) +#define OMAP4430_EXTERNAL_WARM_RST (1 << 5) +#define OMAP4430_SECURE_WDT_RST (1 << 4) +#define OMAP4430_MPU_WDT_RST (1 << 3) +#define OMAP4430_MPU_SECURITY_VIOL_RST (1 << 2) +#define OMAP4430_GLOBAL_WARM_SW_RST (1 << 1) +#define OMAP4430_GLOBAL_COLD_RST (1 << 0) +#define OMAP4430_RSTTIME2 (1 << 8) +#define OMAP4430_RSTTIME1 (1 << 0) +#define OMAP4430_CLKREQ_COND (1 << 0) +#define OMAP4430_VDD_IVA_PRESENCE (1 << 9) +#define OMAP4430_VDD_MPU_PRESENCE (1 << 8) +#define OMAP4430_AUTO_CTRL_VDD_IVA_L (1 << 4) +#define OMAP4430_AUTO_CTRL_VDD_MPU_L (1 << 2) +#define OMAP4430_AUTO_CTRL_VDD_CORE_L (1 << 0) +#define OMAP4430_PWRREQ_COND (1 << 0) +#define OMAP4430_PONOUT_2_PGOODIN_TIME (1 << 8) +#define OMAP4430_PCHARGE_TIME (1 << 0) +#define OMAP4430_ISO_2_ON_TIME (1 << 0) +#define OMAP4430_GLOBAL_WUEN (1 << 16) +#define OMAP4430_WUCLK_STATUS (1 << 9) +#define OMAP4430_WUCLK_CTRL (1 << 8) +#define OMAP4430_ISOCLK_STATUS (1 << 1) +#define OMAP4430_ISOCLK_OVERRIDE (1 << 0) +#define OMAP4430_RAMP_DOWN_PRESCAL (1 << 24) +#define OMAP4430_RAMP_DOWN_COUNT (1 << 16) +#define OMAP4430_RAMP_UP_PRESCAL (1 << 8) +#define OMAP4430_RAMP_UP_COUNT (1 << 0) +#define OMAP4430_ERROROFFSET (1 << 24) +#define OMAP4430_ERRORGAIN (1 << 16) +#define OMAP4430_INITVOLTAGE (1 << 8) +#define OMAP4430_TIMEOUTEN (1 << 3) +#define OMAP4430_INITVDD (1 << 2) +#define OMAP4430_FORCEUPDATE (1 << 1) +#define OMAP4430_VPENABLE (1 << 0) +#define OMAP4430_VPINIDLE (1 << 0) +#define OMAP4430_VDDMAX (1 << 24) +#define OMAP4430_VDDMIN (1 << 16) +#define OMAP4430_TIMEOUT (1 << 0) +#define OMAP4430_VPVOLTAGE (1 << 0) +#define OMAP4430_SMPSWAITTIMEMAX (1 << 8) +#define OMAP4430_VSTEPMAX (1 << 0) +#define OMAP4430_SMPSWAITTIMEMIN (1 << 8) +#define OMAP4430_VSTEPMIN (1 << 0) +#define OMAP4430_SA_VDD_MPU_L (1 << 16) +#define OMAP4430_SA_VDD_IVA_L (1 << 8) +#define OMAP4430_SA_VDD_CORE_L (1 << 0) +#define OMAP4430_VOLRA_VDD_MPU_L (1 << 16) +#define OMAP4430_VOLRA_VDD_IVA_L (1 << 8) +#define OMAP4430_VOLRA_VDD_CORE_L (1 << 0) +#define OMAP4430_CMDRA_VDD_MPU_L (1 << 16) +#define OMAP4430_CMDRA_VDD_IVA_L (1 << 8) +#define OMAP4430_CMDRA_VDD_CORE_L (1 << 0) +#define OMAP4430_ON (1 << 24) +#define OMAP4430_ONLP (1 << 16) +#define OMAP4430_RET (1 << 8) +#define OMAP4430_OFF (1 << 0) +#define OMAP4430_VALID (1 << 24) +#define OMAP4430_DATA (1 << 16) +#define OMAP4430_REGADDR (1 << 8) +#define OMAP4430_SLAVEADDR (1 << 0) +#define OMAP4430_RACEN_VDD_MPU_L (1 << 20) +#define OMAP4430_RAC_VDD_MPU_L (1 << 19) +#define OMAP4430_RAV_VDD_MPU_L (1 << 18) +#define OMAP4430_CMD_VDD_MPU_L (1 << 17) +#define OMAP4430_CMD_VDD_IVA_L (1 << 12) +#define OMAP4430_RACEN_VDD_IVA_L (1 << 11) +#define OMAP4430_RAC_VDD_IVA_L (1 << 10) +#define OMAP4430_RAV_VDD_IVA_L (1 << 9) +#define OMAP4430_CMD_VDD_CORE_L (1 << 4) +#define OMAP4430_RACEN_VDD_CORE_L (1 << 3) +#define OMAP4430_RAC_VDD_CORE_L (1 << 2) +#define OMAP4430_RAV_VDD_CORE_L (1 << 1) +#define OMAP4430_DFILTEREN (1 << 6) +#define OMAP4430_HSMASTER (1 << 5) +#define OMAP4430_SRMODEEN (1 << 4) +#define OMAP4430_HSMODEEN (1 << 3) +#define OMAP4430_HSMCODE (1 << 0) +#define OMAP4430_HSSCLL (1 << 24) +#define OMAP4430_HSSCLH (1 << 16) +#define OMAP4430_SCLL (1 << 8) +#define OMAP4430_SCLH (1 << 0) +#define OMAP4430_SLPCNT_VALUE (1 << 16) +#define OMAP4430_VSETUPCNT_VALUE (1 << 8) +#define OMAP4430_PCHARGECNT_VALUE (1 << 0) +#define OMAP4430_ENABLE_RTA_EXPORT (1 << 0) +#define OMAP4430_AIPOFF (1 << 8) +#define OMAP4430_ENFUNC5 (1 << 7) +#define OMAP4430_ENFUNC4 (1 << 6) +#define OMAP4430_ENFUNC3 (1 << 5) +#define OMAP4430_ENFUNC2_EXPORT (1 << 4) +#define OMAP4430_ENFUNC1 (1 << 3) +#define OMAP4430_ABBOFF_SLEEP_EXPORT (1 << 2) +#define OMAP4430_ABBOFF_ACT_EXPORT (1 << 1) +#define OMAP4430_SRAM_IN_TRANSITION (1 << 9) +#define OMAP4430_SRAMLDO_STATUS (1 << 8) +#define OMAP4430_RETMODE_ENABLE (1 << 0) +#define OMAP4430_SRAM_IN_TRANSITION (1 << 9) +#define OMAP4430_SRAMLDO_STATUS (1 << 8) +#define OMAP4430_SRAM_IN_TRANSITION (1 << 9) +#define OMAP4430_SRAMLDO_STATUS (1 << 8) +#define OMAP4430_SR2_WTCNT_VALUE (1 << 8) +#define OMAP4430_NOCAP_EXPORT (1 << 4) +#define OMAP4430_SLEEP_RBB_SEL (1 << 3) +#define OMAP4430_ACTIVE_FBB_SEL (1 << 2) +#define OMAP4430_ACTIVE_RBB_SEL (1 << 1) +#define OMAP4430_SR2EN (1 << 0) +#define OMAP4430_SR2_IN_TRANSITION (1 << 6) +#define OMAP4430_SR2_STATUS (1 << 3) +#define OMAP4430_OPP_CHANGE (1 << 2) +#define OMAP4430_OPP_SEL (1 << 0) +#define OMAP4430_NOCAP_EXPORT (1 << 4) +#define OMAP4430_SLEEP_RBB_SEL (1 << 3) +#define OMAP4430_ACTIVE_FBB_SEL (1 << 2) +#define OMAP4430_ACTIVE_RBB_SEL (1 << 1) +#define OMAP4430_CBIASSEL (1 << 0) +#define OMAP4430_DEVICE_OFF_ENABLE (1 << 0) +#define OMAP4430_PHASE2B_COMPLETED (1 << 2) +#define OMAP4430_PHASE2A_COMPLETED (1 << 1) +#define OMAP4430_PHASE1_COMPLETED (1 << 0) +#define OMAP4430_PHASE1_CNDP (1 << 0) +#define OMAP4430_PHASE2A_CNDP (1 << 0) +#define OMAP4430_PHASE2B_CNDP (1 << 0) +#define OMAP4430_MODEM_SLEEP_ST (1 << 16) +#define OMAP4430_MODEM_SHUTDOWN_IRQ (1 << 9) +#define OMAP4430_MODEM_WAKE_IRQ (1 << 8) +#define OMAP4430_MODEM_READY (1 << 1) +#define OMAP4430_WAKE_MODEM (1 << 0) +#define OMAP4430_INITVDD_EDGE (1 << 1) +#define OMAP4430_FORCEUPDATE_EDGE (1 << 1) + + +#define OMAP4430_PRM_CLKSEL_MASK BITFIELD(0, 0) +#define OMAP4430_SYS_CLKSEL_MASK BITFIELD(2, 0) +#define OMAP4430_PERIPHMEM_ONSTATE_MASK BITFIELD(21, 20) +#define OMAP4430_AESSMEM_ONSTATE_MASK BITFIELD(17, 16) +#define OMAP4430_PERIPHMEM_RETSTATE_MASK BITFIELD(10, 10) +#define OMAP4430_AESSMEM_RETSTATE_MASK BITFIELD(8, 8) +#define OMAP4430_LOWPOWERSTATECHANGE_MASK BITFIELD(4, 4) +#define OMAP4430_LOGICRETSTATE_MASK BITFIELD(2, 2) +#define OMAP4430_POWERSTATE_MASK BITFIELD(1, 0) +#define OMAP4430_INTRANSITION_MASK BITFIELD(20, 20) +#define OMAP4430_PERIPHMEM_STATEST_MASK BITFIELD(9, 8) +#define OMAP4430_AESSMEM_STATEST_MASK BITFIELD(5, 4) +#define OMAP4430_LOGICSTATEST_MASK BITFIELD(2, 2) +#define OMAP4430_POWERSTATEST_MASK BITFIELD(1, 0) +#define OMAP4430_LOSTMEM_AESSMEM_MASK BITFIELD(8, 8) +#define OMAP4430_LOSTCONTEXT_DFF_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_PDM_DMA_SDMA_MASK BITFIELD(7, 7) +#define OMAP4430_WKUPDEP_PDM_DMA_TESLA_MASK BITFIELD(6, 6) +#define OMAP4430_WKUPDEP_PDM_IRQ_TESLA_MASK BITFIELD(2, 2) +#define OMAP4430_WKUPDEP_PDM_IRQ_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_LOSTMEM_PERIHPMEM_MASK BITFIELD(8, 8) +#define OMAP4430_WKUPDEP_DMIC_DMA_SDMA_MASK BITFIELD(7, 7) +#define OMAP4430_WKUPDEP_DMIC_DMA_TESLA_MASK BITFIELD(6, 6) +#define OMAP4430_WKUPDEP_DMIC_IRQ_TESLA_MASK BITFIELD(2, 2) +#define OMAP4430_WKUPDEP_DMIC_IRQ_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_MCASP1_DMA_SDMA_MASK BITFIELD(7, 7) +#define OMAP4430_WKUPDEP_MCASP1_DMA_TESLA_MASK BITFIELD(6, 6) +#define OMAP4430_WKUPDEP_MCASP1_IRQ_TESLA_MASK BITFIELD(2, 2) +#define OMAP4430_WKUPDEP_MCASP1_IRQ_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_MCBSP1_SDMA_MASK BITFIELD(3, 3) +#define OMAP4430_WKUPDEP_MCBSP1_TESLA_MASK BITFIELD(2, 2) +#define OMAP4430_WKUPDEP_MCBSP1_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_MCBSP2_SDMA_MASK BITFIELD(3, 3) +#define OMAP4430_WKUPDEP_MCBSP2_TESLA_MASK BITFIELD(2, 2) +#define OMAP4430_WKUPDEP_MCBSP2_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_MCBSP3_SDMA_MASK BITFIELD(3, 3) +#define OMAP4430_WKUPDEP_MCBSP3_TESLA_MASK BITFIELD(2, 2) +#define OMAP4430_WKUPDEP_MCBSP3_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_SLIMBUS1_DMA_SDMA_MASK BITFIELD(7, 7) +#define OMAP4430_WKUPDEP_SLIMBUS1_DMA_TESLA_MASK BITFIELD(6, 6) +#define OMAP4430_WKUPDEP_SLIMBUS1_IRQ_TESLA_MASK BITFIELD(2, 2) +#define OMAP4430_WKUPDEP_SLIMBUS1_IRQ_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_TIMER5_TESLA_MASK BITFIELD(2, 2) +#define OMAP4430_WKUPDEP_TIMER5_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_TIMER6_TESLA_MASK BITFIELD(2, 2) +#define OMAP4430_WKUPDEP_TIMER6_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_TIMER7_TESLA_MASK BITFIELD(2, 2) +#define OMAP4430_WKUPDEP_TIMER7_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_TIMER8_TESLA_MASK BITFIELD(2, 2) +#define OMAP4430_WKUPDEP_TIMER8_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_WDT3_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_DSS_MEM_ONSTATE_MASK BITFIELD(17, 16) +#define OMAP4430_DSS_MEM_RETSTATE_MASK BITFIELD(8, 8) +#define OMAP4430_DSS_MEM_STATEST_MASK BITFIELD(5, 4) +#define OMAP4430_WKUPDEP_HDMIDMA_SDMA_MASK BITFIELD(19, 19) +#define OMAP4430_WKUPDEP_HDMIIRQ_TESLA_MASK BITFIELD(14, 14) +#define OMAP4430_WKUPDEP_HDMIIRQ_DUCATI_MASK BITFIELD(13, 13) +#define OMAP4430_WKUPDEP_HDMIIRQ_MPU_MASK BITFIELD(12, 12) +#define OMAP4430_WKUPDEP_DSI2_SDMA_MASK BITFIELD(11, 11) +#define OMAP4430_WKUPDEP_DSI2_TESLA_MASK BITFIELD(10, 10) +#define OMAP4430_WKUPDEP_DSI2_DUCATI_MASK BITFIELD(9, 9) +#define OMAP4430_WKUPDEP_DSI2_MPU_MASK BITFIELD(8, 8) +#define OMAP4430_WKUPDEP_DSI1_SDMA_MASK BITFIELD(7, 7) +#define OMAP4430_WKUPDEP_DSI1_TESLA_MASK BITFIELD(6, 6) +#define OMAP4430_WKUPDEP_DSI1_DUCATI_MASK BITFIELD(5, 5) +#define OMAP4430_WKUPDEP_DSI1_MPU_MASK BITFIELD(4, 4) +#define OMAP4430_WKUPDEP_DISPC_SDMA_MASK BITFIELD(3, 3) +#define OMAP4430_WKUPDEP_DISPC_TESLA_MASK BITFIELD(2, 2) +#define OMAP4430_WKUPDEP_DISPC_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_WKUPDEP_DISPC_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_LOSTMEM_DSS_MEM_MASK BITFIELD(8, 8) +#define OMAP4430_LOSTCONTEXT_RFF_MASK BITFIELD(1, 1) +#define OMAP4430_L3INIT_BANK1_ONSTATE_MASK BITFIELD(17, 16) +#define OMAP4430_L3INIT_BANK1_RETSTATE_MASK BITFIELD(8, 8) +#define OMAP4430_L3INIT_BANK1_STATEST_MASK BITFIELD(5, 4) +#define OMAP4430_WKUPDEP_MMC1_SDMA_MASK BITFIELD(3, 3) +#define OMAP4430_WKUPDEP_MMC1_TESLA_MASK BITFIELD(2, 2) +#define OMAP4430_WKUPDEP_MMC1_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_WKUPDEP_MMC1_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_LOSTMEM_L3INIT_BANK1_MASK BITFIELD(8, 8) +#define OMAP4430_WKUPDEP_MMC2_SDMA_MASK BITFIELD(3, 3) +#define OMAP4430_WKUPDEP_MMC2_TESLA_MASK BITFIELD(2, 2) +#define OMAP4430_WKUPDEP_MMC2_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_WKUPDEP_MMC2_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_LOSTMEM_L3INIT_BANK1_MASK BITFIELD(8, 8) +#define OMAP4430_WKUPDEP_WGM_HSI_WAKE_MPU_MASK BITFIELD(8, 8) +#define OMAP4430_WKUPDEP_HSI_DSP_TESLA_MASK BITFIELD(6, 6) +#define OMAP4430_WKUPDEP_HSI_MCU_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_WKUPDEP_HSI_MCU_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_LOSTMEM_L3INIT_BANK1_MASK BITFIELD(8, 8) +#define OMAP4430_WKUPDEP_UNIPRO1_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_WKUPDEP_UNIPRO1_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_LOSTMEM_L3INIT_BANK1_MASK BITFIELD(8, 8) +#define OMAP4430_WKUPDEP_USB_HOST_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_WKUPDEP_USB_HOST_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_USB_OTG_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_WKUPDEP_USB_OTG_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_LOSTMEM_L3INIT_BANK1_MASK BITFIELD(8, 8) +#define OMAP4430_WKUPDEP_USB_TLL_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_WKUPDEP_USB_TLL_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_LOSTMEM_L3INIT_BANK1_MASK BITFIELD(8, 8) +#define OMAP4430_WKUPDEP_SATA_TESLA_MASK BITFIELD(2, 2) +#define OMAP4430_WKUPDEP_SATA_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_LOSTMEM_L3INIT_BANK1_MASK BITFIELD(8, 8) +#define OMAP4430_LOSTMEM_L3INIT_BANK1_MASK BITFIELD(8, 8) +#define OMAP4430_WKUPDEP_PCIESS_TESLA_MASK BITFIELD(2, 2) +#define OMAP4430_WKUPDEP_PCIESS_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_LOSTMEM_L3INIT_BANK1_MASK BITFIELD(8, 8) +#define OMAP4430_LOSTMEM_L3INIT_BANK1_MASK BITFIELD(8, 8) +#define OMAP4430_WKUPDEP_XHPI_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_LOSTMEM_L3INIT_BANK1_MASK BITFIELD(8, 8) +#define OMAP4430_WKUPDEP_MMC6_TESLA_MASK BITFIELD(2, 2) +#define OMAP4430_WKUPDEP_MMC6_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_WKUPDEP_MMC6_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_LOSTMEM_L3INIT_BANK1_MASK BITFIELD(8, 8) +#define OMAP4430_WKUPDEP_USB_HOST_FS_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_WKUPDEP_USB_HOST_FS_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_NONRETAINED_BANK_ONSTATE_MASK BITFIELD(19, 18) +#define OMAP4430_RETAINED_BANK_ONSTATE_MASK BITFIELD(17, 16) +#define OMAP4430_NONRETAINED_BANK_RETSTATE_MASK BITFIELD(9, 9) +#define OMAP4430_RETAINED_BANK_RETSTATE_MASK BITFIELD(8, 8) +#define OMAP4430_NONRETAINED_BANK_STATEST_MASK BITFIELD(7, 6) +#define OMAP4430_RETAINED_BANK_STATEST_MASK BITFIELD(5, 4) +#define OMAP4430_WKUPDEP_DMTIMER10_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_DMTIMER11_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_WKUPDEP_DMTIMER11_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_DMTIMER2_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_DMTIMER3_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_WKUPDEP_DMTIMER3_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_DMTIMER4_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_WKUPDEP_DMTIMER4_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_DMTIMER9_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_WKUPDEP_DMTIMER9_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_GPIO2_IRQ2_TESLA_MASK BITFIELD(6, 6) +#define OMAP4430_WKUPDEP_GPIO2_IRQ1_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_WKUPDEP_GPIO2_IRQ1_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_GPIO3_IRQ2_TESLA_MASK BITFIELD(6, 6) +#define OMAP4430_WKUPDEP_GPIO3_IRQ1_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_GPIO4_IRQ2_TESLA_MASK BITFIELD(6, 6) +#define OMAP4430_WKUPDEP_GPIO4_IRQ1_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_GPIO5_IRQ2_TESLA_MASK BITFIELD(6, 6) +#define OMAP4430_WKUPDEP_GPIO5_IRQ1_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_GPIO6_IRQ2_TESLA_MASK BITFIELD(6, 6) +#define OMAP4430_WKUPDEP_GPIO6_IRQ1_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_HECC1_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_LOSTMEM_NONRETAINED_BANK_MASK BITFIELD(8, 8) +#define OMAP4430_WKUPDEP_HECC2_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_I2C1_DMA_SDMA_MASK BITFIELD(7, 7) +#define OMAP4430_WKUPDEP_I2C1_IRQ_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_WKUPDEP_I2C1_IRQ_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_LOSTMEM_RETAINED_BANK_MASK BITFIELD(8, 8) +#define OMAP4430_WKUPDEP_I2C2_DMA_SDMA_MASK BITFIELD(7, 7) +#define OMAP4430_WKUPDEP_I2C2_IRQ_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_WKUPDEP_I2C2_IRQ_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_LOSTMEM_RETAINED_BANK_MASK BITFIELD(8, 8) +#define OMAP4430_WKUPDEP_I2C3_DMA_SDMA_MASK BITFIELD(7, 7) +#define OMAP4430_WKUPDEP_I2C3_IRQ_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_WKUPDEP_I2C3_IRQ_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_LOSTMEM_RETAINED_BANK_MASK BITFIELD(8, 8) +#define OMAP4430_WKUPDEP_I2C4_DMA_SDMA_MASK BITFIELD(7, 7) +#define OMAP4430_WKUPDEP_I2C4_IRQ_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_WKUPDEP_I2C4_IRQ_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_LOSTMEM_RETAINED_BANK_MASK BITFIELD(8, 8) +#define OMAP4430_WKUPDEP_MCASP2_DMA_SDMA_MASK BITFIELD(7, 7) +#define OMAP4430_WKUPDEP_MCASP2_DMA_TESLA_MASK BITFIELD(6, 6) +#define OMAP4430_WKUPDEP_MCASP2_IRQ_TESLA_MASK BITFIELD(2, 2) +#define OMAP4430_WKUPDEP_MCASP2_IRQ_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_MCASP3_DMA_SDMA_MASK BITFIELD(7, 7) +#define OMAP4430_WKUPDEP_MCASP3_DMA_TESLA_MASK BITFIELD(6, 6) +#define OMAP4430_WKUPDEP_MCASP3_IRQ_TESLA_MASK BITFIELD(2, 2) +#define OMAP4430_WKUPDEP_MCASP3_IRQ_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_MCBSP4_SDMA_MASK BITFIELD(3, 3) +#define OMAP4430_WKUPDEP_MCBSP4_TESLA_MASK BITFIELD(2, 2) +#define OMAP4430_WKUPDEP_MCBSP4_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_MCSPI1_SDMA_MASK BITFIELD(3, 3) +#define OMAP4430_WKUPDEP_MCSPI1_TESLA_MASK BITFIELD(2, 2) +#define OMAP4430_WKUPDEP_MCSPI1_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_WKUPDEP_MCSPI1_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_MCSPI2_SDMA_MASK BITFIELD(3, 3) +#define OMAP4430_WKUPDEP_MCSPI2_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_WKUPDEP_MCSPI2_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_MCSPI3_SDMA_MASK BITFIELD(3, 3) +#define OMAP4430_WKUPDEP_MCSPI3_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_MCSPI4_SDMA_MASK BITFIELD(3, 3) +#define OMAP4430_WKUPDEP_MCSPI4_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_MMCSD3_SDMA_MASK BITFIELD(3, 3) +#define OMAP4430_WKUPDEP_MMCSD3_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_WKUPDEP_MMCSD3_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_MMCSD4_SDMA_MASK BITFIELD(3, 3) +#define OMAP4430_WKUPDEP_MMCSD4_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_WKUPDEP_MMCSD4_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_SLIMBUS2_DMA_SDMA_MASK BITFIELD(7, 7) +#define OMAP4430_WKUPDEP_SLIMBUS2_DMA_TESLA_MASK BITFIELD(6, 6) +#define OMAP4430_WKUPDEP_SLIMBUS2_IRQ_TESLA_MASK BITFIELD(2, 2) +#define OMAP4430_WKUPDEP_SLIMBUS2_IRQ_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_UART1_SDMA_MASK BITFIELD(3, 3) +#define OMAP4430_WKUPDEP_UART1_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_UART2_SDMA_MASK BITFIELD(3, 3) +#define OMAP4430_WKUPDEP_UART2_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_UART3_SDMA_MASK BITFIELD(3, 3) +#define OMAP4430_WKUPDEP_UART3_TESLA_MASK BITFIELD(2, 2) +#define OMAP4430_WKUPDEP_UART3_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_WKUPDEP_UART3_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_UART4_SDMA_MASK BITFIELD(3, 3) +#define OMAP4430_WKUPDEP_UART4_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_MMCSD5_SDMA_MASK BITFIELD(3, 3) +#define OMAP4430_WKUPDEP_MMCSD5_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_WKUPDEP_MMCSD5_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_LOSTMEM_RETAINED_BANK_MASK BITFIELD(8, 8) +#define OMAP4430_WKUPDEP_WDT2_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_WKUPDEP_WDT2_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_GPIO1_IRQ2_TESLA_MASK BITFIELD(6, 6) +#define OMAP4430_WKUPDEP_GPIO1_IRQ1_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_WKUPDEP_GPIO1_IRQ1_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_TIMER1_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_TIMER12_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_USIM_SDMA_MASK BITFIELD(3, 3) +#define OMAP4430_WKUPDEP_USIM_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_LOSTMEM_WKUP_BANK_MASK BITFIELD(8, 8) +#define OMAP4430_WKUPDEP_KEYBOARD_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_RTC_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_MPU_RAM_ONSTATE_MASK BITFIELD(21, 20) +#define OMAP4430_MPU_L2_ONSTATE_MASK BITFIELD(19, 18) +#define OMAP4430_MPU_L1_ONSTATE_MASK BITFIELD(17, 16) +#define OMAP4430_MPU_RAM_RETSTATE_MASK BITFIELD(10, 10) +#define OMAP4430_MPU_L2_RETSTATE_MASK BITFIELD(9, 9) +#define OMAP4430_MPU_L1_RETSTATE_MASK BITFIELD(8, 8) +#define OMAP4430_MPU_RAM_STATEST_MASK BITFIELD(9, 8) +#define OMAP4430_MPU_L2_STATEST_MASK BITFIELD(7, 6) +#define OMAP4430_MPU_L1_STATEST_MASK BITFIELD(5, 4) +#define OMAP4430_ICECRUSHER_MPU_RST_MASK BITFIELD(1, 1) +#define OMAP4430_EMULATION_RST_MASK BITFIELD(0, 0) +#define OMAP4430_LOSTMEM_MPU_RAM_MASK BITFIELD(10, 10) +#define OMAP4430_LOSTMEM_MPU_L2_MASK BITFIELD(9, 9) +#define OMAP4430_LOSTMEM_MPU_L1_MASK BITFIELD(8, 8) +#define OMAP4430_TESLA_EDMA_ONSTATE_MASK BITFIELD(21, 20) +#define OMAP4430_TESLA_L2_ONSTATE_MASK BITFIELD(19, 18) +#define OMAP4430_TESLA_L1_ONSTATE_MASK BITFIELD(17, 16) +#define OMAP4430_TESLA_EDMA_RETSTATE_MASK BITFIELD(10, 10) +#define OMAP4430_TESLA_L2_RETSTATE_MASK BITFIELD(9, 9) +#define OMAP4430_TESLA_L1_RETSTATE_MASK BITFIELD(8, 8) +#define OMAP4430_TESLA_EDMA_STATEST_MASK BITFIELD(9, 8) +#define OMAP4430_TESLA_L2_STATEST_MASK BITFIELD(7, 6) +#define OMAP4430_TESLA_L1_STATEST_MASK BITFIELD(5, 4) +#define OMAP4430_RST2_MASK BITFIELD(1, 1) +#define OMAP4430_RST1_MASK BITFIELD(0, 0) +#define OMAP4430_TESLA_DSP_EMU_REQ_RSTST_MASK BITFIELD(3, 3) +#define OMAP4430_TESLASS_EMU_RSTST_MASK BITFIELD(2, 2) +#define OMAP4430_RST2ST_MASK BITFIELD(1, 1) +#define OMAP4430_RST1ST_MASK BITFIELD(0, 0) +#define OMAP4430_LOSTMEM_TESLA_EDMA_MASK BITFIELD(10, 10) +#define OMAP4430_LOSTMEM_TESLA_L2_MASK BITFIELD(9, 9) +#define OMAP4430_LOSTMEM_TESLA_L1_MASK BITFIELD(8, 8) +#define OMAP4430_TCM2_MEM_ONSTATE_MASK BITFIELD(23, 22) +#define OMAP4430_TCM1_MEM_ONSTATE_MASK BITFIELD(21, 20) +#define OMAP4430_SL2_MEM_ONSTATE_MASK BITFIELD(19, 18) +#define OMAP4430_HWA_MEM_ONSTATE_MASK BITFIELD(17, 16) +#define OMAP4430_TCM2_MEM_RETSTATE_MASK BITFIELD(11, 11) +#define OMAP4430_TCM1_MEM_RETSTATE_MASK BITFIELD(10, 10) +#define OMAP4430_SL2_MEM_RETSTATE_MASK BITFIELD(9, 9) +#define OMAP4430_HWA_MEM_RETSTATE_MASK BITFIELD(8, 8) +#define OMAP4430_TCM2_MEM_STATEST_MASK BITFIELD(11, 10) +#define OMAP4430_TCM1_MEM_STATEST_MASK BITFIELD(9, 8) +#define OMAP4430_SL2_MEM_STATEST_MASK BITFIELD(7, 6) +#define OMAP4430_HWA_MEM_STATEST_MASK BITFIELD(5, 4) +#define OMAP4430_RST3_MASK BITFIELD(2, 2) +#define OMAP4430_ICECRUSHER_SEQ2_RST2ST_MASK BITFIELD(6, 6) +#define OMAP4430_ICECRUSHER_SEQ1_RST1ST_MASK BITFIELD(5, 5) +#define OMAP4430_EMULATION_SEQ2_RST2ST_MASK BITFIELD(4, 4) +#define OMAP4430_EMULATION_SEQ1_RST1ST_MASK BITFIELD(3, 3) +#define OMAP4430_RST3ST_MASK BITFIELD(2, 2) +#define OMAP4430_LOSTMEM_HWA_MEM_MASK BITFIELD(10, 10) +#define OMAP4430_LOSTMEM_TCM2_MEM_MASK BITFIELD(9, 9) +#define OMAP4430_LOSTMEM_TCM1_MEM_MASK BITFIELD(8, 8) +#define OMAP4430_LOSTMEM_SL2_MEM_MASK BITFIELD(8, 8) +#define OMAP4430_OCP_NRET_BANK_ONSTATE_MASK BITFIELD(25, 24) +#define OMAP4430_DUCATI_UNICACHE_ONSTATE_MASK BITFIELD(23, 22) +#define OMAP4430_DUCATI_L2RAM_ONSTATE_MASK BITFIELD(21, 20) +#define OMAP4430_CORE_OCMRAM_ONSTATE_MASK BITFIELD(19, 18) +#define OMAP4430_CORE_OTHER_BANK_ONSTATE_MASK BITFIELD(17, 16) +#define OMAP4430_OCP_NRET_BANK_RETSTATE_MASK BITFIELD(12, 12) +#define OMAP4430_DUCATI_UNICACHE_RETSTATE_MASK BITFIELD(11, 11) +#define OMAP4430_DUCATI_L2RAM_RETSTATE_MASK BITFIELD(10, 10) +#define OMAP4430_CORE_OCMRAM_RETSTATE_MASK BITFIELD(9, 9) +#define OMAP4430_CORE_OTHER_BANK_RETSTATE_MASK BITFIELD(8, 8) +#define OMAP4430_MEMORYCHANGE_MASK BITFIELD(3, 3) +#define OMAP4430_OCP_NRET_BANK_STATEST_MASK BITFIELD(13, 12) +#define OMAP4430_DUCATI_UNICACHE_STATEST_MASK BITFIELD(11, 10) +#define OMAP4430_DUCATI_L2RAM_STATEST_MASK BITFIELD(9, 8) +#define OMAP4430_CORE_OCMRAM_STATEST_MASK BITFIELD(7, 6) +#define OMAP4430_CORE_OTHER_BANK_STATEST_MASK BITFIELD(5, 4) +#define OMAP4430_LOSTMEM_CORE_OCMRAM_MASK BITFIELD(8, 8) +#define OMAP4430_ICECRUSHER_RST2ST_MASK BITFIELD(6, 6) +#define OMAP4430_ICECRUSHER_RST1ST_MASK BITFIELD(5, 5) +#define OMAP4430_EMULATION_RST2ST_MASK BITFIELD(4, 4) +#define OMAP4430_EMULATION_RST1ST_MASK BITFIELD(3, 3) +#define OMAP4430_LOSTMEM_DUCATI_L2RAM_MASK BITFIELD(9, 9) +#define OMAP4430_LOSTMEM_DUCATI_UNICACHE_MASK BITFIELD(8, 8) +#define OMAP4430_LOSTMEM_CORE_OTHER_BANK_MASK BITFIELD(8, 8) +#define OMAP4430_DMM_LOSTMEM_CORE_NRET_BANK_MASK BITFIELD(9, 9) +#define OMAP4430_LOSTMEM_CORE_NRET_BANK_MASK BITFIELD(8, 8) +#define OMAP4430_REV_MASK BITFIELD(7, 0) +#define OMAP4430_VC_TOERR_ST_MASK BITFIELD(31, 31) +#define OMAP4430_VC_RAERR_ST_MASK BITFIELD(30, 30) +#define OMAP4430_VC_SAERR_ST_MASK BITFIELD(29, 29) +#define OMAP4430_VP_CORE_TRANXDONE_ST_MASK BITFIELD(28, 28) +#define OMAP4430_VP_CORE_EQVALUE_ST_MASK BITFIELD(27, 27) +#define OMAP4430_VP_CORE_NOSMPSACK_ST_MASK BITFIELD(26, 26) +#define OMAP4430_VP_CORE_MAXVDD_ST_MASK BITFIELD(25, 25) +#define OMAP4430_VP_CORE_MINVDD_ST_MASK BITFIELD(24, 24) +#define OMAP4430_VP_CORE_OPPCHANGEDONE_ST_MASK BITFIELD(23, 23) +#define OMAP4430_VP_IVA_TRANXDONE_ST_MASK BITFIELD(22, 22) +#define OMAP4430_VP_IVA_EQVALUE_ST_MASK BITFIELD(21, 21) +#define OMAP4430_VP_IVA_NOSMPSACK_ST_MASK BITFIELD(20, 20) +#define OMAP4430_VP_IVA_MAXVDD_ST_MASK BITFIELD(19, 19) +#define OMAP4430_VP_IVA_MINVDD_ST_MASK BITFIELD(18, 18) +#define OMAP4430_VP_IVA_OPPCHANGEDONE_ST_MASK BITFIELD(17, 17) +#define OMAP4430_VP_MPU_TRANXDONE_ST_MASK BITFIELD(16, 16) +#define OMAP4430_VP_MPU_EQVALUE_ST_MASK BITFIELD(15, 15) +#define OMAP4430_VP_MPU_NOSMPSACK_ST_MASK BITFIELD(14, 14) +#define OMAP4430_VP_MPU_MAXVDD_ST_MASK BITFIELD(13, 13) +#define OMAP4430_VP_MPU_MINVDD_ST_MASK BITFIELD(12, 12) +#define OMAP4430_VP_MPU_OPPCHANGEDONE_ST_MASK BITFIELD(11, 11) +#define OMAP4430_IO_ST_MASK BITFIELD(9, 9) +#define OMAP4430_TRANSITION_ST_MASK BITFIELD(8, 8) +#define OMAP4430_DPLL_UNIPRO_RECAL_ST_MASK BITFIELD(7, 7) +#define OMAP4430_DPLL_DDRPHY_RECAL_ST_MASK BITFIELD(6, 6) +#define OMAP4430_DPLL_USB_RECAL_ST_MASK BITFIELD(5, 5) +#define OMAP4430_DPLL_ABE_RECAL_ST_MASK BITFIELD(4, 4) +#define OMAP4430_DPLL_PER_RECAL_ST_MASK BITFIELD(3, 3) +#define OMAP4430_DPLL_IVA_RECAL_ST_MASK BITFIELD(2, 2) +#define OMAP4430_DPLL_MPU_RECAL_ST_MASK BITFIELD(1, 1) +#define OMAP4430_DPLL_CORE_RECAL_ST_MASK BITFIELD(0, 0) +#define OMAP4430_VC_TOERR_EN_MASK BITFIELD(31, 31) +#define OMAP4430_VC_RAERR_EN_MASK BITFIELD(30, 30) +#define OMAP4430_VC_SAERR_EN_MASK BITFIELD(29, 29) +#define OMAP4430_VP_CORE_TRANXDONE_EN_MASK BITFIELD(28, 28) +#define OMAP4430_VP_CORE_EQVALUE_EN_MASK BITFIELD(27, 27) +#define OMAP4430_VP_CORE_NOSMPSACK_EN_MASK BITFIELD(26, 26) +#define OMAP4430_VP_CORE_MAXVDD_EN_MASK BITFIELD(25, 25) +#define OMAP4430_VP_CORE_MINVDD_EN_MASK BITFIELD(24, 24) +#define OMAP4430_VP_CORE_OPPCHANGEDONE_EN_MASK BITFIELD(23, 23) +#define OMAP4430_VP_IVA_TRANXDONE_EN_MASK BITFIELD(22, 22) +#define OMAP4430_VP_IVA_EQVALUE_EN_MASK BITFIELD(21, 21) +#define OMAP4430_VP_IVA_NOSMPSACK_EN_MASK BITFIELD(20, 20) +#define OMAP4430_VP_IVA_MAXVDD_EN_MASK BITFIELD(19, 19) +#define OMAP4430_VP_IVA_MINVDD_EN_MASK BITFIELD(18, 18) +#define OMAP4430_VP_IVA_OPPCHANGEDONE_EN_MASK BITFIELD(17, 17) +#define OMAP4430_VP_MPU_TRANXDONE_EN_MASK BITFIELD(16, 16) +#define OMAP4430_VP_MPU_EQVALUE_EN_MASK BITFIELD(15, 15) +#define OMAP4430_VP_MPU_NOSMPSACK_EN_MASK BITFIELD(14, 14) +#define OMAP4430_VP_MPU_MAXVDD_EN_MASK BITFIELD(13, 13) +#define OMAP4430_VP_MPU_MINVDD_EN_MASK BITFIELD(12, 12) +#define OMAP4430_VP_MPU_OPPCHANGEDONE_EN_MASK BITFIELD(11, 11) +#define OMAP4430_IO_EN_MASK BITFIELD(9, 9) +#define OMAP4430_TRANSITION_EN_MASK BITFIELD(8, 8) +#define OMAP4430_DPLL_UNIPRO_RECAL_EN_MASK BITFIELD(7, 7) +#define OMAP4430_DPLL_DDRPHY_RECAL_EN_MASK BITFIELD(6, 6) +#define OMAP4430_DPLL_USB_RECAL_EN_MASK BITFIELD(5, 5) +#define OMAP4430_DPLL_ABE_RECAL_EN_MASK BITFIELD(4, 4) +#define OMAP4430_DPLL_PER_RECAL_EN_MASK BITFIELD(3, 3) +#define OMAP4430_DPLL_IVA_RECAL_EN_MASK BITFIELD(2, 2) +#define OMAP4430_DPLL_MPU_RECAL_EN_MASK BITFIELD(1, 1) +#define OMAP4430_DPLL_CORE_RECAL_EN_MASK BITFIELD(0, 0) +#define OMAP4430_VC_TOERR_ST_MASK BITFIELD(31, 31) +#define OMAP4430_VC_RAERR_ST_MASK BITFIELD(30, 30) +#define OMAP4430_VC_SAERR_ST_MASK BITFIELD(29, 29) +#define OMAP4430_VP_CORE_TRANXDONE_ST_MASK BITFIELD(28, 28) +#define OMAP4430_VP_CORE_EQVALUE_ST_MASK BITFIELD(27, 27) +#define OMAP4430_VP_CORE_NOSMPSACK_ST_MASK BITFIELD(26, 26) +#define OMAP4430_VP_CORE_MAXVDD_ST_MASK BITFIELD(25, 25) +#define OMAP4430_VP_CORE_MINVDD_ST_MASK BITFIELD(24, 24) +#define OMAP4430_VP_CORE_OPPCHANGEDONE_ST_MASK BITFIELD(23, 23) +#define OMAP4430_VP_IVA_TRANXDONE_ST_MASK BITFIELD(22, 22) +#define OMAP4430_VP_IVA_EQVALUE_ST_MASK BITFIELD(21, 21) +#define OMAP4430_VP_IVA_NOSMPSACK_ST_MASK BITFIELD(20, 20) +#define OMAP4430_VP_IVA_MAXVDD_ST_MASK BITFIELD(19, 19) +#define OMAP4430_VP_IVA_MINVDD_ST_MASK BITFIELD(18, 18) +#define OMAP4430_VP_IVA_OPPCHANGEDONE_ST_MASK BITFIELD(17, 17) +#define OMAP4430_FORCEWKUP_ST_MASK BITFIELD(10, 10) +#define OMAP4430_DPLL_UNIPRO_RECAL_ST_MASK BITFIELD(7, 7) +#define OMAP4430_DPLL_PER_RECAL_ST_MASK BITFIELD(3, 3) +#define OMAP4430_DPLL_IVA_RECAL_ST_MASK BITFIELD(2, 2) +#define OMAP4430_DPLL_CORE_RECAL_ST_MASK BITFIELD(0, 0) +#define OMAP4430_VC_TOERR_EN_MASK BITFIELD(31, 31) +#define OMAP4430_VC_RAERR_EN_MASK BITFIELD(30, 30) +#define OMAP4430_VC_SAERR_EN_MASK BITFIELD(29, 29) +#define OMAP4430_VP_CORE_TRANXDONE_EN_MASK BITFIELD(28, 28) +#define OMAP4430_VP_CORE_EQVALUE_EN_MASK BITFIELD(27, 27) +#define OMAP4430_VP_CORE_NOSMPSACK_EN_MASK BITFIELD(26, 26) +#define OMAP4430_VP_CORE_MAXVDD_EN_MASK BITFIELD(25, 25) +#define OMAP4430_VP_CORE_MINVDD_EN_MASK BITFIELD(24, 24) +#define OMAP4430_VP_CORE_OPPCHANGEDONE_EN_MASK BITFIELD(23, 23) +#define OMAP4430_VP_IVA_TRANXDONE_EN_MASK BITFIELD(22, 22) +#define OMAP4430_VP_IVA_EQVALUE_EN_MASK BITFIELD(21, 21) +#define OMAP4430_VP_IVA_NOSMPSACK_EN_MASK BITFIELD(20, 20) +#define OMAP4430_VP_IVA_MAXVDD_EN_MASK BITFIELD(19, 19) +#define OMAP4430_VP_IVA_MINVDD_EN_MASK BITFIELD(18, 18) +#define OMAP4430_VP_IVA_OPPCHANGEDONE_EN_MASK BITFIELD(17, 17) +#define OMAP4430_FORCEWKUP_EN_MASK BITFIELD(10, 10) +#define OMAP4430_DPLL_UNIPRO_RECAL_EN_MASK BITFIELD(7, 7) +#define OMAP4430_DPLL_PER_RECAL_EN_MASK BITFIELD(3, 3) +#define OMAP4430_DPLL_IVA_RECAL_EN_MASK BITFIELD(2, 2) +#define OMAP4430_DPLL_CORE_RECAL_EN_MASK BITFIELD(0, 0) +#define OMAP4430_DPLL_ABE_RECAL_ST_MASK BITFIELD(4, 4) +#define OMAP4430_DPLL_IVA_RECAL_ST_MASK BITFIELD(2, 2) +#define OMAP4430_DPLL_ABE_RECAL_EN_MASK BITFIELD(4, 4) +#define OMAP4430_DPLL_IVA_RECAL_EN_MASK BITFIELD(2, 2) +#define OMAP4430_MODULEMODE_MASK BITFIELD(1, 0) +#define OMAP4430_WKUPDEP_SR_MPU_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_SR_IVA_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_WKUPDEP_SR_IVA_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_WKUPDEP_SR_CORE_DUCATI_MASK BITFIELD(1, 1) +#define OMAP4430_WKUPDEP_SR_CORE_MPU_MASK BITFIELD(0, 0) +#define OMAP4430_CAM_MEM_ONSTATE_MASK BITFIELD(17, 16) +#define OMAP4430_CAM_MEM_STATEST_MASK BITFIELD(5, 4) +#define OMAP4430_LOSTMEM_CAM_MEM_MASK BITFIELD(8, 8) +#define OMAP4430_LOSTMEM_CAM_MEM_MASK BITFIELD(8, 8) +#define OMAP4430_GFX_MEM_ONSTATE_MASK BITFIELD(17, 16) +#define OMAP4430_GFX_MEM_STATEST_MASK BITFIELD(5, 4) +#define OMAP4430_LOSTMEM_GFX_MEM_MASK BITFIELD(8, 8) +#define OMAP4430_EMU_BANK_ONSTATE_MASK BITFIELD(17, 16) +#define OMAP4430_EMU_BANK_STATEST_MASK BITFIELD(5, 4) +#define OMAP4430_LOSTMEM_EMU_BANK_MASK BITFIELD(8, 8) +#define OMAP4430_RST_GLOBAL_COLD_SW_MASK BITFIELD(1, 1) +#define OMAP4430_RST_GLOBAL_WARM_SW_MASK BITFIELD(0, 0) +#define OMAP4430_ICEPICK_RST_MASK BITFIELD(9, 9) +#define OMAP4430_VDD_CORE_VOLT_MGR_RST_MASK BITFIELD(8, 8) +#define OMAP4430_VDD_IVA_VOLT_MGR_RST_MASK BITFIELD(7, 7) +#define OMAP4430_VDD_MPU_VOLT_MGR_RST_MASK BITFIELD(6, 6) +#define OMAP4430_EXTERNAL_WARM_RST_MASK BITFIELD(5, 5) +#define OMAP4430_SECURE_WDT_RST_MASK BITFIELD(4, 4) +#define OMAP4430_MPU_WDT_RST_MASK BITFIELD(3, 3) +#define OMAP4430_MPU_SECURITY_VIOL_RST_MASK BITFIELD(2, 2) +#define OMAP4430_GLOBAL_WARM_SW_RST_MASK BITFIELD(1, 1) +#define OMAP4430_GLOBAL_COLD_RST_MASK BITFIELD(0, 0) +#define OMAP4430_RSTTIME2_MASK BITFIELD(12, 8) +#define OMAP4430_RSTTIME1_MASK BITFIELD(7, 0) +#define OMAP4430_CLKREQ_COND_MASK BITFIELD(2, 0) +#define OMAP4430_VDD_IVA_PRESENCE_MASK BITFIELD(9, 9) +#define OMAP4430_VDD_MPU_PRESENCE_MASK BITFIELD(8, 8) +#define OMAP4430_AUTO_CTRL_VDD_IVA_L_MASK BITFIELD(5, 4) +#define OMAP4430_AUTO_CTRL_VDD_MPU_L_MASK BITFIELD(3, 2) +#define OMAP4430_AUTO_CTRL_VDD_CORE_L_MASK BITFIELD(1, 0) +#define OMAP4430_PWRREQ_COND_MASK BITFIELD(1, 0) +#define OMAP4430_PONOUT_2_PGOODIN_TIME_MASK BITFIELD(15, 8) +#define OMAP4430_PCHARGE_TIME_MASK BITFIELD(7, 0) +#define OMAP4430_ISO_2_ON_TIME_MASK BITFIELD(7, 0) +#define OMAP4430_GLOBAL_WUEN_MASK BITFIELD(16, 16) +#define OMAP4430_WUCLK_STATUS_MASK BITFIELD(9, 9) +#define OMAP4430_WUCLK_CTRL_MASK BITFIELD(8, 8) +#define OMAP4430_ISOCLK_STATUS_MASK BITFIELD(1, 1) +#define OMAP4430_ISOCLK_OVERRIDE_MASK BITFIELD(0, 0) +#define OMAP4430_RAMP_DOWN_PRESCAL_MASK BITFIELD(25, 24) +#define OMAP4430_RAMP_DOWN_COUNT_MASK BITFIELD(21, 16) +#define OMAP4430_RAMP_UP_PRESCAL_MASK BITFIELD(9, 8) +#define OMAP4430_RAMP_UP_COUNT_MASK BITFIELD(5, 0) +#define OMAP4430_ERROROFFSET_MASK BITFIELD(31, 24) +#define OMAP4430_ERRORGAIN_MASK BITFIELD(23, 16) +#define OMAP4430_INITVOLTAGE_MASK BITFIELD(15, 8) +#define OMAP4430_TIMEOUTEN_MASK BITFIELD(3, 3) +#define OMAP4430_INITVDD_MASK BITFIELD(2, 2) +#define OMAP4430_FORCEUPDATE_MASK BITFIELD(1, 1) +#define OMAP4430_VPENABLE_MASK BITFIELD(0, 0) +#define OMAP4430_VPINIDLE_MASK BITFIELD(0, 0) +#define OMAP4430_VDDMAX_MASK BITFIELD(31, 24) +#define OMAP4430_VDDMIN_MASK BITFIELD(23, 16) +#define OMAP4430_TIMEOUT_MASK BITFIELD(15, 0) +#define OMAP4430_VPVOLTAGE_MASK BITFIELD(7, 0) +#define OMAP4430_SMPSWAITTIMEMAX_MASK BITFIELD(23, 8) +#define OMAP4430_VSTEPMAX_MASK BITFIELD(7, 0) +#define OMAP4430_SMPSWAITTIMEMIN_MASK BITFIELD(23, 8) +#define OMAP4430_VSTEPMIN_MASK BITFIELD(7, 0) +#define OMAP4430_PRM_VC_SMPS_SA_VDD_MPU_L_MASK BITFIELD(22, 16) +#define OMAP4430_PRM_VC_SMPS_SA_VDD_IVA_L_MASK BITFIELD(14, 8) +#define OMAP4430_PRM_VC_SMPS_SA_VDD_CORE_L_MASK BITFIELD(6, 0) +#define OMAP4430_VOLRA_VDD_MPU_L_MASK BITFIELD(23, 16) +#define OMAP4430_VOLRA_VDD_IVA_L_MASK BITFIELD(15, 8) +#define OMAP4430_VOLRA_VDD_CORE_L_MASK BITFIELD(7, 0) +#define OMAP4430_CMDRA_VDD_MPU_L_MASK BITFIELD(23, 16) +#define OMAP4430_CMDRA_VDD_IVA_L_MASK BITFIELD(15, 8) +#define OMAP4430_CMDRA_VDD_CORE_L_MASK BITFIELD(7, 0) +#define OMAP4430_ON_MASK BITFIELD(31, 24) +#define OMAP4430_ONLP_MASK BITFIELD(23, 16) +#define OMAP4430_RET_MASK BITFIELD(15, 8) +#define OMAP4430_OFF_MASK BITFIELD(7, 0) +#define OMAP4430_VALID_MASK BITFIELD(24, 24) +#define OMAP4430_DATA_MASK BITFIELD(23, 16) +#define OMAP4430_REGADDR_MASK BITFIELD(15, 8) +#define OMAP4430_SLAVEADDR_MASK BITFIELD(6, 0) +#define OMAP4430_RACEN_VDD_MPU_L_MASK BITFIELD(20, 20) +#define OMAP4430_RAC_VDD_MPU_L_MASK BITFIELD(19, 19) +#define OMAP4430_RAV_VDD_MPU_L_MASK BITFIELD(18, 18) +#define OMAP4430_CMD_VDD_MPU_L_MASK BITFIELD(17, 17) +#define OMAP4430_PRM_VC_CFG_CHANNEL_SA_VDD_MPU_L_MASK BITFIELD(16, 16) +#define OMAP4430_CMD_VDD_IVA_L_MASK BITFIELD(12, 12) +#define OMAP4430_RACEN_VDD_IVA_L_MASK BITFIELD(11, 11) +#define OMAP4430_RAC_VDD_IVA_L_MASK BITFIELD(10, 10) +#define OMAP4430_RAV_VDD_IVA_L_MASK BITFIELD(9, 9) +#define OMAP4430_PRM_VC_CFG_CHANNEL_SA_VDD_IVA_L_MASK BITFIELD(8, 8) +#define OMAP4430_CMD_VDD_CORE_L_MASK BITFIELD(4, 4) +#define OMAP4430_RACEN_VDD_CORE_L_MASK BITFIELD(3, 3) +#define OMAP4430_RAC_VDD_CORE_L_MASK BITFIELD(2, 2) +#define OMAP4430_RAV_VDD_CORE_L_MASK BITFIELD(1, 1) +#define OMAP4430_PRM_VC_CFG_CHANNEL_SA_VDD_CORE_L_MASK BITFIELD(0, 0) +#define OMAP4430_DFILTEREN_MASK BITFIELD(6, 6) +#define OMAP4430_HSMASTER_MASK BITFIELD(5, 5) +#define OMAP4430_SRMODEEN_MASK BITFIELD(4, 4) +#define OMAP4430_HSMODEEN_MASK BITFIELD(3, 3) +#define OMAP4430_HSMCODE_MASK BITFIELD(2, 0) +#define OMAP4430_HSSCLL_MASK BITFIELD(31, 24) +#define OMAP4430_HSSCLH_MASK BITFIELD(23, 16) +#define OMAP4430_SCLL_MASK BITFIELD(15, 8) +#define OMAP4430_SCLH_MASK BITFIELD(7, 0) +#define OMAP4430_SLPCNT_VALUE_MASK BITFIELD(23, 16) +#define OMAP4430_VSETUPCNT_VALUE_MASK BITFIELD(15, 8) +#define OMAP4430_PCHARGECNT_VALUE_MASK BITFIELD(5, 0) +#define OMAP4430_ENABLE_RTA_EXPORT_MASK BITFIELD(0, 0) +#define OMAP4430_AIPOFF_MASK BITFIELD(8, 8) +#define OMAP4430_ENFUNC5_MASK BITFIELD(7, 7) +#define OMAP4430_ENFUNC4_MASK BITFIELD(6, 6) +#define OMAP4430_ENFUNC3_MASK BITFIELD(5, 5) +#define OMAP4430_ENFUNC2_EXPORT_MASK BITFIELD(4, 4) +#define OMAP4430_ENFUNC1_MASK BITFIELD(3, 3) +#define OMAP4430_ABBOFF_SLEEP_EXPORT_MASK BITFIELD(2, 2) +#define OMAP4430_ABBOFF_ACT_EXPORT_MASK BITFIELD(1, 1) +#define OMAP4430_SRAM_IN_TRANSITION_MASK BITFIELD(9, 9) +#define OMAP4430_SRAMLDO_STATUS_MASK BITFIELD(8, 8) +#define OMAP4430_RETMODE_ENABLE_MASK BITFIELD(0, 0) +#define OMAP4430_SRAM_IN_TRANSITION_MASK BITFIELD(9, 9) +#define OMAP4430_SRAMLDO_STATUS_MASK BITFIELD(8, 8) +#define OMAP4430_RETMODE_ENABLE_MASK BITFIELD(0, 0) +#define OMAP4430_SRAM_IN_TRANSITION_MASK BITFIELD(9, 9) +#define OMAP4430_SRAMLDO_STATUS_MASK BITFIELD(8, 8) +#define OMAP4430_RETMODE_ENABLE_MASK BITFIELD(0, 0) +#define OMAP4430_SR2_WTCNT_VALUE_MASK BITFIELD(15, 8) +#define OMAP4430_NOCAP_EXPORT_MASK BITFIELD(4, 4) +#define OMAP4430_SLEEP_RBB_SEL_MASK BITFIELD(3, 3) +#define OMAP4430_ACTIVE_FBB_SEL_MASK BITFIELD(2, 2) +#define OMAP4430_ACTIVE_RBB_SEL_MASK BITFIELD(1, 1) +#define OMAP4430_SR2EN_MASK BITFIELD(0, 0) +#define OMAP4430_SR2_IN_TRANSITION_MASK BITFIELD(6, 6) +#define OMAP4430_SR2_STATUS_MASK BITFIELD(4, 3) +#define OMAP4430_OPP_CHANGE_MASK BITFIELD(2, 2) +#define OMAP4430_OPP_SEL_MASK BITFIELD(1, 0) +#define OMAP4430_NOCAP_EXPORT_MASK BITFIELD(4, 4) +#define OMAP4430_SLEEP_RBB_SEL_MASK BITFIELD(3, 3) +#define OMAP4430_ACTIVE_FBB_SEL_MASK BITFIELD(2, 2) +#define OMAP4430_ACTIVE_RBB_SEL_MASK BITFIELD(1, 1) +#define OMAP4430_CBIASSEL_MASK BITFIELD(0, 0) +#define OMAP4430_DEVICE_OFF_ENABLE_MASK BITFIELD(0, 0) +#define OMAP4430_PHASE2B_COMPLETED_MASK BITFIELD(2, 2) +#define OMAP4430_PHASE2A_COMPLETED_MASK BITFIELD(1, 1) +#define OMAP4430_PHASE1_COMPLETED_MASK BITFIELD(0, 0) +#define OMAP4430_PHASE1_CNDP_MASK BITFIELD(31, 0) +#define OMAP4430_PHASE2A_CNDP_MASK BITFIELD(31, 0) +#define OMAP4430_PHASE2B_CNDP_MASK BITFIELD(31, 0) +#define OMAP4430_MODEM_SLEEP_ST_MASK BITFIELD(16, 16) +#define OMAP4430_MODEM_SHUTDOWN_IRQ_MASK BITFIELD(9, 9) +#define OMAP4430_MODEM_WAKE_IRQ_MASK BITFIELD(8, 8) +#define OMAP4430_MODEM_READY_MASK BITFIELD(1, 1) +#define OMAP4430_WAKE_MODEM_MASK BITFIELD(0, 0) +#endif /* __ARCH_ARM_MACH_OMAP2_PRM_REG BITS_44XX_H */ diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h index 9937e2814696..bacfc97612ba 100644 --- a/arch/arm/mach-omap2/prm.h +++ b/arch/arm/mach-omap2/prm.h @@ -4,10 +4,11 @@ /* * OMAP2/3 Power/Reset Management (PRM) register definitions * - * Copyright (C) 2007 Texas Instruments, Inc. + * Copyright (C) 2007-2009 Texas Instruments, Inc. * Copyright (C) 2007 Nokia Corporation * * Written by Paul Walmsley + * Updated for OMAP4 by 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 version 2 as @@ -22,13 +23,15 @@ IO_ADDRESS(OMAP2430_PRM_BASE + (module) + (reg)) #define OMAP34XX_PRM_REGADDR(module, reg) \ IO_ADDRESS(OMAP3430_PRM_BASE + (module) + (reg)) +#define OMAP44XX_PRM_REGADDR(module, reg) \ + IO_ADDRESS(OMAP4430_PRM_BASE + (module) + (reg)) /* * Architecture-specific global PRM registers * Use __raw_{read,write}l() with these registers. * * With a few exceptions, these are the register names beginning with - * PRCM_* on 24xx, and PRM_* on 34xx. (The exceptions are the + * PRCM_* on 24xx, and PRM_* on 34xx and 44xx. (The exceptions are the * IRQSTATUS and IRQENABLE bits.) * */ @@ -160,6 +163,305 @@ #define OMAP3_PRM_CLKOUT_CTRL_OFFSET 0x0070 #define OMAP3430_PRM_CLKOUT_CTRL OMAP34XX_PRM_REGADDR(OMAP3430_CCR_MOD, 0x0070) +#define OMAP4430_CM_ABE_DSS_SYS_CLKSEL OMAP44XX_PRM_REGADDR(OMAP4430_CKGEN_MOD, 0x0) +#define OMAP4430_CM_DPLL_SYS_REF_CLKSEL OMAP44XX_PRM_REGADDR(OMAP4430_CKGEN_MOD, 0x4) +#define OMAP4430_CM_L4_WKUP_CLKSEL OMAP44XX_PRM_REGADDR(OMAP4430_CKGEN_MOD, 0x8) +#define OMAP4430_CM_ABE_PLL_REF_CLKSEL OMAP44XX_PRM_REGADDR(OMAP4430_CKGEN_MOD, 0xC) +#define OMAP4430_CM_SYS_CLKSEL OMAP44XX_PRM_REGADDR(OMAP4430_CKGEN_MOD, 0x10) +#define OMAP4430_PM_ABE_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_ABE_MOD, 0x0) +#define OMAP4430_PM_ABE_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_ABE_MOD, 0x4) +#define OMAP4430_RM_ABE_AESS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_ABE_MOD, 0x2C) +#define OMAP4430_PM_ABE_PDM_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_ABE_MOD, 0x30) +#define OMAP4430_RM_ABE_PDM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_ABE_MOD, 0x34) +#define OMAP4430_PM_ABE_DMIC_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_ABE_MOD, 0x38) +#define OMAP4430_RM_ABE_DMIC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_ABE_MOD, 0x3C) +#define OMAP4430_PM_ABE_MCASP_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_ABE_MOD, 0x40) +#define OMAP4430_RM_ABE_MCASP_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_ABE_MOD, 0x44) +#define OMAP4430_PM_ABE_MCBSP1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_ABE_MOD, 0x48) +#define OMAP4430_RM_ABE_MCBSP1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_ABE_MOD, 0x4C) +#define OMAP4430_PM_ABE_MCBSP2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_ABE_MOD, 0x50) +#define OMAP4430_RM_ABE_MCBSP2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_ABE_MOD, 0x54) +#define OMAP4430_PM_ABE_MCBSP3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_ABE_MOD, 0x58) +#define OMAP4430_RM_ABE_MCBSP3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_ABE_MOD, 0x5C) +#define OMAP4430_PM_ABE_SLIMBUS_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_ABE_MOD, 0x60) +#define OMAP4430_RM_ABE_SLIMBUS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_ABE_MOD, 0x64) +#define OMAP4430_PM_ABE_TIMER5_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_ABE_MOD, 0x68) +#define OMAP4430_RM_ABE_TIMER5_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_ABE_MOD, 0x6C) +#define OMAP4430_PM_ABE_TIMER6_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_ABE_MOD, 0x70) +#define OMAP4430_RM_ABE_TIMER6_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_ABE_MOD, 0x74) +#define OMAP4430_PM_ABE_TIMER7_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_ABE_MOD, 0x78) +#define OMAP4430_RM_ABE_TIMER7_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_ABE_MOD, 0x7C) +#define OMAP4430_PM_ABE_TIMER8_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_ABE_MOD, 0x80) +#define OMAP4430_RM_ABE_TIMER8_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_ABE_MOD, 0x84) +#define OMAP4430_PM_ABE_WDT3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_ABE_MOD, 0x88) +#define OMAP4430_RM_ABE_WDT3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_ABE_MOD, 0x8C) +#define OMAP4430_PM_DSS_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_DSS_MOD, 0x0) +#define OMAP4430_PM_DSS_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_DSS_MOD, 0x4) +#define OMAP4430_PM_DSS_DSS_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_DSS_MOD, 0x20) +#define OMAP4430_RM_DSS_DSS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_DSS_MOD, 0x24) +#define OMAP4430_RM_DSS_DEISS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_DSS_MOD, 0x2C) +#define OMAP4430_PM_L3INIT_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0x0) +#define OMAP4430_PM_L3INIT_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0x4) +#define OMAP4430_PM_L3INIT_MMC1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0x28) +#define OMAP4430_RM_L3INIT_MMC1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0x2C) +#define OMAP4430_PM_L3INIT_MMC2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0x30) +#define OMAP4430_RM_L3INIT_MMC2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0x34) +#define OMAP4430_PM_L3INIT_HSI_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0x38) +#define OMAP4430_RM_L3INIT_HSI_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0x3C) +#define OMAP4430_PM_L3INIT_UNIPRO1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0x40) +#define OMAP4430_RM_L3INIT_UNIPRO1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0x44) +#define OMAP4430_PM_L3INIT_USB_HOST_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0x58) +#define OMAP4430_RM_L3INIT_USB_HOST_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0x5C) +#define OMAP4430_PM_L3INIT_USB_OTG_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0x60) +#define OMAP4430_RM_L3INIT_USB_OTG_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0x64) +#define OMAP4430_PM_L3INIT_USB_TLL_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0x68) +#define OMAP4430_RM_L3INIT_USB_TLL_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0x6C) +#define OMAP4430_RM_L3INIT_P1500_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0x7C) +#define OMAP4430_RM_L3INIT_EMAC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0x84) +#define OMAP4430_PM_L3INIT_SATA_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0x88) +#define OMAP4430_RM_L3INIT_SATA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0x8C) +#define OMAP4430_RM_L3INIT_TPPSS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0x94) +#define OMAP4430_PM_L3INIT_PCIESS_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0x98) +#define OMAP4430_RM_L3INIT_PCIESS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0x9C) +#define OMAP4430_RM_L3INIT_CCPTX_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0xAC) +#define OMAP4430_PM_L3INIT_XHPI_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0xC0) +#define OMAP4430_RM_L3INIT_XHPI_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0xC4) +#define OMAP4430_PM_L3INIT_MMC6_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0xC8) +#define OMAP4430_RM_L3INIT_MMC6_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0xCC) +#define OMAP4430_PM_L3INIT_USB_HOST_FS_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0xD0) +#define OMAP4430_RM_L3INIT_USB_HOST_FS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0xD4) +#define OMAP4430_RM_L3INIT_USBPHYOCP2SCP_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L3INIT_MOD, 0xE4) +#define OMAP4430_PM_L4PER_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x0) +#define OMAP4430_PM_L4PER_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x4) +#define OMAP4430_RM_L4PER_ADC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x24) +#define OMAP4430_PM_L4PER_GPTIMER10_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x28) +#define OMAP4430_RM_L4PER_GPTIMER10_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x2C) +#define OMAP4430_PM_L4PER_GPTIMER11_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x30) +#define OMAP4430_RM_L4PER_GPTIMER11_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x34) +#define OMAP4430_PM_L4PER_GPTIMER2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x38) +#define OMAP4430_RM_L4PER_GPTIMER2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x3C) +#define OMAP4430_PM_L4PER_GPTIMER3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x40) +#define OMAP4430_RM_L4PER_GPTIMER3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x44) +#define OMAP4430_PM_L4PER_GPTIMER4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x48) +#define OMAP4430_RM_L4PER_GPTIMER4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x4C) +#define OMAP4430_PM_L4PER_GPTIMER9_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x50) +#define OMAP4430_RM_L4PER_GPTIMER9_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x54) +#define OMAP4430_RM_L4PER_ELM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x5C) +#define OMAP4430_PM_L4PER_GPIO2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x60) +#define OMAP4430_RM_L4PER_GPIO2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x64) +#define OMAP4430_PM_L4PER_GPIO3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x68) +#define OMAP4430_RM_L4PER_GPIO3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x6C) +#define OMAP4430_PM_L4PER_GPIO4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x70) +#define OMAP4430_RM_L4PER_GPIO4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x74) +#define OMAP4430_PM_L4PER_GPIO5_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x78) +#define OMAP4430_RM_L4PER_GPIO5_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x7C) +#define OMAP4430_PM_L4PER_GPIO6_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x80) +#define OMAP4430_RM_L4PER_GPIO6_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x84) +#define OMAP4430_RM_L4PER_HDQ1W_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x8C) +#define OMAP4430_PM_L4PER_HECC1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x90) +#define OMAP4430_RM_L4PER_HECC1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x94) +#define OMAP4430_PM_L4PER_HECC2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x98) +#define OMAP4430_RM_L4PER_HECC2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x9C) +#define OMAP4430_PM_L4PER_I2C1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0xA0) +#define OMAP4430_RM_L4PER_I2C1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0xA4) +#define OMAP4430_PM_L4PER_I2C2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0xA8) +#define OMAP4430_RM_L4PER_I2C2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0xAC) +#define OMAP4430_PM_L4PER_I2C3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0xB0) +#define OMAP4430_RM_L4PER_I2C3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0xB4) +#define OMAP4430_PM_L4PER_I2C4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0xB8) +#define OMAP4430_RM_L4PER_I2C4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0xBC) +#define OMAP4430_RM_L4PER_L4_PER_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0xC0) +#define OMAP4430_PM_L4PER_MCASP2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0xD0) +#define OMAP4430_RM_L4PER_MCASP2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0xD4) +#define OMAP4430_PM_L4PER_MCASP3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0xD8) +#define OMAP4430_RM_L4PER_MCASP3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0xDC) +#define OMAP4430_PM_L4PER_MCBSP4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0xE0) +#define OMAP4430_RM_L4PER_MCBSP4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0xE4) +#define OMAP4430_RM_L4PER_MGATE_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0xEC) +#define OMAP4430_PM_L4PER_MCSPI1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0xF0) +#define OMAP4430_RM_L4PER_MCSPI1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0xF4) +#define OMAP4430_PM_L4PER_MCSPI2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0xF8) +#define OMAP4430_RM_L4PER_MCSPI2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0xFC) +#define OMAP4430_PM_L4PER_MCSPI3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x100) +#define OMAP4430_RM_L4PER_MCSPI3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x104) +#define OMAP4430_PM_L4PER_MCSPI4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x108) +#define OMAP4430_RM_L4PER_MCSPI4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x10C) +#define OMAP4430_PM_L4PER_MMCSD3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x120) +#define OMAP4430_RM_L4PER_MMCSD3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x124) +#define OMAP4430_PM_L4PER_MMCSD4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x128) +#define OMAP4430_RM_L4PER_MMCSD4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x12C) +#define OMAP4430_RM_L4PER_MSPROHG_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x134) +#define OMAP4430_PM_L4PER_SLIMBUS2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x138) +#define OMAP4430_RM_L4PER_SLIMBUS2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x13C) +#define OMAP4430_PM_L4PER_UART1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x140) +#define OMAP4430_RM_L4PER_UART1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x144) +#define OMAP4430_PM_L4PER_UART2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x148) +#define OMAP4430_RM_L4PER_UART2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x14C) +#define OMAP4430_PM_L4PER_UART3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x150) +#define OMAP4430_RM_L4PER_UART3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x154) +#define OMAP4430_PM_L4PER_UART4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x158) +#define OMAP4430_RM_L4PER_UART4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x15C) +#define OMAP4430_PM_L4PER_MMCSD5_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x160) +#define OMAP4430_RM_L4PER_MMCSD5_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x164) +#define OMAP4430_RM_L4SEC_AES1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x1A4) +#define OMAP4430_RM_L4SEC_AES2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x1AC) +#define OMAP4430_RM_L4SEC_DES3DES_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x1B4) +#define OMAP4430_RM_L4SEC_PKAEIP29_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x1BC) +#define OMAP4430_RM_L4SEC_RNG_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x1C4) +#define OMAP4430_RM_L4SEC_SHA2MD51_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x1CC) +#define OMAP4430_RM_L4SEC_CRYPTODMA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_L4PER_MOD, 0x1DC) +#define OMAP4430_RM_WKUP_L4WKUP_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_WKUP_MOD, 0x24) +#define OMAP4430_RM_WKUP_WDT1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_WKUP_MOD, 0x2C) +#define OMAP4430_PM_WKUP_WDT2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_WKUP_MOD, 0x30) +#define OMAP4430_RM_WKUP_WDT2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_WKUP_MOD, 0x34) +#define OMAP4430_PM_WKUP_GPIO1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_WKUP_MOD, 0x38) +#define OMAP4430_RM_WKUP_GPIO1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_WKUP_MOD, 0x3C) +#define OMAP4430_PM_WKUP_TIMER1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_WKUP_MOD, 0x40) +#define OMAP4430_RM_WKUP_TIMER1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_WKUP_MOD, 0x44) +#define OMAP4430_PM_WKUP_TIMER12_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_WKUP_MOD, 0x48) +#define OMAP4430_RM_WKUP_TIMER12_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_WKUP_MOD, 0x4C) +#define OMAP4430_RM_WKUP_SYNCTIMER_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_WKUP_MOD, 0x54) +#define OMAP4430_PM_WKUP_USIM_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_WKUP_MOD, 0x58) +#define OMAP4430_RM_WKUP_USIM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_WKUP_MOD, 0x5C) +#define OMAP4430_RM_WKUP_SARRAM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_WKUP_MOD, 0x64) +#define OMAP4430_PM_WKUP_KEYBOARD_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_WKUP_MOD, 0x78) +#define OMAP4430_RM_WKUP_KEYBOARD_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_WKUP_MOD, 0x7C) +#define OMAP4430_PM_WKUP_RTC_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_WKUP_MOD, 0x80) +#define OMAP4430_RM_WKUP_RTC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_WKUP_MOD, 0x84) +#define OMAP4430_PM_MPU_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_MPU_MOD, 0x0) +#define OMAP4430_PM_MPU_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_MPU_MOD, 0x4) +#define OMAP4430_RM_MPU_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_MPU_MOD, 0x14) +#define OMAP4430_RM_MPU_MPU_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_MPU_MOD, 0x24) +#define OMAP4430_PM_TESLA_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_DSP_MOD, 0x0) +#define OMAP4430_PM_TESLA_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_DSP_MOD, 0x4) +#define OMAP4430_RM_TESLA_RSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_DSP_MOD, 0x10) +#define OMAP4430_RM_TESLA_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_DSP_MOD, 0x14) +#define OMAP4430_RM_TESLA_TESLA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_DSP_MOD, 0x24) +#define OMAP4430_PM_IVAHD_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x0) +#define OMAP4430_PM_IVAHD_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x4) +#define OMAP4430_RM_IVAHD_RSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x10) +#define OMAP4430_RM_IVAHD_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x14) +#define OMAP4430_RM_IVAHD_IVAHD_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x24) +#define OMAP4430_RM_IVAHD_SL2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x2C) +#define OMAP4430_PM_CORE_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_CORE_MOD, 0x0) +#define OMAP4430_PM_CORE_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_CORE_MOD, 0x4) +#define OMAP4430_RM_L3_1_L3_1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x24) +#define OMAP4430_RM_L3_2_L3_2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x124) +#define OMAP4430_RM_L3_2_GPMC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x12C) +#define OMAP4430_RM_L3_2_OCMC_RAM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x134) +#define OMAP4430_RM_DUCATI_RSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x210) +#define OMAP4430_RM_DUCATI_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x214) +#define OMAP4430_RM_DUCATI_DUCATI_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x224) +#define OMAP4430_RM_SDMA_SDMA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x324) +#define OMAP4430_RM_MEMIF_DMM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x424) +#define OMAP4430_RM_MEMIF_EMIF_FW_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x42C) +#define OMAP4430_RM_MEMIF_EMIF_1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x434) +#define OMAP4430_RM_MEMIF_EMIF_2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x43C) +#define OMAP4430_RM_MEMIF_DLL_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x444) +#define OMAP4430_RM_MEMIF_EMIF_H1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x454) +#define OMAP4430_RM_MEMIF_EMIF_H2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x45C) +#define OMAP4430_RM_MEMIF_DLL_H_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x464) +#define OMAP4430_RM_D2D_SAD2D_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x524) +#define OMAP4430_RM_D2D_MODEM_ICR_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x52C) +#define OMAP4430_RM_L4CFG_L4_CFG_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x624) +#define OMAP4430_RM_L4CFG_HW_SEM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x62C) +#define OMAP4430_RM_L4CFG_MAILBOX_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x634) +#define OMAP4430_RM_L4CFG_SAR_ROM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x63C) +#define OMAP4430_RM_L3INSTR_L3_3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x724) +#define OMAP4430_RM_L3INSTR_L3_INSTR_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x72C) +#define OMAP4430_RM_L3INSTR_OCP_WP1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_IVAHD_MOD, 0x744) +#define OMAP4430_REVISION_PRM OMAP44XX_PRM_REGADDR(OMAP4430_OCP_SOCKET_MOD, 0x0) +#define OMAP4430_PRM_IRQSTATUS_MPU OMAP44XX_PRM_REGADDR(OMAP4430_OCP_SOCKET_MOD, 0x10) +#define OMAP4430_PRM_IRQENABLE_MPU OMAP44XX_PRM_REGADDR(OMAP4430_OCP_SOCKET_MOD, 0x18) +#define OMAP4430_PRM_IRQSTATUS_DUCATI OMAP44XX_PRM_REGADDR(OMAP4430_OCP_SOCKET_MOD, 0x20) +#define OMAP4430_PRM_IRQENABLE_DUCATI OMAP44XX_PRM_REGADDR(OMAP4430_OCP_SOCKET_MOD, 0x28) +#define OMAP4430_PRM_IRQSTATUS_TESLA OMAP44XX_PRM_REGADDR(OMAP4430_OCP_SOCKET_MOD, 0x30) +#define OMAP4430_PRM_IRQENABLE_TESLA OMAP44XX_PRM_REGADDR(OMAP4430_OCP_SOCKET_MOD, 0x38) +#define OMAP4430_PRM_PRM_PROFILING_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_OCP_SOCKET_MOD, 0x40) +#define OMAP4430_RM_ALWON_MDMINTC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_ALWAYS_ON_MOD, 0x24) +#define OMAP4430_PM_ALWON_SR_MPU_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_ALWAYS_ON_MOD, 0x28) +#define OMAP4430_RM_ALWON_SR_MPU_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_ALWAYS_ON_MOD, 0x2C) +#define OMAP4430_PM_ALWON_SR_IVA_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_ALWAYS_ON_MOD, 0x30) +#define OMAP4430_RM_ALWON_SR_IVA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_ALWAYS_ON_MOD, 0x34) +#define OMAP4430_PM_ALWON_SR_CORE_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_ALWAYS_ON_MOD, 0x38) +#define OMAP4430_RM_ALWON_SR_CORE_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_ALWAYS_ON_MOD, 0x3C) +#define OMAP4430_PM_CAM_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_CAM_MOD, 0x0) +#define OMAP4430_PM_CAM_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_CAM_MOD, 0x4) +#define OMAP4430_RM_CAM_ISS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_CAM_MOD, 0x24) +#define OMAP4430_RM_CAM_FDIF_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_CAM_MOD, 0x2C) +#define OMAP4430_PM_GFX_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_GFX_MOD, 0x0) +#define OMAP4430_PM_GFX_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_GFX_MOD, 0x4) +#define OMAP4430_RM_GFX_GFX_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_GFX_MOD, 0x24) +#define OMAP4430_PM_EMU_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_EMU_MOD, 0x0) +#define OMAP4430_PM_EMU_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_EMU_MOD, 0x4) +#define OMAP4430_RM_EMU_DEBUGSS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_EMU_MOD, 0x24) +#define OMAP4430_PM_CEFUSE_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_CEFUSE_MOD, 0x0) +#define OMAP4430_PM_CEFUSE_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_CEFUSE_MOD, 0x4) +#define OMAP4430_RM_CEFUSE_CEFUSE_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_CEFUSE_MOD, 0x24) +#define OMAP4430_PRM_RSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x0) +#define OMAP4430_PRM_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x4) +#define OMAP4430_PRM_RSTTIME OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x8) +#define OMAP4430_PRM_CLKREQCTRL OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0xC) +#define OMAP4430_PRM_VOLTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x10) +#define OMAP4430_PRM_PWRREQCTRL OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x14) +#define OMAP4430_PRM_PSCON_COUNT OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x18) +#define OMAP4430_PRM_IO_COUNT OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x1C) +#define OMAP4430_PRM_IO_PMCTRL OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x20) +#define OMAP4430_PRM_VOLTSETUP_CORE_OFF OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x24) +#define OMAP4430_PRM_VOLTSETUP_MPU_OFF OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x28) +#define OMAP4430_PRM_VOLTSETUP_IVA_OFF OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x2C) +#define OMAP4430_PRM_VOLTSETUP_CORE_RET_SLEEP OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x30) +#define OMAP4430_PRM_VOLTSETUP_MPU_RET_SLEEP OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x34) +#define OMAP4430_PRM_VOLTSETUP_IVA_RET_SLEEP OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x38) +#define OMAP4430_PRM_VP_CORE_CONFIG OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x3C) +#define OMAP4430_PRM_VP_CORE_STATUS OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x40) +#define OMAP4430_PRM_VP_CORE_VLIMITTO OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x44) +#define OMAP4430_PRM_VP_CORE_VOLTAGE OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x48) +#define OMAP4430_PRM_VP_CORE_VSTEPMAX OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x4C) +#define OMAP4430_PRM_VP_CORE_VSTEPMIN OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x50) +#define OMAP4430_PRM_VP_MPU_CONFIG OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x54) +#define OMAP4430_PRM_VP_MPU_STATUS OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x58) +#define OMAP4430_PRM_VP_MPU_VLIMITTO OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x5C) +#define OMAP4430_PRM_VP_MPU_VOLTAGE OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x60) +#define OMAP4430_PRM_VP_MPU_VSTEPMAX OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x64) +#define OMAP4430_PRM_VP_MPU_VSTEPMIN OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x68) +#define OMAP4430_PRM_VP_IVA_CONFIG OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x6C) +#define OMAP4430_PRM_VP_IVA_STATUS OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x70) +#define OMAP4430_PRM_VP_IVA_VLIMITTO OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x74) +#define OMAP4430_PRM_VP_IVA_VOLTAGE OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x78) +#define OMAP4430_PRM_VP_IVA_VSTEPMAX OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x7C) +#define OMAP4430_PRM_VP_IVA_VSTEPMIN OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x80) +#define OMAP4430_PRM_VC_SMPS_SA OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x84) +#define OMAP4430_PRM_VC_VAL_SMPS_RA_VOL OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x88) +#define OMAP4430_PRM_VC_VAL_SMPS_RA_CMD OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x8C) +#define OMAP4430_PRM_VC_VAL_CMD_VDD_CORE_L OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x90) +#define OMAP4430_PRM_VC_VAL_CMD_VDD_MPU_L OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x94) +#define OMAP4430_PRM_VC_VAL_CMD_VDD_IVA_L OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x98) +#define OMAP4430_PRM_VC_VAL_BYPASS OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0x9C) +#define OMAP4430_PRM_VC_CFG_CHANNEL OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0xA0) +#define OMAP4430_PRM_VC_CFG_I2C_MODE OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0xA4) +#define OMAP4430_PRM_VC_CFG_I2C_CLK OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0xA8) +#define OMAP4430_PRM_SRAM_COUNT OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0xAC) +#define OMAP4430_PRM_SRAM_WKUP_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0xB0) +#define OMAP4430_PRM_LDO_SRAM_CORE_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0xB4) +#define OMAP4430_PRM_LDO_SRAM_CORE_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0xB8) +#define OMAP4430_PRM_LDO_SRAM_MPU_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0xBC) +#define OMAP4430_PRM_LDO_SRAM_MPU_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0xC0) +#define OMAP4430_PRM_LDO_SRAM_IVA_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0xC4) +#define OMAP4430_PRM_LDO_SRAM_IVA_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0xC8) +#define OMAP4430_PRM_LDO_ABB_MPU_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0xCC) +#define OMAP4430_PRM_LDO_ABB_MPU_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0xD0) +#define OMAP4430_PRM_LDO_ABB_IVA_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0xD4) +#define OMAP4430_PRM_LDO_ABB_IVA_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0xD8) +#define OMAP4430_PRM_LDO_BANDGAP_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0xDC) +#define OMAP4430_PRM_DEVICE_OFF_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0xE0) +#define OMAP4430_PRM_RESTORE_ST OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0xE4) +#define OMAP4430_PRM_PHASE1_CNDP OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0xE8) +#define OMAP4430_PRM_PHASE2A_CNDP OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0xEC) +#define OMAP4430_PRM_PHASE2B_CNDP OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0xF0) +#define OMAP4430_PRM_MODEM_IF_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_DEVICE_MOD, 0xF4) +#define OMAP4430_CM_WKUP_GPTIMER1_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_WKUP_CM_MOD, 0x40) + /* * Module specific PRM registers from PRM_BASE + domain offset * diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index b094c15bfe47..aa6c2f33fbf0 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -97,6 +97,16 @@ static struct plat_serial8250_port serial_platform_data[] = { .regshift = 2, .uartclk = OMAP24XX_BASE_BAUD * 16, }, { +#ifdef CONFIG_ARCH_OMAP4 + .membase = IO_ADDRESS(OMAP_UART4_BASE), + .mapbase = OMAP_UART4_BASE, + .irq = 70, + .flags = UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = OMAP24XX_BASE_BAUD * 16, + }, { +#endif .flags = 0 } }; @@ -197,11 +207,16 @@ static inline void omap_uart_enable_clocks(struct omap_uart_state *uart) { if (uart->clocked) return; - - clk_enable(uart->ick); - clk_enable(uart->fck); - uart->clocked = 1; - omap_uart_restore_context(uart); + /* + * FIX-ME: Replace with correct clk node when clk + * framework is available + */ + if (!cpu_is_omap44xx()) { + clk_enable(uart->ick); + clk_enable(uart->fck); + uart->clocked = 1; + omap_uart_restore_context(uart); + } } #ifdef CONFIG_PM @@ -511,23 +526,30 @@ void __init omap_serial_init(void) continue; } - sprintf(name, "uart%d_ick", i+1); - uart->ick = clk_get(NULL, name); - if (IS_ERR(uart->ick)) { - printk(KERN_ERR "Could not get uart%d_ick\n", i+1); - uart->ick = NULL; - } - - sprintf(name, "uart%d_fck", i+1); - uart->fck = clk_get(NULL, name); - if (IS_ERR(uart->fck)) { - printk(KERN_ERR "Could not get uart%d_fck\n", i+1); - uart->fck = NULL; - } + /* + * FIX-ME: Replace with correct clk node when clk + * framework is available + */ + if (!cpu_is_omap44xx()) { + sprintf(name, "uart%d_ick", i+1); + uart->ick = clk_get(NULL, name); + if (IS_ERR(uart->ick)) { + printk(KERN_ERR "Could not get uart%d_ick\n", \ + i+1); + uart->ick = NULL; + } - if (!uart->ick || !uart->fck) - continue; + sprintf(name, "uart%d_fck", i+1); + uart->fck = clk_get(NULL, name); + if (IS_ERR(uart->fck)) { + printk(KERN_ERR "Could not get uart%d_fck\n", \ + i+1); + uart->fck = NULL; + } + if (!uart->ick || !uart->fck) + continue; + } uart->num = i; p->private_data = uart; uart->p = p; diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index f332d454651a..e7ac4f7b9688 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig @@ -27,6 +27,7 @@ config ARCH_OMAP4 bool "TI OMAP4" select CPU_V7 select ARM_GIC + select COMMON_CLKDEV endchoice diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile index a83279523958..cfc0967df153 100644 --- a/arch/arm/plat-omap/Makefile +++ b/arch/arm/plat-omap/Makefile @@ -4,7 +4,7 @@ # Common support obj-y := common.o sram.o clock.o devices.o dma.o mux.o gpio.o \ - usb.o fb.o io.o + usb.o fb.o vram.o vrfb.o io.o obj-m := obj-n := obj- := diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c index e8c327a45a55..972694b217fe 100644 --- a/arch/arm/plat-omap/clock.c +++ b/arch/arm/plat-omap/clock.c @@ -40,36 +40,10 @@ static struct clk_functions *arch_clock; * clock framework is not up , it is defined here to avoid rework in * every driver. Also dummy prcm reset function is added */ -/* Dummy hooks only for OMAP4.For rest OMAPs, common clkdev is used */ -#if defined(CONFIG_ARCH_OMAP4) -struct clk *clk_get(struct device *dev, const char *id) -{ - return NULL; -} -EXPORT_SYMBOL(clk_get); - -void clk_put(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_put); - -void omap2_clk_prepare_for_reboot(void) -{ -} -EXPORT_SYMBOL(omap2_clk_prepare_for_reboot); - -void omap_prcm_arch_reset(char mode) -{ -} -EXPORT_SYMBOL(omap_prcm_arch_reset); -#endif int clk_enable(struct clk *clk) { unsigned long flags; int ret = 0; - if (cpu_is_omap44xx()) - /* OMAP4 clk framework not supported yet */ - return 0; if (clk == NULL || IS_ERR(clk)) return -EINVAL; diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c index ebcf006406f9..a2d5298f656c 100644 --- a/arch/arm/plat-omap/common.c +++ b/arch/arm/plat-omap/common.c @@ -372,6 +372,7 @@ static struct omap_globals omap4_globals = { .ctrl = OMAP2_IO_ADDRESS(OMAP443X_CTRL_BASE), .prm = OMAP2_IO_ADDRESS(OMAP4430_PRM_BASE), .cm = OMAP2_IO_ADDRESS(OMAP4430_CM_BASE), + .cm2 = OMAP2_IO_ADDRESS(OMAP4430_CM2_BASE), }; void __init omap2_set_globals_443x(void) diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c index afba7af9da90..04f43d5ee8cb 100755 --- a/arch/arm/plat-omap/devices.c +++ b/arch/arm/plat-omap/devices.c @@ -384,6 +384,31 @@ static void omap_init_rng(void) static inline void omap_init_rng(void) {} #endif +#if defined(CONFIG_VIDEO_OMAP_VIDEOOUT) || \ + defined(CONFIG_VIDEO_OMAP_VIDEOOUT_MODULE) +#ifdef CONFIG_FB_OMAP2 +static struct resource sdp4430_vout_resource[3 - CONFIG_FB_OMAP2_NUM_FBS] = { +}; +#else +static struct resource sdp4430_vout_resource[2] = { +}; +#endif + +static struct platform_device sdp4430_vout_device = { + .name = "omap_vout", + .num_resources = ARRAY_SIZE(sdp4430_vout_resource), + .resource = &sdp4430_vout_resource[0], + .id = -1, +}; + +static void omap_init_vout(void) +{ + (void) platform_device_register(&sdp4430_vout_device); +} +#else +static inline void omap_init_vout(void) {} +#endif + /* * This gets called after board-specific INIT_MACHINE, and initializes most * on-chip peripherals accessible on this board (except for few like USB): @@ -414,6 +439,7 @@ static int __init omap_init_devices(void) omap_init_uwire(); omap_init_wdt(); omap_init_rng(); + omap_init_vout(); return 0; } arch_initcall(omap_init_devices); diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c index 3746222bed10..1dc34154d794 100644 --- a/arch/arm/plat-omap/fb.c +++ b/arch/arm/plat-omap/fb.c @@ -28,13 +28,13 @@ #include <linux/platform_device.h> #include <linux/bootmem.h> #include <linux/io.h> +#include <linux/omapfb.h> #include <mach/hardware.h> #include <asm/mach/map.h> #include <mach/board.h> #include <mach/sram.h> -#include <mach/omapfb.h> #if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE) @@ -327,6 +327,34 @@ static inline int omap_init_fb(void) arch_initcall(omap_init_fb); +#elif defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE) + +static u64 omap_fb_dma_mask = ~(u32)0; +static struct omapfb_platform_data omapfb_config; + +static struct platform_device omap_fb_device = { + .name = "omapfb", + .id = -1, + .dev = { + .dma_mask = &omap_fb_dma_mask, + .coherent_dma_mask = ~(u32)0, + .platform_data = &omapfb_config, + }, + .num_resources = 0, +}; + +void omapfb_set_platform_data(struct omapfb_platform_data *data) +{ + omapfb_config = *data; +} + +static inline int omap_init_fb(void) +{ + return platform_device_register(&omap_fb_device); +} + +arch_initcall(omap_init_fb); + #else void omapfb_reserve_sdram(void) {} diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 26b387c12423..bec76cf618df 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -115,28 +115,65 @@ #define OMAP24XX_GPIO_REVISION 0x0000 #define OMAP24XX_GPIO_SYSCONFIG 0x0010 -#define OMAP24XX_GPIO_SYSSTATUS 0x0014 -#define OMAP24XX_GPIO_IRQSTATUS1 0x0018 -#define OMAP24XX_GPIO_IRQSTATUS2 0x0028 -#define OMAP24XX_GPIO_IRQENABLE2 0x002c -#define OMAP24XX_GPIO_IRQENABLE1 0x001c -#define OMAP24XX_GPIO_WAKE_EN 0x0020 -#define OMAP24XX_GPIO_CTRL 0x0030 -#define OMAP24XX_GPIO_OE 0x0034 -#define OMAP24XX_GPIO_DATAIN 0x0038 -#define OMAP24XX_GPIO_DATAOUT 0x003c -#define OMAP24XX_GPIO_LEVELDETECT0 0x0040 -#define OMAP24XX_GPIO_LEVELDETECT1 0x0044 -#define OMAP24XX_GPIO_RISINGDETECT 0x0048 -#define OMAP24XX_GPIO_FALLINGDETECT 0x004c -#define OMAP24XX_GPIO_DEBOUNCE_EN 0x0050 -#define OMAP24XX_GPIO_DEBOUNCE_VAL 0x0054 -#define OMAP24XX_GPIO_CLEARIRQENABLE1 0x0060 -#define OMAP24XX_GPIO_SETIRQENABLE1 0x0064 -#define OMAP24XX_GPIO_CLEARWKUENA 0x0080 -#define OMAP24XX_GPIO_SETWKUENA 0x0084 -#define OMAP24XX_GPIO_CLEARDATAOUT 0x0090 -#define OMAP24XX_GPIO_SETDATAOUT 0x0094 + +#ifdef CONFIG_ARCH_OMAP4 +#define OMAP24XX_GPIO_SYSSTATUS 0x0114 +#define OMAP24XX_GPIO_IRQSTATUS1 0x0118 +#define OMAP24XX_GPIO_IRQSTATUS2 0x0128 +#define OMAP24XX_GPIO_IRQENABLE2 0x012c +#define OMAP24XX_GPIO_IRQENABLE1 0x011c +#define OMAP24XX_GPIO_WAKE_EN 0x0120 +#define OMAP24XX_GPIO_CTRL 0x0130 +#define OMAP24XX_GPIO_OE 0x0134 +#define OMAP24XX_GPIO_DATAIN 0x0138 +#define OMAP24XX_GPIO_DATAOUT 0x013c +#define OMAP24XX_GPIO_LEVELDETECT0 0x0140 +#define OMAP24XX_GPIO_LEVELDETECT1 0x0144 +#define OMAP24XX_GPIO_RISINGDETECT 0x0148 +#define OMAP24XX_GPIO_FALLINGDETECT 0x014c +#define OMAP24XX_GPIO_DEBOUNCE_EN 0x0150 +#define OMAP24XX_GPIO_DEBOUNCE_VAL 0x0154 +#define OMAP24XX_GPIO_CLEARIRQENABLE1 0x0160 +#define OMAP24XX_GPIO_SETIRQENABLE1 0x0164 +#define OMAP24XX_GPIO_CLEARWKUENA 0x0180 +#define OMAP24XX_GPIO_SETWKUENA 0x0184 +#define OMAP24XX_GPIO_CLEARDATAOUT 0x0190 +#define OMAP24XX_GPIO_SETDATAOUT 0x0194 +#define OMAP24XX_GPIO_STATUS_RAW_0 0x0024 +#define OMAP24XX_GPIO_STATUS_RAW_1 0x0028 +#define OMAP24XX_GPIO_IRQ_STATUS_0 0x002C +#define OMAP24XX_GPIO_IRQ_STATUS_1 0x0030 +#define OMAP24XX_GPIO_IRQ_STATUS_SET_0 0x0034 +#define OMAP24XX_GPIO_IRQ_STATUS_SET_1 0x0038 +#define OMAP24XX_GPIO_IRQ_STATUS_CLR_0 0x003C +#define OMAP24XX_GPIO_IRQ_STATUS_CLR_1 0x0040 +#define OMAP24XX_GPIO_IRQ_WAKE_ENABLE_0 0x0044 +#define OMAP24XX_GPIO_IRQ_WAKE_ENABLE_1 0x0048 + +#else +#define OMAP24XX_GPIO_SYSSTATUS 0x0014 +#define OMAP24XX_GPIO_IRQSTATUS1 0x0018 +#define OMAP24XX_GPIO_IRQSTATUS2 0x0028 +#define OMAP24XX_GPIO_IRQENABLE2 0x002c +#define OMAP24XX_GPIO_IRQENABLE1 0x001c +#define OMAP24XX_GPIO_WAKE_EN 0x0020 +#define OMAP24XX_GPIO_CTRL 0x0030 +#define OMAP24XX_GPIO_OE 0x0034 +#define OMAP24XX_GPIO_DATAIN 0x0038 +#define OMAP24XX_GPIO_DATAOUT 0x003c +#define OMAP24XX_GPIO_LEVELDETECT0 0x0040 +#define OMAP24XX_GPIO_LEVELDETECT1 0x0044 +#define OMAP24XX_GPIO_RISINGDETECT 0x0048 +#define OMAP24XX_GPIO_FALLINGDETECT 0x004c +#define OMAP24XX_GPIO_DEBOUNCE_EN 0x0050 +#define OMAP24XX_GPIO_DEBOUNCE_VAL 0x0054 +#define OMAP24XX_GPIO_CLEARIRQENABLE1 0x0060 +#define OMAP24XX_GPIO_SETIRQENABLE1 0x0064 +#define OMAP24XX_GPIO_CLEARWKUENA 0x0080 +#define OMAP24XX_GPIO_SETWKUENA 0x0084 +#define OMAP24XX_GPIO_CLEARDATAOUT 0x0090 +#define OMAP24XX_GPIO_SETDATAOUT 0x0094 +#endif /* * omap34xx specific GPIO registers @@ -784,11 +821,16 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) break; #endif #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ - defined(CONFIG_ARCH_OMAP4) +defined(CONFIG_ARCH_OMAP4) case METHOD_GPIO_24XX: + #ifdef CONFIG_ARCH_OMAP4 + reg += OMAP24XX_GPIO_IRQ_STATUS_0; + #else reg += OMAP24XX_GPIO_IRQSTATUS1; + #endif break; #endif + default: WARN_ON(1); return; @@ -796,14 +838,20 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) __raw_writel(gpio_mask, reg); /* Workaround for clearing DSP GPIO interrupts to allow retention */ -#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) +#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ +defined(CONFIG_ARCH_OMAP4) +#ifdef CONFIG_ARCH_OMAP4 + reg = bank->base + OMAP24XX_GPIO_IRQ_STATUS_1; +#else reg = bank->base + OMAP24XX_GPIO_IRQSTATUS2; - if (cpu_is_omap24xx() || cpu_is_omap34xx()) +#endif + if (cpu_is_omap24xx() || cpu_is_omap34xx() || cpu_is_omap44xx()) __raw_writel(gpio_mask, reg); /* Flush posted write for the irq status to avoid spurious interrupts */ __raw_readl(reg); #endif + } static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio) @@ -856,7 +904,11 @@ static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank) #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ defined(CONFIG_ARCH_OMAP4) case METHOD_GPIO_24XX: +#ifdef CONFIG_ARCH_OMAP4 + reg += OMAP24XX_GPIO_IRQ_STATUS_SET_0; +#else reg += OMAP24XX_GPIO_IRQENABLE1; +#endif mask = 0xffffffff; break; #endif @@ -1115,7 +1167,11 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ defined(CONFIG_ARCH_OMAP4) if (bank->method == METHOD_GPIO_24XX) + #ifdef CONFIG_ARCH_OMAP4 + isr_reg = bank->base + OMAP24XX_GPIO_IRQ_STATUS_0; + #else isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1; + #endif #endif while(1) { u32 isr_saved, level_mask = 0; @@ -1464,14 +1520,21 @@ static int __init _omap_gpio_init(void) #endif #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) + /* + * FIX-ME: Replace with correct clk node when clk + * framework is available + */ if (cpu_is_omap34xx() || cpu_is_omap44xx()) { - for (i = 0; i < OMAP34XX_NR_GPIOS; i++) { - sprintf(clk_name, "gpio%d_ick", i + 1); - gpio_iclks[i] = clk_get(NULL, clk_name); - if (IS_ERR(gpio_iclks[i])) - printk(KERN_ERR "Could not get %s\n", clk_name); - else - clk_enable(gpio_iclks[i]); + if (!cpu_is_omap44xx()) { + for (i = 0; i < OMAP34XX_NR_GPIOS; i++) { + sprintf(clk_name, "gpio%d_ick", i + 1); + gpio_iclks[i] = clk_get(NULL, clk_name); + if (IS_ERR(gpio_iclks[i])) + printk(KERN_ERR "Could not get %s\n", + clk_name); + else + clk_enable(gpio_iclks[i]); + } } } #endif @@ -1581,9 +1644,17 @@ static int __init _omap_gpio_init(void) static const u32 non_wakeup_gpios[] = { 0xe203ffc0, 0x08700040 }; - - __raw_writel(0x00000000, bank->base + OMAP24XX_GPIO_IRQENABLE1); - __raw_writel(0xffffffff, bank->base + OMAP24XX_GPIO_IRQSTATUS1); +#ifdef CONFIG_ARCH_OMAP4 + __raw_writel(0x00000000, bank->base + + OMAP24XX_GPIO_IRQ_STATUS_CLR_0); + __raw_writel(0xffffffff, bank->base + + OMAP24XX_GPIO_IRQ_STATUS_0); +#else + __raw_writel(0x00000000, bank->base + + OMAP24XX_GPIO_IRQENABLE1); + __raw_writel(0xffffffff, bank->base + + OMAP24XX_GPIO_IRQSTATUS1); +#endif __raw_writew(0x0015, bank->base + OMAP24XX_GPIO_SYSCONFIG); __raw_writel(0x00000000, bank->base + OMAP24XX_GPIO_DEBOUNCE_EN); @@ -1633,12 +1704,18 @@ static int __init _omap_gpio_init(void) } set_irq_chained_handler(bank->irq, gpio_irq_handler); set_irq_data(bank->irq, bank); - + /* + * FIX-ME: Replace with correct clk node when clk + * framework is available + */ if (cpu_is_omap34xx() || cpu_is_omap44xx()) { - sprintf(clk_name, "gpio%d_dbck", i + 1); - bank->dbck = clk_get(NULL, clk_name); - if (IS_ERR(bank->dbck)) - printk(KERN_ERR "Could not get %s\n", clk_name); + if (!cpu_is_omap44xx()) { + sprintf(clk_name, "gpio%d_dbck", i + 1); + bank->dbck = clk_get(NULL, clk_name); + if (IS_ERR(bank->dbck)) + printk(KERN_ERR "Could not get %s\n", + clk_name); + } } } diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c index 8b848391f0c8..778e591f6112 100644 --- a/arch/arm/plat-omap/i2c.c +++ b/arch/arm/plat-omap/i2c.c @@ -53,9 +53,15 @@ static struct resource i2c_resources[][2] = { #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) { I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE2, INT_24XX_I2C2_IRQ) }, #endif +#if defined(CONFIG_ARCH_OMAP4) + { I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE2, INT_44XX_I2C2_IRQ) }, +#endif #if defined(CONFIG_ARCH_OMAP34XX) { I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE3, INT_34XX_I2C3_IRQ) }, #endif +#if defined(CONFIG_ARCH_OMAP4) + { I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE3, INT_44XX_I2C3_IRQ) }, +#endif }; #define I2C_DEV_BUILDER(bus_id, res, data) \ @@ -72,10 +78,11 @@ static struct resource i2c_resources[][2] = { static u32 i2c_rate[ARRAY_SIZE(i2c_resources)]; static struct platform_device omap_i2c_devices[] = { I2C_DEV_BUILDER(1, i2c_resources[0], &i2c_rate[0]), -#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) +#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ +defined(CONFIG_ARCH_OMAP4) I2C_DEV_BUILDER(2, i2c_resources[1], &i2c_rate[1]), #endif -#if defined(CONFIG_ARCH_OMAP34XX) +#if defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP4) I2C_DEV_BUILDER(3, i2c_resources[2], &i2c_rate[2]), #endif }; @@ -88,7 +95,7 @@ static const int omap24xx_pins[][2] = { #else static const int omap24xx_pins[][2] = {}; #endif -#if defined(CONFIG_ARCH_OMAP34XX) +#if defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP4) static const int omap34xx_pins[][2] = { { K21_34XX_I2C1_SCL, J21_34XX_I2C1_SDA}, { AF15_34XX_I2C2_SCL, AE15_34XX_I2C2_SDA}, @@ -110,7 +117,7 @@ static void __init omap_i2c_mux_pins(int bus) } else if (cpu_is_omap24xx()) { scl = omap24xx_pins[bus][0]; sda = omap24xx_pins[bus][1]; - } else if (cpu_is_omap34xx()) { + } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) { scl = omap34xx_pins[bus][0]; sda = omap34xx_pins[bus][1]; } else { @@ -129,7 +136,7 @@ static int __init omap_i2c_nr_ports(void) ports = 1; else if (cpu_is_omap24xx()) ports = 2; - else if (cpu_is_omap34xx()) + else if (cpu_is_omap34xx() || cpu_is_omap44xx()) ports = 3; return ports; @@ -151,6 +158,10 @@ static int __init omap_i2c_add_bus(int bus_id) base = OMAP2_I2C_BASE1; irq = INT_24XX_I2C1_IRQ; } + if (cpu_is_omap44xx()) { + base = OMAP2_I2C_BASE1; + irq = INT_44XX_I2C1_IRQ; + } res[0].start = base; res[0].end = base + OMAP_I2C_SIZE; res[1].start = irq; diff --git a/arch/arm/plat-omap/include/mach/clock.h b/arch/arm/plat-omap/include/mach/clock.h index f9f65e1ba3f1..e0cac22fd4cc 100644 --- a/arch/arm/plat-omap/include/mach/clock.h +++ b/arch/arm/plat-omap/include/mach/clock.h @@ -63,6 +63,10 @@ struct dpll_data { u8 recal_en_bit; u8 recal_st_bit; # endif + +#if defined(CONFIG_ARCH_OMAP4) + struct clk *clk_hsd_bypass; +#endif }; #endif @@ -154,6 +158,7 @@ extern const struct clkops clkops_null; #define RATE_IN_243X (1 << 2) #define RATE_IN_343X (1 << 3) /* rates common to all 343X */ #define RATE_IN_3430ES2 (1 << 4) /* 3430ES2 rates only */ +#define RATE_IN_443X (1 << 5) #define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X) diff --git a/arch/arm/plat-omap/include/mach/common.h b/arch/arm/plat-omap/include/mach/common.h index fdeab421b4dc..878c4f96c2d3 100644 --- a/arch/arm/plat-omap/include/mach/common.h +++ b/arch/arm/plat-omap/include/mach/common.h @@ -55,6 +55,7 @@ struct omap_globals { void __iomem *ctrl; /* System Control Module */ void __iomem *prm; /* Power and Reset Management */ void __iomem *cm; /* Clock Management */ + void __iomem *cm2; }; void omap2_set_globals_242x(void); diff --git a/arch/arm/plat-omap/include/mach/control.h b/arch/arm/plat-omap/include/mach/control.h index 8140dbccb7bc..e97a15c95ea8 100644 --- a/arch/arm/plat-omap/include/mach/control.h +++ b/arch/arm/plat-omap/include/mach/control.h @@ -25,10 +25,13 @@ IO_ADDRESS(OMAP243X_CTRL_BASE + (reg)) #define OMAP343X_CTRL_REGADDR(reg) \ IO_ADDRESS(OMAP343X_CTRL_BASE + (reg)) +#define OMAP44XX_CTRL_REGADDR(reg) \ + IO_ADDRESS(OMAP44XX_CTRL_BASE + (reg)) #else #define OMAP242X_CTRL_REGADDR(reg) IO_ADDRESS(OMAP242X_CTRL_BASE + (reg)) #define OMAP243X_CTRL_REGADDR(reg) IO_ADDRESS(OMAP243X_CTRL_BASE + (reg)) #define OMAP343X_CTRL_REGADDR(reg) IO_ADDRESS(OMAP343X_CTRL_BASE + (reg)) +#define OMAP44XX_CTRL_REGADDR(reg) IO_ADDRESS(OMAP44XX_CTRL_BASE + (reg)) #endif /* __ASSEMBLY__ */ /* diff --git a/arch/arm/plat-omap/include/mach/display.h b/arch/arm/plat-omap/include/mach/display.h new file mode 100644 index 000000000000..70fa053d8fd6 --- /dev/null +++ b/arch/arm/plat-omap/include/mach/display.h @@ -0,0 +1,541 @@ +/* + * linux/include/asm-arm/arch-omap/display.h + * + * Copyright (C) 2008 Nokia Corporation + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __ASM_ARCH_OMAP_DISPLAY_H +#define __ASM_ARCH_OMAP_DISPLAY_H + +#include <linux/list.h> +#include <linux/kobject.h> +#include <linux/device.h> +#include <asm/atomic.h> + +#define DISPC_IRQ_FRAMEDONE (1 << 0) +#define DISPC_IRQ_VSYNC (1 << 1) +#define DISPC_IRQ_EVSYNC_EVEN (1 << 2) +#define DISPC_IRQ_EVSYNC_ODD (1 << 3) +#define DISPC_IRQ_ACBIAS_COUNT_STAT (1 << 4) +#define DISPC_IRQ_PROG_LINE_NUM (1 << 5) +#define DISPC_IRQ_GFX_FIFO_UNDERFLOW (1 << 6) +#define DISPC_IRQ_GFX_END_WIN (1 << 7) +#define DISPC_IRQ_PAL_GAMMA_MASK (1 << 8) +#define DISPC_IRQ_OCP_ERR (1 << 9) +#define DISPC_IRQ_VID1_FIFO_UNDERFLOW (1 << 10) +#define DISPC_IRQ_VID1_END_WIN (1 << 11) +#define DISPC_IRQ_VID2_FIFO_UNDERFLOW (1 << 12) +#define DISPC_IRQ_VID2_END_WIN (1 << 13) +#define DISPC_IRQ_SYNC_LOST (1 << 14) +#define DISPC_IRQ_SYNC_LOST_DIGIT (1 << 15) +#define DISPC_IRQ_WAKEUP (1 << 16) + +struct omap_dss_device; +struct omap_overlay_manager; + +enum omap_display_type { + OMAP_DISPLAY_TYPE_NONE = 0, + OMAP_DISPLAY_TYPE_DPI = 1 << 0, + OMAP_DISPLAY_TYPE_DBI = 1 << 1, + OMAP_DISPLAY_TYPE_SDI = 1 << 2, + OMAP_DISPLAY_TYPE_DSI = 1 << 3, + OMAP_DISPLAY_TYPE_VENC = 1 << 4, +}; + +enum omap_plane { + OMAP_DSS_GFX = 0, + OMAP_DSS_VIDEO1 = 1, + OMAP_DSS_VIDEO2 = 2 +}; + +enum omap_channel { + OMAP_DSS_CHANNEL_LCD = 0, + OMAP_DSS_CHANNEL_DIGIT = 1, +}; + +enum omap_color_mode { + OMAP_DSS_COLOR_CLUT1 = 1 << 0, /* BITMAP 1 */ + OMAP_DSS_COLOR_CLUT2 = 1 << 1, /* BITMAP 2 */ + OMAP_DSS_COLOR_CLUT4 = 1 << 2, /* BITMAP 4 */ + OMAP_DSS_COLOR_CLUT8 = 1 << 3, /* BITMAP 8 */ + OMAP_DSS_COLOR_RGB12U = 1 << 4, /* RGB12, 16-bit container */ + OMAP_DSS_COLOR_ARGB16 = 1 << 5, /* ARGB16 */ + OMAP_DSS_COLOR_RGB16 = 1 << 6, /* RGB16 */ + OMAP_DSS_COLOR_RGB24U = 1 << 7, /* RGB24, 32-bit container */ + OMAP_DSS_COLOR_RGB24P = 1 << 8, /* RGB24, 24-bit container */ + OMAP_DSS_COLOR_YUV2 = 1 << 9, /* YUV2 4:2:2 co-sited */ + OMAP_DSS_COLOR_UYVY = 1 << 10, /* UYVY 4:2:2 co-sited */ + OMAP_DSS_COLOR_ARGB32 = 1 << 11, /* ARGB32 */ + OMAP_DSS_COLOR_RGBA32 = 1 << 12, /* RGBA32 */ + OMAP_DSS_COLOR_RGBX32 = 1 << 13, /* RGBx32 */ + + OMAP_DSS_COLOR_GFX_OMAP3 = + OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 | + OMAP_DSS_COLOR_CLUT4 | OMAP_DSS_COLOR_CLUT8 | + OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_ARGB16 | + OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U | + OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_ARGB32 | + OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32, + + OMAP_DSS_COLOR_VID_OMAP3 = + OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_ARGB16 | + OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U | + OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_ARGB32 | + OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32 | + OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_UYVY, +}; + +enum omap_lcd_display_type { + OMAP_DSS_LCD_DISPLAY_STN, + OMAP_DSS_LCD_DISPLAY_TFT, +}; + +enum omap_dss_load_mode { + OMAP_DSS_LOAD_CLUT_AND_FRAME = 0, + OMAP_DSS_LOAD_CLUT_ONLY = 1, + OMAP_DSS_LOAD_FRAME_ONLY = 2, + OMAP_DSS_LOAD_CLUT_ONCE_FRAME = 3, +}; + +enum omap_dss_trans_key_type { + OMAP_DSS_COLOR_KEY_GFX_DST = 0, + OMAP_DSS_COLOR_KEY_VID_SRC = 1, +}; + +enum omap_rfbi_te_mode { + OMAP_DSS_RFBI_TE_MODE_1 = 1, + OMAP_DSS_RFBI_TE_MODE_2 = 2, +}; + +enum omap_panel_config { + OMAP_DSS_LCD_IVS = 1<<0, + OMAP_DSS_LCD_IHS = 1<<1, + OMAP_DSS_LCD_IPC = 1<<2, + OMAP_DSS_LCD_IEO = 1<<3, + OMAP_DSS_LCD_RF = 1<<4, + OMAP_DSS_LCD_ONOFF = 1<<5, + + OMAP_DSS_LCD_TFT = 1<<20, +}; + +enum omap_dss_venc_type { + OMAP_DSS_VENC_TYPE_COMPOSITE, + OMAP_DSS_VENC_TYPE_SVIDEO, +}; + +enum omap_display_caps { + OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE = 1 << 0, +}; + +enum omap_dss_update_mode { + OMAP_DSS_UPDATE_DISABLED = 0, + OMAP_DSS_UPDATE_AUTO, + OMAP_DSS_UPDATE_MANUAL, +}; + +enum omap_dss_display_state { + OMAP_DSS_DISPLAY_DISABLED = 0, + OMAP_DSS_DISPLAY_ACTIVE, + OMAP_DSS_DISPLAY_SUSPENDED, +}; + +/* XXX perhaps this should be removed */ +enum omap_dss_overlay_managers { + OMAP_DSS_OVL_MGR_LCD, + OMAP_DSS_OVL_MGR_TV, +}; + +enum omap_dss_rotation_type { + OMAP_DSS_ROT_DMA = 0, + OMAP_DSS_ROT_VRFB = 1, +}; + +enum omap_overlay_caps { + OMAP_DSS_OVL_CAP_SCALE = 1 << 0, + OMAP_DSS_OVL_CAP_DISPC = 1 << 1, +}; + +enum omap_overlay_manager_caps { + OMAP_DSS_OVL_MGR_CAP_DISPC = 1 << 0, +}; + +/* RFBI */ + +struct rfbi_timings { + int cs_on_time; + int cs_off_time; + int we_on_time; + int we_off_time; + int re_on_time; + int re_off_time; + int we_cycle_time; + int re_cycle_time; + int cs_pulse_width; + int access_time; + + int clk_div; + + u32 tim[5]; /* set by rfbi_convert_timings() */ + + int converted; +}; + +void omap_rfbi_write_command(const void *buf, u32 len); +void omap_rfbi_read_data(void *buf, u32 len); +void omap_rfbi_write_data(const void *buf, u32 len); +void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width, + u16 x, u16 y, + u16 w, u16 h); +int omap_rfbi_enable_te(bool enable, unsigned line); +int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode, + unsigned hs_pulse_time, unsigned vs_pulse_time, + int hs_pol_inv, int vs_pol_inv, int extif_div); + +/* DSI */ +void dsi_bus_lock(void); +void dsi_bus_unlock(void); +int dsi_vc_dcs_write(int channel, u8 *data, int len); +int dsi_vc_dcs_write_nosync(int channel, u8 *data, int len); +int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen); +int dsi_vc_set_max_rx_packet_size(int channel, u16 len); +int dsi_vc_send_null(int channel); + +/* Board specific data */ +struct omap_dss_board_info { + int (*get_last_off_on_transaction_id)(struct device *dev); + int num_devices; + struct omap_dss_device **devices; + struct omap_dss_device *default_device; +}; + +struct omap_video_timings { + /* Unit: pixels */ + u16 x_res; + /* Unit: pixels */ + u16 y_res; + /* Unit: KHz */ + u32 pixel_clock; + /* Unit: pixel clocks */ + u16 hsw; /* Horizontal synchronization pulse width */ + /* Unit: pixel clocks */ + u16 hfp; /* Horizontal front porch */ + /* Unit: pixel clocks */ + u16 hbp; /* Horizontal back porch */ + /* Unit: line clocks */ + u16 vsw; /* Vertical synchronization pulse width */ + /* Unit: line clocks */ + u16 vfp; /* Vertical front porch */ + /* Unit: line clocks */ + u16 vbp; /* Vertical back porch */ +}; + +#ifdef CONFIG_OMAP2_DSS_VENC +/* Hardcoded timings for tv modes. Venc only uses these to + * identify the mode, and does not actually use the configs + * itself. However, the configs should be something that + * a normal monitor can also show */ +const extern struct omap_video_timings omap_dss_pal_timings; +const extern struct omap_video_timings omap_dss_ntsc_timings; +#endif + +struct omap_overlay_info { + bool enabled; + + u32 paddr; + void __iomem *vaddr; + u16 screen_width; + u16 width; + u16 height; + enum omap_color_mode color_mode; + u8 rotation; + enum omap_dss_rotation_type rotation_type; + bool mirror; + + u16 pos_x; + u16 pos_y; + u16 out_width; /* if 0, out_width == width */ + u16 out_height; /* if 0, out_height == height */ + u8 global_alpha; +}; + +struct omap_overlay { + struct kobject kobj; + struct list_head list; + + /* static fields */ + const char *name; + int id; + enum omap_color_mode supported_modes; + enum omap_overlay_caps caps; + + /* dynamic fields */ + struct omap_overlay_manager *manager; + struct omap_overlay_info info; + + /* if true, info has been changed, but not applied() yet */ + bool info_dirty; + + int (*set_manager)(struct omap_overlay *ovl, + struct omap_overlay_manager *mgr); + int (*unset_manager)(struct omap_overlay *ovl); + + int (*set_overlay_info)(struct omap_overlay *ovl, + struct omap_overlay_info *info); + void (*get_overlay_info)(struct omap_overlay *ovl, + struct omap_overlay_info *info); + + int (*wait_for_go)(struct omap_overlay *ovl); +}; + +struct omap_overlay_manager_info { + u32 default_color; + + enum omap_dss_trans_key_type trans_key_type; + u32 trans_key; + bool trans_enabled; + + bool alpha_enabled; +}; + +struct omap_overlay_manager { + struct kobject kobj; + struct list_head list; + + /* static fields */ + const char *name; + int id; + enum omap_overlay_manager_caps caps; + int num_overlays; + struct omap_overlay **overlays; + enum omap_display_type supported_displays; + + /* dynamic fields */ + struct omap_dss_device *device; + struct omap_overlay_manager_info info; + + bool device_changed; + /* if true, info has been changed but not applied() yet */ + bool info_dirty; + + int (*set_device)(struct omap_overlay_manager *mgr, + struct omap_dss_device *dssdev); + int (*unset_device)(struct omap_overlay_manager *mgr); + + int (*set_manager_info)(struct omap_overlay_manager *mgr, + struct omap_overlay_manager_info *info); + void (*get_manager_info)(struct omap_overlay_manager *mgr, + struct omap_overlay_manager_info *info); + + int (*apply)(struct omap_overlay_manager *mgr); + int (*wait_for_go)(struct omap_overlay_manager *mgr); +}; + +struct omap_dss_device { + struct device dev; + + enum omap_display_type type; + + union { + struct { + u8 data_lines; + } dpi; + + struct { + u8 channel; + u8 data_lines; + } rfbi; + + struct { + u8 datapairs; + unsigned pad_off_pe:1; /* pull pads if disabled */ + unsigned pad_off_pu:1; /* pull up */ + } sdi; + + struct { + u8 clk_lane; + u8 clk_pol; + u8 data1_lane; + u8 data1_pol; + u8 data2_lane; + u8 data2_pol; + unsigned long lp_clk_hz; + unsigned long ddr_clk_hz; + + bool ext_te; + u8 ext_te_gpio; + } dsi; + + struct { + enum omap_dss_venc_type type; + } venc; + } phy; + + struct { + struct omap_video_timings timings; + + int acbi; /* ac-bias pin transitions per interrupt */ + /* Unit: line clocks */ + int acb; /* ac-bias pin frequency */ + + enum omap_panel_config config; + + u8 recommended_bpp; + + struct omap_dss_device *ctrl; + } panel; + + struct { + u8 pixel_size; + struct rfbi_timings rfbi_timings; + struct omap_dss_device *panel; + } ctrl; + + int reset_gpio; + + int max_backlight_level; + + const char *name; + + /* used to match device to driver */ + const char *driver_name; + + void *data; + + struct omap_dss_driver *driver; + + /* helper variable for driver suspend/resume */ + bool activate_after_resume; + + enum omap_display_caps caps; + + struct omap_overlay_manager *manager; + + enum omap_dss_display_state state; + + int (*enable)(struct omap_dss_device *dssdev); + void (*disable)(struct omap_dss_device *dssdev); + + int (*suspend)(struct omap_dss_device *dssdev); + int (*resume)(struct omap_dss_device *dssdev); + + void (*get_resolution)(struct omap_dss_device *dssdev, + u16 *xres, u16 *yres); + int (*get_recommended_bpp)(struct omap_dss_device *dssdev); + + int (*check_timings)(struct omap_dss_device *dssdev, + struct omap_video_timings *timings); + void (*set_timings)(struct omap_dss_device *dssdev, + struct omap_video_timings *timings); + void (*get_timings)(struct omap_dss_device *dssdev, + struct omap_video_timings *timings); + int (*update)(struct omap_dss_device *dssdev, + u16 x, u16 y, u16 w, u16 h); + int (*sync)(struct omap_dss_device *dssdev); + int (*wait_vsync)(struct omap_dss_device *dssdev); + + int (*set_update_mode)(struct omap_dss_device *dssdev, + enum omap_dss_update_mode); + enum omap_dss_update_mode (*get_update_mode) + (struct omap_dss_device *dssdev); + + int (*enable_te)(struct omap_dss_device *dssdev, bool enable); + int (*get_te)(struct omap_dss_device *dssdev); + int (*wait_for_te)(struct omap_dss_device *dssdev); + + u8 (*get_rotate)(struct omap_dss_device *dssdev); + int (*set_rotate)(struct omap_dss_device *dssdev, u8 rotate); + + bool (*get_mirror)(struct omap_dss_device *dssdev); + int (*set_mirror)(struct omap_dss_device *dssdev, bool enable); + + int (*run_test)(struct omap_dss_device *dssdev, int test); + int (*memory_read)(struct omap_dss_device *dssdev, + void *buf, size_t size, + u16 x, u16 y, u16 w, u16 h); + + int (*set_wss)(struct omap_dss_device *dssdev, u32 wss); + u32 (*get_wss)(struct omap_dss_device *dssdev); + + /* platform specific */ + int (*platform_enable)(struct omap_dss_device *dssdev); + void (*platform_disable)(struct omap_dss_device *dssdev); + int (*set_backlight)(struct omap_dss_device *dssdev, int level); + int (*get_backlight)(struct omap_dss_device *dssdev); +}; + +struct omap_dss_driver { + struct device_driver driver; + + int (*probe)(struct omap_dss_device *); + void (*remove)(struct omap_dss_device *); + + int (*enable)(struct omap_dss_device *display); + void (*disable)(struct omap_dss_device *display); + int (*suspend)(struct omap_dss_device *display); + int (*resume)(struct omap_dss_device *display); + int (*run_test)(struct omap_dss_device *display, int test); + + void (*setup_update)(struct omap_dss_device *dssdev, + u16 x, u16 y, u16 w, u16 h); + + int (*enable_te)(struct omap_dss_device *dssdev, bool enable); + int (*wait_for_te)(struct omap_dss_device *dssdev); + + u8 (*get_rotate)(struct omap_dss_device *dssdev); + int (*set_rotate)(struct omap_dss_device *dssdev, u8 rotate); + + bool (*get_mirror)(struct omap_dss_device *dssdev); + int (*set_mirror)(struct omap_dss_device *dssdev, bool enable); + + int (*memory_read)(struct omap_dss_device *dssdev, + void *buf, size_t size, + u16 x, u16 y, u16 w, u16 h); +}; + +int omap_dss_register_driver(struct omap_dss_driver *); +void omap_dss_unregister_driver(struct omap_dss_driver *); + +int omap_dss_register_device(struct omap_dss_device *); +void omap_dss_unregister_device(struct omap_dss_device *); + +void omap_dss_get_device(struct omap_dss_device *dssdev); +void omap_dss_put_device(struct omap_dss_device *dssdev); +#define for_each_dss_dev(d) while ((d = omap_dss_get_next_device(d)) != NULL) +struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from); +struct omap_dss_device *omap_dss_find_device(void *data, + int (*match)(struct omap_dss_device *dssdev, void *data)); + +int omap_dss_start_device(struct omap_dss_device *dssdev); +void omap_dss_stop_device(struct omap_dss_device *dssdev); + +int omap_dss_get_num_overlay_managers(void); +struct omap_overlay_manager *omap_dss_get_overlay_manager(int num); + +int omap_dss_get_num_overlays(void); +struct omap_overlay *omap_dss_get_overlay(int num); + +typedef void (*omap_dispc_isr_t) (void *arg, u32 mask); +int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask); +int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask); + +int omap_dispc_wait_for_irq_timeout(u32 irqmask, unsigned long timeout); +int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask, + unsigned long timeout); + +#define to_dss_driver(x) container_of((x), struct omap_dss_driver, driver) +#define to_dss_device(x) container_of((x), struct omap_dss_device, dev) + +#endif diff --git a/arch/arm/plat-omap/include/mach/dma.h b/arch/arm/plat-omap/include/mach/dma.h index 923cf213f316..866e37eb8474 100755 --- a/arch/arm/plat-omap/include/mach/dma.h +++ b/arch/arm/plat-omap/include/mach/dma.h @@ -335,6 +335,7 @@ #define OMAP44XX_DMA_UART4_DMA_TX 55 /* S_DMA_54 */ #define OMAP44XX_DMA_UART4_DMA_RX 56 /* S_DMA_55 */ #define OMAP44XX_DMA_MMC4_DMA_TX 57 /* S_DMA_56 */ +#define OMAP44XX_DMA_MMC4_DMA_RX 58 /* S_DMA_57 */ #define OMAP44XX_DMA_MMC5_DMA_TX 59 /* S_DMA_58 */ #define OMAP44XX_DMA_MMC5_DMA_RX 60 /* S_DMA_59 */ #define OMAP44XX_DMA_MCPDM_UP 65 /* S_DMA_64 */ diff --git a/arch/arm/plat-omap/include/mach/irqs.h b/arch/arm/plat-omap/include/mach/irqs.h index 34b6d09c1413..8725136695c5 100644 --- a/arch/arm/plat-omap/include/mach/irqs.h +++ b/arch/arm/plat-omap/include/mach/irqs.h @@ -503,6 +503,7 @@ #define INT_44XX_FPKA_READY_IRQ (50 + IRQ_GIC_START) #define INT_44XX_SHA1MD51_IRQ (51 + IRQ_GIC_START) #define INT_44XX_RNG_IRQ (52 + IRQ_GIC_START) +#define INT_44XX_MMC5_IRQ (59 + IRQ_GIC_START) #define INT_44XX_I2C3_IRQ (61 + IRQ_GIC_START) #define INT_44XX_FPKA_ERROR_IRQ (64 + IRQ_GIC_START) #define INT_44XX_PBIAS_IRQ (75 + IRQ_GIC_START) @@ -511,6 +512,9 @@ #define INT_44XX_TLL_IRQ (78 + IRQ_GIC_START) #define INT_44XX_PARTHASH_IRQ (79 + IRQ_GIC_START) #define INT_44XX_MMC3_IRQ (94 + IRQ_GIC_START) +#define INT_44XX_MMC4_IRQ (96 + IRQ_GIC_START) +#define INT_44XX_MCPDM_IRQ (112 + IRQ_GIC_START) +#define INT_44XX_SYS_NIRQ2 (119 + IRQ_GIC_START) #define INT_44XX_DUCATI_MMU_IRQ (100 + IRQ_GIC_START) /* Max. 128 level 2 IRQs (OMAP1610), 192 GPIOs (OMAP730/850) and @@ -551,8 +555,20 @@ #endif #define TWL4030_GPIO_IRQ_END (TWL4030_GPIO_IRQ_BASE + TWL4030_GPIO_NR_IRQS) +#define TWL6030_IRQ_BASE (OMAP_FPGA_IRQ_END) +#ifdef CONFIG_TWL6030_CORE +#define TWL6030_BASE_NR_IRQS 20 +#else +#define TWL6030_BASE_NR_IRQS 0 +#endif +#define TWL6030_IRQ_END (TWL6030_IRQ_BASE + TWL6030_BASE_NR_IRQS) + /* Total number of interrupts depends on the enabled blocks above */ +#ifdef CONFIG_TWL4030_CORE #define NR_IRQS TWL4030_GPIO_IRQ_END +#else +#define NR_IRQS TWL6030_IRQ_END +#endif #define OMAP_IRQ_BIT(irq) (1 << ((irq) % 32)) diff --git a/arch/arm/plat-omap/include/mach/mcbsp.h b/arch/arm/plat-omap/include/mach/mcbsp.h index bb154ea76769..ec6f81e06d39 100644 --- a/arch/arm/plat-omap/include/mach/mcbsp.h +++ b/arch/arm/plat-omap/include/mach/mcbsp.h @@ -53,6 +53,11 @@ #define OMAP34XX_MCBSP4_BASE 0x49026000 #define OMAP34XX_MCBSP5_BASE 0x48096000 +#define OMAP44XX_MCBSP1_BASE 0x49022000 +#define OMAP44XX_MCBSP2_BASE 0x49024000 +#define OMAP44XX_MCBSP3_BASE 0x49026000 +#define OMAP44XX_MCBSP4_BASE 0x48074000 + #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP730) #define OMAP_MCBSP_REG_DRR2 0x00 @@ -98,7 +103,8 @@ #define AUDIO_DMA_TX OMAP_DMA_MCBSP1_TX #define AUDIO_DMA_RX OMAP_DMA_MCBSP1_RX -#elif defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) +#elif defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ + defined(CONFIG_ARCH_OMAP4) #define OMAP_MCBSP_REG_DRR2 0x00 #define OMAP_MCBSP_REG_DRR1 0x04 diff --git a/arch/arm/plat-omap/include/mach/mmc.h b/arch/arm/plat-omap/include/mach/mmc.h index 81d5b36534b3..2dfb4734f4b4 100644 --- a/arch/arm/plat-omap/include/mach/mmc.h +++ b/arch/arm/plat-omap/include/mach/mmc.h @@ -25,11 +25,19 @@ #define OMAP24XX_NR_MMC 2 #define OMAP34XX_NR_MMC 3 +#define OMAP44XX_NR_MMC 5 #define OMAP2420_MMC_SIZE OMAP1_MMC_SIZE #define HSMMC_SIZE 0x200 #define OMAP2_MMC1_BASE 0x4809c000 #define OMAP2_MMC2_BASE 0x480b4000 #define OMAP3_MMC3_BASE 0x480ad000 +#define OMAP4_MMC1_BASE 0x4809c100 +#define OMAP4_MMC2_BASE 0x480b4100 +#define OMAP4_MMC3_BASE 0x480ad100 +#define OMAP4_MMC4_BASE 0x480d1100 +#define OMAP4_MMC5_BASE 0x480d5100 +#define HSMMC5 (1 << 4) +#define HSMMC4 (1 << 3) #define HSMMC3 (1 << 2) #define HSMMC2 (1 << 1) #define HSMMC1 (1 << 0) diff --git a/arch/arm/plat-omap/include/mach/mux.h b/arch/arm/plat-omap/include/mach/mux.h index 85a621705766..fc82f7b15f6b 100644 --- a/arch/arm/plat-omap/include/mach/mux.h +++ b/arch/arm/plat-omap/include/mach/mux.h @@ -208,7 +208,7 @@ struct pin_config { const unsigned int mux_reg; unsigned char debug; -#if defined(CONFIG_ARCH_OMAP34XX) +#if defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP4) u16 mux_val; /* Wake-up, off mode, pull, mux mode */ #endif @@ -855,6 +855,89 @@ enum omap34xx_index { J25_34XX_GPIO170, }; +enum omap44xx_index { + + AA3_4430_McSPI1_CLK, + Y2_4430_McSPI1_SIMO, + Y3_4430_McSPI1_SOMI, + Y4_4430_McSPI1_CS0, + Y4_4430_McSPI1_CS1, + Y4_4430_McSPI1_CS2, + Y4_4430_McSPI1_CS3, + + AA3_4430_McBSP1_CLK, + Y2_4430_McBSP1_DX, + Y3_4430_McBSP1_DR, + Y4_4430_McBSP1_FSX, + + PAD0_4430_UNIPRO_TX0, + PAD1_4430_UNIPRO_TY0, + PAD0_4430_UNIPRO_TX1, + PAD1_4430_UNIPRO_TY1, + PAD0_4430_UNIPRO_TX2, + PAD1_4430_UNIPRO_TY2, + PAD0_4430_UNIPRO_RX0, + PAD1_4430_UNIPRO_RY0, + PAD0_4430_UNIPRO_RX1, + PAD1_4430_UNIPRO_RY1, + PAD0_4430_UNIPRO_RX2, + PAD1_4430_UNIPRO_RY2, + + PAD1_4430_SYS_NIRQ1, + PAD0_4430_SYS_NIRQ2, + + A1_4430_MMC1_CLK, + C1_4430_MMC1_CMD, + D0_4430_MMC1_DAT0, + D1_4430_MMC1_DAT1, + D2_4430_MMC1_DAT2, + D3_4430_MMC1_DAT3, + D4_4430_MMC1_DAT4, + D5_4430_MMC1_DAT5, + D6_4430_MMC1_DAT6, + D7_4430_MMC1_DAT7, + + A1_4430_MMC2_CLK, + C1_4430_MMC2_CMD, + D0_4430_MMC2_DAT0, + D1_4430_MMC2_DAT1, + D2_4430_MMC2_DAT2, + D3_4430_MMC2_DAT3, + D4_4430_MMC2_DAT4, + D5_4430_MMC2_DAT5, + D6_4430_MMC2_DAT6, + D7_4430_MMC2_DAT7, + + A1_4430_MMC3_CLK, + C1_4430_MMC3_CMD, + D0_4430_MMC3_DAT0, + D1_4430_MMC3_DAT1, + D2_4430_MMC3_DAT2, + D3_4430_MMC3_DAT3, + + A1_4430_MMC4_CLK, + C1_4430_MMC4_CMD, + D0_4430_MMC4_DAT0, + D1_4430_MMC4_DAT1, + D2_4430_MMC4_DAT2, + D3_4430_MMC4_DAT3, + + A1_4430_MMC5_CLK, + C1_4430_MMC5_CMD, + D0_4430_MMC5_DAT0, + D1_4430_MMC5_DAT1, + D2_4430_MMC5_DAT2, + D3_4430_MMC5_DAT3, + + AG25_4430_ABE_PDM_UL_DATA, + AF25_4430_ABE_PDM_DL_DATA, + AE25_4430_ABE_PDM_FRAME, + AF26_4430_ABE_PDM_LB_CLK, + AH26_4430_ABE_PDM_CLKS, + AA27_4430_GPIO_127, + +}; + struct omap_mux_cfg { struct pin_config *pins; unsigned long size; diff --git a/arch/arm/plat-omap/include/mach/omap44xx.h b/arch/arm/plat-omap/include/mach/omap44xx.h index 6a545d33dee0..1ddffeb1fb98 100644 --- a/arch/arm/plat-omap/include/mach/omap44xx.h +++ b/arch/arm/plat-omap/include/mach/omap44xx.h @@ -25,11 +25,13 @@ #define L3_ABE_44XX_BASE 0x49000000 #define OMAP4430_32KSYNCT_BASE 0x4a304000 -#define OMAP4430_CM_BASE 0x4a004000 -#define OMAP4430_PRM_BASE 0x48306000 +#define OMAP4430_CM1_BASE 0x4A30A000 +#define OMAP4430_CM_BASE OMAP4430_CM1_BASE +#define OMAP4430_CM2_BASE 0x4A008000 +#define OMAP4430_PRM_BASE 0x4A306000 #define OMAP44XX_GPMC_BASE 0x50000000 #define OMAP443X_SCM_BASE 0x4a002000 -#define OMAP443X_CTRL_BASE OMAP443X_SCM_BASE +#define OMAP443X_CTRL_BASE 0x4A100000 #define OMAP44XX_IC_BASE 0x48200000 #define OMAP44XX_IVA_INTC_BASE 0x40000000 #define IRQ_SIR_IRQ 0x0040 diff --git a/arch/arm/plat-omap/include/mach/vram.h b/arch/arm/plat-omap/include/mach/vram.h new file mode 100644 index 000000000000..8639e08c5efa --- /dev/null +++ b/arch/arm/plat-omap/include/mach/vram.h @@ -0,0 +1,34 @@ +/* + * File: arch/arm/plat-omap/include/mach/vram.h + * + * Copyright (C) 2009 Nokia Corporation + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.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. + */ + +#ifndef __OMAPVRAM_H +#define __OMAPVRAM_H + +#include <asm/types.h> + +extern int omap_vram_add_region(unsigned long paddr, size_t size); +extern int omap_vram_free(unsigned long paddr, size_t size); +extern int omap_vram_alloc(int mtype, size_t size, unsigned long *paddr); +extern int omap_vram_reserve(unsigned long paddr, size_t size); +extern void omap2_set_sdram_vram(u32 size, u32 start); +extern void omap2_set_sram_vram(u32 size, u32 start); + +#endif diff --git a/arch/arm/plat-omap/include/mach/vrfb.h b/arch/arm/plat-omap/include/mach/vrfb.h new file mode 100644 index 000000000000..9647d82c1cdd --- /dev/null +++ b/arch/arm/plat-omap/include/mach/vrfb.h @@ -0,0 +1,51 @@ +/* + * File: arch/arm/plat-omap/include/mach/vrfb.h + * + * VRFB + * + * Copyright (C) 2009 Nokia Corporation + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.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. + */ + +#ifndef __VRFB_H +#define __VRFB_H + +#include <mach/display.h> +#define OMAP_VRFB_LINE_LEN 2048 + +struct vrfb +{ + u8 context; + void __iomem *vaddr[4]; + unsigned long paddr[4]; + u16 xoffset; + u16 yoffset; + u8 bytespp; +}; + +extern int omap_vrfb_request_ctx(struct vrfb *vrfb); +extern void omap_vrfb_release_ctx(struct vrfb *vrfb); +extern void omap_vrfb_suspend_ctx(struct vrfb *vrfb); +extern void omap_vrfb_resume_ctx(struct vrfb *vrfb); +extern void omap_vrfb_adjust_size(u16 *width, u16 *height, + u8 bytespp); +extern void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr, + u16 width, u16 height, + enum omap_color_mode color_mode); +extern void omap_vrfb_restore_context(void); + +#endif /* __VRFB_H */ diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index efa0e0111f38..39e594f05dfe 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -934,21 +934,25 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev) mcbsp->rx_irq = pdata->rx_irq; mcbsp->dma_rx_sync = pdata->dma_rx_sync; mcbsp->dma_tx_sync = pdata->dma_tx_sync; + /* + * FIX-ME: Replace with correct clk node when clk + * framework is available + */ + if (!cpu_is_omap44xx()) { + mcbsp->iclk = clk_get(&pdev->dev, "ick"); + if (IS_ERR(mcbsp->iclk)) { + ret = PTR_ERR(mcbsp->iclk); + dev_err(&pdev->dev, "unable to get ick: %d\n", ret); + goto err_iclk; + } - mcbsp->iclk = clk_get(&pdev->dev, "ick"); - if (IS_ERR(mcbsp->iclk)) { - ret = PTR_ERR(mcbsp->iclk); - dev_err(&pdev->dev, "unable to get ick: %d\n", ret); - goto err_iclk; - } - - mcbsp->fclk = clk_get(&pdev->dev, "fck"); - if (IS_ERR(mcbsp->fclk)) { - ret = PTR_ERR(mcbsp->fclk); - dev_err(&pdev->dev, "unable to get fck: %d\n", ret); - goto err_fclk; + mcbsp->fclk = clk_get(&pdev->dev, "fck"); + if (IS_ERR(mcbsp->fclk)) { + ret = PTR_ERR(mcbsp->fclk); + dev_err(&pdev->dev, "unable to get fck: %d\n", ret); + goto err_fclk; + } } - mcbsp->pdata = pdata; mcbsp->dev = &pdev->dev; mcbsp_ptr[id] = mcbsp; diff --git a/arch/arm/plat-omap/mux.c b/arch/arm/plat-omap/mux.c index 8d329fb20740..80b040fd5ca7 100644 --- a/arch/arm/plat-omap/mux.c +++ b/arch/arm/plat-omap/mux.c @@ -54,9 +54,6 @@ int __init_or_module omap_cfg_reg(const unsigned long index) { struct pin_config *reg; - if (cpu_is_omap44xx()) - return 0; - if (mux_cfg == NULL) { printk(KERN_ERR "Pin mux table not initialized\n"); return -ENODEV; diff --git a/arch/arm/plat-omap/vram.c b/arch/arm/plat-omap/vram.c new file mode 100644 index 000000000000..93be46a9f3fd --- /dev/null +++ b/arch/arm/plat-omap/vram.c @@ -0,0 +1,632 @@ +/* + * linux/arch/arm/plat-omap/vram.c + * + * Copyright (C) 2008 Nokia Corporation + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> + * + * Some code and ideas taken from drivers/video/omap/ driver + * by Imre Deak. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +/*#define DEBUG*/ + +#include <linux/vmalloc.h> +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/list.h> +#include <linux/dma-mapping.h> +#include <linux/seq_file.h> +#include <linux/bootmem.h> +#include <linux/omapfb.h> +#include <linux/completion.h> +#include <linux/debugfs.h> + +#include <asm/setup.h> + +#include <mach/sram.h> +#include <mach/vram.h> +#include <mach/dma.h> + +#ifdef DEBUG +#define DBG(format, ...) printk(KERN_DEBUG "VRAM: " format, ## __VA_ARGS__) +#else +#define DBG(format, ...) +#endif + +#define OMAP2_SRAM_START 0x40200000 +/* Maximum size, in reality this is smaller if SRAM is partially locked. */ +#define OMAP2_SRAM_SIZE 0xa0000 /* 640k */ + +#define REG_MAP_SIZE(_page_cnt) \ + ((_page_cnt + (sizeof(unsigned long) * 8) - 1) / 8) +#define REG_MAP_PTR(_rg, _page_nr) \ + (((_rg)->map) + (_page_nr) / (sizeof(unsigned long) * 8)) +#define REG_MAP_MASK(_page_nr) \ + (1 << ((_page_nr) & (sizeof(unsigned long) * 8 - 1))) + +/* #if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE) */ + +/* postponed regions are used to temporarily store region information at boot + * time when we cannot yet allocate the region list */ +#define MAX_POSTPONED_REGIONS 10 + +static bool vram_initialized; +static int postponed_cnt; +static struct { + unsigned long paddr; + size_t size; +} postponed_regions[MAX_POSTPONED_REGIONS]; + +struct vram_alloc { + struct list_head list; + unsigned long paddr; + unsigned pages; +}; + +struct vram_region { + struct list_head list; + struct list_head alloc_list; + unsigned long paddr; + unsigned pages; +}; + +static DEFINE_MUTEX(region_mutex); +static LIST_HEAD(region_list); + +static inline int region_mem_type(unsigned long paddr) +{ + if (paddr >= OMAP2_SRAM_START && + paddr < OMAP2_SRAM_START + OMAP2_SRAM_SIZE) + return OMAPFB_MEMTYPE_SRAM; + else + return OMAPFB_MEMTYPE_SDRAM; +} + +static struct vram_region *omap_vram_create_region(unsigned long paddr, + unsigned pages) +{ + struct vram_region *rm; + + rm = kzalloc(sizeof(*rm), GFP_KERNEL); + + if (rm) { + INIT_LIST_HEAD(&rm->alloc_list); + rm->paddr = paddr; + rm->pages = pages; + } + + return rm; +} + +#if 0 +static void omap_vram_free_region(struct vram_region *vr) +{ + list_del(&vr->list); + kfree(vr); +} +#endif + +static struct vram_alloc *omap_vram_create_allocation(struct vram_region *vr, + unsigned long paddr, unsigned pages) +{ + struct vram_alloc *va; + struct vram_alloc *new; + + new = kzalloc(sizeof(*va), GFP_KERNEL); + + if (!new) + return NULL; + + new->paddr = paddr; + new->pages = pages; + + list_for_each_entry(va, &vr->alloc_list, list) { + if (va->paddr > new->paddr) + break; + } + + list_add_tail(&new->list, &va->list); + + return new; +} + +static void omap_vram_free_allocation(struct vram_alloc *va) +{ + list_del(&va->list); + kfree(va); +} + +int omap_vram_add_region(unsigned long paddr, size_t size) +{ + struct vram_region *rm; + unsigned pages; + + if (vram_initialized) { + DBG("adding region paddr %08lx size %d\n", + paddr, size); + + size &= PAGE_MASK; + pages = size >> PAGE_SHIFT; + + rm = omap_vram_create_region(paddr, pages); + if (rm == NULL) + return -ENOMEM; + + list_add(&rm->list, ®ion_list); + } else { + if (postponed_cnt == MAX_POSTPONED_REGIONS) + return -ENOMEM; + + postponed_regions[postponed_cnt].paddr = paddr; + postponed_regions[postponed_cnt].size = size; + + ++postponed_cnt; + } + return 0; +} + +int omap_vram_free(unsigned long paddr, size_t size) +{ + struct vram_region *rm; + struct vram_alloc *alloc; + unsigned start, end; + + DBG("free mem paddr %08lx size %d\n", paddr, size); + + size = PAGE_ALIGN(size); + + mutex_lock(®ion_mutex); + + list_for_each_entry(rm, ®ion_list, list) { + list_for_each_entry(alloc, &rm->alloc_list, list) { + start = alloc->paddr; + end = alloc->paddr + (alloc->pages >> PAGE_SHIFT); + + if (start >= paddr && end < paddr + size) + goto found; + } + } + + mutex_unlock(®ion_mutex); + return -EINVAL; + +found: + omap_vram_free_allocation(alloc); + + mutex_unlock(®ion_mutex); + return 0; +} +EXPORT_SYMBOL(omap_vram_free); + +static int _omap_vram_reserve(unsigned long paddr, unsigned pages) +{ + struct vram_region *rm; + struct vram_alloc *alloc; + size_t size; + + size = pages << PAGE_SHIFT; + + list_for_each_entry(rm, ®ion_list, list) { + unsigned long start, end; + + DBG("checking region %lx %d\n", rm->paddr, rm->pages); + + if (region_mem_type(rm->paddr) != region_mem_type(paddr)) + continue; + + start = rm->paddr; + end = start + (rm->pages << PAGE_SHIFT) - 1; + if (start > paddr || end < paddr + size - 1) + continue; + + DBG("block ok, checking allocs\n"); + + list_for_each_entry(alloc, &rm->alloc_list, list) { + end = alloc->paddr - 1; + + if (start <= paddr && end >= paddr + size - 1) + goto found; + + start = alloc->paddr + (alloc->pages << PAGE_SHIFT); + } + + end = rm->paddr + (rm->pages << PAGE_SHIFT) - 1; + + if (!(start <= paddr && end >= paddr + size - 1)) + continue; +found: + DBG("FOUND area start %lx, end %lx\n", start, end); + + if (omap_vram_create_allocation(rm, paddr, pages) == NULL) + return -ENOMEM; + + return 0; + } + + return -ENOMEM; +} + +int omap_vram_reserve(unsigned long paddr, size_t size) +{ + unsigned pages; + int r; + + DBG("reserve mem paddr %08lx size %d\n", paddr, size); + + size = PAGE_ALIGN(size); + pages = size >> PAGE_SHIFT; + + mutex_lock(®ion_mutex); + + r = _omap_vram_reserve(paddr, pages); + + mutex_unlock(®ion_mutex); + + return r; +} +EXPORT_SYMBOL(omap_vram_reserve); + +static void _omap_vram_dma_cb(int lch, u16 ch_status, void *data) +{ + struct completion *compl = data; + complete(compl); +} + +static int _omap_vram_clear(u32 paddr, unsigned pages) +{ + struct completion compl; + unsigned elem_count; + unsigned frame_count; + int r; + int lch; + + init_completion(&compl); + + r = omap_request_dma(OMAP_DMA_NO_DEVICE, "VRAM DMA", + _omap_vram_dma_cb, + &compl, &lch); + if (r) { + pr_err("VRAM: request_dma failed for memory clear\n"); + return -EBUSY; + } + + elem_count = pages * PAGE_SIZE / 4; + frame_count = 1; + + omap_set_dma_transfer_params(lch, OMAP_DMA_DATA_TYPE_S32, + elem_count, frame_count, + OMAP_DMA_SYNC_ELEMENT, + 0, 0); + + omap_set_dma_dest_params(lch, 0, OMAP_DMA_AMODE_POST_INC, + paddr, 0, 0); + + omap_set_dma_color_mode(lch, OMAP_DMA_CONSTANT_FILL, 0x000000); + + omap_start_dma(lch); + + if (wait_for_completion_timeout(&compl, msecs_to_jiffies(1000)) == 0) { + omap_stop_dma(lch); + pr_err("VRAM: dma timeout while clearing memory\n"); + r = -EIO; + goto err; + } + + r = 0; +err: + omap_free_dma(lch); + + return r; +} + +static int _omap_vram_alloc(int mtype, unsigned pages, unsigned long *paddr) +{ + struct vram_region *rm; + struct vram_alloc *alloc; + + list_for_each_entry(rm, ®ion_list, list) { + unsigned long start, end; + + DBG("checking region %lx %d\n", rm->paddr, rm->pages); + + if (region_mem_type(rm->paddr) != mtype) + continue; + + start = rm->paddr; + + list_for_each_entry(alloc, &rm->alloc_list, list) { + end = alloc->paddr; + + if (end - start >= pages << PAGE_SHIFT) + goto found; + + start = alloc->paddr + (alloc->pages << PAGE_SHIFT); + } + + end = rm->paddr + (rm->pages << PAGE_SHIFT); +found: + if (end - start < pages << PAGE_SHIFT) + continue; + + DBG("FOUND %lx, end %lx\n", start, end); + + alloc = omap_vram_create_allocation(rm, start, pages); + if (alloc == NULL) + return -ENOMEM; + + *paddr = start; + + _omap_vram_clear(start, pages); + + return 0; + } + + return -ENOMEM; +} + +int omap_vram_alloc(int mtype, size_t size, unsigned long *paddr) +{ + unsigned pages; + int r; + + BUG_ON(mtype > OMAPFB_MEMTYPE_MAX || !size); + + DBG("alloc mem type %d size %d\n", mtype, size); + + size = PAGE_ALIGN(size); + pages = size >> PAGE_SHIFT; + + mutex_lock(®ion_mutex); + + r = _omap_vram_alloc(mtype, pages, paddr); + + mutex_unlock(®ion_mutex); + + return r; +} +EXPORT_SYMBOL(omap_vram_alloc); + +#if defined(CONFIG_DEBUG_FS) +static int vram_debug_show(struct seq_file *s, void *unused) +{ + struct vram_region *vr; + struct vram_alloc *va; + unsigned size; + + mutex_lock(®ion_mutex); + + list_for_each_entry(vr, ®ion_list, list) { + size = vr->pages << PAGE_SHIFT; + seq_printf(s, "%08lx-%08lx (%d bytes)\n", + vr->paddr, vr->paddr + size - 1, + size); + + list_for_each_entry(va, &vr->alloc_list, list) { + size = va->pages << PAGE_SHIFT; + seq_printf(s, " %08lx-%08lx (%d bytes)\n", + va->paddr, va->paddr + size - 1, + size); + } + } + + mutex_unlock(®ion_mutex); + + return 0; +} + +static int vram_debug_open(struct inode *inode, struct file *file) +{ + return single_open(file, vram_debug_show, inode->i_private); +} + +static const struct file_operations vram_debug_fops = { + .open = vram_debug_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init omap_vram_create_debugfs(void) +{ + struct dentry *d; + + d = debugfs_create_file("vram", S_IRUGO, NULL, + NULL, &vram_debug_fops); + if (IS_ERR(d)) + return PTR_ERR(d); + + return 0; +} +#endif + +static __init int omap_vram_init(void) +{ + int i; + + vram_initialized = 1; + + for (i = 0; i < postponed_cnt; i++) + omap_vram_add_region(postponed_regions[i].paddr, + postponed_regions[i].size); + +#ifdef CONFIG_DEBUG_FS + if (omap_vram_create_debugfs()) + pr_err("VRAM: Failed to create debugfs file\n"); +#endif + + return 0; +} + +arch_initcall(omap_vram_init); + +/* boottime vram alloc stuff */ + +/* set from board file */ +static u32 omapfb_sram_vram_start __initdata; +static u32 omapfb_sram_vram_size __initdata; + +/* set from board file */ +static u32 omapfb_sdram_vram_start __initdata; +static u32 omapfb_sdram_vram_size __initdata; + +/* set from kernel cmdline */ +static u32 omapfb_def_sdram_vram_size __initdata; +static u32 omapfb_def_sdram_vram_start __initdata; + +static void __init omapfb_early_vram(char **p) +{ + omapfb_def_sdram_vram_size = memparse(*p, p); + if (**p == ',') + omapfb_def_sdram_vram_start = simple_strtoul((*p) + 1, p, 16); +} +__early_param("vram=", omapfb_early_vram); + +/* + * Called from map_io. We need to call to this early enough so that we + * can reserve the fixed SDRAM regions before VM could get hold of them. + */ +void __init omapfb_reserve_sdram(void) +{ + struct bootmem_data *bdata; + unsigned long sdram_start, sdram_size; + u32 paddr; + u32 size = 0; + + /* cmdline arg overrides the board file definition */ + if (omapfb_def_sdram_vram_size) { + size = omapfb_def_sdram_vram_size; + paddr = omapfb_def_sdram_vram_start; + } + + if (!size) { + size = omapfb_sdram_vram_size; + paddr = omapfb_sdram_vram_start; + } + +#ifdef CONFIG_OMAP2_DSS_VRAM_SIZE + if (!size) { + size = CONFIG_OMAP2_DSS_VRAM_SIZE * 1024 * 1024; + paddr = 0; + } +#endif + + if (!size) + return; + + size = PAGE_ALIGN(size); + + bdata = NODE_DATA(0)->bdata; + sdram_start = bdata->node_min_pfn << PAGE_SHIFT; + sdram_size = (bdata->node_low_pfn << PAGE_SHIFT) - sdram_start; + + if (paddr) { + if ((paddr & ~PAGE_MASK) || paddr < sdram_start || + paddr + size > sdram_start + sdram_size) { + printk(KERN_ERR "Illegal SDRAM region for VRAM\n"); + return; + } + + if (reserve_bootmem(paddr, size, BOOTMEM_EXCLUSIVE) < 0) { + pr_err("FB: failed to reserve VRAM\n"); + return; + } + } else { + if (size > sdram_size) { + printk(KERN_ERR "Illegal SDRAM size for VRAM\n"); + return; + } + + paddr = virt_to_phys(alloc_bootmem_pages(size)); + BUG_ON(paddr & ~PAGE_MASK); + } + + omap_vram_add_region(paddr, size); + + pr_info("Reserving %u bytes SDRAM for VRAM\n", size); +} + +/* + * Called at sram init time, before anything is pushed to the SRAM stack. + * Because of the stack scheme, we will allocate everything from the + * start of the lowest address region to the end of SRAM. This will also + * include padding for page alignment and possible holes between regions. + * + * As opposed to the SDRAM case, we'll also do any dynamic allocations at + * this point, since the driver built as a module would have problem with + * freeing / reallocating the regions. + */ +unsigned long __init omapfb_reserve_sram(unsigned long sram_pstart, + unsigned long sram_vstart, + unsigned long sram_size, + unsigned long pstart_avail, + unsigned long size_avail) +{ + unsigned long pend_avail; + unsigned long reserved; + u32 paddr; + u32 size; + + paddr = omapfb_sram_vram_start; + size = omapfb_sram_vram_size; + + if (!size) + return 0; + + reserved = 0; + pend_avail = pstart_avail + size_avail; + + if (!paddr) { + /* Dynamic allocation */ + if ((size_avail & PAGE_MASK) < size) { + printk(KERN_ERR "Not enough SRAM for VRAM\n"); + return 0; + } + size_avail = (size_avail - size) & PAGE_MASK; + paddr = pstart_avail + size_avail; + } + + if (paddr < sram_pstart || + paddr + size > sram_pstart + sram_size) { + printk(KERN_ERR "Illegal SRAM region for VRAM\n"); + return 0; + } + + /* Reserve everything above the start of the region. */ + if (pend_avail - paddr > reserved) + reserved = pend_avail - paddr; + size_avail = pend_avail - reserved - pstart_avail; + + omap_vram_add_region(paddr, size); + + if (reserved) + pr_info("Reserving %lu bytes SRAM for VRAM\n", reserved); + + return reserved; +} + +void __init omap2_set_sdram_vram(u32 size, u32 start) +{ + omapfb_sdram_vram_start = start; + omapfb_sdram_vram_size = size; +} + +void __init omap2_set_sram_vram(u32 size, u32 start) +{ + omapfb_sram_vram_start = start; + omapfb_sram_vram_size = size; +} + +/* #endif */ + diff --git a/arch/arm/plat-omap/vrfb.c b/arch/arm/plat-omap/vrfb.c new file mode 100644 index 000000000000..201640ad1301 --- /dev/null +++ b/arch/arm/plat-omap/vrfb.c @@ -0,0 +1,282 @@ +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/ioport.h> +#include <linux/io.h> +#include <linux/bitops.h> +#include <linux/mutex.h> + +#include <mach/io.h> +#include <mach/vrfb.h> +/*#define DEBUG*/ + +#ifdef DEBUG +#define DBG(format, ...) printk(KERN_DEBUG "VRFB: " format, ## __VA_ARGS__) +#else +#define DBG(format, ...) +#endif + +#define SMS_ROT_VIRT_BASE(context, rot) \ + (((context >= 4) ? 0xD0000000 : 0x70000000) \ + + (0x4000000 * (context)) \ + + (0x1000000 * (rot))) + +#define OMAP_VRFB_SIZE (2048 * 2048 * 4) + +#define VRFB_PAGE_WIDTH_EXP 5 /* Assuming SDRAM pagesize= 1024 */ +#define VRFB_PAGE_HEIGHT_EXP 5 /* 1024 = 2^5 * 2^5 */ +#define VRFB_PAGE_WIDTH (1 << VRFB_PAGE_WIDTH_EXP) +#define VRFB_PAGE_HEIGHT (1 << VRFB_PAGE_HEIGHT_EXP) +#define SMS_IMAGEHEIGHT_OFFSET 16 +#define SMS_IMAGEWIDTH_OFFSET 0 +#define SMS_PH_OFFSET 8 +#define SMS_PW_OFFSET 4 +#define SMS_PS_OFFSET 0 + +#define OMAP_SMS_BASE 0x6C000000 +#define SMS_ROT_CONTROL(context) (OMAP_SMS_BASE + 0x180 + 0x10 * context) +#define SMS_ROT_SIZE(context) (OMAP_SMS_BASE + 0x184 + 0x10 * context) +#define SMS_ROT_PHYSICAL_BA(context) (OMAP_SMS_BASE + 0x188 + 0x10 * context) + +#define VRFB_NUM_CTXS 12 +/* bitmap of reserved contexts */ +static unsigned long ctx_map; +/* bitmap of contexts for which we have to keep the HW context valid */ +static unsigned long ctx_map_active; + +static DEFINE_MUTEX(ctx_lock); + +/* + * Access to this happens from client drivers or the PM core after wake-up. + * For the first case we require locking at the driver level, for the second + * we don't need locking, since no drivers will run until after the wake-up + * has finished. + */ +static struct { + u32 physical_ba; + u32 control; + u32 size; +} vrfb_hw_context[VRFB_NUM_CTXS]; + +static inline void restore_hw_context(int ctx) +{ + omap_writel(vrfb_hw_context[ctx].control, SMS_ROT_CONTROL(ctx)); + omap_writel(vrfb_hw_context[ctx].size, SMS_ROT_SIZE(ctx)); + omap_writel(vrfb_hw_context[ctx].physical_ba, SMS_ROT_PHYSICAL_BA(ctx)); +} + +void omap_vrfb_restore_context(void) +{ + int i; + unsigned long map = ctx_map_active; + + for (i = ffs(map); i; i = ffs(map)) { + /* i=1..32 */ + i--; + map &= ~(1 << i); + restore_hw_context(i); + } +} + +void omap_vrfb_adjust_size(u16 *width, u16 *height, + u8 bytespp) +{ + *width = ALIGN(*width * bytespp, VRFB_PAGE_WIDTH) / bytespp; + *height = ALIGN(*height, VRFB_PAGE_HEIGHT); +} +EXPORT_SYMBOL(omap_vrfb_adjust_size); + +void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr, + u16 width, u16 height, + enum omap_color_mode color_mode) +{ + unsigned pixel_size_exp; + u16 vrfb_width; + u16 vrfb_height; + u8 ctx = vrfb->context; + u8 bytespp; + u32 size; + u32 control; + + DBG("omapfb_set_vrfb(%d, %lx, %dx%d, %d)\n", ctx, paddr, + width, height, color_mode); + + switch (color_mode) { + case OMAP_DSS_COLOR_RGB16: + case OMAP_DSS_COLOR_ARGB16: + bytespp = 2; + break; + + case OMAP_DSS_COLOR_RGB24P: + bytespp = 3; + break; + + case OMAP_DSS_COLOR_RGB24U: + case OMAP_DSS_COLOR_ARGB32: + case OMAP_DSS_COLOR_RGBA32: + case OMAP_DSS_COLOR_RGBX32: + case OMAP_DSS_COLOR_YUV2: + case OMAP_DSS_COLOR_UYVY: + bytespp = 4; + break; + + default: + BUG(); + } + + if (color_mode == OMAP_DSS_COLOR_YUV2 || + color_mode == OMAP_DSS_COLOR_UYVY) + width >>= 1; + + if (bytespp == 4) + pixel_size_exp = 2; + else if (bytespp == 2) + pixel_size_exp = 1; + else + BUG(); + + vrfb_width = ALIGN(width * bytespp, VRFB_PAGE_WIDTH) / bytespp; + vrfb_height = ALIGN(height, VRFB_PAGE_HEIGHT); + + DBG("vrfb w %u, h %u bytespp %d\n", vrfb_width, vrfb_height, bytespp); + + size = vrfb_width << SMS_IMAGEWIDTH_OFFSET; + size |= vrfb_height << SMS_IMAGEHEIGHT_OFFSET; + + control = pixel_size_exp << SMS_PS_OFFSET; + control |= VRFB_PAGE_WIDTH_EXP << SMS_PW_OFFSET; + control |= VRFB_PAGE_HEIGHT_EXP << SMS_PH_OFFSET; + + vrfb_hw_context[ctx].physical_ba = paddr; + vrfb_hw_context[ctx].size = size; + vrfb_hw_context[ctx].control = control; + + omap_writel(paddr, SMS_ROT_PHYSICAL_BA(ctx)); + omap_writel(size, SMS_ROT_SIZE(ctx)); + omap_writel(control, SMS_ROT_CONTROL(ctx)); + + DBG("vrfb offset pixels %d, %d\n", + vrfb_width - width, vrfb_height - height); + + vrfb->xoffset = vrfb_width - width; + vrfb->yoffset = vrfb_height - height; + vrfb->bytespp = bytespp; +} +EXPORT_SYMBOL(omap_vrfb_setup); + +void omap_vrfb_release_ctx(struct vrfb *vrfb) +{ + int rot; + int ctx = vrfb->context; + + if (ctx == 0xff) + return; + + DBG("release ctx %d\n", ctx); + + mutex_lock(&ctx_lock); + + BUG_ON(!(ctx_map & (1 << ctx))); + + clear_bit(ctx, &ctx_map_active); + clear_bit(ctx, &ctx_map); + + for (rot = 0; rot < 4; ++rot) { + if (vrfb->paddr[rot]) { + release_mem_region(vrfb->paddr[rot], OMAP_VRFB_SIZE); + vrfb->paddr[rot] = 0; + } + } + + vrfb->context = 0xff; + + mutex_unlock(&ctx_lock); +} +EXPORT_SYMBOL(omap_vrfb_release_ctx); + +int omap_vrfb_request_ctx(struct vrfb *vrfb) +{ + int rot; + u32 paddr; + u8 ctx; + int r; + + DBG("request ctx\n"); + + mutex_lock(&ctx_lock); + + for (ctx = 0; ctx < VRFB_NUM_CTXS; ++ctx) + if ((ctx_map & (1 << ctx)) == 0) + break; + + if (ctx == VRFB_NUM_CTXS) { + printk(KERN_ERR "vrfb: no free contexts\n"); + r = -EBUSY; + goto out; + } + + DBG("found free ctx %d\n", ctx); + + set_bit(ctx, &ctx_map); + WARN_ON(ctx_map_active & (1 << ctx)); + set_bit(ctx, &ctx_map_active); + + memset(vrfb, 0, sizeof(*vrfb)); + + vrfb->context = ctx; + + for (rot = 0; rot < 4; ++rot) { + paddr = SMS_ROT_VIRT_BASE(ctx, rot); + if (!request_mem_region(paddr, OMAP_VRFB_SIZE, "vrfb")) { + printk(KERN_ERR "vrfb: failed to reserve VRFB " + "area for ctx %d, rotation %d\n", + ctx, rot * 90); + omap_vrfb_release_ctx(vrfb); + r = -ENOMEM; + goto out; + } + + vrfb->paddr[rot] = paddr; + + DBG("VRFB %d/%d: %lx\n", ctx, rot*90, vrfb->paddr[rot]); + } + + r = 0; +out: + mutex_unlock(&ctx_lock); + return r; +} +EXPORT_SYMBOL(omap_vrfb_request_ctx); + +void omap_vrfb_suspend_ctx(struct vrfb *vrfb) +{ + DBG("suspend ctx %d\n", vrfb->context); + mutex_lock(&ctx_lock); + + BUG_ON(vrfb->context >= VRFB_NUM_CTXS); + BUG_ON(!((1 << vrfb->context) & ctx_map_active)); + + clear_bit(vrfb->context, &ctx_map_active); + mutex_unlock(&ctx_lock); +} +EXPORT_SYMBOL(omap_vrfb_suspend_ctx); + +void omap_vrfb_resume_ctx(struct vrfb *vrfb) +{ + DBG("resume ctx %d\n", vrfb->context); + mutex_lock(&ctx_lock); + + BUG_ON(vrfb->context >= VRFB_NUM_CTXS); + BUG_ON((1 << vrfb->context) & ctx_map_active); + + /* + * omap_vrfb_restore_context is normally called by the core domain + * save / restore logic, but since this VRFB context was suspended + * those calls didn't actually restore the context and now we might + * have an invalid context. Do an explicit restore here. + */ + restore_hw_context(vrfb->context); + set_bit(vrfb->context, &ctx_map_active); + mutex_unlock(&ctx_lock); +} +EXPORT_SYMBOL(omap_vrfb_resume_ctx); + diff --git a/drivers/Kconfig b/drivers/Kconfig index 48bbdbe43e69..820bdc190e9d 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -113,4 +113,6 @@ source "drivers/xen/Kconfig" source "drivers/staging/Kconfig" source "drivers/platform/Kconfig" + +source "drivers/media/video/tiler/Kconfig" endmenu diff --git a/drivers/Makefile b/drivers/Makefile index 75fb1c315ec0..210ae0b69142 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -109,6 +109,8 @@ obj-$(CONFIG_VIRTIO) += virtio/ obj-$(CONFIG_VLYNQ) += vlynq/ obj-$(CONFIG_STAGING) += staging/ obj-y += platform/ +obj-y += ieee802154/ +obj-$(CONFIG_DMM_TILER) += media/ obj-$(CONFIG_MPU_SYSLINK_IPC) += dsp/syslink/multicore_ipc/ obj-$(CONFIG_MPU_BRIDGE_NOTIFY) += dsp/syslink/omap_notify/ obj-$(CONFIG_NOTIFY_DISPATCHER) += dsp/syslink/notify_dispatcher/ diff --git a/drivers/gpio/twl4030-gpio.c b/drivers/gpio/twl4030-gpio.c index afad14792141..a93a36303e44 100644 --- a/drivers/gpio/twl4030-gpio.c +++ b/drivers/gpio/twl4030-gpio.c @@ -34,7 +34,7 @@ #include <linux/platform_device.h> #include <linux/slab.h> -#include <linux/i2c/twl4030.h> +#include <linux/i2c/twl.h> /* @@ -80,7 +80,7 @@ static unsigned int gpio_usage_count; */ static inline int gpio_twl4030_write(u8 address, u8 data) { - return twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, data, address); + return twl_i2c_write_u8(TWL4030_MODULE_GPIO, data, address); } /*----------------------------------------------------------------------*/ @@ -117,7 +117,7 @@ static inline int gpio_twl4030_read(u8 address) u8 data; int ret = 0; - ret = twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &data, address); + ret = twl_i2c_read_u8(TWL4030_MODULE_GPIO, &data, address); return (ret < 0) ? ret : data; } @@ -142,7 +142,7 @@ static void twl4030_led_set_value(int led, int value) cached_leden &= ~mask; else cached_leden |= mask; - status = twl4030_i2c_write_u8(TWL4030_MODULE_LED, cached_leden, + status = twl_i2c_write_u8(TWL4030_MODULE_LED, cached_leden, TWL4030_LED_LEDEN); mutex_unlock(&gpio_lock); } @@ -223,23 +223,23 @@ static int twl_request(struct gpio_chip *chip, unsigned offset) } /* initialize PWM to always-drive */ - status = twl4030_i2c_write_u8(module, 0x7f, + status = twl_i2c_write_u8(module, 0x7f, TWL4030_PWMx_PWMxOFF); if (status < 0) goto done; - status = twl4030_i2c_write_u8(module, 0x7f, + status = twl_i2c_write_u8(module, 0x7f, TWL4030_PWMx_PWMxON); if (status < 0) goto done; /* init LED to not-driven (high) */ module = TWL4030_MODULE_LED; - status = twl4030_i2c_read_u8(module, &cached_leden, + status = twl_i2c_read_u8(module, &cached_leden, TWL4030_LED_LEDEN); if (status < 0) goto done; cached_leden &= ~ledclr_mask; - status = twl4030_i2c_write_u8(module, cached_leden, + status = twl_i2c_write_u8(module, cached_leden, TWL4030_LED_LEDEN); if (status < 0) goto done; @@ -250,7 +250,7 @@ static int twl_request(struct gpio_chip *chip, unsigned offset) /* on first use, turn GPIO module "on" */ if (!gpio_usage_count) { - struct twl4030_gpio_platform_data *pdata; + struct twl_gpio_platform_data *pdata; u8 value = MASK_GPIO_CTRL_GPIO_ON; /* optionally have the first two GPIOs switch vMMC1 @@ -370,7 +370,7 @@ static int __devinit gpio_twl4030_pulls(u32 ups, u32 downs) message[i] = bit_mask; } - return twl4030_i2c_write(TWL4030_MODULE_GPIO, message, + return twl_i2c_write(TWL4030_MODULE_GPIO, message, REG_GPIOPUPDCTR1, 5); } @@ -387,7 +387,7 @@ static int __devinit gpio_twl4030_debounce(u32 debounce, u8 mmc_cd) debounce >>= 8; message[3] = (debounce & 0x03); - return twl4030_i2c_write(TWL4030_MODULE_GPIO, message, + return twl_i2c_write(TWL4030_MODULE_GPIO, message, REG_GPIO_DEBEN1, 3); } @@ -395,7 +395,7 @@ static int gpio_twl4030_remove(struct platform_device *pdev); static int __devinit gpio_twl4030_probe(struct platform_device *pdev) { - struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data; + struct twl_gpio_platform_data *pdata = pdev->dev.platform_data; int ret; /* maybe setup IRQs */ @@ -462,7 +462,7 @@ no_irqs: static int __devexit gpio_twl4030_remove(struct platform_device *pdev) { - struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data; + struct twl_gpio_platform_data *pdata = pdev->dev.platform_data; int status; if (pdata->teardown) { diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index d258b02aef44..58f00b9cbf64 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -27,7 +27,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - #include <linux/module.h> #include <linux/delay.h> #include <linux/i2c.h> @@ -48,12 +47,36 @@ /* timeout waiting for the controller to respond */ #define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000)) +#define OMAP_I2C_WE_REG 0x0c +#ifdef CONFIG_ARCH_OMAP4 +#define OMAP_I2C_REVNB_LO 0x00 +#define OMAP_I2C_REVNB_HI 0x04 +#define OMAP_I2C_IV_REG 0x34 +#define OMAP_I2C_IRQSTATUS_RAW 0x24 +#define OMAP_I2C_STAT_REG 0x28 +#define OMAP_I2C_IRQENABLE_SET 0x2C +#define OMAP_I2C_IRQENABLE_CLR 0x30 +#define OMAP_I2C_SYSS_REG 0x90 +#define OMAP_I2C_BUF_REG 0x94 +#define OMAP_I2C_CNT_REG 0x98 +#define OMAP_I2C_DATA_REG 0x9C +#define OMAP_I2C_SYSC_REG 0x10 +#define OMAP_I2C_CON_REG 0xA4 +#define OMAP_I2C_OA_REG 0xA8 +#define OMAP_I2C_SA_REG 0xAC +#define OMAP_I2C_PSC_REG 0xB0 +#define OMAP_I2C_SCLL_REG 0xB4 +#define OMAP_I2C_SCLH_REG 0xB8 +#define OMAP_I2C_SYSTEST_REG 0xBC +#define OMAP_I2C_BUFSTAT_REG 0xC0 +#define OMAP_I2C_IE_REG OMAP_I2C_IRQENABLE_SET +#define OMAP_I2C_REV_REG OMAP_I2C_REVNB_HI +#else #define OMAP_I2C_REV_REG 0x00 #define OMAP_I2C_IE_REG 0x04 #define OMAP_I2C_STAT_REG 0x08 #define OMAP_I2C_IV_REG 0x0c /* For OMAP3 I2C_IV has changed to I2C_WE (wakeup enable) */ -#define OMAP_I2C_WE_REG 0x0c #define OMAP_I2C_SYSS_REG 0x10 #define OMAP_I2C_BUF_REG 0x14 #define OMAP_I2C_CNT_REG 0x18 @@ -67,7 +90,8 @@ #define OMAP_I2C_SCLH_REG 0x38 #define OMAP_I2C_SYSTEST_REG 0x3c #define OMAP_I2C_BUFSTAT_REG 0x40 - +#define OMAP_I2C_IRQENABLE_CLR OMAP_I2C_IE_REG +#endif /* I2C Interrupt Enable Register (OMAP_I2C_IE): */ #define OMAP_I2C_IE_XDR (1 << 14) /* TX Buffer drain int enable */ #define OMAP_I2C_IE_RDR (1 << 13) /* RX Buffer drain int enable */ @@ -242,7 +266,10 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev) WARN_ON(dev->idle); dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); - omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0); + if (cpu_is_omap44xx()) + omap_i2c_write_reg(dev, OMAP_I2C_IRQENABLE_CLR, 1); + else + omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0); if (dev->rev < OMAP_I2C_REV_2) { iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG); /* Read clears */ } else { @@ -282,10 +309,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) /* SYSC register is cleared by the reset; rewrite it */ if (dev->rev == OMAP_I2C_REV_ON_2430) { - omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, SYSC_AUTOIDLE_MASK); - } else if (dev->rev >= OMAP_I2C_REV_ON_3430) { u32 v; @@ -302,6 +327,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) * WFI instruction. * REVISIT: Some wkup sources might not be needed. */ + if (!cpu_is_omap44xx()) omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, OMAP_I2C_WE_ALL); @@ -331,7 +357,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) psc = fclk_rate / 12000000; } - if (cpu_is_omap2430() || cpu_is_omap34xx()) { + if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) { /* * HSI2C controller internal clk rate should be 19.2 Mhz for @@ -345,7 +371,10 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) internal_clk = 9600; else internal_clk = 4000; - fclk_rate = clk_get_rate(dev->fclk) / 1000; + if (cpu_is_omap44xx()) + fclk_rate = 96000; + else + fclk_rate = clk_get_rate(dev->fclk) / 1000; /* Compute prescaler divisor */ psc = fclk_rate / internal_clk; @@ -708,7 +737,8 @@ complete: dev->buf_len--; /* Data reg from 2430 is 8 bit wide */ if (!cpu_is_omap2430() && - !cpu_is_omap34xx()) { + !cpu_is_omap34xx() + && !cpu_is_omap44xx()) { if (dev->buf_len) { *dev->buf++ = w >> 8; dev->buf_len--; @@ -748,7 +778,8 @@ complete: dev->buf_len--; /* Data reg from 2430 is 8 bit wide */ if (!cpu_is_omap2430() && - !cpu_is_omap34xx()) { + !cpu_is_omap34xx() && + !cpu_is_omap44xx()) { if (dev->buf_len) { w |= *dev->buf++ << 8; dev->buf_len--; @@ -861,15 +892,20 @@ omap_i2c_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, dev); - - if ((r = omap_i2c_get_clocks(dev)) != 0) - goto err_iounmap; + /* + * FIX-ME: Replace with correct clk node when clk + * framework is available + */ + if (!cpu_is_omap44xx()) { + if ((r = omap_i2c_get_clocks(dev)) != 0) + goto err_iounmap; + } omap_i2c_unidle(dev); dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff; - if (cpu_is_omap2430() || cpu_is_omap34xx()) { + if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) { u16 s; /* Set up the fifo size - Get total size */ @@ -881,8 +917,13 @@ omap_i2c_probe(struct platform_device *pdev) * size. This is to ensure that we can handle the status on int * call back latencies. */ - dev->fifo_size = (dev->fifo_size / 2); - dev->b_hw = 1; /* Enable hardware fixes */ + if (cpu_is_omap44xx()) { + dev->fifo_size = 0; + dev->b_hw = 0; /* Enable hardware fixes */ + } else { + dev->fifo_size = (dev->fifo_size / 2); + dev->b_hw = 1; /* Enable hardware fixes */ + } } /* reset ASAP, clearing any IRQs */ diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index a6b989a9dc07..630f49db3ec1 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -322,7 +322,7 @@ config KEYBOARD_SH_KEYSC config KEYBOARD_OMAP tristate "TI OMAP keypad support" - depends on (ARCH_OMAP1 || ARCH_OMAP2) + depends on (ARCH_OMAP1 || ARCH_OMAP2 || ARCH_OMAP4) help Say Y here if you want to use the OMAP keypad. diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index 87ec7b18ac69..fc96c7128172 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c @@ -44,6 +44,36 @@ #undef NEW_BOARD_LEARNING_MODE +#define OMAP4_KBDOCP_BASE 0x4A31C000 +#define OMAP4_KBD_REVISION 0x00 +#define OMAP4_KBD_SYSCONFIG 0x10 +#define OMAP4_KBD_SYSSTATUS 0x14 +#define OMAP4_KBD_IRQSTATUS 0x18 +#define OMAP4_KBD_IRQENABLE 0x1C +#define OMAP4_KBD_WAKEUPENABLE 0x20 +#define OMAP4_KBD_PENDING 0x24 +#define OMAP4_KBD_CTRL 0x28 +#define OMAP4_KBD_DEBOUNCINGTIME 0x2C +#define OMAP4_KBD_LONGKEYTIME 0x30 +#define OMAP4_KBD_TIMEOUT 0x34 +#define OMAP4_KBD_STATEMACHINE 0x38 +#define OMAP4_KBD_ROWINPUTS 0x3C +#define OMAP4_KBD_COLUMNOUTPUTS 0x40 +#define OMAP4_KBD_FULLCODE31_0 0x44 +#define OMAP4_KBD_FULLCODE63_32 0x48 + +#define OMAP4_KBD_SYSCONFIG_SOFTRST (1 << 1) +#define OMAP4_KBD_SYSCONFIG_ENAWKUP (1 << 2) +#define OMAP4_KBD_IRQENABLE_EVENTEN (1 << 0) +#define OMAP4_KBD_IRQENABLE_LONGKEY (1 << 1) +#define OMAP4_KBD_IRQENABLE_TIMEOUTEN (1 << 2) +#define OMAP4_KBD_CTRL_NOSOFTMODE (1 << 1) +#define OMAP4_KBD_CTRLPTVVALUE (1 << 2) +#define OMAP4_KBD_CTRLPTV (1 << 1) +#define OMAP4_KBD_IRQDISABLE 0x00 + +#define OMAP4_KBD_IRQSTATUSDISABLE 0xffff + static void omap_kp_tasklet(unsigned long); static void omap_kp_timer(unsigned long); @@ -114,6 +144,13 @@ static irqreturn_t omap_kp_interrupt(int irq, void *dev_id) else disable_irq(gpio_irq); } + } else if (cpu_is_omap44xx()) { + /* disable keyboard interrupt and schedule for handling */ + omap_writel(OMAP4_KBD_IRQDISABLE, OMAP4_KBDOCP_BASE + + OMAP4_KBD_IRQENABLE); + + omap_writel(omap_readl(OMAP4_KBDOCP_BASE + OMAP4_KBD_IRQSTATUS), + OMAP4_KBDOCP_BASE + OMAP4_KBD_IRQSTATUS); } else /* disable keyboard interrupt and schedule for handling */ omap_writew(1, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); @@ -131,7 +168,7 @@ static void omap_kp_timer(unsigned long data) static void omap_kp_scan_keypad(struct omap_kp *omap_kp, unsigned char *state) { int col = 0; - + u32 *p = (u32 *) state; /* read the keypad status */ if (cpu_is_omap24xx()) { /* read the keypad status */ @@ -141,6 +178,10 @@ static void omap_kp_scan_keypad(struct omap_kp *omap_kp, unsigned char *state) } set_col_gpio_val(omap_kp, 0); + } else if (cpu_is_omap44xx()) { + *p = omap_readl(OMAP4_KBDOCP_BASE + OMAP4_KBD_FULLCODE31_0); + *(p + 1) = omap_readl(OMAP4_KBDOCP_BASE + + OMAP4_KBD_FULLCODE63_32); } else { /* disable keyboard interrupt and schedule for handling */ omap_writew(1, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); @@ -198,7 +239,12 @@ static void omap_kp_tasklet(unsigned long data) row, (new_state[col] & (1 << row)) ? "pressed" : "released"); #else - key = omap_kp_find_key(col, row); + /* Keymappings have changed in omap4.*/ + if (cpu_is_omap44xx()) + key = omap_kp_find_key(row, col); + else + key = omap_kp_find_key(col, row); + if (key < 0) { printk(KERN_WARNING "omap-keypad: Spurious key event %d-%d\n", @@ -213,8 +259,14 @@ static void omap_kp_tasklet(unsigned long data) continue; kp_cur_group = key & GROUP_MASK; - input_report_key(omap_kp_data->input, key & ~GROUP_MASK, - new_state[col] & (1 << row)); + if (cpu_is_omap44xx()) + input_report_key(omap_kp_data->input, + key & ~GROUP_MASK, new_state[col] + & (1 << row)); + else + input_report_key(omap_kp_data->input, + key & ~GROUP_MASK, new_state[col] + & (1 << row)); #endif } } @@ -233,10 +285,18 @@ static void omap_kp_tasklet(unsigned long data) int i; for (i = 0; i < omap_kp_data->rows; i++) enable_irq(gpio_to_irq(row_gpios[i])); - } else { - omap_writew(0, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); - kp_cur_group = -1; - } + + } else if (cpu_is_omap44xx()) { + omap_writew(OMAP4_KBD_IRQENABLE_EVENTEN | + OMAP4_KBD_IRQENABLE_LONGKEY, + OMAP4_KBDOCP_BASE + + OMAP4_KBD_IRQENABLE); + kp_cur_group = -1; + } else { + omap_writew(0, OMAP_MPUIO_BASE + + OMAP_MPUIO_KBD_MASKIT); + kp_cur_group = -1; + } } } @@ -316,7 +376,7 @@ static int __devinit omap_kp_probe(struct platform_device *pdev) omap_kp->input = input_dev; /* Disable the interrupt for the MPUIO keyboard */ - if (!cpu_is_omap24xx()) + if (!cpu_is_omap24xx() && !cpu_is_omap44xx()) omap_writew(1, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); keymap = pdata->keymap; @@ -390,19 +450,33 @@ static int __devinit omap_kp_probe(struct platform_device *pdev) goto err3; } - if (pdata->dbounce) - omap_writew(0xff, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_DEBOUNCING); - + if (pdata->dbounce) { + if (cpu_is_omap44xx()) + omap_writew(0xff, OMAP_MPUIO_BASE + + OMAP4_KBD_DEBOUNCINGTIME); + else + omap_writew(0xff, OMAP_MPUIO_BASE + + OMAP_MPUIO_GPIO_DEBOUNCING); + } /* scan current status and enable interrupt */ omap_kp_scan_keypad(omap_kp, keypad_state); + + /* Configuring OMAP4 keypad registers */ + if (cpu_is_omap44xx()) { + omap_writew(OMAP4_KBD_SYSCONFIG_SOFTRST | + OMAP4_KBD_SYSCONFIG_ENAWKUP, OMAP4_KBDOCP_BASE + + OMAP4_KBD_SYSCONFIG); + omap_writew((OMAP4_KBD_CTRLPTVVALUE << OMAP4_KBD_CTRLPTV) | + OMAP4_KBD_CTRL_NOSOFTMODE, + OMAP4_KBDOCP_BASE + OMAP4_KBD_CTRL); + } if (!cpu_is_omap24xx()) { omap_kp->irq = platform_get_irq(pdev, 0); - if (omap_kp->irq >= 0) { - if (request_irq(omap_kp->irq, omap_kp_interrupt, 0, + if (request_irq(152, omap_kp_interrupt, 0, "omap-keypad", omap_kp) < 0) goto err4; - } - omap_writew(0, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); + if (!cpu_is_omap44xx()) + omap_writew(0, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); } else { for (irq_idx = 0; irq_idx < omap_kp->rows; irq_idx++) { if (request_irq(gpio_to_irq(row_gpios[irq_idx]), @@ -412,6 +486,11 @@ static int __devinit omap_kp_probe(struct platform_device *pdev) goto err5; } } + if (cpu_is_omap44xx()) { + omap_writew(OMAP4_KBD_IRQENABLE_EVENTEN | + OMAP4_KBD_IRQENABLE_LONGKEY, OMAP4_KBDOCP_BASE + + OMAP4_KBD_IRQENABLE); + } return 0; err5: for (i = irq_idx - 1; i >=0; i--) diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index ba69beeb0e21..9318e73fde87 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig @@ -5,6 +5,7 @@ menuconfig MEDIA_SUPPORT tristate "Multimedia support" depends on HAS_IOMEM + default y help If you want to use Video for Linux, DVB for Linux, or DAB adapters, enable this option and other options below. @@ -19,6 +20,7 @@ comment "Multimedia core support" config VIDEO_DEV tristate "Video For Linux" + default y ---help--- V4L core support for video capture and overlay devices, webcams and AM/FM radio cards. diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 84b6fc15519d..9a516ebd659d 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -718,6 +718,18 @@ config VIDEO_CAFE_CCIC CMOS camera controller. This is the controller found on first- generation OLPC systems. +config VIDEO_OMAP3 + bool "OMAP2/OMAP3/OMAP4 Camera and V4L2-DSS drivers" + select VIDEOBUF_GEN + select VIDEOBUF_DMA_SG + select OMAP2_DSS + depends on VIDEO_DEV && (ARCH_OMAP24XX || ARCH_OMAP34XX || ARCH_OMAP4) + default y + ---help--- + V4L2 DSS and Camera driver support for OMAP2/3/4 based boards. + +source "drivers/media/video/omap/Kconfig" + config SOC_CAMERA tristate "SoC camera support" depends on VIDEO_V4L2 && HAS_DMA && I2C diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 9f2e3214a482..ceff5fcc2e1b 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -117,6 +117,8 @@ obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o obj-$(CONFIG_VIDEO_CAFE_CCIC) += cafe_ccic.o +obj-$(CONFIG_VIDEO_OMAP3) += omap/ + obj-$(CONFIG_USB_DABUSB) += dabusb.o obj-$(CONFIG_USB_OV511) += ov511.o obj-$(CONFIG_USB_SE401) += se401.o @@ -160,6 +162,8 @@ obj-$(CONFIG_USB_VIDEO_CLASS) += uvc/ obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o +obj-$(CONFIG_DMM_TILER) += tiler/ + EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core EXTRA_CFLAGS += -Idrivers/media/dvb/frontends EXTRA_CFLAGS += -Idrivers/media/common/tuners diff --git a/drivers/media/video/omap/Kconfig b/drivers/media/video/omap/Kconfig new file mode 100644 index 000000000000..d7293a46839e --- /dev/null +++ b/drivers/media/video/omap/Kconfig @@ -0,0 +1,27 @@ +config VIDEO_OMAP_VIDEOLIB + tristate "OMAP Video out library" + depends on VIDEO_OMAP3 + default VIDEO_OMAP3 + +config VIDEO_OMAP_VIDEOOUT + tristate "OMAP Video out driver" + select VIDEOBUF_DMA_SG + select VIDEOBUF_GEN + depends on VIDEO_OMAP3 + default VIDEO_OMAP3 + +choice + prompt "TV Mode" + default NTSC_M + +config NTSC_M + bool "Use NTSC_M mode" + help + Select this option if you want NTSC_M mode on TV + +config PAL_BDGHI + bool "Use PAL_BDGHI mode" + help + Select this option if you want PAL_BDGHI mode on TV + +endchoice diff --git a/drivers/media/video/omap/Makefile b/drivers/media/video/omap/Makefile new file mode 100644 index 000000000000..75e01d346c4d --- /dev/null +++ b/drivers/media/video/omap/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_VIDEO_OMAP_VIDEOLIB) += omap_voutlib.o +obj-$(CONFIG_VIDEO_OMAP_VIDEOOUT) += omap_vout.o + diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c new file mode 100644 index 000000000000..0b736754bd11 --- /dev/null +++ b/drivers/media/video/omap/omap_vout.c @@ -0,0 +1,2687 @@ +/* + * drivers/media/video/omap/omap_vout.c + * + * Copyright (C) 2005-2009 Texas Instruments. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + * + * Leveraged code from the OMAP2 camera driver + * Video-for-Linux (Version 2) camera capture driver for + * the OMAP24xx camera controller. + * + * Author: Andy Lowe (source@mvista.com) + * + * Copyright (C) 2004 MontaVista Software, Inc. + * Copyright (C) 2009 Texas Instruments. + * + * History: + * 20-APR-2006 Khasim Modified VRFB based Rotation, + * The image data is always read from 0 degree + * view and written + * to the virtual space of desired rotation angle + * 4-DEC-2006 Jian Changed to support better memory management + * + * 17-Nov-2008 Hardik Changed to used the new DSS paches by Tomi + * Changed driver to use video_ioctl2 + * + */ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/errno.h> +#include <linux/fs.h> +#include <linux/kernel.h> +#include <linux/vmalloc.h> +#include <linux/interrupt.h> +#include <linux/kdev_t.h> +#include <linux/types.h> +#include <linux/wait.h> +#include <linux/videodev2.h> +#include <linux/platform_device.h> +#include <linux/dma-mapping.h> +#include <linux/irq.h> + +#include <media/videobuf-dma-sg.h> +#include <media/v4l2-dev.h> +#include <media/v4l2-ioctl.h> +#include <media/v4l2-common.h> +#include <media/v4l2-device.h> + +#include <asm/processor.h> +#include <mach/dma.h> +#include <mach/vram.h> +#include <mach/vrfb.h> +#include <mach/display.h> +#include "omap_voutlib.h" +#include "omap_voutdef.h" +MODULE_AUTHOR("Texas Instruments."); +MODULE_DESCRIPTION("OMAP Video for Linux Video out driver"); +MODULE_LICENSE("GPL"); + +#define OMAP_VIDEO1 0 +#define OMAP_VIDEO2 1 + +/* configuration macros */ +#define VOUT_NAME "omap_vout" + +#define QQVGA_WIDTH 160 +#define QQVGA_HEIGHT 120 + +#define NUM_OF_VIDEO_CHANNELS 2 + +#define VID_MAX_WIDTH 1280 /* Largest width */ +#define VID_MAX_HEIGHT 720/* Largest height */ + +/* Mimimum requirement is 2x2 for DSS */ +#define VID_MIN_WIDTH 2 +#define VID_MIN_HEIGHT 2 + +/* 2048 x 2048 is max res supported by OMAP display controller */ +#define DMA_CHAN_ALLOTED 1 +#define DMA_CHAN_NOT_ALLOTED 0 +#define MAX_PIXELS_PER_LINE 2048 +#define VRFB_TX_TIMEOUT 1000 + +/* IRQ Bits mask of DSS */ +#define OMAP_VOUT_MAX_BUF_SIZE (VID_MAX_WIDTH*VID_MAX_HEIGHT*4) + +static struct videobuf_queue_ops video_vbq_ops; + +static u32 video1_numbuffers = 3; +static u32 video2_numbuffers = 3; +static u32 video1_bufsize = OMAP_VOUT_MAX_BUF_SIZE; +static u32 video2_bufsize = OMAP_VOUT_MAX_BUF_SIZE; +static u32 vid1_static_vrfb_alloc; +static u32 vid2_static_vrfb_alloc; +static int debug; + +/* Module parameters */ +module_param(video1_numbuffers, uint, S_IRUGO); +MODULE_PARM_DESC(video1_numbuffers, "Number of buffers to be allocated at \ + init time for Video1 device."); + +module_param(video2_numbuffers, uint, S_IRUGO); +MODULE_PARM_DESC(video2_numbuffers, "Number of buffers to be allocated at \ + init time for Video2 device."); + +module_param(video1_bufsize, uint, S_IRUGO); +MODULE_PARM_DESC(video1_bufsize, "Size of the buffer to be allocated for \ + video1 device"); + +module_param(video2_bufsize, uint, S_IRUGO); +MODULE_PARM_DESC(video2_bufsize, "Size of the buffer to be allocated for \ + video2 device"); + +module_param(vid1_static_vrfb_alloc, bool, S_IRUGO); +MODULE_PARM_DESC(vid1_static_vrfb_alloc, "Static allocation of the VRFB \ + buffer for video1 device"); + +module_param(vid2_static_vrfb_alloc, bool, S_IRUGO); +MODULE_PARM_DESC(vid2_static_vrfb_alloc, "Static allocation of the VRFB \ + buffer for video2 device"); + +module_param(debug, bool, S_IRUGO); +MODULE_PARM_DESC(debug, "Debug level (0-1)"); + +/* Local Helper functions */ +static int omap_vout_create_video_devices(struct platform_device *pdev); +static int omapvid_apply_changes(struct omap_vout_device *vout); +static int omapvid_init(struct omap_vout_device *vout, u32 addr); +static int omapvid_setup_overlay(struct omap_vout_device *vout, + struct omap_overlay *ovl, int posx, int posy, + int outw, int outh, u32 addr); +static enum omap_color_mode video_mode_to_dss_mode(struct omap_vout_device + *vout); +static void omap_vout_isr(void *arg, unsigned int irqstatus); +static void omap_vout_cleanup_device(struct omap_vout_device *vout); + +/* + * Maximum amount of memory to use for rendering buffers. + * Default is enough to four (RGB24) DVI 720P buffers. + */ +#define MAX_ALLOWED_VIDBUFFERS 4 + +/* list of image formats supported by OMAP2 video pipelines */ +const static struct v4l2_fmtdesc omap_formats[] = { + { + /* Note: V4L2 defines RGB565 as: + * + * Byte 0 Byte 1 + * g2 g1 g0 r4 r3 r2 r1 r0 b4 b3 b2 b1 b0 g5 g4 g3 + * + * We interpret RGB565 as: + * + * Byte 0 Byte 1 + * g2 g1 g0 b4 b3 b2 b1 b0 r4 r3 r2 r1 r0 g5 g4 g3 + */ + .description = "RGB565, le", + .pixelformat = V4L2_PIX_FMT_RGB565, + }, + { + /* Note: V4L2 defines RGB32 as: RGB-8-8-8-8 we use + * this for RGB24 unpack mode, the last 8 bits are ignored + * */ + .description = "RGB32, le", + .pixelformat = V4L2_PIX_FMT_RGB32, + }, + { + /* Note: V4L2 defines RGB24 as: RGB-8-8-8 we use + * this for RGB24 packed mode + * + */ + .description = "RGB24, le", + .pixelformat = V4L2_PIX_FMT_RGB24, + }, + { + .description = "YUYV (YUV 4:2:2), packed", + .pixelformat = V4L2_PIX_FMT_YUYV, + }, + { + .description = "UYVY, packed", + .pixelformat = V4L2_PIX_FMT_UYVY, + }, +}; + +#define NUM_OUTPUT_FORMATS (ARRAY_SIZE(omap_formats)) + +/* Allocate buffers */ +static unsigned long omap_vout_alloc_buffer(u32 buf_size, u32 *phys_addr) +{ + unsigned long virt_addr, addr; + u32 order, size; + + size = PAGE_ALIGN(buf_size); + order = get_order(size); + virt_addr = __get_free_pages(GFP_KERNEL | GFP_DMA, order); + addr = virt_addr; + if (virt_addr) { + while (size > 0) { + SetPageReserved(virt_to_page(addr)); + addr += PAGE_SIZE; + size -= PAGE_SIZE; + } + } + *phys_addr = (u32) virt_to_phys((void *) virt_addr); + return virt_addr; +} + +/* Free buffers */ +static void omap_vout_free_buffer(unsigned long virtaddr, u32 phys_addr, + u32 buf_size) +{ + unsigned long addr = virtaddr; + u32 order, size; + + size = PAGE_ALIGN(buf_size); + order = get_order(size); + while (size > 0) { + ClearPageReserved(virt_to_page(addr)); + addr += PAGE_SIZE; + size -= PAGE_SIZE; + } + free_pages((unsigned long) virtaddr, order); +} + +/* Function for allocating video buffers */ +static int omap_vout_allocate_vrfb_buffers(struct omap_vout_device *vout, + int count, int startindex) +{ + int i, j; + + for (i = 0; i < count; i++) { + if (!vout->smsshado_virt_addr[i]) { + vout->smsshado_virt_addr[i] = + omap_vout_alloc_buffer(vout->smsshado_size, + &vout->smsshado_phy_addr[i]); + } + if (!vout->smsshado_virt_addr[i] && startindex != -1) { + if (V4L2_MEMORY_MMAP == vout->memory + && i >= startindex) + break; + } + if (!vout->smsshado_virt_addr[i]) { + for (j = 0; j < i; j++) { + omap_vout_free_buffer( + vout->smsshado_virt_addr[j], + vout->smsshado_phy_addr[j], + vout->smsshado_size); + vout->smsshado_virt_addr[j] = 0; + vout->smsshado_phy_addr[j] = 0; + } + count = 0; + return -ENOMEM; + } + memset((void *) vout->smsshado_virt_addr[i], 0, + vout->smsshado_size); + } + return 0; +} + +/* Try format */ +static int omap_vout_try_format(struct v4l2_pix_format *pix) +{ + int ifmt, bpp = 0; + + pix->height = clamp(pix->height, (u32)VID_MIN_HEIGHT, + (u32)VID_MAX_HEIGHT); + pix->width = clamp(pix->width, (u32)VID_MIN_WIDTH, (u32)VID_MAX_WIDTH); + + for (ifmt = 0; ifmt < NUM_OUTPUT_FORMATS; ifmt++) { + if (pix->pixelformat == omap_formats[ifmt].pixelformat) + break; + } + + if (ifmt == NUM_OUTPUT_FORMATS) + ifmt = 0; + + pix->pixelformat = omap_formats[ifmt].pixelformat; + pix->field = V4L2_FIELD_ANY; + pix->priv = 0; + + switch (pix->pixelformat) { + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_UYVY: + default: + pix->colorspace = V4L2_COLORSPACE_JPEG; + bpp = YUYV_BPP; + break; + case V4L2_PIX_FMT_RGB565: + case V4L2_PIX_FMT_RGB565X: + pix->colorspace = V4L2_COLORSPACE_SRGB; + bpp = RGB565_BPP; + break; + case V4L2_PIX_FMT_RGB24: + pix->colorspace = V4L2_COLORSPACE_SRGB; + bpp = RGB24_BPP; + break; + case V4L2_PIX_FMT_RGB32: + case V4L2_PIX_FMT_BGR32: + pix->colorspace = V4L2_COLORSPACE_SRGB; + bpp = RGB32_BPP; + break; + } + pix->bytesperline = pix->width * bpp; + pix->sizeimage = pix->bytesperline * pix->height; + return bpp; +} + +/* + * omap_vout_uservirt_to_phys: This inline function is used to convert user + * space virtual address to physical address. + */ +static inline u32 omap_vout_uservirt_to_phys(u32 virtp) +{ + unsigned long physp = 0; + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; + + vma = find_vma(mm, virtp); + /* For kernel direct-mapped memory, take the easy way */ + if (virtp >= PAGE_OFFSET) { + physp = virt_to_phys((void *) virtp); + } else if ((vma) && (vma->vm_flags & VM_IO) + && (vma->vm_pgoff)) { + /* this will catch, kernel-allocated, + mmaped-to-usermode addresses */ + physp = (vma->vm_pgoff << PAGE_SHIFT) + (virtp - vma->vm_start); + } else { + /* otherwise, use get_user_pages() for general userland pages */ + int res, nr_pages = 1; + struct page *pages; + down_read(¤t->mm->mmap_sem); + + res = get_user_pages(current, current->mm, virtp, nr_pages, + 1, 0, &pages, NULL); + up_read(¤t->mm->mmap_sem); + + if (res == nr_pages) { + physp = __pa(page_address(&pages[0]) + + (virtp & ~PAGE_MASK)); + } else { + printk(KERN_WARNING VOUT_NAME + "omap_vout_uservirt_to_phys:\ + get_user_pages failed\n"); + return 0; + } + } + + return physp; +} + +/* This functions wakes up the application once + * the DMA transfer to VRFB space is completed. */ +static void omap_vout_vrfb_dma_tx_callback(int lch, u16 ch_status, void *data) +{ + struct vid_vrfb_dma *t = (struct vid_vrfb_dma *) data; + + t->tx_status = 1; + wake_up_interruptible(&t->wait); +} + +/* Release the VRFB context once the module exits */ +static void omap_vout_release_vrfb(struct omap_vout_device *vout) +{ +#ifndef CONFIG_ARCH_OMAP4 +/* TODO: this is temporary disabling of vrfb to test V4L2: needs to be + corrected for future +*/ + int i; + for (i = 0; i < 4; i++) + omap_vrfb_release_ctx(&vout->vrfb_context[i]); +#endif + if (vout->vrfb_dma_tx.req_status == DMA_CHAN_ALLOTED) { + vout->vrfb_dma_tx.req_status = DMA_CHAN_NOT_ALLOTED; + omap_free_dma(vout->vrfb_dma_tx.dma_ch); + } + +} + +/* Return true if rotation is 90 or 270 */ +static inline int rotate_90_or_270(struct omap_vout_device *vout) +{ + return (vout->rotation == dss_rotation_90_degree || + vout->rotation == dss_rotation_270_degree); +} + +/* Return true if rotation is enabled */ +static inline int rotation_enabled(struct omap_vout_device *vout) +{ + return vout->rotation || vout->mirror; +} + +/* Reverse the rotation degree if mirroring is enabled */ +static inline int calc_rotation(struct omap_vout_device *vout) +{ + if (!vout->mirror) + return vout->rotation; + + switch (vout->rotation) { + case dss_rotation_90_degree: + return dss_rotation_270_degree; + case dss_rotation_270_degree: + return dss_rotation_90_degree; + case dss_rotation_180_degree: + return dss_rotation_0_degree; + default: + return dss_rotation_180_degree; + } +} + +/* Free the V4L2 buffers */ +static void omap_vout_free_buffers(struct omap_vout_device *vout) +{ + int i, numbuffers; + + /* Allocate memory for the buffes */ + numbuffers = (vout->vid) ? video2_numbuffers : video1_numbuffers; + vout->buffer_size = (vout->vid) ? video2_bufsize : video1_bufsize; + + for (i = 0; i < numbuffers; i++) { + omap_vout_free_buffer(vout->buf_virt_addr[i], + vout->buf_phy_addr[i], vout->buffer_size); + vout->buf_phy_addr[i] = 0; + vout->buf_virt_addr[i] = 0; + } +} + +/* Free VRFB buffers */ +static void omap_vout_free_vrfb_buffers(struct omap_vout_device *vout) +{ + int j; + + for (j = 0; j < 4; j++) { + omap_vout_free_buffer(vout->smsshado_virt_addr[j], + vout->smsshado_phy_addr[j], + vout->smsshado_size); + vout->smsshado_virt_addr[j] = 0; + vout->smsshado_phy_addr[j] = 0; + } +} + +/* Allocate the buffers for the VRFB space. Data is copied from V4L2 + * buffers to the VRFB buffers using the DMA engine.*/ +static int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout, + unsigned int *count, unsigned int startindex) +{ + int i; + + /* Allocate the VRFB buffers only if the buffers are not + * allocated during init time. + */ + if ((rotation_enabled(vout)) && + !vout->vrfb_static_allocation) + if (omap_vout_allocate_vrfb_buffers(vout, *count, startindex)) + return -ENOMEM; + +#ifndef CONFIG_ARCH_OMAP4 +/* TODO: this is temporary disabling of vrfb to test V4L2: needs to be + corrected for future +*/ + for (i = 0; i < *count; i++) { + omap_vrfb_setup(&vout->vrfb_context[i], + vout->smsshado_phy_addr[i], + vout->pix.width, vout->pix.height, + vout->dss_mode); + } +#endif + return 0; +} + +/* Convert V4L2 rotation to DSS rotation + * V4L2 understand 0, 90, 180, 270. + * convert to 0, 1, 2 and 3 repsectively for DSS */ +static int v4l2_rot_to_dss_rot(int v4l2_rotation, enum dss_rotation *rotation, + bool mirror) +{ + switch (v4l2_rotation) { + case 90: + *rotation = dss_rotation_90_degree; + return 0; + case 180: + *rotation = dss_rotation_180_degree; + return 0; + case 270: + *rotation = dss_rotation_270_degree; + return 0; + case 0: + *rotation = dss_rotation_0_degree; + return 0; + default: + return -EINVAL; + } + +} + +/* Calculate the buffer offsets from which the streaming should + * start. This offset calculation is mainly required because of + * the VRFB 32 pixels alignment with rotation + */ +static int omap_vout_calculate_offset(struct omap_vout_device *vout) +{ + struct v4l2_pix_format *pix = &(vout->pix); + struct v4l2_rect *crop = &(vout->crop); + enum dss_rotation rotation; + bool mirroring = vout->mirror; + int vr_ps = 1, ps = 2, temp_ps = 2; + int offset = 0, ctop = 0, cleft = 0, line_length = 0; + struct omapvideo_info *ovid; + struct omap_overlay *ovl; + struct omap_dss_device *cur_display; + int *cropped_offset = &(vout->cropped_offset); + + ovid = &(vout->vid_info); + ovl = ovid->overlays[0]; + /* get the display device attached to the overlay */ + if (!ovl->manager || !ovl->manager->device) + return -1; + cur_display = ovl->manager->device; + + rotation = calc_rotation(vout); + + if (V4L2_PIX_FMT_YUYV == pix->pixelformat || + V4L2_PIX_FMT_UYVY == pix->pixelformat) { + if (rotation_enabled(vout)) { + /* + * ps - Actual pixel size for YUYV/UYVY for + * VRFB/Mirroring is 4 bytes + * vr_ps - Virtually pixel size for YUYV/UYVY is + * 2 bytes + */ + ps = 4; + vr_ps = 2; + } else { + ps = 2; /* otherwise the pixel size is 2 byte */ + } + } else if (V4L2_PIX_FMT_RGB32 == pix->pixelformat) { + ps = 4; + } else if (V4L2_PIX_FMT_RGB24 == pix->pixelformat) { + ps = 3; + } + vout->ps = ps; + vout->vr_ps = vr_ps; + if (rotation_enabled(vout)) { + line_length = MAX_PIXELS_PER_LINE; + ctop = (pix->height - crop->height) - crop->top; + cleft = (pix->width - crop->width) - crop->left; + } else { + line_length = pix->width; + } + vout->line_length = line_length; + switch (rotation) { + case dss_rotation_90_degree: + offset = vout->vrfb_context[0].yoffset * + vout->vrfb_context[0].bytespp; + temp_ps = ps / vr_ps; + if (mirroring == 0) { + *cropped_offset = offset + line_length * + temp_ps * cleft + crop->top * temp_ps; + } else { + *cropped_offset = offset + line_length * temp_ps * + cleft + crop->top * temp_ps + (line_length * + ((crop->width / (vr_ps)) - 1) * ps); + } + break; + case dss_rotation_180_degree: + offset = ((MAX_PIXELS_PER_LINE * vout->vrfb_context[0].yoffset * + vout->vrfb_context[0].bytespp) + + (vout->vrfb_context[0].xoffset * + vout->vrfb_context[0].bytespp)); + if (mirroring == 0) { + *cropped_offset = offset + (line_length * ps * ctop) + + (cleft / vr_ps) * ps; + + } else { + *cropped_offset = offset + (line_length * ps * ctop) + + (cleft / vr_ps) * ps + (line_length * + (crop->height - 1) * ps); + } + break; + case dss_rotation_270_degree: + offset = MAX_PIXELS_PER_LINE * vout->vrfb_context[0].xoffset * + vout->vrfb_context[0].bytespp; + temp_ps = ps / vr_ps; + if (mirroring == 0) { + *cropped_offset = offset + line_length * + temp_ps * crop->left + ctop * ps; + } else { + *cropped_offset = offset + line_length * + temp_ps * crop->left + ctop * ps + + (line_length * ((crop->width / vr_ps) - 1) * + ps); + } + break; + case dss_rotation_0_degree: + if (mirroring == 0) { + *cropped_offset = (line_length * ps) * + crop->top + (crop->left / vr_ps) * ps; + } else { + *cropped_offset = (line_length * ps) * + crop->top + (crop->left / vr_ps) * ps + + (line_length * (crop->height - 1) * ps); + } + break; + default: + *cropped_offset = (line_length * ps * crop->top) / + vr_ps + (crop->left * ps) / vr_ps + + ((crop->width / vr_ps) - 1) * ps; + break; + } + v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, + "%s Offset:%x\n", __func__, *cropped_offset); + return 0; +} + +/* Initialize the overlay structure */ +int omapvid_init(struct omap_vout_device *vout, u32 addr) +{ + int r = 0; + struct omapvideo_info *ovid = &(vout->vid_info); + struct omap_overlay *ovl; + int posx, posy; + int outw, outh, temp, rotation; + int i; + struct v4l2_window *win; + struct omap_video_timings *timing; + + win = &vout->win; + rotation = vout->rotation; + for (i = 0; i < ovid->num_overlays; i++) { + ovl = ovid->overlays[i]; + if (!ovl->manager || !ovl->manager->device) + return -EINVAL; + + timing = &ovl->manager->device->panel.timings; + + outw = win->w.width; + outh = win->w.height; + switch (rotation) { + + case dss_rotation_90_degree: + /* Invert the height and widht for 90 + * and 270 degree rotation + */ + temp = outw; + outw = outh; + outh = temp; + posy = (timing->y_res - win->w.width)- + win->w.left; + posx = win->w.top; + break; + + case dss_rotation_180_degree: + posx = (timing->x_res - win->w.width) - + win->w.left; + posy = (timing->y_res - win->w.height) - + win->w.top; + break; + + case dss_rotation_270_degree: + temp = outw; + outw = outh; + outh = temp; + posy = win->w.left; + posx = (timing->x_res - win->w.height) + - win->w.top; + break; + + default: + posx = win->w.left; + posy = win->w.top; + break; + } + + r = omapvid_setup_overlay(vout, ovl, posx, posy, outw, + outh, addr); + if (r) + goto err; + } + return 0; +err: + printk(KERN_WARNING VOUT_NAME "apply_changes failed\n"); + return r; +} + +/* Apply the changes set the go bit of DSS */ +int omapvid_apply_changes(struct omap_vout_device *vout) +{ + struct omapvideo_info *ovid = &(vout->vid_info); + struct omap_overlay *ovl; + int i; + + for (i = 0; i < ovid->num_overlays; i++) { + ovl = ovid->overlays[i]; + if (!ovl->manager || !ovl->manager->device) + return -EINVAL; + ovl->manager->apply(ovl->manager); + } + return 0; + +} + +/* Setup the overlay */ +int omapvid_setup_overlay(struct omap_vout_device *vout, + struct omap_overlay *ovl, int posx, int posy, int outw, + int outh, u32 addr) +{ + int r = 0; + enum omap_color_mode mode = 0; + enum dss_rotation rotation; + bool mirror; + int cropheight, cropwidth, pixheight, pixwidth; + struct omap_overlay_info info; + + if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0 && + (outw != vout->pix.width || outh != vout->pix.height)) { + r = -EINVAL; + goto err; + } + + vout->dss_mode = video_mode_to_dss_mode(vout); + + if (mode == -EINVAL) { + r = -EINVAL; + goto err; + } + + rotation = vout->rotation; + mirror = vout->mirror; + + /* Setup the input plane parameters according to + * rotation value selected. + */ + if (rotate_90_or_270(vout)) { + cropheight = vout->crop.width; + cropwidth = vout->crop.height; + pixheight = vout->pix.width; + pixwidth = vout->pix.height; + } else { + cropheight = vout->crop.height; + cropwidth = vout->crop.width; + pixheight = vout->pix.height; + pixwidth = vout->pix.width; + } + + ovl->get_overlay_info(ovl, &info); + info.paddr = addr; + info.vaddr = NULL; + info.width = cropwidth; + info.height = cropheight; + info.color_mode = vout->dss_mode; + info.mirror = mirror; + info.pos_x = posx; + info.pos_y = posy; + info.out_width = outw; + info.out_height = outh; + info.global_alpha = vout->win.global_alpha; + if (!rotation_enabled(vout)) { + info.rotation = 0; + info.rotation_type = OMAP_DSS_ROT_DMA; + info.screen_width = pixwidth; + } else { + info.rotation = vout->rotation; + info.rotation_type = OMAP_DSS_ROT_VRFB; + info.screen_width = 2048; + } + + v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, + "%s info.enable=%d info.addr=%x info.width=%d\n info.height=%d \ + info.color_mode=%d info.rotation=%d info.mirror=%d\n \ + info.posx=%d info.posy=%d info.out_width = %d info.out_height=%d\n \ + info.rotation_type=%d info.screen_width=%d\n", __func__, info.enabled, + info.paddr, info.width, info.height, info.color_mode, info.rotation, + info.mirror, info.pos_x, info.pos_y, info.out_width, info.out_height, + info.rotation_type, info.screen_width); + + r = ovl->set_overlay_info(ovl, &info); + if (r) + goto err; + + return 0; +err: + printk(KERN_WARNING VOUT_NAME "setup_overlay failed\n"); + return r; +} + +/* convert V4L2 pixel format to DSS pixel format */ +static enum omap_color_mode video_mode_to_dss_mode(struct omap_vout_device + *vout) +{ + struct v4l2_pix_format *pix = &vout->pix; + + switch (pix->pixelformat) { + case 0: + break; + case V4L2_PIX_FMT_YUYV: + return OMAP_DSS_COLOR_YUV2; + + case V4L2_PIX_FMT_UYVY: + return OMAP_DSS_COLOR_UYVY; + + case V4L2_PIX_FMT_RGB565: + return OMAP_DSS_COLOR_RGB16; + + case V4L2_PIX_FMT_RGB24: + return OMAP_DSS_COLOR_RGB24P; + + case V4L2_PIX_FMT_RGB32: + return (vout->vid == OMAP_VIDEO1) ? + OMAP_DSS_COLOR_RGB24U : OMAP_DSS_COLOR_ARGB32; + case V4L2_PIX_FMT_BGR32: + return OMAP_DSS_COLOR_RGBX32; + + default: + return -EINVAL; + } + return -EINVAL; +} + +/* Video buffer call backs */ + +/* Buffer setup function is called by videobuf layer when REQBUF ioctl is + * called. This is used to setup buffers and return size and count of + * buffers allocated. After the call to this buffer, videobuf layer will + * setup buffer queue depending on the size and count of buffers + */ +static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count, + unsigned int *size) +{ + struct omap_vout_device *vout = q->priv_data; + int startindex = 0, i, j; + u32 phy_addr = 0, virt_addr = 0; + + if (!vout) + return -EINVAL; + + if (V4L2_BUF_TYPE_VIDEO_OUTPUT != q->type) + return -EINVAL; + + startindex = (vout->vid == OMAP_VIDEO1) ? + video1_numbuffers : video2_numbuffers; + if (V4L2_MEMORY_MMAP == vout->memory && *count < startindex) + *count = startindex; + +#if defined CONFIG_ARCH_OMAP4 + vout->rotation = 0; + printk(KERN_WARNING VOUT_NAME + " setting rotation to 0 in buffer setup\n"); +#endif + if ((rotation_enabled(vout)) + && *count > 4) + *count = 4; + +#ifndef CONFIG_ARCH_OMAP4 +/* TODO: this is temporary disabling of vrfb to test V4L2: needs to be + corrected for future*/ + /* If rotation is enabled, allocate memory for VRFB space also */ + if (rotation_enabled(vout)) { + if (omap_vout_vrfb_buffer_setup(vout, count, startindex)) + return -ENOMEM; + } +#endif + if (V4L2_MEMORY_MMAP != vout->memory) + return 0; + + /* Now allocated the V4L2 buffers */ + *size = vout->buffer_size; + startindex = (vout->vid == OMAP_VIDEO1) ? + video1_numbuffers : video2_numbuffers; + for (i = startindex; i < *count; i++) { + vout->buffer_size = *size; + + virt_addr = omap_vout_alloc_buffer(vout->buffer_size, + &phy_addr); + if (!virt_addr) { + printk(KERN_WARNING VOUT_NAME + "Memory not available: virt address " + "problem in buffer setup\n"); + if (!rotation_enabled(vout)) + break; + /* Free the VRFB buffers if no space for V4L2 buffers */ + for (j = i; j < *count; j++) { + omap_vout_free_buffer( + vout->smsshado_virt_addr[j], + vout->smsshado_phy_addr[j], + vout->smsshado_size); + vout->smsshado_virt_addr[j] = 0; + vout->smsshado_phy_addr[j] = 0; + } + } + vout->buf_virt_addr[i] = virt_addr; + vout->buf_phy_addr[i] = phy_addr; + } + *count = vout->buffer_allocated = i; + return 0; +} + +/* Free the V4L2 buffers additionally allocated than default + * number of buffers and free all the VRFB buffers */ +static void omap_vout_free_allbuffers(struct omap_vout_device *vout) +{ + int num_buffers = 0, i; + + num_buffers = (vout->vid == OMAP_VIDEO1) ? + video1_numbuffers : video2_numbuffers; + for (i = num_buffers; i < vout->buffer_allocated; i++) { + if (vout->buf_virt_addr[i]) { + omap_vout_free_buffer(vout->buf_virt_addr[i], + vout->buf_phy_addr[i], vout->buffer_size); + } + vout->buf_virt_addr[i] = 0; + vout->buf_phy_addr[i] = 0; + } + /* Free the VRFB buffers only if they are allocated + * during reqbufs. Don't free if init time allocated + */ + if (!vout->vrfb_static_allocation) { + for (i = 0; i < 4; i++) { + if (vout->smsshado_virt_addr[i]) { + omap_vout_free_buffer( + vout->smsshado_virt_addr[i], + vout->smsshado_phy_addr[i], + vout->smsshado_size); + vout->smsshado_virt_addr[i] = 0; + vout->smsshado_phy_addr[i] = 0; + } + } + } + vout->buffer_allocated = num_buffers; +} + +/* This function will be called when VIDIOC_QBUF ioctl is called. + * It prepare buffers before give out for the display. This function + * user space virtual address into physical address if userptr memory + * exchange mechanism is used. If rotation is enabled, it copies entire + * buffer into VRFB memory space before giving it to the DSS. + */ +static int omap_vout_buffer_prepare(struct videobuf_queue *q, + struct videobuf_buffer *vb, + enum v4l2_field field) +{ + struct omap_vout_device *vout = q->priv_data; + struct videobuf_dmabuf *dmabuf = NULL; +#ifndef CONFIG_ARCH_OMAP4 + u32 dest_frame_index = 0, src_element_index = 0; + u32 dest_element_index = 0, src_frame_index = 0; + u32 elem_count = 0, frame_count = 0, pixsize = 2; + enum dss_rotation rotation; + struct vid_vrfb_dma *tx; +#endif + if (VIDEOBUF_NEEDS_INIT == vb->state) { + vb->width = vout->pix.width; + vb->height = vout->pix.height; + vb->size = vb->width * vb->height * vout->bpp; + vb->field = field; + } + vb->state = VIDEOBUF_PREPARED; + /* if user pointer memory mechanism is used, get the physical + * address of the buffer + */ + if (V4L2_MEMORY_USERPTR == vb->memory) { + if (0 == vb->baddr) + return -EINVAL; + /* Virtual address */ + /* priv points to struct videobuf_pci_sg_memory. But we went + * pointer to videobuf_dmabuf, which is member of + * videobuf_pci_sg_memory */ + dmabuf = videobuf_to_dma(q->bufs[vb->i]); + dmabuf->vmalloc = (void *) vb->baddr; + + /* Physical address */ + dmabuf->bus_addr = + (dma_addr_t) omap_vout_uservirt_to_phys(vb->baddr); + } + + if (!rotation_enabled(vout)) { + dmabuf = videobuf_to_dma(q->bufs[vb->i]); + + vout->queued_buf_addr[vb->i] = (u8 *) dmabuf->bus_addr; + return 0; + } +#ifndef CONFIG_ARCH_OMAP4 + dmabuf = videobuf_to_dma(q->bufs[vb->i]); + /* If rotation is enabled, copy input buffer into VRFB + * memory space using DMA. We are copying input buffer + * into VRFB memory space of desired angle and DSS will + * read image VRFB memory for 0 degree angle + */ + pixsize = vout->bpp * vout->vrfb_bpp; + /* + * DMA transfer in double index mode + */ + + /* Frame index */ + dest_frame_index = ((MAX_PIXELS_PER_LINE * pixsize) - + (vout->pix.width * vout->bpp)) + 1; + + /* Source and destination parameters */ + src_element_index = 0; + src_frame_index = 0; + dest_element_index = 1; + /* Number of elements per frame */ + elem_count = vout->pix.width * vout->bpp; + frame_count = vout->pix.height; + tx = &vout->vrfb_dma_tx; + tx->tx_status = 0; + omap_set_dma_transfer_params(tx->dma_ch, OMAP_DMA_DATA_TYPE_S32, + (elem_count / 4), frame_count, OMAP_DMA_SYNC_ELEMENT, + tx->dev_id, 0x0); + /* src_port required only for OMAP1 */ + omap_set_dma_src_params(tx->dma_ch, 0, OMAP_DMA_AMODE_POST_INC, + dmabuf->bus_addr, src_element_index, src_frame_index); + /*set dma source burst mode for VRFB */ + omap_set_dma_src_burst_mode(tx->dma_ch, OMAP_DMA_DATA_BURST_16); + rotation = calc_rotation(vout); + + /* dest_port required only for OMAP1 */ + omap_set_dma_dest_params(tx->dma_ch, 0, OMAP_DMA_AMODE_DOUBLE_IDX, + vout->vrfb_context[vb->i].paddr[0], dest_element_index, + dest_frame_index); + /*set dma dest burst mode for VRFB */ + omap_set_dma_dest_burst_mode(tx->dma_ch, OMAP_DMA_DATA_BURST_16); + omap_dma_set_global_params(DMA_DEFAULT_ARB_RATE, 0x20, 0); + + omap_start_dma(tx->dma_ch); + interruptible_sleep_on_timeout(&tx->wait, VRFB_TX_TIMEOUT); + + if (tx->tx_status == 0) { + omap_stop_dma(tx->dma_ch); + return -EINVAL; + } + /* Store buffers physical address into an array. Addresses + * from this array will be used to configure DSS */ + vout->queued_buf_addr[vb->i] = (u8 *) + vout->vrfb_context[vb->i].paddr[rotation]; +#endif + return 0; +} + +/* Buffer queue funtion will be called from the videobuf layer when _QBUF + * ioctl is called. It is used to enqueue buffer, which is ready to be + * displayed. */ +static void omap_vout_buffer_queue(struct videobuf_queue *q, + struct videobuf_buffer *vb) +{ + struct omap_vout_device *vout = q->priv_data; + + /* Driver is also maintainig a queue. So enqueue buffer in the driver + * queue */ + list_add_tail(&vb->queue, &vout->dma_queue); + + vb->state = VIDEOBUF_PREPARED; +} + +/* Buffer release function is called from videobuf layer to release buffer + * which are already allocated */ +static void omap_vout_buffer_release(struct videobuf_queue *q, + struct videobuf_buffer *vb) +{ + struct omap_vout_device *vout = q->priv_data; + + vb->state = VIDEOBUF_NEEDS_INIT; + + if (V4L2_MEMORY_MMAP != vout->memory) + return; +} + +/* + * File operations + */ +static void omap_vout_vm_open(struct vm_area_struct *vma) +{ + struct omap_vout_device *vout = vma->vm_private_data; + + v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, + "vm_open [vma=%08lx-%08lx]\n", vma->vm_start, vma->vm_end); + vout->mmap_count++; +} + +static void omap_vout_vm_close(struct vm_area_struct *vma) +{ + struct omap_vout_device *vout = vma->vm_private_data; + + v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, + "vm_close [vma=%08lx-%08lx]\n", vma->vm_start, vma->vm_end); + vout->mmap_count--; +} + +static struct vm_operations_struct omap_vout_vm_ops = { + .open = omap_vout_vm_open, + .close = omap_vout_vm_close, +}; + +static int omap_vout_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct omap_vout_device *vout = file->private_data; + struct videobuf_queue *q = &vout->vbq; + unsigned long size = (vma->vm_end - vma->vm_start); + unsigned long start = vma->vm_start; + int i; + void *pos; + struct videobuf_dmabuf *dmabuf = NULL; + + v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, + " %s pgoff=0x%lx, start=0x%lx, end=0x%lx\n", __func__, + vma->vm_pgoff, vma->vm_start, vma->vm_end); + + /* look for the buffer to map */ + for (i = 0; i < VIDEO_MAX_FRAME; i++) { + if (NULL == q->bufs[i]) + continue; + if (V4L2_MEMORY_MMAP != q->bufs[i]->memory) + continue; + if (q->bufs[i]->boff == (vma->vm_pgoff << PAGE_SHIFT)) + break; + } + + if (VIDEO_MAX_FRAME == i) { + v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, + "offset invalid [offset=0x%lx]\n", + (vma->vm_pgoff << PAGE_SHIFT)); + return -EINVAL; + } + q->bufs[i]->baddr = vma->vm_start; + + vma->vm_flags |= VM_RESERVED; + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); + vma->vm_ops = &omap_vout_vm_ops; + vma->vm_private_data = (void *) vout; + dmabuf = videobuf_to_dma(q->bufs[i]); + + pos = dmabuf->vmalloc; + vma->vm_pgoff = virt_to_phys((void *)pos) >> PAGE_SHIFT; + while (size > 0) { + unsigned long pfn; + pfn = virt_to_phys((void *) pos) >> PAGE_SHIFT; + if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, PAGE_SHARED)) + return -EAGAIN; + start += PAGE_SIZE; + pos += PAGE_SIZE; + size -= PAGE_SIZE; + } + vout->mmap_count++; + v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__); + return 0; +} + +static int omap_vout_release(struct file *file) +{ + + struct omap_vout_device *vout = file->private_data; + struct videobuf_queue *q; + unsigned int t; + struct omapvideo_info *ovid; + unsigned int r; + + v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__); + ovid = &(vout->vid_info); + + if (!vout) + return 0; + q = &vout->vbq; + + /* Disable all the overlay managers connected with this interface */ + for (t = 0; t < ovid->num_overlays; t++) { + struct omap_overlay *ovl = ovid->overlays[t]; + if (ovl->manager && ovl->manager->device) { + struct omap_overlay_info info; + ovl->get_overlay_info(ovl, &info); + info.enabled = 0; + ovl->set_overlay_info(ovl, &info); + } + + } + /* Turn off the pipeline */ + r = omapvid_apply_changes(vout); + if (r) + printk(KERN_WARNING VOUT_NAME "Unable to apply changes\n"); + + /* Free all buffers */ + omap_vout_free_allbuffers(vout); + videobuf_mmap_free(q); + + /* Even if apply changes fails we should continue + freeing allocated memeory */ + if (vout->streaming) { + u32 mask = 0; + + mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | + DISPC_IRQ_EVSYNC_ODD; + omap_dispc_unregister_isr(omap_vout_isr, vout, mask); + vout->streaming = 0; + + videobuf_streamoff(q); + videobuf_queue_cancel(q); + + } + + if (vout->mmap_count != 0) + vout->mmap_count = 0; + + vout->opened -= 1; + file->private_data = NULL; + + if (vout->buffer_allocated) + videobuf_mmap_free(q); + v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__); + return r; +} + +static int omap_vout_open(struct file *file) +{ + struct omap_vout_device *vout = NULL; + struct videobuf_queue *q; + + vout = video_drvdata(file); + v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__); + + if (vout == NULL) + return -ENODEV; + + /* for now, we only support single open */ + if (vout->opened) + return -EBUSY; + + vout->opened += 1; + + file->private_data = vout; + vout->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + + q = &vout->vbq; + video_vbq_ops.buf_setup = omap_vout_buffer_setup; + video_vbq_ops.buf_prepare = omap_vout_buffer_prepare; + video_vbq_ops.buf_release = omap_vout_buffer_release; + video_vbq_ops.buf_queue = omap_vout_buffer_queue; + spin_lock_init(&vout->vbq_lock); + + videobuf_queue_sg_init(q, &video_vbq_ops, NULL, &vout->vbq_lock, + vout->type, V4L2_FIELD_NONE, sizeof + (struct videobuf_buffer), vout); + v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__); + return 0; +} + +/* V4L2 ioctls */ +static int vidioc_querycap(struct file *file, void *fh, + struct v4l2_capability *cap) +{ + struct omap_vout_device *vout = fh; + + strlcpy(cap->driver, VOUT_NAME, + sizeof(cap->driver)); + strlcpy(cap->card, vout->vfd->name, sizeof(cap->card)); + cap->bus_info[0] = '\0'; + cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT; + return 0; +} + +static int vidioc_enum_fmt_vid_out(struct file *file, void *fh, + struct v4l2_fmtdesc *fmt) +{ + int index = fmt->index; + enum v4l2_buf_type type = fmt->type; + + fmt->index = index; + fmt->type = type; + if (index >= NUM_OUTPUT_FORMATS) + return -EINVAL; + + fmt->flags = omap_formats[index].flags; + strlcpy(fmt->description, omap_formats[index].description, + sizeof(fmt->description)); + fmt->pixelformat = omap_formats[index].pixelformat; + return 0; +} + +static int vidioc_g_fmt_vid_out(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct omap_vout_device *vout = fh; + + f->fmt.pix = vout->pix; + return 0; + +} + +static int vidioc_try_fmt_vid_out(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct omap_vout_device *vout = fh; + struct omapvideo_info *ovid; + struct omap_overlay *ovl; + struct omap_video_timings *timing; + + if (vout->streaming) + return -EBUSY; + + ovid = &(vout->vid_info); + ovl = ovid->overlays[0]; + + if (!ovl->manager || !ovl->manager->device) + return -EINVAL; + /* get the display device attached to the overlay */ + timing = &ovl->manager->device->panel.timings; + + vout->fbuf.fmt.height = timing->y_res; + vout->fbuf.fmt.width = timing->x_res; + + omap_vout_try_format(&f->fmt.pix); + return 0; +} + +static int vidioc_s_fmt_vid_out(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct omap_vout_device *vout = fh; + int bpp; + int r; + struct omapvideo_info *ovid; + struct omap_overlay *ovl; + struct omap_video_timings *timing; + + if (vout->streaming) + return -EBUSY; + + mutex_lock(&vout->lock); + + ovid = &(vout->vid_info); + ovl = ovid->overlays[0]; + + /* get the display device attached to the overlay */ + if (!ovl->manager || !ovl->manager->device) { + mutex_unlock(&vout->lock); + return -EINVAL; + } + timing = &ovl->manager->device->panel.timings; + +#ifdef CONFIG_ARCH_OMAP4 + if (rotation_enabled(vout)) + vout->rotation = -1; +#endif + /* TODO: check if TILER ADAPTATION is needed here. */ + /* We dont support RGB24-packed mode if vrfb rotation + * is enabled*/ + if ((rotation_enabled(vout)) && + f->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24) { + mutex_unlock(&vout->lock); + return -EINVAL; + } + + /* get the framebuffer parameters */ + + if (rotate_90_or_270(vout)) { + vout->fbuf.fmt.height = timing->x_res; + vout->fbuf.fmt.width = timing->y_res; + } else { + vout->fbuf.fmt.height = timing->y_res; + vout->fbuf.fmt.width = timing->x_res; + } + + /* change to samller size is OK */ + + bpp = omap_vout_try_format(&f->fmt.pix); + f->fmt.pix.sizeimage = f->fmt.pix.width * f->fmt.pix.height * bpp; + + /* try & set the new output format */ + vout->bpp = bpp; + vout->pix = f->fmt.pix; + vout->vrfb_bpp = 1; + + /* If YUYV then vrfb bpp is 2, for others its 1 */ + if (V4L2_PIX_FMT_YUYV == vout->pix.pixelformat || + V4L2_PIX_FMT_UYVY == vout->pix.pixelformat) + vout->vrfb_bpp = 2; + + /* set default crop and win */ + omap_vout_new_format(&vout->pix, &vout->fbuf, &vout->crop, &vout->win); + + /* Save the changes in the overlay strcuture */ + r = omapvid_init(vout, 0); + if (r) { + printk(KERN_ERR VOUT_NAME "failed to change mode\n"); + mutex_unlock(&vout->lock); + return -EINVAL; + } + mutex_unlock(&vout->lock); + return 0; +} + +static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, + struct v4l2_format *f) +{ + int err = -EINVAL; + struct omap_vout_device *vout = fh; + struct v4l2_window *win = &f->fmt.win; + + err = omap_vout_try_window(&vout->fbuf, win); + + if (err) + return err; + + if (vout->vid == OMAP_VIDEO1) + win->global_alpha = 255; + else + win->global_alpha = f->fmt.win.global_alpha; + return 0; +} + +static int vidioc_s_fmt_vid_overlay(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct omap_vout_device *vout = fh; + int err = -EINVAL; + struct omap_overlay *ovl; + struct omapvideo_info *ovid; + struct v4l2_window *win = &f->fmt.win; + + mutex_lock(&vout->lock); + ovid = &vout->vid_info; + ovl = ovid->overlays[0]; + err = omap_vout_new_window(&vout->crop, &vout->win, &vout->fbuf, win); + if (err) { + mutex_unlock(&vout->lock); + return err; + } + if (ovl->id == OMAP_DSS_VIDEO1) + vout->win.global_alpha = 255; + else + vout->win.global_alpha = f->fmt.win.global_alpha; + + vout->win.chromakey = f->fmt.win.chromakey; + mutex_unlock(&vout->lock); + return 0; +} + +static int vidioc_enum_fmt_vid_overlay(struct file *file, void *fh, + struct v4l2_fmtdesc *fmt) +{ + int index = fmt->index; + enum v4l2_buf_type type = fmt->type; + + fmt->index = index; + fmt->type = type; + if (index >= NUM_OUTPUT_FORMATS) + return -EINVAL; + + fmt->flags = omap_formats[index].flags; + strlcpy(fmt->description, omap_formats[index].description, + sizeof(fmt->description)); + fmt->pixelformat = omap_formats[index].pixelformat; + return 0; +} + +static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct omap_vout_device *vout = fh; + struct omap_overlay *ovl; + struct omapvideo_info *ovid; + struct omap_overlay_manager_info info; + struct v4l2_window *win = &f->fmt.win; + u32 key_value = 0; + + ovid = &(vout->vid_info); + ovl = ovid->overlays[0]; + + win->w = vout->win.w; + win->field = vout->win.field; + win->global_alpha = vout->win.global_alpha; + + if (ovl->manager && ovl->manager->get_manager_info) { + ovl->manager->get_manager_info(ovl->manager, &info); + key_value = info.trans_key; + } + win->chromakey = key_value; + return 0; +} + +static int vidioc_cropcap(struct file *file, void *fh, + struct v4l2_cropcap *cropcap) +{ + struct omap_vout_device *vout = fh; + enum v4l2_buf_type type = cropcap->type; + struct v4l2_pix_format *pix = &vout->pix; + + cropcap->type = type; + if (type != V4L2_BUF_TYPE_VIDEO_OUTPUT) + return -EINVAL; + + /* Width and height are always even */ + cropcap->bounds.width = pix->width & ~1; + cropcap->bounds.height = pix->height & ~1; + + omap_vout_default_crop(&vout->pix, &vout->fbuf, &cropcap->defrect); + cropcap->pixelaspect.numerator = 1; + cropcap->pixelaspect.denominator = 1; + return 0; +} + +static int vidioc_g_crop(struct file *file, void *fh, + struct v4l2_crop *crop) +{ + struct omap_vout_device *vout = fh; + + if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) + return -EINVAL; + crop->c = vout->crop; + return 0; +} + +static int vidioc_s_crop(struct file *file, void *fh, + struct v4l2_crop *crop) +{ + struct omap_vout_device *vout = fh; + int err = -EINVAL; + struct omapvideo_info *ovid; + struct omap_overlay *ovl; + struct omap_video_timings *timing; + + if (vout->streaming) + return -EBUSY; + + mutex_lock(&vout->lock); + ovid = &(vout->vid_info); + ovl = ovid->overlays[0]; + + if (!ovl->manager || !ovl->manager->device) { + mutex_unlock(&vout->lock); + return -EINVAL; + } + /* get the display device attached to the overlay */ + timing = &ovl->manager->device->panel.timings; + + if (rotate_90_or_270(vout)) { + vout->fbuf.fmt.height = timing->x_res; + vout->fbuf.fmt.width = timing->y_res; + } else { + vout->fbuf.fmt.height = timing->y_res; + vout->fbuf.fmt.width = timing->x_res; + } + + if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { + err = omap_vout_new_crop(&vout->pix, &vout->crop, &vout->win, + &vout->fbuf, &crop->c); + mutex_unlock(&vout->lock); + return err; + } else { + mutex_unlock(&vout->lock); + return -EINVAL; + } +} + +static int vidioc_queryctrl(struct file *file, void *fh, + struct v4l2_queryctrl *ctrl) +{ + switch (ctrl->id) { + case V4L2_CID_ROTATE: + v4l2_ctrl_query_fill(ctrl, 0, 270, 90, 0); + break; + case V4L2_CID_BG_COLOR: + v4l2_ctrl_query_fill(ctrl, 0, 0xFFFFFF, 1, 0); + break; + case V4L2_CID_VFLIP: + v4l2_ctrl_query_fill(ctrl, 0, 1, 1, 0); + default: + ctrl->name[0] = '\0'; + return -EINVAL; + + } + return 0; +} + +static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *ctrl) +{ + struct omap_vout_device *vout = fh; + + switch (ctrl->id) { + case V4L2_CID_ROTATE: + ctrl->value = vout->control[0].value; + return 0; + case V4L2_CID_BG_COLOR: + { + struct omap_overlay_manager_info info; + struct omap_overlay *ovl; + ovl = vout->vid_info.overlays[0]; + + if (!ovl->manager || !ovl->manager->get_manager_info) + return -EINVAL; + + ovl->manager->get_manager_info(ovl->manager, &info); + ctrl->value = info.default_color; + return 0; + } + + case V4L2_CID_VFLIP: + ctrl->value = vout->control[2].value; + return 0; + default: + return -EINVAL; + } +} + +static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *a) +{ + struct omap_vout_device *vout = fh; + + switch (a->id) { + case V4L2_CID_ROTATE: + { + int rotation = a->value; + + mutex_lock(&vout->lock); + + if (rotation && + vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) { + mutex_unlock(&vout->lock); + return -EINVAL; + } + + if ((v4l2_rot_to_dss_rot(rotation, &vout->rotation, + vout->mirror))) { + mutex_unlock(&vout->lock); + return -EINVAL; + } + vout->control[0].value = rotation; + mutex_unlock(&vout->lock); + return 0; + } + case V4L2_CID_BG_COLOR: + { + unsigned int color = a->value; + struct omap_overlay_manager_info info;; + struct omap_overlay *ovl; + ovl = vout->vid_info.overlays[0]; + + mutex_lock(&vout->lock); + if (!ovl->manager || !ovl->manager->get_manager_info) { + mutex_unlock(&vout->lock); + return -EINVAL; + } + ovl->manager->get_manager_info(ovl->manager, &info); + info.default_color = color; + if (ovl->manager->set_manager_info(ovl->manager, &info)) { + mutex_unlock(&vout->lock); + return -EINVAL; + } + + vout->control[1].value = color; + mutex_unlock(&vout->lock); + return 0; + } + case V4L2_CID_VFLIP: + { + unsigned int mirror = a->value; + struct omapvideo_info *ovid; + struct omap_overlay *ovl; + ovid = &(vout->vid_info); + ovl = ovid->overlays[0]; + + mutex_lock(&vout->lock); + + if (mirror && vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) { + mutex_unlock(&vout->lock); + return -EINVAL; + } + vout->mirror = mirror; + vout->control[2].value = mirror; + mutex_unlock(&vout->lock); + return 0; + } + + default: + return -EINVAL; + } + +} + +static int vidioc_reqbufs(struct file *file, void *fh, + struct v4l2_requestbuffers *req) +{ + struct omap_vout_device *vout = fh; + struct videobuf_queue *q = &(vout->vbq); + unsigned int i, num_buffers = 0; + int ret = 0; + struct videobuf_dmabuf *dmabuf = NULL; + + printk(KERN_INFO VOUT_NAME + "entered REQbuf: \n"); + + if ((req->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) || (req->count < 0)) + return -EINVAL; + /* if memory is not mmp or userptr + return error */ + if ((V4L2_MEMORY_MMAP != req->memory) && + (V4L2_MEMORY_USERPTR != req->memory)) + return -EINVAL; + + mutex_lock(&vout->lock); + /* Cannot be requested when streaming is on */ + if (vout->streaming) { + mutex_unlock(&vout->lock); + return -EBUSY; + } + + /* If buffers are already allocated free them */ + if (q->bufs[0] && (V4L2_MEMORY_MMAP == q->bufs[0]->memory)) { + if (vout->mmap_count) { + mutex_unlock(&vout->lock); + return -EBUSY; + } + num_buffers = (vout->vid == OMAP_VIDEO1) ? + video1_numbuffers : video2_numbuffers; + for (i = num_buffers; i < vout->buffer_allocated; i++) { + dmabuf = videobuf_to_dma(q->bufs[i]); + omap_vout_free_buffer((u32)dmabuf->vmalloc, + dmabuf->bus_addr, vout->buffer_size); + vout->buf_virt_addr[i] = 0; + vout->buf_phy_addr[i] = 0; + } + vout->buffer_allocated = num_buffers; + videobuf_mmap_free(q); + } else if (q->bufs[0] && (V4L2_MEMORY_USERPTR == q->bufs[0]->memory)) { + if (vout->buffer_allocated) { + videobuf_mmap_free(q); + for (i = 0; i < vout->buffer_allocated; i++) { + kfree(q->bufs[i]); + q->bufs[i] = NULL; + } + vout->buffer_allocated = 0; + } + } + + /*store the memory type in data structure */ + vout->memory = req->memory; + + INIT_LIST_HEAD(&vout->dma_queue); + + /* call videobuf_reqbufs api */ + ret = videobuf_reqbufs(q, req); + if (ret < 0) { + mutex_unlock(&vout->lock); + return ret; + } + + vout->buffer_allocated = req->count; + for (i = 0; i < req->count; i++) { + dmabuf = videobuf_to_dma(q->bufs[i]); + dmabuf->vmalloc = (void *) vout->buf_virt_addr[i]; + dmabuf->bus_addr = (dma_addr_t) vout->buf_phy_addr[i]; + dmabuf->sglen = 1; + } + mutex_unlock(&vout->lock); + return 0; +} + +static int vidioc_querybuf(struct file *file, void *fh, + struct v4l2_buffer *b) +{ + struct omap_vout_device *vout = fh; + + return videobuf_querybuf(&(vout->vbq), b); +} + +static int vidioc_qbuf(struct file *file, void *fh, + struct v4l2_buffer *buffer) +{ + struct omap_vout_device *vout = fh; + struct videobuf_queue *q = &vout->vbq; + int ret = 0; + + printk(KERN_INFO VOUT_NAME + "entered qbuf: buffer address: %x \n", (unsigned int) buffer); + + if ((V4L2_BUF_TYPE_VIDEO_OUTPUT != buffer->type) || + (buffer->index >= vout->buffer_allocated) || + + (q->bufs[buffer->index]->memory != buffer->memory)) { + return -EINVAL; + } + if (V4L2_MEMORY_USERPTR == buffer->memory) { + if ((buffer->length < vout->pix.sizeimage) || + (0 == buffer->m.userptr)) { + return -EINVAL; + } + } + + if ((rotation_enabled(vout)) && + vout->vrfb_dma_tx.req_status == DMA_CHAN_NOT_ALLOTED) { + printk(KERN_WARNING VOUT_NAME + "DMA Channel not allocated for Rotation\n"); + return -EINVAL; + } + + ret = videobuf_qbuf(q, buffer); + return ret; +} + +static int vidioc_dqbuf(struct file *file, void *fh, + struct v4l2_buffer *b) +{ + struct omap_vout_device *vout = fh; + struct videobuf_queue *q = &vout->vbq; + int ret = 0; + + printk(KERN_INFO VOUT_NAME + "entered DQbuf: buffer address: %x \n", (unsigned int) b); + + if (!vout->streaming) + return -EINVAL; + + if (file->f_flags & O_NONBLOCK) + /* Call videobuf_dqbuf for non blocking mode */ + ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 1); + else + /* Call videobuf_dqbuf for blocking mode */ + ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 0); + return ret; +} + +static int vidioc_streamon(struct file *file, void *fh, + enum v4l2_buf_type i) +{ + struct omap_vout_device *vout = fh; + struct videobuf_queue *q = &vout->vbq; + u32 addr = 0; + int r = 0; + int t; + struct omapvideo_info *ovid = &(vout->vid_info); + u32 mask = 0; + + printk(KERN_INFO VOUT_NAME + "entered streamon-before mutex lock \n\n"); + + mutex_lock(&vout->lock); + + printk(KERN_INFO VOUT_NAME + "streamon: mutex acquired\n"); + + if (vout->streaming) { + mutex_unlock(&vout->lock); + return -EBUSY; + } + + r = videobuf_streamon(q); + if (r < 0) { + mutex_unlock(&vout->lock); + return r; + } + + if (list_empty(&vout->dma_queue)) { + mutex_unlock(&vout->lock); + return -EIO; + } + /* Get the next frame from the buffer queue */ + vout->next_frm = vout->cur_frm = list_entry(vout->dma_queue.next, + struct videobuf_buffer, queue); + /* Remove buffer from the buffer queue */ + list_del(&vout->cur_frm->queue); + /* Mark state of the current frame to active */ + vout->cur_frm->state = VIDEOBUF_ACTIVE; + /* Initialize field_id and started member */ + vout->field_id = 0; + + /* set flag here. Next QBUF will start DMA */ + vout->streaming = 1; + + vout->first_int = 1; + + if (omap_vout_calculate_offset(vout)) { + mutex_unlock(&vout->lock); + return -EINVAL; + } + addr = (unsigned long) vout->queued_buf_addr[vout->cur_frm->i] + + vout->cropped_offset; + + mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | + DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_FRAMEDONE; + + omap_dispc_register_isr(omap_vout_isr, vout, mask); + + for (t = 0; t < ovid->num_overlays; t++) { + struct omap_overlay *ovl = ovid->overlays[t]; + if (ovl->manager && ovl->manager->device) { + struct omap_overlay_info info; + ovl->get_overlay_info(ovl, &info); + info.enabled = 1; + info.paddr = addr; + if (ovl->set_overlay_info(ovl, &info)) + return -EINVAL; + } + } + + /* First save the configuration in ovelray structure */ + r = omapvid_init(vout, addr); + if (r) + printk(KERN_ERR VOUT_NAME "failed to set overlay info\n"); + /* Enable the pipeline and set the Go bit */ + r = omapvid_apply_changes(vout); + if (r) + printk(KERN_ERR VOUT_NAME "failed to change mode\n"); + + mutex_unlock(&vout->lock); + return r; +} + +static int vidioc_streamoff(struct file *file, void *fh, + enum v4l2_buf_type i) +{ + struct omap_vout_device *vout = fh; + int t, r = 0; + struct omapvideo_info *ovid = &(vout->vid_info); + u32 mask = 0; + + if (!vout->streaming) + return -EINVAL; + + vout->streaming = 0; + mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | + DISPC_IRQ_EVSYNC_ODD; + + omap_dispc_unregister_isr(omap_vout_isr, vout, mask); + + for (t = 0; t < ovid->num_overlays; t++) { + struct omap_overlay *ovl = ovid->overlays[t]; + if (ovl->manager && ovl->manager->device) { + struct omap_overlay_info info; + + ovl->get_overlay_info(ovl, &info); + info.enabled = 0; + r = ovl->set_overlay_info(ovl, &info); + if (r) { + printk(KERN_ERR VOUT_NAME "failed to \ + update overlay info\n"); + return r; + } + } + + /* Turn of the pipeline */ + r = omapvid_apply_changes(vout); + if (r) { + printk(KERN_ERR VOUT_NAME "failed to change mode\n"); + return r; + } + videobuf_streamoff(&vout->vbq); + videobuf_queue_cancel(&vout->vbq); + } + return 0; +} + +static int vidioc_s_fbuf(struct file *file, void *fh, + struct v4l2_framebuffer *a) +{ + struct omap_vout_device *vout = fh; + struct omapvideo_info *ovid; + struct omap_overlay *ovl; + struct omap_overlay_manager_info info; + enum omap_dss_trans_key_type key_type = OMAP_DSS_COLOR_KEY_GFX_DST; + int enable = 0; + + ovid = &(vout->vid_info); + ovl = ovid->overlays[0]; + + /* OMAP DSS doesn't support Source and Destination color + key together */ + if ((a->flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY) && + (a->flags & V4L2_FBUF_FLAG_CHROMAKEY)) + return -EINVAL; + /* OMAP DSS Doesn't support the Destination color key + and alpha blending together */ + if (a->flags & V4L2_FBUF_FLAG_CHROMAKEY && + (a->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA)) + return -EINVAL; + + if ((a->flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY)) { + vout->fbuf.flags |= V4L2_FBUF_FLAG_SRC_CHROMAKEY; + key_type = OMAP_DSS_COLOR_KEY_VID_SRC; + } else + vout->fbuf.flags &= ~V4L2_FBUF_FLAG_SRC_CHROMAKEY; + + if ((a->flags & V4L2_FBUF_FLAG_CHROMAKEY)) { + vout->fbuf.flags |= V4L2_FBUF_FLAG_CHROMAKEY; + key_type = OMAP_DSS_COLOR_KEY_GFX_DST; + } else + vout->fbuf.flags &= ~V4L2_FBUF_FLAG_CHROMAKEY; + + if (a->flags & (V4L2_FBUF_FLAG_CHROMAKEY | + V4L2_FBUF_FLAG_SRC_CHROMAKEY)) + enable = 1; + else + enable = 0; + + if (ovl->manager && ovl->manager->get_manager_info && + ovl->manager->set_manager_info) { + ovl->manager->get_manager_info(ovl->manager, &info); + info.trans_enabled = enable; + info.trans_key_type = key_type; + info.trans_key = vout->win.chromakey; + if (ovl->manager->set_manager_info(ovl->manager, &info)) + return -EINVAL; + } + + if (a->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) { + vout->fbuf.flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA; + enable = 1; + } else { + vout->fbuf.flags &= ~V4L2_FBUF_FLAG_LOCAL_ALPHA; + enable = 0; + } + if (ovl->manager && ovl->manager->get_manager_info && + ovl->manager->set_manager_info) { + ovl->manager->get_manager_info(ovl->manager, &info); + info.alpha_enabled = enable; + if (ovl->manager->set_manager_info(ovl->manager, &info)) + return -EINVAL; + } + + return 0; +} + +static int vidioc_g_fbuf(struct file *file, void *fh, + struct v4l2_framebuffer *a) +{ + struct omap_vout_device *vout = fh; + struct omap_overlay_manager_info info; + struct omapvideo_info *ovid; + struct omap_overlay *ovl; + enum omap_dss_trans_key_type key_type; + + ovid = &(vout->vid_info); + ovl = ovid->overlays[0]; + + a->flags = 0x0; + + a->capability = V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_CHROMAKEY + | V4L2_FBUF_CAP_SRC_CHROMAKEY; + + if (ovl->manager && ovl->manager->get_manager_info) { + ovl->manager->get_manager_info(ovl->manager, &info); + if (info.trans_key_type == OMAP_DSS_COLOR_KEY_VID_SRC) + a->flags |= V4L2_FBUF_FLAG_SRC_CHROMAKEY; + if (info.trans_key_type == OMAP_DSS_COLOR_KEY_GFX_DST) + a->flags |= V4L2_FBUF_FLAG_CHROMAKEY; + + } + if (ovl->manager && ovl->manager->get_manager_info) { + ovl->manager->get_manager_info(ovl->manager, &info); + if (info.alpha_enabled) + a->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA; + } + + return 0; +} + +static const struct v4l2_ioctl_ops vout_ioctl_ops = { + .vidioc_querycap = vidioc_querycap, + .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out, + .vidioc_g_fmt_vid_out = vidioc_g_fmt_vid_out, + .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out, + .vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out, + .vidioc_queryctrl = vidioc_queryctrl, + .vidioc_g_ctrl = vidioc_g_ctrl, + .vidioc_s_fbuf = vidioc_s_fbuf, + .vidioc_g_fbuf = vidioc_g_fbuf, + .vidioc_s_ctrl = vidioc_s_ctrl, + .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay, + .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay, + .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_overlay, + .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay, + .vidioc_cropcap = vidioc_cropcap, + .vidioc_g_crop = vidioc_g_crop, + .vidioc_s_crop = vidioc_s_crop, + .vidioc_reqbufs = vidioc_reqbufs, + .vidioc_querybuf = vidioc_querybuf, + .vidioc_qbuf = vidioc_qbuf, + .vidioc_dqbuf = vidioc_dqbuf, + .vidioc_streamon = vidioc_streamon, + .vidioc_streamoff = vidioc_streamoff, +}; + +static const struct v4l2_file_operations omap_vout_fops = { + .owner = THIS_MODULE, + .ioctl = video_ioctl2, + .mmap = omap_vout_mmap, + .open = omap_vout_open, + .release = omap_vout_release, +}; + +/* Init functions used during driver intitalization */ +/* Initial setup of video_data */ +static int __init omap_vout_setup_video_data(struct omap_vout_device *vout) +{ + struct v4l2_pix_format *pix; + struct video_device *vfd; + struct v4l2_control *control; + struct omap_dss_device *display = + vout->vid_info.overlays[0]->manager->device; + + /* set the default pix */ + pix = &vout->pix; + + /* Set the default picture of QVGA */ + pix->width = QQVGA_WIDTH; + pix->height = QQVGA_HEIGHT; + + /* Default pixel format is RGB 5-6-5 */ + pix->pixelformat = V4L2_PIX_FMT_RGB565; + pix->field = V4L2_FIELD_ANY; + pix->bytesperline = pix->width * 2; + pix->sizeimage = pix->bytesperline * pix->height; + pix->priv = 0; + pix->colorspace = V4L2_COLORSPACE_JPEG; + + vout->bpp = RGB565_BPP; + vout->fbuf.fmt.width = display->panel.timings.x_res; + vout->fbuf.fmt.height = display->panel.timings.y_res; + + /* Set the data structures for the overlay parameters*/ + vout->win.global_alpha = 255; + vout->fbuf.flags = 0; + vout->fbuf.capability = V4L2_FBUF_CAP_LOCAL_ALPHA | + V4L2_FBUF_CAP_SRC_CHROMAKEY | V4L2_FBUF_CAP_CHROMAKEY; + vout->win.chromakey = 0; + + omap_vout_new_format(pix, &vout->fbuf, &vout->crop, &vout->win); + + /*Disable the rotation. */ + control = vout->control; + + control[0].id = V4L2_CID_ROTATE; + control[0].value = 0; + vout->rotation = -1; + vout->mirror = 0; + vout->vrfb_bpp = 2; + + control[1].id = V4L2_CID_BG_COLOR; + control[1].value = 0; + + /* initialize the video_device struct */ + vfd = vout->vfd = video_device_alloc(); + + if (!vfd) { + printk(KERN_ERR VOUT_NAME ": could not allocate\ + video device struct\n"); + return -ENOMEM; + } + vfd->release = video_device_release; + vfd->ioctl_ops = &vout_ioctl_ops; + + strlcpy(vfd->name, VOUT_NAME, sizeof(vfd->name)); + vfd->vfl_type = VFL_TYPE_GRABBER; + + /* need to register for a VID_HARDWARE_* ID in videodev.h */ + vfd->fops = &omap_vout_fops; + mutex_init(&vout->lock); + + vfd->minor = -1; + return 0; + +} + +/* Setup video buffers */ +static int __init omap_vout_setup_video_bufs(struct platform_device *pdev, + int vid_num) +{ + struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev); + struct omap2video_device *vid_dev = container_of(v4l2_dev, struct + omap2video_device, v4l2_dev); + struct omap_vout_device *vout; + int i, r = 0; + unsigned numbuffers; + struct video_device *vfd; +#ifndef CONFIG_ARCH_OMAP4 /* TODO: related to rotation */ + int j; + int image_width, image_height; + int static_vrfb_allocation = 0, vrfb_num_bufs = 4; +#endif + vout = vid_dev->vouts[vid_num]; + vfd = vout->vfd; + + numbuffers = (vid_num == 0) ? video1_numbuffers : video2_numbuffers; + vout->buffer_size = (vid_num == 0) ? video1_bufsize : video2_bufsize; + printk(KERN_INFO VOUT_NAME "Buffer Size = %d\n", vout->buffer_size); + for (i = 0; i < numbuffers; i++) { + vout->buf_virt_addr[i] = + omap_vout_alloc_buffer(vout->buffer_size, + (u32 *) &vout->buf_phy_addr[i]); + if (!vout->buf_virt_addr[i]) { + numbuffers = i; + r = -ENOMEM; + goto free_buffers; + } + } + +#ifndef CONFIG_ARCH_OMAP4 +/*TODO: removal of vrfb for OMAP4 V4L2 testing: to be cleaned.*/ + for (i = 0; i < 4; i++) { + + if (omap_vrfb_request_ctx(&vout->vrfb_context[i])) { + printk(KERN_INFO VOUT_NAME ": VRFB Region allocation \ + for rotation failed\n"); + r = -ENOMEM; + break; + } + } + if (r == -ENOMEM) { + for (j = 0; j < i; j++) + omap_vrfb_release_ctx(&vout->vrfb_context[j]); + + goto free_buffers; + } + + vout->cropped_offset = 0; + + /* Calculate VRFB memory size */ + /* allocate for worst case size */ + image_width = VID_MAX_WIDTH / TILE_SIZE; + if (VID_MAX_WIDTH % TILE_SIZE) + image_width++; + + image_width = image_width * TILE_SIZE; + image_height = VID_MAX_HEIGHT / TILE_SIZE; + + if (VID_MAX_HEIGHT % TILE_SIZE) + image_height++; + + image_height = image_height * TILE_SIZE; + vout->smsshado_size = PAGE_ALIGN(image_width * image_height * 2 * 2); + + /* + * Request and Initialize DMA, for DMA based VRFB transfer + */ + vout->vrfb_dma_tx.dev_id = OMAP_DMA_NO_DEVICE; + vout->vrfb_dma_tx.dma_ch = -1; + vout->vrfb_dma_tx.req_status = DMA_CHAN_ALLOTED; + r = omap_request_dma(vout->vrfb_dma_tx.dev_id, "VRFB DMA TX", + omap_vout_vrfb_dma_tx_callback, + (void *) &vout->vrfb_dma_tx, &vout->vrfb_dma_tx.dma_ch); + if (r < 0) { + vout->vrfb_dma_tx.req_status = DMA_CHAN_NOT_ALLOTED; + printk(KERN_INFO VOUT_NAME ": DMA Channel not alloted\ + for video%d [v4l2]\n", vfd->minor); + } + init_waitqueue_head(&vout->vrfb_dma_tx.wait); + + /* Allocate VRFB buffers if selected through bootargs */ + static_vrfb_allocation = (vid_num == 0) ? + vid1_static_vrfb_alloc : vid2_static_vrfb_alloc; + + /* statically allocated the VRFB buffer is done through + commands line aruments */ + if (static_vrfb_allocation) { + if (omap_vout_allocate_vrfb_buffers(vout, vrfb_num_bufs, -1)) { + r = -ENOMEM; + goto free_buffers; + } + vout->vrfb_static_allocation = 1; + } +#endif + return 0; + +free_buffers: + for (i = 0; i < numbuffers; i++) { + omap_vout_free_buffer(vout->buf_virt_addr[i], + vout->buf_phy_addr[i], vout->buffer_size); + vout->buf_virt_addr[i] = 0; + vout->buf_phy_addr[i] = 0; + } + return r; + +} + +/* Create video out devices */ +static int __init omap_vout_create_video_devices(struct platform_device *pdev) +{ + int r = 0, k; + struct omap_vout_device *vout; + struct video_device *vfd = NULL; + struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev); + + struct omap2video_device *vid_dev = container_of(v4l2_dev, struct + omap2video_device, v4l2_dev); + for (k = 0; k < pdev->num_resources; k++) { + + vout = kmalloc(sizeof(struct omap_vout_device), GFP_KERNEL); + if (!vout) { + printk(KERN_ERR VOUT_NAME ": could not allocate \ + memory\n"); + return -ENOMEM; + } + + memset(vout, 0, sizeof(struct omap_vout_device)); + + vout->vid = k; + vid_dev->vouts[k] = vout; + vout->vid_dev = vid_dev; + if (pdev->num_resources == 1) + vout->vid_info.overlays[0] = vid_dev->overlays[k + 2]; + else + /* Else select video1 and video2 one by one. */ + vout->vid_info.overlays[0] = vid_dev->overlays[k + 1]; + vout->vid_info.num_overlays = 1; + vout->vid_info.id = k + 1; + vid_dev->num_videos++; + + /* Setup the default configuration for the video devices + */ + if (omap_vout_setup_video_data(vout) != 0) { + r = -ENOMEM; + goto error; + } + + /* Allocate default number of buffers for the video streaming + * and reserve the VRFB space for rotation + */ + if (omap_vout_setup_video_bufs(pdev, k) != 0) { + r = -ENOMEM; + goto error1; + } + + /* Register the Video device with V4L2 + */ + vfd = vout->vfd; + if (video_register_device(vfd, VFL_TYPE_GRABBER, k + 1) < 0) { + printk(KERN_ERR VOUT_NAME ": could not register \ + Video for Linux device\n"); + vfd->minor = -1; + r = -ENODEV; + goto error2; + } + video_set_drvdata(vfd, vout); + + /* Configure the overlay structure */ + r = omapvid_init(vid_dev->vouts[k], 0); + + if (r) + goto error2; + else + goto success; +error2: +#ifndef CONFIG_ARCH_OMAP4 + omap_vout_release_vrfb(vout); +#endif + omap_vout_free_buffers(vout); +error1: + video_device_release(vfd); +error: + kfree(vout); + return r; + +success: + printk(KERN_INFO VOUT_NAME ": registered and initialized\ + video device %d [v4l2]\n", vfd->minor); + if (k == (pdev->num_resources - 1)) + return 0; + } + return -ENODEV; + +} +/* Driver functions */ +static int omap_vout_remove(struct platform_device *pdev) +{ + struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev); + struct omap2video_device *vid_dev = container_of(v4l2_dev, struct + omap2video_device, v4l2_dev); + int k; + + v4l2_device_unregister(v4l2_dev); + for (k = 0; k < pdev->num_resources; k++) + omap_vout_cleanup_device(vid_dev->vouts[k]); + + for (k = 0; k < vid_dev->num_displays; k++) { + if (vid_dev->displays[k]->state != OMAP_DSS_DISPLAY_DISABLED) + vid_dev->displays[k]->disable(vid_dev->displays[k]); + + omap_dss_put_device(vid_dev->displays[k]); + } + kfree(vid_dev); + return 0; +} + +static int __init omap_vout_probe(struct platform_device *pdev) +{ + int r = 0, i; + struct omap2video_device *vid_dev = NULL; + struct omap_overlay *ovl; + struct omap_dss_device *def_display; + struct omap_dss_device *dssdev; + + if (pdev->num_resources == 0) { + dev_err(&pdev->dev, "probed for an unknown device\n"); + r = -ENODEV; + return r; + } + + vid_dev = kzalloc(sizeof(struct omap2video_device), GFP_KERNEL); + if (vid_dev == NULL) { + r = -ENOMEM; + return r; + } + + vid_dev->num_displays = 0; + dssdev = NULL; + for_each_dss_dev(dssdev) { + omap_dss_get_device(dssdev); + vid_dev->displays[vid_dev->num_displays++] = dssdev; + } + + if (vid_dev->num_displays == 0) { + dev_err(&pdev->dev, "no displays\n"); + r = -EINVAL; + goto error0; + } + + vid_dev->num_overlays = omap_dss_get_num_overlays(); + for (i = 0; i < vid_dev->num_overlays; i++) + vid_dev->overlays[i] = omap_dss_get_overlay(i); + + vid_dev->num_managers = omap_dss_get_num_overlay_managers(); + for (i = 0; i < vid_dev->num_managers; i++) + vid_dev->managers[i] = omap_dss_get_overlay_manager(i); + + /* Get the Video1 overlay and video2 overlay. + * Setup the Display attached to that overlays + */ + for (i = 1; i < 3; i++) { + ovl = omap_dss_get_overlay(i); + if (ovl->manager && ovl->manager->device) { + def_display = ovl->manager->device; + } else { + dev_warn(&pdev->dev, "cannot find display\n"); + def_display = NULL; + } + if (def_display) { + r = def_display->enable(def_display); + if (r) { + /* Here we are not considering a error as display may be + enabled by frame buffer driver */ + dev_warn(&pdev->dev, + "'%s' Display already enabled\n", + def_display->name); + } + /* set the update mode */ + if (def_display->caps & + OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { +#ifdef CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE + if (def_display->set_update_mode) + def_display->set_update_mode( + def_display, + OMAP_DSS_UPDATE_AUTO); + if (def_display->enable_te) + def_display->enable_te(def_display, 1); +#else + if (def_display->set_update_mode) + def_display->set_update_mode( + def_display, + OMAP_DSS_UPDATE_MANUAL); + if (def_display->enable_te) + def_display->enable_te(def_display, 0); +#endif + } else { + if (def_display->set_update_mode) + def_display->set_update_mode( + def_display, + OMAP_DSS_UPDATE_AUTO); + } + } + } + + if (v4l2_device_register(&pdev->dev, &vid_dev->v4l2_dev) < 0) { + printk(KERN_ERR VOUT_NAME + "v4l2_device_register unsuccessful\n"); + return -ENODEV; + } + + r = omap_vout_create_video_devices(pdev); + if (r) + goto error0; + + for (i = 0; i < vid_dev->num_displays; i++) { + struct omap_dss_device *display = vid_dev->displays[i]; + + if (display->update) + display->update(display, 0, 0, + display->panel.timings.x_res, + display->panel.timings.y_res); + } + printk(KERN_INFO VOUT_NAME "display->updated\n"); + return 0; + +error0: + kfree(vid_dev); + return r; +} + +static struct platform_driver omap_vout_driver = { + .driver = { + .name = VOUT_NAME, + }, + .probe = omap_vout_probe, + .remove = omap_vout_remove, +}; + +void omap_vout_isr(void *arg, unsigned int irqstatus) +{ + int r; + struct timeval timevalue; + struct omap_vout_device *vout = + (struct omap_vout_device *) arg; + u32 addr, fid; + struct omapvideo_info *ovid; + struct omap_overlay *ovl; + struct omap_dss_device *cur_display; + + printk(KERN_INFO VOUT_NAME + "entered vout isr \n"); + + if (!vout->streaming) + return; + + printk(KERN_INFO VOUT_NAME + "starting processing \n"); + + ovid = &(vout->vid_info); + ovl = ovid->overlays[0]; + /* get the display device attached to the overlay */ + if (!ovl->manager || !ovl->manager->device) + return; + cur_display = ovl->manager->device; + + printk(KERN_INFO VOUT_NAME + " isr: before vbq_lock \n"); + + spin_lock(&vout->vbq_lock); + do_gettimeofday(&timevalue); + + printk(KERN_INFO VOUT_NAME + " isr: after spin_lock and gettime \n"); + + if (cur_display->type == OMAP_DISPLAY_TYPE_DPI) { + if (!(irqstatus & DISPC_IRQ_VSYNC)) + return; + if (!vout->first_int && (vout->cur_frm != vout->next_frm)) { + vout->cur_frm->ts = timevalue; + vout->cur_frm->state = VIDEOBUF_DONE; + wake_up_interruptible(&vout->cur_frm->done); + vout->cur_frm = vout->next_frm; + } + vout->first_int = 0; + if (list_empty(&vout->dma_queue)) { + spin_unlock(&vout->vbq_lock); + return; + } + + vout->next_frm = list_entry(vout->dma_queue.next, + struct videobuf_buffer, queue); + list_del(&vout->next_frm->queue); + + vout->next_frm->state = VIDEOBUF_ACTIVE; + + addr = (unsigned long) vout->queued_buf_addr[vout->next_frm->i] + + vout->cropped_offset; + + /* First save the configuration in ovelray structure */ + r = omapvid_init(vout, addr); + if (r) + printk(KERN_ERR VOUT_NAME "failed to set overlay info\n"); + /* Enable the pipeline and set the Go bit */ + r = omapvid_apply_changes(vout); + if (r) + printk(KERN_ERR VOUT_NAME "failed to change mode\n"); + } else { + + if (vout->first_int) { + vout->first_int = 0; + spin_unlock(&vout->vbq_lock); + return; + } + if (irqstatus & DISPC_IRQ_EVSYNC_ODD) { + fid = 1; + } else if (irqstatus & DISPC_IRQ_EVSYNC_EVEN) { + fid = 0; + } else { + spin_unlock(&vout->vbq_lock); + return; + } + vout->field_id ^= 1; + if (fid != vout->field_id) { + if (0 == fid) + vout->field_id = fid; + + spin_unlock(&vout->vbq_lock); + return; + } + if (0 == fid) { + if (vout->cur_frm == vout->next_frm) { + spin_unlock(&vout->vbq_lock); + return; + } + vout->cur_frm->ts = timevalue; + vout->cur_frm->state = VIDEOBUF_DONE; + wake_up_interruptible(&vout->cur_frm->done); + vout->cur_frm = vout->next_frm; + } else if (1 == fid) { + if (list_empty(&vout->dma_queue) || + (vout->cur_frm != vout->next_frm)) { + spin_unlock(&vout->vbq_lock); + return; + } + vout->next_frm = list_entry(vout->dma_queue.next, + struct videobuf_buffer, queue); + list_del(&vout->next_frm->queue); + + vout->next_frm->state = VIDEOBUF_ACTIVE; + addr = (unsigned long) + vout->queued_buf_addr[vout->next_frm->i] + + vout->cropped_offset; + /* First save the configuration in ovelray structure */ + r = omapvid_init(vout, addr); + if (r) + printk(KERN_ERR VOUT_NAME "failed to set overlay info\n"); + /* Enable the pipeline and set the Go bit */ + r = omapvid_apply_changes(vout); + if (r) + printk(KERN_ERR VOUT_NAME "failed to change mode\n"); + } + + } + spin_unlock(&vout->vbq_lock); +} + +static void omap_vout_cleanup_device(struct omap_vout_device *vout) +{ + + struct video_device *vfd; + + if (!vout) + return; + vfd = vout->vfd; + + if (vfd) { + if (vfd->minor == -1) { + /* + * The device was never registered, so release the + * video_device struct directly. + */ + video_device_release(vfd); + } else { + /* + * The unregister function will release the video_device + * struct as well as unregistering it. + */ + video_unregister_device(vfd); + } + } + +#ifndef CONFIG_ARCH_OMAP4 + omap_vout_release_vrfb(vout); +#endif + omap_vout_free_buffers(vout); +#ifndef CONFIG_ARCH_OMAP4 + /* Free the VRFB buffer if allocated + * init time + */ + if (vout->vrfb_static_allocation) + omap_vout_free_vrfb_buffers(vout); +#endif + kfree(vout); +} + +static int __init omap_vout_init(void) +{ + + if (platform_driver_register(&omap_vout_driver) != 0) { + printk(KERN_ERR VOUT_NAME ": could not register \ + Video driver\n"); + return -EINVAL; + } + return 0; +} + +static void omap_vout_cleanup(void) +{ + platform_driver_unregister(&omap_vout_driver); +} + +late_initcall(omap_vout_init); +module_exit(omap_vout_cleanup); diff --git a/drivers/media/video/omap/omap_voutdef.h b/drivers/media/video/omap/omap_voutdef.h new file mode 100644 index 000000000000..eb19a219998d --- /dev/null +++ b/drivers/media/video/omap/omap_voutdef.h @@ -0,0 +1,150 @@ +/* + * drivers/media/video/omap/omap_voutdef.h + * + * Copyright (C) 2009 Texas Instruments. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#ifndef OMAP_VOUTDEF_H +#define OMAP_VOUTDEF_H + +#include <mach/display.h> + +#define YUYV_BPP 2 +#define RGB565_BPP 2 +#define RGB24_BPP 3 +#define RGB32_BPP 4 +#define TILE_SIZE 32 +#define YUYV_VRFB_BPP 2 +#define RGB_VRFB_BPP 1 +#define MAX_CID 3 + +#define MAC_VRFB_CTXS 4 +#define MAX_VOUT_DEV 2 +#define MAX_OVLS 3 +#define MAX_DISPLAYS 3 +#define MAX_MANAGERS 3 + +/* Enum for Rotation + * DSS understands rotation in 0, 1, 2, 3 context + * while V4L2 driver understands it as 0, 90, 180, 270 + */ +enum dss_rotation { + dss_rotation_0_degree = 0, + dss_rotation_90_degree = 1, + dss_rotation_180_degree = 2, + dss_rotation_270_degree = 3, +}; + +/* + * This structure is used to store the DMA transfer parameters + * for VRFB hidden buffer + */ +struct vid_vrfb_dma { + int dev_id; + int dma_ch; + int req_status; + int tx_status; + wait_queue_head_t wait; +}; + +struct omapvideo_info { + int id; + int num_overlays; + struct omap_overlay *overlays[MAX_OVLS]; +}; + +struct omap2video_device { + struct mutex mtx; + + int state; + + struct v4l2_device v4l2_dev; + int num_videos; + struct omap_vout_device *vouts[MAX_VOUT_DEV]; + + int num_displays; + struct omap_dss_device *displays[MAX_DISPLAYS]; + int num_overlays; + struct omap_overlay *overlays[MAX_OVLS]; + int num_managers; + struct omap_overlay_manager *managers[MAX_MANAGERS]; +}; + +/* per-device data structure */ +struct omap_vout_device { + + struct omapvideo_info vid_info; + struct video_device *vfd; + struct omap2video_device *vid_dev; + int vid; + int opened; + + /* we don't allow to change image fmt/size once buffer has + * been allocated + */ + int buffer_allocated; + /* allow to reuse previosuly allocated buffer which is big enough */ + int buffer_size; + /* keep buffer info accross opens */ + unsigned long buf_virt_addr[VIDEO_MAX_FRAME]; + unsigned long buf_phy_addr[VIDEO_MAX_FRAME]; + enum omap_color_mode dss_mode; + + /* we don't allow to request new buffer when old buffers are + * still mmaped + */ + int mmap_count; + + spinlock_t vbq_lock; /* spinlock for videobuf queues */ + unsigned long field_count; /* field counter for videobuf_buffer */ + + /* non-NULL means streaming is in progress. */ + bool streaming; + + struct v4l2_pix_format pix; + struct v4l2_rect crop; + struct v4l2_window win; + struct v4l2_framebuffer fbuf; + + /* Lock to protect the shared data structures in ioctl */ + struct mutex lock; + + /* V4L2 control structure for different control id */ + struct v4l2_control control[MAX_CID]; + enum dss_rotation rotation; + bool mirror; + int flicker_filter; + /* V4L2 control structure for different control id */ + + int bpp; /* bytes per pixel */ + int vrfb_bpp; /* bytes per pixel with respect to VRFB */ + + struct vid_vrfb_dma vrfb_dma_tx; + unsigned int smsshado_phy_addr[MAC_VRFB_CTXS]; + unsigned int smsshado_virt_addr[MAC_VRFB_CTXS]; + struct vrfb vrfb_context[MAC_VRFB_CTXS]; + bool vrfb_static_allocation; + unsigned int smsshado_size; + unsigned char pos; + + int ps, vr_ps, line_length, first_int, field_id; + enum v4l2_memory memory; + struct videobuf_buffer *cur_frm, *next_frm; + struct list_head dma_queue; + u8 *queued_buf_addr[VIDEO_MAX_FRAME]; + u32 cropped_offset; + s32 tv_field1_offset; + void *isr_handle; + + /* Buffer queue variabled */ + struct omap_vout_device *vout; + enum v4l2_buf_type type; + struct videobuf_queue vbq; + int io_allowed; + +}; +#endif /* ifndef OMAP_VOUTDEF_H */ diff --git a/drivers/media/video/omap/omap_voutlib.c b/drivers/media/video/omap/omap_voutlib.c new file mode 100644 index 000000000000..37fed10107cc --- /dev/null +++ b/drivers/media/video/omap/omap_voutlib.c @@ -0,0 +1,257 @@ +/* + * drivers/media/video/omap/omap_voutlib.c + * + * Copyright (C) 2005-2009 Texas Instruments. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + * + * Based on the OMAP2 camera driver + * Video-for-Linux (Version 2) camera capture driver for + * the OMAP24xx camera controller. + * + * Author: Andy Lowe (source@mvista.com) + * + * Copyright (C) 2004 MontaVista Software, Inc. + * Copyright (C) 2009 Texas Instruments. + * + */ + +#include <linux/module.h> +#include <linux/errno.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/videodev2.h> + +MODULE_AUTHOR("Texas Instruments."); +MODULE_DESCRIPTION("OMAP Video library"); +MODULE_LICENSE("GPL"); + +/* Return the default overlay cropping rectangle in crop given the image + * size in pix and the video display size in fbuf. The default + * cropping rectangle is the largest rectangle no larger than the capture size + * that will fit on the display. The default cropping rectangle is centered in + * the image. All dimensions and offsets are rounded down to even numbers. + */ +void omap_vout_default_crop(struct v4l2_pix_format *pix, + struct v4l2_framebuffer *fbuf, struct v4l2_rect *crop) +{ + crop->width = (pix->width < fbuf->fmt.width) ? + pix->width : fbuf->fmt.width; + crop->height = (pix->height < fbuf->fmt.height) ? + pix->height : fbuf->fmt.height; + crop->width &= ~1; + crop->height &= ~1; + crop->left = ((pix->width - crop->width) >> 1) & ~1; + crop->top = ((pix->height - crop->height) >> 1) & ~1; +} +EXPORT_SYMBOL_GPL(omap_vout_default_crop); + +/* Given a new render window in new_win, adjust the window to the + * nearest supported configuration. The adjusted window parameters are + * returned in new_win. + * Returns zero if succesful, or -EINVAL if the requested window is + * impossible and cannot reasonably be adjusted. + */ +int omap_vout_try_window(struct v4l2_framebuffer *fbuf, + struct v4l2_window *new_win) +{ + struct v4l2_rect try_win; + + /* make a working copy of the new_win rectangle */ + try_win = new_win->w; + + /* adjust the preview window so it fits on the display by clipping any + * offscreen areas + */ + if (try_win.left < 0) { + try_win.width += try_win.left; + try_win.left = 0; + } + if (try_win.top < 0) { + try_win.height += try_win.top; + try_win.top = 0; + } + try_win.width = (try_win.width < fbuf->fmt.width) ? + try_win.width : fbuf->fmt.width; + try_win.height = (try_win.height < fbuf->fmt.height) ? + try_win.height : fbuf->fmt.height; + if (try_win.left + try_win.width > fbuf->fmt.width) + try_win.width = fbuf->fmt.width - try_win.left; + if (try_win.top + try_win.height > fbuf->fmt.height) + try_win.height = fbuf->fmt.height - try_win.top; + try_win.width &= ~1; + try_win.height &= ~1; + + if (try_win.width <= 0 || try_win.height <= 0) + return -EINVAL; + + /* We now have a valid preview window, so go with it */ + new_win->w = try_win; + new_win->field = V4L2_FIELD_ANY; + return 0; +} +EXPORT_SYMBOL_GPL(omap_vout_try_window); + +/* Given a new render window in new_win, adjust the window to the + * nearest supported configuration. The image cropping window in crop + * will also be adjusted if necessary. Preference is given to keeping the + * the window as close to the requested configuration as possible. If + * successful, new_win, vout->win, and crop are updated. + * Returns zero if succesful, or -EINVAL if the requested preview window is + * impossible and cannot reasonably be adjusted. + */ +int omap_vout_new_window(struct v4l2_rect *crop, + struct v4l2_window *win, struct v4l2_framebuffer *fbuf, + struct v4l2_window *new_win) +{ + int err; + + err = omap_vout_try_window(fbuf, new_win); + if (err) + return err; + + /* update our preview window */ + win->w = new_win->w; + win->field = new_win->field; + win->chromakey = new_win->chromakey; + + /* adjust the cropping window to allow for resizing limitations */ + if ((crop->height/win->w.height) >= 4) { + /* The maximum vertical downsizing ratio is 4:1 */ + crop->height = win->w.height * 4; + } + if ((crop->width/win->w.width) >= 4) { + /* The maximum horizontal downsizing ratio is 4:1 */ + crop->width = win->w.width * 4; + } + return 0; +} +EXPORT_SYMBOL_GPL(omap_vout_new_window); + +/* Given a new cropping rectangle in new_crop, adjust the cropping rectangle to + * the nearest supported configuration. The image render window in win will + * also be adjusted if necessary. The preview window is adjusted such that the + * horizontal and vertical rescaling ratios stay constant. If the render + * window would fall outside the display boundaries, the cropping rectangle + * will also be adjusted to maintain the rescaling ratios. If successful, crop + * and win are updated. + * Returns zero if succesful, or -EINVAL if the requested cropping rectangle is + * impossible and cannot reasonably be adjusted. + */ +int omap_vout_new_crop(struct v4l2_pix_format *pix, + struct v4l2_rect *crop, struct v4l2_window *win, + struct v4l2_framebuffer *fbuf, const struct v4l2_rect *new_crop) +{ + struct v4l2_rect try_crop; + unsigned long vresize, hresize; + + /* make a working copy of the new_crop rectangle */ + try_crop = *new_crop; + + /* adjust the cropping rectangle so it fits in the image */ + if (try_crop.left < 0) { + try_crop.width += try_crop.left; + try_crop.left = 0; + } + if (try_crop.top < 0) { + try_crop.height += try_crop.top; + try_crop.top = 0; + } + try_crop.width = (try_crop.width < pix->width) ? + try_crop.width : pix->width; + try_crop.height = (try_crop.height < pix->height) ? + try_crop.height : pix->height; + if (try_crop.left + try_crop.width > pix->width) + try_crop.width = pix->width - try_crop.left; + if (try_crop.top + try_crop.height > pix->height) + try_crop.height = pix->height - try_crop.top; + try_crop.width &= ~1; + try_crop.height &= ~1; + if (try_crop.width <= 0 || try_crop.height <= 0) + return -EINVAL; + + if (crop->height != win->w.height) { + /* If we're resizing vertically, we can't support a crop width + * wider than 768 pixels. + */ + if (try_crop.width > 768) + try_crop.width = 768; + } + /* vertical resizing */ + vresize = (1024 * crop->height) / win->w.height; + if (vresize > 4096) + vresize = 4096; + else if (vresize == 0) + vresize = 1; + win->w.height = ((1024 * try_crop.height) / vresize) & ~1; + if (win->w.height == 0) + win->w.height = 2; + if (win->w.height + win->w.top > fbuf->fmt.height) { + /* We made the preview window extend below the bottom of the + * display, so clip it to the display boundary and resize the + * cropping height to maintain the vertical resizing ratio. + */ + win->w.height = (fbuf->fmt.height - win->w.top) & ~1; + if (try_crop.height == 0) + try_crop.height = 2; + } + /* horizontal resizing */ + hresize = (1024 * crop->width) / win->w.width; + if (hresize > 4096) + hresize = 4096; + else if (hresize == 0) + hresize = 1; + win->w.width = ((1024 * try_crop.width) / hresize) & ~1; + if (win->w.width == 0) + win->w.width = 2; + if (win->w.width + win->w.left > fbuf->fmt.width) { + /* We made the preview window extend past the right side of the + * display, so clip it to the display boundary and resize the + * cropping width to maintain the horizontal resizing ratio. + */ + win->w.width = (fbuf->fmt.width - win->w.left) & ~1; + if (try_crop.width == 0) + try_crop.width = 2; + } + + /* Check for resizing constraints */ + if ((try_crop.height/win->w.height) >= 4) { + /* The maximum vertical downsizing ratio is 4:1 */ + try_crop.height = win->w.height * 4; + } + if ((try_crop.width/win->w.width) >= 4) { + /* The maximum horizontal downsizing ratio is 4:1 */ + try_crop.width = win->w.width * 4; + } + + /* update our cropping rectangle and we're done */ + *crop = try_crop; + return 0; +} +EXPORT_SYMBOL_GPL(omap_vout_new_crop); + +/* Given a new format in pix and fbuf, crop and win + * structures are initialized to default values. crop + * is initialized to the largest window size that will fit on the display. The + * crop window is centered in the image. win is initialized to + * the same size as crop and is centered on the display. + * All sizes and offsets are constrained to be even numbers. + */ +void omap_vout_new_format(struct v4l2_pix_format *pix, + struct v4l2_framebuffer *fbuf, struct v4l2_rect *crop, + struct v4l2_window *win) +{ + /* crop defines the preview source window in the image capture + * buffer + */ + omap_vout_default_crop(pix, fbuf, crop); + + /* win defines the preview target window on the display */ + win->w.width = crop->width; + win->w.height = crop->height; + win->w.left = ((fbuf->fmt.width - win->w.width) >> 1) & ~1; + win->w.top = ((fbuf->fmt.height - win->w.height) >> 1) & ~1; +} +EXPORT_SYMBOL_GPL(omap_vout_new_format); diff --git a/drivers/media/video/omap/omap_voutlib.h b/drivers/media/video/omap/omap_voutlib.h new file mode 100644 index 000000000000..8ef6e25b9e62 --- /dev/null +++ b/drivers/media/video/omap/omap_voutlib.h @@ -0,0 +1,34 @@ +/* + * drivers/media/video/omap/omap_voutlib.h + * + * Copyright (C) 2009 Texas Instruments. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + * + */ + +#ifndef OMAP_VOUTLIB_H +#define OMAP_VOUTLIB_H + +extern void omap_vout_default_crop(struct v4l2_pix_format *pix, + struct v4l2_framebuffer *fbuf, struct v4l2_rect *crop); + +extern int omap_vout_new_crop(struct v4l2_pix_format *pix, + struct v4l2_rect *crop, struct v4l2_window *win, + struct v4l2_framebuffer *fbuf, + const struct v4l2_rect *new_crop); + +extern int omap_vout_try_window(struct v4l2_framebuffer *fbuf, + struct v4l2_window *new_win); + +extern int omap_vout_new_window(struct v4l2_rect *crop, + struct v4l2_window *win, struct v4l2_framebuffer *fbuf, + struct v4l2_window *new_win); + +extern void omap_vout_new_format(struct v4l2_pix_format *pix, + struct v4l2_framebuffer *fbuf, struct v4l2_rect *crop, + struct v4l2_window *win); +#endif /* #ifndef OMAP_LIB_H */ + diff --git a/drivers/media/video/tiler/Kconfig b/drivers/media/video/tiler/Kconfig new file mode 100644 index 000000000000..926349dbe9a9 --- /dev/null +++ b/drivers/media/video/tiler/Kconfig @@ -0,0 +1,18 @@ + + +menuconfig dmm_tiler + bool "dmm_tiler" + default y + +if dmm_tiler + +config DMM_TILER + tristate "dmm_tiler" + default y + help + dmm tiler driver +endif + + + + diff --git a/drivers/media/video/tiler/Makefile b/drivers/media/video/tiler/Makefile new file mode 100644 index 000000000000..3b3885541fe2 --- /dev/null +++ b/drivers/media/video/tiler/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_DMM_TILER) += tiler.o
+tiler-objs = dmm.o dmm_hl_drv.o dmm_2d_alloc.o dmm_ll_drv.o
+
diff --git a/drivers/media/video/tiler/dmm.c b/drivers/media/video/tiler/dmm.c new file mode 100644 index 000000000000..9b78c109dfaf --- /dev/null +++ b/drivers/media/video/tiler/dmm.c @@ -0,0 +1,588 @@ +/* + * dmm.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/init.h> +#include <linux/module.h> +#include <linux/cdev.h> /* struct cdev */ +#include <linux/kdev_t.h> /* MKDEV() */ +#include <linux/fs.h> /* register_chrdev_region() */ +#include <linux/device.h> /* struct class */ +#include <linux/platform_device.h> /* platform_device() */ +#include <linux/err.h> /* IS_ERR() */ +#include <linux/errno.h> +#include <linux/io.h> /* ioremap() */ +#include "dmm.h" +#include "dmm_drv.h" +#include "dmm_prv.h" +#include "dmm_def.h" + +#define DMM_MAJOR 0 +#define DMM_MINOR 0 + +#define DMM_IO_BASE_ADDR 0x4e000000 + +unsigned long *dmmvabase; + +static int +dmm_open(struct inode *i, struct file *f); +static int +dmm_release(struct inode *i, struct file *f); +static int +dmm_ioctl(struct inode *i, struct file *f, + unsigned int c, unsigned long a); +static void +dmm_config(); + +static int dmm_major; +static int dmm_minor; + +struct dmm_dev { + struct cdev cdev; +}; + +static struct dmm_dev *dmm_device; +static struct class *dmmdev_class; +static const struct file_operations dmm_fops = { + .open = dmm_open, + .ioctl = dmm_ioctl, + .release = dmm_release, +}; + +static struct platform_driver tiler_driver_ldm = { + .driver = { + .owner = THIS_MODULE, + .name = "tiler", + }, + .probe = NULL, + .shutdown = NULL, + .remove = NULL, +}; + +struct dmmInstanceCtxT dmmInstanceCtxStatic = { + 0, +}; + +static int +__init dmm_init(void) +{ + dev_t dev = 0; + int retval = -1; + + if (dmm_major) { + dev = MKDEV(dmm_major, dmm_minor); + retval = register_chrdev_region(dev, 1, "tiler"); + } else { + retval = alloc_chrdev_region(&dev, dmm_minor, 1, "tiler"); + dmm_major = MAJOR(dev); + } + + dmm_device = kmalloc(sizeof(struct dmm_dev), GFP_KERNEL); + if (!dmm_device) { + retval = -ENOMEM; + unregister_chrdev_region(dev, 1); + printk(KERN_ERR "kmalloc():failed\n"); + goto EXIT; + } + memset(dmm_device, 0x0, sizeof(struct dmm_dev)); + cdev_init(&dmm_device->cdev, &dmm_fops); + dmm_device->cdev.owner = THIS_MODULE; + dmm_device->cdev.ops = &dmm_fops; + + retval = cdev_add(&dmm_device->cdev, dev, 1); + if (retval) + printk(KERN_ERR "cdev_add():failed\n"); + + dmmdev_class = class_create(THIS_MODULE, "tiler"); + + if (IS_ERR(dmmdev_class)) { + printk(KERN_ERR "class_create():failed\n"); + goto EXIT; + } + + retval = device_create(dmmdev_class, NULL, dev, NULL, "tiler"); + + retval = platform_driver_register(&tiler_driver_ldm); + + /* map the TILER i/o physical addr to krnl virt addr */ + dmmvabase = ioremap(DMM_IO_BASE_ADDR, 2048); + + /* config LISA/PAT */ + dmm_config(); + +EXIT: + return retval; +} + +static void +__exit dmm_exit(void) +{ + platform_driver_unregister(&tiler_driver_ldm); + + cdev_del(&dmm_device->cdev); + kfree(dmm_device); + + device_destroy(dmmdev_class, MKDEV(dmm_major, dmm_minor)); + class_destroy(dmmdev_class); + + iounmap(dmmvabase); +} + +static int +dmm_open(struct inode *ip, struct file *filp) +{ + int retval = -1; + retval = 0; + return retval; +} + +static int +dmm_release(struct inode *ip, struct file *filp) +{ + int retval = -1; + retval = 0; + return retval; +} + +static int +dmm_ioctl(struct inode *ip, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + struct dmm_data *d = NULL; + void *SSPtr = NULL; + int retval = -1; + int error = -1; + + switch (cmd) { + case IOCGALLOC: + d = (struct dmm_data *)arg; + + error = dmm_tiler_buf_alloc(&dmmInstanceCtxStatic, + d->w, + d->h, + d->pixfmt, + &SSPtr, + NULL); + if (error == 0) { + retval = 0; + d->ssptr = SSPtr; + } else { + printk(KERN_ERR "%s::%s():%d\n", + __FILE__, __func__, __LINE__); + } + break; + case IOCSFREE: + d = (struct dmm_data *)arg; + + error = dmm_tiler_buf_free(&dmmInstanceCtxStatic, + d->ssptr, + 1); + if (error == 0) + retval = 0; + break; + case IOCGTSPTR: + d = (struct dmm_data *)arg; + struct dmmViewOrientT orient; + + orient.dmm90Rotate = d->syx >> 2 & 1; + orient.dmmXInvert = d->syx >> 1 & 1; + orient.dmmYInvert = d->syx >> 0 & 1; + + error = dmm_tiler_translate_sysptr(dmm_get_context_pointer(), + (void *)d->ssptr, + orient, 0, 0, 1, 0); + + if (error == 0) + retval = 0; + break; + } + + return retval; +} + +static void +dmm_config() +{ + struct dmmPATIrqConfigLstT patEvents; + struct dmmPATEngineConfigLstT patEngineConf[2]; + struct dmmPATViewConfigLstT patViewConf[16]; + struct dmmPATViewMapConfigLstT patViewMapConf[4]; + struct dmmLISAConfigLstT lisaMemMapConf[1]; + struct dmmTILERConfigLstT dmmTilerAliasView[16]; + unsigned int retCode = 0x0; + unsigned int i = 0x0; + + /* clear irq event registers */ + patEvents.nextConf = NULL; + patEvents.irqConf.clrEvents = 1; + patEvents.irqConf.irqEvnts.irqAreaSelect = 0; + patEvents.irqConf.irqEvnts.lutMiss = 1; + patEvents.irqConf.irqEvnts.updData = 1; + patEvents.irqConf.irqEvnts.updCtrl = 1; + patEvents.irqConf.irqEvnts.updArea = 1; + patEvents.irqConf.irqEvnts.invData = 1; + patEvents.irqConf.irqEvnts.invDsc = 1; + patEvents.irqConf.irqEvnts.fillLst = 1; + patEvents.irqConf.irqEvnts.fillDsc = 1; + + if (dmm_pat_irq_config_set((struct dmmPATIrqConfigLstT *)&patEvents) != + DMM_NO_ERROR) { + printk(KERN_ERR "%s::%s():%d: ERROR!\n", + __FILE__, __func__, __LINE__); + retCode = 0x2; + } + + /* configure pat engines */ + patEngineConf[0].nextConf = &patEngineConf[1]; + patEngineConf[0].engineConf.dmmPatEngineSel = 0; + patEngineConf[0].engineConf.engineMode = NORMAL_MODE; + + patEngineConf[1].nextConf = NULL; + patEngineConf[1].engineConf.dmmPatEngineSel = 1; + patEngineConf[1].engineConf.engineMode = NORMAL_MODE; + + if (dmm_module_config(NULL, NULL, NULL, + (struct dmmPATEngineConfigLstT *)patEngineConf, + NULL, NULL, NULL) != + DMM_NO_ERROR) { + printk(KERN_ERR "%s::%s():%d: ERROR!\n", + __FILE__, __func__, __LINE__); + retCode = 0x2; + } + + /* configure LISA map 0 */ + lisaMemMapConf[0].nextConf = NULL; + lisaMemMapConf[0].mapConf.lisaMemMapIndx = 0; + lisaMemMapConf[0].mapConf.sysAddr = 0x80; + lisaMemMapConf[0].mapConf.sysSize = 0x5; + lisaMemMapConf[0].mapConf.sdrcIntl = 0x0 ; + lisaMemMapConf[0].mapConf.sdrcAddrspc = 0x1; + lisaMemMapConf[0].mapConf.sdrcMap = 0x1; + lisaMemMapConf[0].mapConf.sdrcAddr = 0x00; + + if (dmm_module_config(NULL, NULL, + (struct dmmLISAConfigLstT *)lisaMemMapConf, + NULL, NULL, NULL, NULL) != DMM_NO_ERROR) { + printk(KERN_ERR "%s::%s():%d: ERROR!\n", + __FILE__, __func__, __LINE__); + retCode = 0x2; + } + + /* */ + for (i = 0; i < 16; i++) { + patViewConf[i].nextConf = &patViewConf[i+1]; + patViewConf[i].aliasViewConf.initiatorId = i; + patViewConf[i].aliasViewConf.viewIndex = 0; + } + patViewConf[15].nextConf = NULL; + + if (dmm_module_config(NULL, NULL, NULL, NULL, + (struct dmmPATViewConfigLstT *)&patViewConf, + NULL, NULL) != + DMM_NO_ERROR) { + printk(KERN_ERR "%s::%s():%d: ERROR!\n", + __FILE__, __func__, __LINE__); + retCode = 0x2; + } + + /* configure pat view map 0 */ + patViewMapConf[0].nextConf = &patViewMapConf[1]; + patViewMapConf[0].viewConf.patViewMapIndx = 0; + patViewMapConf[0].viewConf.memoryAccessMode = MODE_8_BIT; + patViewMapConf[0].viewConf.contX = 0; + patViewMapConf[0].viewConf.transType = INDIRECT; + + /* Setting only the MSB seems to have no effect whatsoever */ + patViewMapConf[0].viewConf.dmmPATViewBase = 0xFFFFFFFF; + + patViewMapConf[1].nextConf = &patViewMapConf[2]; + patViewMapConf[1].viewConf.patViewMapIndx = 0; + patViewMapConf[1].viewConf.memoryAccessMode = MODE_16_BIT; + patViewMapConf[1].viewConf.contX = 0; + patViewMapConf[1].viewConf.transType = INDIRECT; + + /* Setting only the MSB seems to have no effect whatsoever */ + patViewMapConf[1].viewConf.dmmPATViewBase = 0xFFFFFFFF; + + patViewMapConf[2].nextConf = &patViewMapConf[3]; + patViewMapConf[2].viewConf.patViewMapIndx = 0; + patViewMapConf[2].viewConf.memoryAccessMode = MODE_32_BIT; + patViewMapConf[2].viewConf.contX = 0; + patViewMapConf[2].viewConf.transType = INDIRECT; + + /* Setting only the MSB seems to have no effect whatsoever */ + patViewMapConf[2].viewConf.dmmPATViewBase = 0xFFFFFFFF; + + patViewMapConf[3].nextConf = NULL; + patViewMapConf[3].viewConf.patViewMapIndx = 0; + patViewMapConf[3].viewConf.memoryAccessMode = MODE_PAGE; + patViewMapConf[3].viewConf.contX = 0; + patViewMapConf[3].viewConf.transType = INDIRECT; + + /* Setting only the MSB seems to have no effect whatsoever */ + patViewMapConf[3].viewConf.dmmPATViewBase = 0xFFFFFFFF; + + if (dmm_module_config(NULL, NULL, NULL, NULL, NULL, + (struct dmmPATViewMapConfigLstT *)&patViewMapConf, + NULL) != DMM_NO_ERROR) { + printk(KERN_ERR "%s::%s():%d: ERROR!\n", + __FILE__, __func__, __LINE__); + retCode = 0x2; + } + + /* set all initiators to zero degree natural */ + for (i = 0; i < 16; i++) { + dmmTilerAliasView[i].nextConf = &dmmTilerAliasView[i + 1]; + dmmTilerAliasView[i].aliasConf.initiatorId = i; + dmmTilerAliasView[i].aliasConf.orient.dmm90Rotate = 0; + dmmTilerAliasView[i].aliasConf.orient.dmmXInvert = 0; + dmmTilerAliasView[i].aliasConf.orient.dmmYInvert = 0; + } + dmmTilerAliasView[15].nextConf = NULL; + + if (dmm_module_config((struct dmmTILERConfigLstT *)dmmTilerAliasView, + NULL, NULL, NULL, NULL, NULL, NULL) != + DMM_NO_ERROR) { + printk(KERN_ERR "%s::%s():%d: ERROR!\n", + __FILE__, __func__, __LINE__); + retCode = 0x2; + } +} + +int +dmm_tiler_buf_alloc(void *dmmInstanceCtxPtr, + unsigned short sizeWidth, + unsigned short sizeHeight, + int contMod, + void **allocedPtr, + void *custmPagesPtr) +{ + enum errorCodeT eCode = DMM_NO_ERROR; + + struct dmmTILERContCtxT *dmmTilerCtx = + &((struct dmmInstanceCtxT *)dmmInstanceCtxPtr)->dmmTilerCtx; + + struct dmmTILERContPageAreaT *bufferMappedZone; + + if (eCode == DMM_NO_ERROR) { + eCode = dmm_tiler_container_map_area(dmmTilerCtx, + sizeWidth, + sizeHeight, + contMod, + allocedPtr, + &bufferMappedZone); + } + + if (eCode == DMM_NO_ERROR) { + + bufferMappedZone->xPageOfst = 0; + bufferMappedZone->yPageOfst = 0; + bufferMappedZone->xPageCount = + bufferMappedZone->x1 - bufferMappedZone->x0 + 1; + bufferMappedZone->yPageCount = + bufferMappedZone->y1 - bufferMappedZone->y0 + 1; + + eCode = dmm_pat_phy2virt_mapping(bufferMappedZone, + custmPagesPtr); + } + + if (eCode != DMM_NO_ERROR) + *allocedPtr = NULL; + + return eCode; +} +EXPORT_SYMBOL(dmm_tiler_buf_alloc); + +int +dmm_tiler_buf_free(void *dmmInstanceCtxPtr, + void *allocedPtr, + int aliasViewPtr) +{ + enum errorCodeT eCode = DMM_NO_ERROR; + struct dmmTILERContCtxT *dmmTilerCtx = + &((struct dmmInstanceCtxT *)dmmInstanceCtxPtr)->dmmTilerCtx; + + struct dmmTILERContPageAreaT *areaToFree; + + if (aliasViewPtr) { + allocedPtr = (void *)((unsigned long)allocedPtr & + DMM_ALIAS_VIEW_CLEAR); + } + + areaToFree = dmm_tiler_get_area_from_sysptr(dmmTilerCtx, allocedPtr); + + if (areaToFree != NULL) + eCode = dmm_tiler_container_unmap_area(dmmTilerCtx, areaToFree); + else + eCode = DMM_SYS_ERROR; + + return eCode; +} +EXPORT_SYMBOL(dmm_tiler_buf_free); + +void * +dmm_tiler_translate_sysptr(void *dmmInstanceCtxPtr, + void *sysPtr, + struct dmmViewOrientT orient, + unsigned int validDataWidth, + unsigned int validDataHeight, + int aliasViewPtr, + int ptrToaliasView) +{ + struct dmmTILERContPageAreaT *bufferMappedZone; + + struct dmmTILERContCtxT *dmmTilerCtx = + &((struct dmmInstanceCtxT *)dmmInstanceCtxPtr)->dmmTilerCtx; + + signed long pageDimmensionX; + signed long pageDimmensionY; + unsigned long addrAlignment; + enum dmmMemoryAccessT accessModeM; + + unsigned long areaX0; + unsigned long areaY0; + unsigned long areaX1; + unsigned long areaY1; + + unsigned long contWidth; + unsigned long contHeight; + + unsigned long newX; + unsigned long newY; + + if (aliasViewPtr) + sysPtr = (void *)((unsigned long)sysPtr & DMM_ALIAS_VIEW_CLEAR); + + accessModeM = DMM_GET_ACC_MODE(sysPtr); + + bufferMappedZone = dmm_tiler_get_area_from_sysptr(dmmTilerCtx, sysPtr); + + if (bufferMappedZone == NULL) + return NULL; + + switch (accessModeM) { + case MODE_8_BIT: + if (orient.dmm90Rotate) { + contWidth = DMM_TILER_CONT_HEIGHT_8; + contHeight = DMM_TILER_CONT_WIDTH_8; + } else { + contWidth = DMM_TILER_CONT_WIDTH_8; + contHeight = DMM_TILER_CONT_HEIGHT_8; + } + pageDimmensionX = DMM_PAGE_DIMM_X_MODE_8; + pageDimmensionY = DMM_PAGE_DIMM_Y_MODE_8; + addrAlignment = 0; + areaX0 = bufferMappedZone->x0; + areaY0 = bufferMappedZone->y0; + areaX1 = bufferMappedZone->x1; + areaY1 = bufferMappedZone->y1; + break; + case MODE_16_BIT: + if (orient.dmm90Rotate) { + contWidth = DMM_TILER_CONT_HEIGHT_16; + contHeight = DMM_TILER_CONT_WIDTH_16; + } else { + contWidth = DMM_TILER_CONT_WIDTH_16; + contHeight = DMM_TILER_CONT_HEIGHT_16; + } + pageDimmensionX = DMM_PAGE_DIMM_X_MODE_16; + pageDimmensionY = DMM_PAGE_DIMM_Y_MODE_16; + addrAlignment = 1; + areaX0 = bufferMappedZone->x0; + areaY0 = bufferMappedZone->y0; + areaX1 = bufferMappedZone->x1; + areaY1 = bufferMappedZone->y1; + break; + case MODE_32_BIT: + if (orient.dmm90Rotate) { + contWidth = DMM_TILER_CONT_HEIGHT_32; + contHeight = DMM_TILER_CONT_WIDTH_32; + } else { + contWidth = DMM_TILER_CONT_WIDTH_32; + contHeight = DMM_TILER_CONT_HEIGHT_32; + } + pageDimmensionX = DMM_PAGE_DIMM_X_MODE_32; + pageDimmensionY = DMM_PAGE_DIMM_Y_MODE_32; + addrAlignment = 2; + areaX0 = bufferMappedZone->x0; + areaY0 = bufferMappedZone->y0; + areaX1 = bufferMappedZone->x1; + areaY1 = bufferMappedZone->y1; + break; + case MODE_PAGE: + if (orient.dmm90Rotate) { + contWidth = DMM_TILER_CONT_HEIGHT_8; + contHeight = DMM_TILER_CONT_WIDTH_8; + } else { + contWidth = DMM_TILER_CONT_WIDTH_8; + contHeight = DMM_TILER_CONT_HEIGHT_8; + } + pageDimmensionX = DMM_PAGE_DIMM_X_MODE_8; + pageDimmensionY = DMM_PAGE_DIMM_Y_MODE_8; + addrAlignment = 0; + areaX0 = bufferMappedZone->x0; + areaY0 = bufferMappedZone->y0; + areaX1 = bufferMappedZone->x1; + areaY1 = bufferMappedZone->y1; + break; + default: + return NULL; + } + + if (orient.dmmXInvert) { + if (validDataWidth > 0 && validDataHeight) + newX = contWidth - validDataWidth; + else + newX = contWidth - (areaX1 + 1) * pageDimmensionX; + } else { + newX = areaX0 * pageDimmensionX; + } + + if (orient.dmmYInvert) { + if (validDataWidth > 0 && validDataHeight) + newY = contHeight - validDataHeight; + else + newY = contHeight - (areaY1 + 1) * pageDimmensionY; + } else { + newY = areaY0 * pageDimmensionY; + } + + if (orient.dmm90Rotate) + sysPtr = (void *)((newX*contHeight+newY)<< + ((unsigned long)addrAlignment)); + else + sysPtr = (void *)((newY*contWidth+newX)<< + ((unsigned long)addrAlignment)); + + if (ptrToaliasView) { + sysPtr = DMM_COMPOSE_TILER_ALIAS_PTR(sysPtr, accessModeM); + } else { + sysPtr = DMM_COMPOSE_TILER_PTR(sysPtr, + orient.dmm90Rotate, + orient.dmmYInvert, + orient.dmmXInvert, + accessModeM); + } + + return sysPtr; +} +EXPORT_SYMBOL(dmm_tiler_translate_sysptr); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("davidsin@ti.com"); +module_init(dmm_init); +module_exit(dmm_exit); + + diff --git a/drivers/media/video/tiler/dmm.h b/drivers/media/video/tiler/dmm.h new file mode 100644 index 000000000000..b5907d619d73 --- /dev/null +++ b/drivers/media/video/tiler/dmm.h @@ -0,0 +1,65 @@ +/* + * dmm.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_H +#define DMM_H + +extern int errno; + +struct dmm_data { + int pixfmt; + unsigned short w; + unsigned short h; + short seczone; + unsigned long ssptr; + unsigned long tsptr; + short syx; +}; + +struct dmmViewOrientT { + unsigned char dmm90Rotate; + unsigned char dmmXInvert; + unsigned char dmmYInvert; +}; + +#define IOCSINIT _IOWR('z', 100, unsigned long) +#define IOCGALLOC _IOWR('z', 101, unsigned long) +#define IOCSFREE _IOWR('z', 102, unsigned long) +#define IOCGTSPTR _IOWR('z', 103, unsigned long) + +int +dmm_tiler_buf_alloc(void *dmmInstanceCtxPtr, + unsigned short sizeWidth, + unsigned short sizeHeight, + int contMod, + void **allocedPtr, + void *custmPagesPtr); + +int +dmm_tiler_buf_free(void *dmmInstanceCtxPtr, + void *allocedPtr, + int aliasViewPtr); + +void * +dmm_tiler_translate_sysptr(void *dmmInstanceCtxPtr, + void *sysPtr, + struct dmmViewOrientT orient, + unsigned int validDataWidth, + unsigned int validDataHeight, + int aliasViewPtr, + int ptrToaliasView); + +#endif diff --git a/drivers/media/video/tiler/dmm_2d_alloc.c b/drivers/media/video/tiler/dmm_2d_alloc.c new file mode 100644 index 000000000000..00f67cfa0945 --- /dev/null +++ b/drivers/media/video/tiler/dmm_2d_alloc.c @@ -0,0 +1,1541 @@ +/* + * 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/vmalloc.h> +#include "dmm_def.h" +#include "dmm_2d_alloc.h" +#include "dmm_prv.h" + +/* ========================================================================== */ +/** + * overlapping_test() + * + * @brief Performs an area overlap test for errors. Debug only. + * + * @param tlrCtx - dmmTILERContCtxT* - [in] TILER context structure. + * + * @return int: 1 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)){ + printk(KERN_ERR"overlap test fail\n"); + } + } + itr2 = itr2->pgArNext; + } + itr1 = itr1->pgArNext; + } + return; +} + +/* ========================================================================== */ +/** + * point_free_test() + * + * @brief Tests if a page on a given coordinate is unoccupied. + * + * @param tlrCtx - dmmTILERContCtxT* - [in] TILER context structure. + * + * @param X - signed long - [in] X page coordinate. + * + * @param Y - signed long - [in] Y page coordinate. + * + * @param areaHit - dmmTILERContPageAreaT** - [out] Returns a pointer to the + * allocated area that was hit by the specified coordinate. + * + * @return int: 1 if the selected coordinate page is unoccupied. + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see + */ +/* ========================================================================== */ +inline int 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 0; + } + arUsd = arUsd->pgArNext; + } + return 1; +} + +/* ========================================================================== */ +/** + * point_area_hit() + * + * @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 - dmmTILERContPageAreaT* - [in] Given area to check if + * contains the given coordinate point. + * + * @return int: 1 if the given coordinate is contained in the + * given area. + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see + */ +/* ========================================================================== */ +inline int point_area_hit(signed long X, + signed long Y, + struct dmmTILERContPageAreaT *area) +{ + if ((area->x0 <= X && area->x1 >= X) && + (area->y0 <= Y && area->y1 >= Y)) + return 1; + return 0; +} + +/* ========================================================================== */ +/** + * 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 - dmmTILERContPageAreaT* - [in] Given area to check. + * + * @return int: 1 if the given areas overlap. + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see + */ +/* ========================================================================== */ +inline int 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 1; + } + return 0; +} + +/* ========================================================================== */ +/** + * line_area_hit() + * + * @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 - dmmTILERContPageAreaT* - [in] Given area to check. + * + * @return int: 1 if the given areas overlap. + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see + */ +/* ========================================================================== */ +inline int line_area_hit(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 1; + } + + return 0; +} + +/* ========================================================================== */ +/** + * expand_right() + * + * @brief Finds all of the unocupied pages ("expansion") along the specified + * coordinate line (1D check). + * + * @param tlrCtx - dmmTILERContCtxT* - [in] TILER context structure. + * + * @param X - signed long - [in] X page coordinate. + * + * @param Y - signed long - [in] Y page coordinate. + * + * @param areaHit - 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 (0 == 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 - dmmTILERContCtxT* - [in] TILER context structure. + * + * @param X - signed long - [in] X page coordinate. + * + * @param Y - signed long - [in] Y page coordinate. + * + * @param areaHit - 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 (0 == 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 - dmmTILERContCtxT* - [in] TILER context structure. + * + * @param X - signed long - [in] X page coordinate. + * + * @param Y - signed long - [in] Y page coordinate. + * + * @param areaHit - 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 (0 == 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 - dmmTILERContCtxT* - [in] TILER context structure. + * + * @param X - signed long - [in] X page coordinate. + * + * @param Y - signed long - [in] Y page coordinate. + * + * @param areaHit - 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 (0 == 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 - 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 - 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; +} + +/* ========================================================================== */ +/** + * expand_line_on_top_to_right() + * + * @brief Finds all of the unocupied pages ("expansion") along the specified + * coordinate line area (2D check). + * + * @param tlrCtx - 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_top_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_top_to_left() + * + * @brief Finds all of the unocupied pages ("expansion") along the specified + * coordinate line area (2D check). + * + * @param tlrCtx - 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_top_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 - 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 - 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 - 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; +} + +/* ========================================================================== */ +/** + * expand_line_on_left_to_bottom() + * + * @brief Finds all of the unocupied pages ("expansion") along the specified + * coordinate line area (2D check). + * + * @param tlrCtx - 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_left_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_left_to_top() + * + * @brief Finds all of the unocupied pages ("expansion") along the specified + * coordinate line area (2D check). + * + * @param tlrCtx - 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_left_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 - 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 - dmmTILERContPageAreaT* - [in] Required 2D area to be + * allocated. + * + * @param areaTotal - dmmTILERContPageAreaT* - [in] Total 2D area allocated for + * this area attachment. + * + * @param areaAlloc - 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 - 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; + } +} + +/* ========================================================================== */ +/** + * 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 - 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 - dmmTILERContCtxT* - [in] TILER context structure. + * + * @param areaReq - dmmTILERContPageAreaT* - [in] Required allcoation area. + * + * @return int: True if the specified area is the new best fit. + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see + */ +/* ========================================================================== */ +int 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 ((tmpArea->ttlExpndAr.x1 - tmpArea->ttlExpndAr.x0) * + (tmpArea->ttlExpndAr.y1 - + tmpArea->ttlExpndAr.y0) < + (tlrCtx->tmpArSelect.ttlExpndAr.x1 - + tlrCtx->tmpArSelect.ttlExpndAr.x0) * + (tlrCtx->tmpArSelect.ttlExpndAr.y1 - + tlrCtx->tmpArSelect.ttlExpndAr.y0)) { + + 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 1; + } + } + + return 0; +} + +/* ========================================================================== */ +/** + * 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 - dmmTILERContPageAreaT* - [in] Required allcoation area. + * + * @param atchAr - dmmTILERContPageAreaT* - [in] Area along which specified + * side the search for a new free area is performed. + * + * @param tlrCtx - dmmTILERContCtxT* - [in] TILER context structure. + * + * @return int: True if a qualified free zones is discovered. + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see + */ +/* ========================================================================== */ +int 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; + int fit; + + areaHit = NULL; + fitArea.anchrAr = atchAr; + X = atchAr->x0 - 1; + Y = atchAr->y0; + anchorX = X; + anchorY = Y; + fit = 0; + + 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) { + Y = (unsigned short)expand_top(tlrCtx, + X, Y, &areaHit); + } + fitArea.ttlExpndAr.y0 = (unsigned short)(Y); + fitArea.ttlExpndAr.y1 = + (unsigned short)expand_bottom(tlrCtx, + X, Y, &areaHit); + 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; + 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) { + Y = areaHit->y1 + 1; + areaHit = NULL; + } else { + printk(KERN_ERR"area fit failure\n"); + } + } + } + + 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 - dmmTILERContPageAreaT* - [in] Required allcoation area. + * + * @param atchAr - dmmTILERContPageAreaT* - [in] Area along which specified + * side the search for a new free area is performed. + * + * @param tlrCtx - dmmTILERContCtxT* - [in] TILER context structure. + * + * @return int: True if a qualified free zones is discovered. + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see + */ +/* ========================================================================== */ +int 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; + int fit; + + areaHit = NULL; + fitArea.anchrAr = atchAr; + X = atchAr->x1 + 1; + Y = atchAr->y0; + anchorX = X; + anchorY = Y; + fit = 0; + + 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) { + Y = (unsigned short)expand_top(tlrCtx, + X, Y, &areaHit); + } + + fitArea.ttlExpndAr.y0 = (unsigned short)(Y); + fitArea.ttlExpndAr.y1 = + (unsigned short)expand_bottom(tlrCtx, + X, Y, &areaHit); + 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; + 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) { + Y = areaHit->y1 + 1; + areaHit = NULL; + } else { + printk(KERN_ERR"area fit failure\n"); + } + } + } + + 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 - dmmTILERContPageAreaT* - [in] Required allcoation area. + * + * @param atchAr - dmmTILERContPageAreaT* - [in] Area along which specified + * side the search for a new free area is performed. + * + * @param tlrCtx - dmmTILERContCtxT* - [in] TILER context structure. + * + * @return int: True if a qualified free zones is discovered. + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see + */ +/* ========================================================================== */ +int 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; + int fit; + + areaHit = NULL; + fitArea.anchrAr = atchAr; + X = atchAr->x0; + Y = atchAr->y0 - 1; + anchorX = X; + anchorY = Y; + fit = 0; + + 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) { + X = (unsigned short)expand_left(tlrCtx, + X, Y, &areaHit); + } + + fitArea.ttlExpndAr.x0 = (unsigned short)(X); + fitArea.ttlExpndAr.x1 = + (unsigned short)expand_right(tlrCtx, + X, Y, &areaHit); + 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; + 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) { + X = areaHit->x1 + 1; + areaHit = NULL; + } else { + printk(KERN_ERR"area fit failure\n"); + } + } + } + + 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 - dmmTILERContPageAreaT* - [in] Required allcoation area. + * + * @param atchAr - dmmTILERContPageAreaT* - [in] Area along which specified + * side the search for a new free area is performed. + * + * @param tlrCtx - dmmTILERContCtxT* - [in] TILER context structure. + * + * @return int: True if a qualified free zones is discovered. + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see + */ +/* ========================================================================== */ +int 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; + int fit; + + areaHit = NULL; + fitArea.anchrAr = atchAr; + X = atchAr->x0; + Y = atchAr->y1 + 1; + anchorX = X; + anchorY = Y; + fit = 0; + + 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) { + X = (unsigned short)expand_left(tlrCtx, + X, Y, &areaHit); + } + + fitArea.ttlExpndAr.x0 = (unsigned short)(X); + fitArea.ttlExpndAr.x1 = (unsigned short) + expand_right(tlrCtx, X, Y, &areaHit); + 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; + + 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) { + X = areaHit->x1 + 1; + areaHit = NULL; + } else { + printk(KERN_ERR"area fit failure\n"); + } + } + } + + return fit; +} + +/* ========================================================================== */ +/** + * alloc_2d_area() + * + * @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) +{ + 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; + + 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 = (struct dmmTILERContPageLstT *) + vmalloc(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 = (struct dmmTILERContPageLstT *) + vmalloc(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; + } + + if (allocatedArea == NULL) + return NULL; + else + return &(allocatedArea->pgAr); +} + +/* ========================================================================== */ +/** + * dealloc_2d_area() + * + * @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 + */ +/* ========================================================================== */ +int dealloc_2d_area(struct dmmTILERContCtxT *dmmTilerCtx, + struct dmmTILERContPageAreaT *areaRem) +{ + struct dmmTILERContPageLstT *delItm; + struct dmmTILERContPageLstT *usedIter; + struct dmmTILERContPageLstT *usedPrev; + + 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; + } + + if (delItm != NULL) { + + signed long iter; + enum errorCodeT eCode = DMM_NO_ERROR; + + if (delItm->pgAr.patCustomPages == 0) { + unsigned long numPages = (delItm->pgAr.x1 - + delItm->pgAr.x0 + 1)*(delItm->pgAr.y1 - + delItm->pgAr.y0 + 1); + vfree(va); + } + + if (eCode == DMM_NO_ERROR) { + vfree(delItm->pgAr.patPageEntriesSpace); + delItm->pgAr.patPageEntries = NULL; + delItm->pgAr.patPageEntriesSpace = NULL; + } + + vfree(delItm); + return 1; + } else { + return 0; + } +} + +/* ========================================================================== */ +/** + * search_2d_area() + * + * @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, + int xInvert, + int yInvert) +{ + struct dmmTILERContPageLstT *usedIter; + usedIter = dmmTilerCtx->usdArList; + + if (!xInvert && !yInvert) { + while (usedIter != NULL) { + if (X == usedIter->pgAr.x0 && Y == usedIter->pgAr.y0) + return &(usedIter->pgAr); + + usedIter = usedIter->pgArNext; + } + } else if (xInvert && !yInvert) { + while (usedIter != NULL) { + if (X == usedIter->pgAr.x1 && Y == usedIter->pgAr.y0) + return &(usedIter->pgAr); + + usedIter = usedIter->pgArNext; + } + } else if (!xInvert && yInvert) { + while (usedIter != NULL) { + if (X == usedIter->pgAr.x0 && Y == usedIter->pgAr.y1) + return &(usedIter->pgAr); + + usedIter = usedIter->pgArNext; + } + } else { + while (usedIter != NULL) { + if (X == usedIter->pgAr.x1 && 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 new file mode 100644 index 000000000000..096251ab57b7 --- /dev/null +++ b/drivers/media/video/tiler/dmm_2d_alloc.h @@ -0,0 +1,143 @@ +/* + * 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 + +enum SideAffinity { + PSA_NONE, + PSA_LEFT, + PSA_TOP, + PSA_BOTTOM, + PSA_RIGHT +}; + +struct dmmTILERContPageAreaT { + unsigned char x0; + unsigned char y0; + unsigned char x1; + unsigned char y1; + unsigned char xPageOfst; + unsigned char yPageOfst; + unsigned char xPageCount; + unsigned char yPageCount; + enum SideAffinity fitToSide; + int patCustomPages; + unsigned long *patPageEntriesSpace; + unsigned long *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; +}; + +extern unsigned long *va; + +/* ========================================================================== */ +/** + * 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 + */ +/* ========================================================================== */ +int 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, + int xInvert, + int yInvert); + +#endif /* _DMM_2D_ALLOC_H */ + diff --git a/drivers/media/video/tiler/dmm_def.h b/drivers/media/video/tiler/dmm_def.h new file mode 100644 index 000000000000..e1f89c96d121 --- /dev/null +++ b/drivers/media/video/tiler/dmm_def.h @@ -0,0 +1,302 @@ +/* + * dmm_def.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_DEF_H +#define _DMM_DEF_H + +#include "dmm.h" + +#define DMM_4KiB_SIZE (4096) +#define DMM_TILER_CONT_WIDTH_8 (16384) +#define DMM_TILER_CONT_WIDTH_16 (16384) +#define DMM_TILER_CONT_WIDTH_32 (8192) +#define DMM_TILER_CONT_HEIGHT_8 (8192) +#define DMM_TILER_CONT_HEIGHT_16 (4096) +#define DMM_TILER_CONT_HEIGHT_32 (4096) + +/** @struc MSP_Dmm_eventNotificationT +* Structure defining Dmm driver context for user event notification +* (user callback and application specific data pointer. */ +struct MSP_Dmm_eventNotificationT { + void *hMSP; + void *usrAppData; +}; + +/** @enum errorCodeT +* Defining enumarated identifiers for general dmm driver errors. */ +enum errorCodeT { + DMM_NO_ERROR, + DMM_WRONG_PARAM, + DMM_HRDW_CONFIG_FAILED, + DMM_HRDW_NOT_READY, + DMM_SYS_ERROR +}; + +/** @enum dmmPATStatusErrT +* Defining enumarated identifiers for PAT area status error field. */ +enum dmmPATStatusErrT { + NO_ERROR = 0x0, + INVALID_DESCR = 0x1, + INVALID_DATA_PTR = 0x2, + UNEXP_AREA_UPDATE = 0x4, + UNEXP_CONTROL_UPDATE = 0x8, + UNEXP_DATA_UPDATE = 0x10, + UNEXP_ACCESS = 0x20 +}; + +/** @struc dmmPATStatusT +* Structure defining PAT area status. */ +struct dmmPATStatusT { + enum dmmPATStatusErrT error; + unsigned char ready; + unsigned char validDescriptor; + unsigned char engineRunning; + unsigned char done; + unsigned char linkedReconfig; + unsigned char remainingLinesCounter; +}; + +/** @enum dmmMemSectionSizeT +* Defining enumarated identifiers for memory section sizes used by LISA. */ +enum dmmMemSectionSizeT { + SEC_16MiB, + SEC_32MiB, + SEC_64MiB, + SEC_128MiB, + SEC_256MiB, + SEC_512MiB, + SEC_1GiB, + SEC_2GiB +}; + +/** @enum dmmMemSdrcIntlModeT +* Defining enumarated identifiers for memory section interleaving +* used by LISA.*/ +enum dmmMemSdrcIntlModeT { + SEC_INTL_NONE, + SEC_INTL_128B, + SEC_INTL_256B, + SEC_INTL_512B +}; + +/** @enum dmmMemSectionMappingT +* Defining enumarated identifiers for memory section mapping used by LISA. */ +enum dmmMemSectionMappingT { + SEC_UNMAPPED, + SEC_MAPPED_SDRC0, + SEC_MAPPED_SDRC1, + SEC_MAPPED_INTL +}; + +/** @struc dmmLISAConfigT +* Structure defining LISA memory map configuration. */ +struct dmmLISAConfigT { + signed long lisaMemMapIndx; + unsigned long sysAddr; + enum dmmMemSectionSizeT sysSize; + enum dmmMemSdrcIntlModeT sdrcIntl; + unsigned long sdrcAddrspc; + enum dmmMemSectionMappingT sdrcMap; + unsigned long sdrcAddr; +}; + +/** @struc dmmLISAConfigLstT +* Structure defining LISA memory map configuration linked list. */ +struct dmmLISAConfigLstT { + struct dmmLISAConfigLstT *nextConf; + struct dmmLISAConfigT mapConf; +}; + +/** @enum dmmMemoryAccessT +* Defining enumarated identifiers for memory memory access types through TILER +* and PAT. */ +enum dmmMemoryAccessT { + MODE_8_BIT, + MODE_16_BIT, + MODE_32_BIT, + MODE_PAGE +}; + +/** @enum dmmPATTranslationT +* Defining enumarated identifiers for possible PAT address translation +* schemes. */ +enum dmmPATTranslationT { + DIRECT, + INDIRECT +}; + +/** @enum dmmPATEngineAccessT +* Defining enumarated identifiers for possible PAT engines memory access +* schemes. */ +enum dmmPATEngineAccessT { + NORMAL_MODE, + DIRECT_LUT +}; + +/** @enum dmmPATRefillMethodT +* Defining enumarated identifiers for possible PAT area refill methods. */ +enum dmmPATRefillMethodT{ + MANUAL, + AUTO +}; + +/** @struc PATAreaT +* Structure defining PAT page-area register. */ +struct PATAreaT{ + int x0:8; + int y0:8; + int x1:8; + int y1:8; +}; + +/** @struc PATCtrlT +* Structure defining PAT control register. */ +struct PATCtrlT { + int start:4; + int direction:4; + int lutID:8; + int sync:12; + int initiator:4; +}; + +/** @struc PATDescrT +* Structure defining PAT area descriptor, needed for area refill procedures. */ +struct PATDescrT { + struct PATDescrT *nextPatEntry; + struct PATAreaT area; + struct PATCtrlT ctrl; + unsigned long data; +}; + +/** @struc dmmPATIrqEventsT +* Structure defining PAT interrupt events. */ +struct dmmPATIrqEventsT { + unsigned char irqAreaSelect; + unsigned char lutMiss; + unsigned char updData; + unsigned char updCtrl; + unsigned char updArea; + unsigned char invData; + unsigned char invDsc; + unsigned char fillLst; + unsigned char fillDsc; +}; + +/** @struc dmmPatIrqConfigT +* Structure defining PAT interrupt configuration. */ +struct dmmPatIrqConfigT { + struct dmmPATIrqEventsT irqEvnts; + int clrEvents; +}; + +/** @struc dmmPATIrqConfigLstT +* Structure defining PAT interrupt configuration linked list. */ +struct dmmPATIrqConfigLstT { + struct dmmPATIrqConfigLstT *nextConf; + struct dmmPatIrqConfigT irqConf; +}; + +/** @struc dmmPATEngineConfigT +* Structure defining PAT engine configuration. */ +struct dmmPATEngineConfigT { + signed long dmmPatEngineSel; + enum dmmPATEngineAccessT engineMode; +} ; + +/** @struc dmmPATEngineConfigLstT +* Structure defining PAT engine configuration linked list. */ +struct dmmPATEngineConfigLstT { + struct dmmPATEngineConfigLstT *nextConf; + struct dmmPATEngineConfigT engineConf; +}; + +/** @struc dmmPATViewConfigT +* Structure defining PAT view configuration. */ +struct dmmPATViewConfigT { + signed long initiatorId; + signed long viewIndex; +}; + +/** @struc dmmPATViewConfigLstT +* Structure defining PAT alias view configuration linked list. */ +struct dmmPATViewConfigLstT { + struct dmmPATViewConfigLstT *nextConf; + struct dmmPATViewConfigT aliasViewConf; +}; + +/** @struc dmmPATViewMapConfigT +* Structure defining PAT view map configuration. */ +struct dmmPATViewMapConfigT { + unsigned long patViewMapIndx; + enum dmmMemoryAccessT memoryAccessMode; + unsigned long contX; + enum dmmPATTranslationT transType; + unsigned long dmmPATViewBase; +}; + +/** @struc dmmPATViewMapConfigLstT +* Structure defining PAT view map configuration linked list. */ +struct dmmPATViewMapConfigLstT { + struct dmmPATViewMapConfigLstT *nextConf; + struct dmmPATViewMapConfigT viewConf; +}; + +/** @struc dmmTILERConfigT +* Structure defining TILER alias view configuration. */ +struct dmmTILERConfigT { + signed long initiatorId; + struct dmmViewOrientT orient; +}; + +/** @struc dmmTILERConfigLstT +* Structure defining TILER alias view configuration linked list. */ +struct dmmTILERConfigLstT { + struct dmmTILERConfigLstT *nextConf; + struct dmmTILERConfigT aliasConf; +}; + +/** @struc dmmPEGConfigT +* Structure defining PEG priority configuration. */ +struct dmmPEGConfigT { + signed long initiatorId; + unsigned long prio; +}; + +/** @struc dmmPEGConfigLstT +* Structure defining PEG priority configuration linked list. */ +struct dmmPEGConfigLstT { + struct dmmPEGConfigLstT *nextConf; + struct dmmPEGConfigT prioConf; +}; + +/** @struc dmmPATStatusLstT +* Structure defining PAT area status linked list. */ +struct dmmPATStatusLstT { + struct dmmPATStatusLstT *nextConf; + signed long areaSelect; + struct dmmPATStatusT patAreaStatus; +}; + +/** @enum MSP_Dmm_Phy2VirtOpsT +* Defining all of the control commands related to physical to +* virtual transforms. */ +/*enum MSP_Dmm_Phy2VirtOpsT +{ + DMM_P2V_SWAP +}*/ + +#endif /* _DMM_DEF_H */ + diff --git a/drivers/media/video/tiler/dmm_drv.h b/drivers/media/video/tiler/dmm_drv.h new file mode 100644 index 000000000000..53601b134a8b --- /dev/null +++ b/drivers/media/video/tiler/dmm_drv.h @@ -0,0 +1,801 @@ +/* + * dmm_drv.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_DRV_H +#define _DMM_DRV_H + +#include "dmm_def.h" + +/* ========================================================================== */ +/** + * dmm_tiler_alias_orientation_set() + * + * @brief Set specific TILER alias orientation setting per initiator ID + * (alias view). + * + * @param initiatorID - signed long - [in] OCP id of DMM transfer initiator + * which alias view will be editted. + * + * @param viewOrientation - dmmViewOrientT - [in] New alias view orientation + * setting. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmViewOrientT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_tiler_alias_orientation_set(signed long initiatorID, + struct dmmViewOrientT viewOrientation); + +/* ========================================================================== */ +/** + * dmm_tiler_alias_orientation_get() + * + * @brief Set specific TILER alias orientation setting per initiator ID + * (alias view). + * + * @param initiatorID - signed long - [in] OCP id of DMM transfer initiator + * which alias view will be editted. + * + * @param viewOrientation - dmmViewOrientT* - [out] Pointer to write alias view + * orientation setting to. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmViewOrientT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_tiler_alias_orientation_get(signed long initiatorID, + struct dmmViewOrientT *viewOrientation); + +/* ========================================================================== */ +/** + * dmm_peg_priority_set() + * + * @brief Set specific PEG priority setting per initiator ID. + * + * @param initiatorID - signed long - [in] OCP id of DMM transfer initiator + * which priority will be editted. + * + * @param prio - unsigned long - [in] New priority setting. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_peg_priority_set(signed long initiatorID, + unsigned long prio); + +/* ========================================================================== */ +/** + * dmm_peg_priority_get() + * + * @brief Get specific PEG priority setting per initiator ID. + * + * @param initiatorID - signed long - [in] OCP id of DMM transfer initiator + * which priority will be editted. + * + * @param prio - unsigned long* - [out] Poitner to write the priority setting. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_peg_priority_get(signed long initiatorID, + unsigned long *prio); + +/* ========================================================================== */ +/** + * dmm_pat_area_refill() + * + * @brief Initiate a PAT area refill (or terminate an ongoing - consult + * documentation). + * + * @param patDesc - PATDescrT* - [in] Pointer to a PAT area descriptor that's + * needed to extract settings from for the refill procedure initation. + * + * @param dmmPatAreaSel - signed long - [in] Selects which PAT area will be + * configured for a area refill procedure. + * + * @param refillType - dmmPATRefillMethodT - [in] Selects the refill method - + * manual or automatic. + * + * @param forcedRefill - int - [in] Selects if forced refill should be used + * effectively terminating any ongoing area refills related to the selected + * area. + * + * @return errorCodeT + * + * @pre If forced mode is not used, no refills should be ongoing for the + * selected + * area - error status returned if this occurs. + * + * @post If non valid data is provided for patDesc and the refill engines fail + * to perform the request, an error status is returned. + * + * @see errorCodeT, PATDescrT, dmmPATRefillMethodT, int for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_pat_area_refill(struct PATDescrT *patDesc, + signed long dmmPatAreaSel, + enum dmmPATRefillMethodT refillType, + int forcedRefill); + +/* ========================================================================== */ +/** + * dmm_pat_refill_area_status_get() + * + * @brief Gets the status for the selected PAT area. + * + * @param dmmPatAreaSel - signed long - [in] Selects which PAT area status will + * be queried. + * + * @param areaStatus - dmmPATStatusT* - [out] Structure containing the PAT area + * status that will be filled by dmmPatRefillAreaStatusGet(). + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post If the query fails the provided areaStatus structure is not updated at + * all! + * + * @see errorCodeT, dmmPATStatusT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_pat_refill_area_status_get(signed long dmmPatAreaStatSel, + struct dmmPATStatusT *areaStatus); + +/* ========================================================================== */ +/** + * dmm_pat_refill_engine_config() + * + * @brief Configure the selected PAT refill engine. + * + * @param dmmPatEngineSel - signed long - [in] Selects which PAT engine will + * be configured. + * + * @param engineMode - dmmPATEngineAccessT - [in] New engine mode. + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmPATEngineAccessT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_pat_refill_engine_config(signed long dmmPatEngineSel, + enum dmmPATEngineAccessT engineMode); + +/* ========================================================================== */ +/** + * dmm_pat_refill_engine_config_get() + * + * @brief Get the selected PAT refill engine configuration. + * + * @param dmmPatEngineSel - signed long - [in] Selects which PAT engine will be + * configured. + * + * @param engineMode - dmmPATEngineAccessT* - [out] Pointer to write the engine + * mode. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmPATEngineAccessT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_pat_refill_engine_config_get(signed long dmmPatEngineSel, + enum dmmPATEngineAccessT *engineMode); + +/* ========================================================================== */ +/** + * dmm_pat_view_set() + * + * @brief Set specific PAT initiator view settings. + * + * @param initiatorID - signed long - [in] OCP id of DMM transfer initiator + * which PAT view will be editted. + * + * @param patViewIndx - signed long - [in] New view map setting. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_pat_view_set(signed long initiatorID, + signed long patViewIndx); + +/* ========================================================================== */ +/** + * dmm_pat_view_get() + * + * @brief Get specific PAT initiator view settings. + * + * @param initiatorID - signed long - [in] OCP id of DMM transfer initiator + * which PAT view will be editted. + * + * @param patViewIndx - signed long* - [out] Pointer to write the view map + * setting. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_pat_view_get(signed long initiatorID, + signed long *patViewIndx); + +/* ========================================================================== */ +/** + * dmm_pat_view_map_config() + * + * @brief Configure selected PAT view map. + * + * @param patViewMapIndx - signed long - [in] Index of the selected PAT view + * map. + * + * @param memoryAccessMode - dmmMemoryAccessT - [in] Type of memory access to + * perform through this view. + * + * @param contX - unsigned long - [in] CONT_x register value. + * + * @param transType - dmmPATTranslationT - [in] Address translation schemes. + * + * @param dmmPATViewBase - unsigned long - [in] View map base address + * (31-bit only considered). + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmMemoryAccessT, dmmPATTranslationT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_pat_view_map_config(signed long patViewMapIndx, + enum dmmMemoryAccessT memoryAccessMode, + unsigned long contX, + enum dmmPATTranslationT transType, + unsigned long dmmPATViewBase); + +/* ========================================================================== */ +/** + * dmm_pat_view_map_config_get() + * + * @brief Get selected PAT view map configuration. + * + * @param patViewMapIndx - signed long - [in] Index of the selected PAT view + * map. + * + * @param memoryAccessMode - dmmMemoryAccessT - [int] Type of memory access + * that configuration is queried. + * + * @param contX - unsigned long* - [out] Pointer to write the CONT_x register + * value. + * + * @param transType - dmmPATTranslationT* - [out] Pointer to write the + * address translation schemes. + * + * @param dmmPATViewBase - unsigned long* - [out] Pointer to write the view + * map base address. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmMemoryAccessT, dmmPATTranslationT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_pat_view_map_config_get(signed long patViewMapIndx, + enum dmmMemoryAccessT memoryAccessMode, + unsigned long *contX, + enum dmmPATTranslationT *transType, + unsigned long *dmmPATViewBase); + +/* ========================================================================== */ +/** + * dmm_lisa_memory_map_config() + * + * @brief Configure selected LISA memory map. + * + * @param lisaMemMapIndx - signed long - [in] Index of the selected LISA memory + * map. + * + * @param sysSize - dmmMemSectionSizeT - [in] Size of the memory section. + * + * @param sdrcIntl - dmmMemSdrcIntlModeT - [in] SDRAM controller interleaving + * mode + * + * @param sdrcAddrspc - unsigned long - [in] SDRAM controller address space. + * + * @param sdrcMap - dmmMemSectionMappingT - [in] SDRAM controller mapping. + * + * @param sdrcAddr - unsigned long - [in] SDRAM controller address MSB. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmMemSectionSizeT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_lisa_memory_map_config(signed long lisaMemMapIndx, + unsigned long sysAddr, + enum dmmMemSectionSizeT sysSize, + enum dmmMemSdrcIntlModeT sdrcIntl, + unsigned long sdrcAddrspc, + enum dmmMemSectionMappingT sdrcMap, + unsigned long sdrcAddr); + +/* ========================================================================== */ +/** + * dmm_lisa_memory_map_config_get() + * + * @brief Get selected LISA memory map configuration. + * + * @param lisaMemMapIndx - signed long - [in] Index of the selected LISA + * memory map. + * + * @param sysSize - dmmMemSectionSizeT* - [out] Pointer to write size of + * the memory section. + * + * @param sdrcIntl - dmmMemSdrcIntlModeT* - [out] Pointer to write SDRAM + * controller interleaving mode. + * + * @param sdrcAddrspc - unsigned long* - [out] Pointer to write SDRAM + * controller address space. + * + * @param sdrcMap - dmmMemSectionMappingT* - [out] Pointer to write SDRAM + * controller mapping. + * + * @param sdrcAddr - unsigned long* - [out] Pointer to write SDRAM + * controller address MSB. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmMemSectionSizeT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_lisa_memory_map_config_get(signed long lisaMemMapIndx, + unsigned long *sysAddr, + enum dmmMemSectionSizeT *sysSize, + enum dmmMemSdrcIntlModeT *sdrcIntl, + unsigned long *sdrcAddrspc, + enum dmmMemSectionMappingT *sdrcMap, + unsigned long *sdrcAddr); + +/* ========================================================================== */ +/** + * dmm_engage_lisa_lock() + * + * @brief Sets the LISA lock register preventing further writting to the + * LISA memory map registers. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post Only a software reset of the DMM module can clear the lock bit. + * + * @see errorCodeT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_engage_lisa_lock(); + +/* ========================================================================== */ +/** + * dmm_sys_config_set() + * + * @brief DMM clock management configuration. + * + * @param dmmIdleMode - unsigned long - [in] Idle mode. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post Only a software reset of the DMM module can clear the lock bit. + * + * @see errorCodeT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_sys_config_set(unsigned long dmmIdleMode); + +/* ========================================================================== */ +/** + * dmm_sys_config_get() + * + * @brief DMM clock management configuration. + * + * @param dmmIdleMode - unsigned long* - [out] Idle mode status. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_sys_config_get(unsigned long *dmmIdleMode); + +/* ========================================================================== */ +/** + * dmm_pat_irq_mode_set() + * + * @brief Enable/disable PAT interrupt events. + * + * @param patIrqEvnt - dmmPATIrqEventsT* - [in] Interrupt events to set. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmPATIrqEventsT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_pat_irq_mode_set(struct dmmPATIrqEventsT *patIrqEvnt); + +/* ========================================================================== */ +/** + * dmm_pat_irq_mode_get() + * + * @brief Enable/disable PAT interrupt events. + * + * @param patIrqEvnt - dmmPATIrqEventsT* - [in/out] Get interrupt events masks. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmPATIrqEventsT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_pat_irq_mode_get(struct dmmPATIrqEventsT *patIrqEvnt); + +/* ========================================================================== */ +/** + * dmm_pat_irq_status_get() + * + * @brief Get the statuses of PAT interrupt events. + * + * @param patIrqEvnt - dmmPATIrqEventsT* - [in/out] Interrupt events statuses. + * + * @param clrEvents - int - [in] Celar events upon retrieval. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmPATIrqEventsT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_pat_irq_status_get(struct dmmPATIrqEventsT *patIrqEvnt, + int clrEvents); + +/* ========================================================================== */ +/** + * dmm_module_config() + * + * @brief Configure selected DMM modules. + * + * @param tilerConf - dmmTILERConfigLstT* - [in] A NULL termintated linked list + * of all configurations for the specific DMM module or NULL if not to be + * configured. + * + * @param pegConf - dmmPEGConfigLstT* - [in] A NULL termintated linked list + * of all configurations for the specific DMM module or NULL if not to be + * configured. + * + * @param lisaConf - dmmLISAConfigLstT* - [in] A NULL termintated linked list + * of all configurations for the specific DMM module or NULL if not to be + * configured. + * + * @param patEngineConf - dmmPATEngineConfigLstT* - [in] A NULL termintated + * linked list of all configurations for the specific DMM module or NULL if + * not to be configured. + * + * @param patViewCOnf - dmmPATViewConfigLstT* - [in] A NULL termintated + * linked list of all configurations for the specific DMM module or NULL + * if not to be configured. + * + * @param patViewMapConf - dmmPATViewMapConfigLstT* - [in] A NULL termintated + * linked list of all configurations for the specific DMM module or NULL if + * not to be configured. + * + * @param dmmSysConfig - unsigned long* - [in] Clock configuration of DMM, + * NULL if not to be set. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmTILERConfigLstT, dmmPEGConfigLstT, + * dmmLISAConfigLstT, dmmPATEngineConfigLstT, dmmPATViewConfigLstT, + * dmmPATViewMapConfigLstT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_module_config(struct dmmTILERConfigLstT *tilerConf, + struct dmmPEGConfigLstT *pegConf, + struct dmmLISAConfigLstT *lisaConf, + struct dmmPATEngineConfigLstT *patEngineConf, + struct dmmPATViewConfigLstT *patViewCOnf, + struct dmmPATViewMapConfigLstT *patViewMapConf, + unsigned long *dmmSysConfig); + +/* ========================================================================== */ +/** + * dmm_module_get_config() + * + * @brief Read the configuration of selected DMM modules. + * + * @param tilerConf - dmmTILERConfigLstT* - [out] A NULL termintated linked list + * of all configurations for the specific DMM module to be read to. + * + * @param pegConf - dmmPEGConfigLstT* - [out] A NULL termintated linked list + * of all configurations for the specific DMM module to be read to. + * + * @param lisaConf - dmmLISAConfigLstT* - [out] A NULL termintated linked list + * of all configurations for the specific DMM module to be read to. + * + * @param patEngineConf - dmmPATEngineConfigLstT* - [out] A NULL termintated + * linked list of all configurations for the specific DMM module to be read to. + * + * @param patViewCOnf - dmmPATViewConfigLstT* - [out] A NULL termintated linked + * list of all configurations for the specific DMM module to be read to. + * + * @param patViewMapConf - dmmPATViewMapConfigLstT* - [out] A NULL termintated + * linked list of all configurations for the specific DMM module to be read to. + * + * @param patAreaStatus - dmmPATStatusLstT* - [out] A NULL termintated linked + * list of all PAT area status' to be read. + * + * @param dmmSysConfig - unsigned long* - [out] Clock configuration of DMM, + * NULL if not to be read. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmTILERConfigLstT, dmmPEGConfigLstT, + * dmmLISAConfigLstT, dmmPATEngineConfigLstT, dmmPATViewConfigLstT, + * dmmPATViewMapConfigLstT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_module_get_config(struct dmmTILERConfigLstT *tilerConf, + struct dmmPEGConfigLstT *pegConf, + struct dmmLISAConfigLstT *lisaConf, + struct dmmPATEngineConfigLstT *patEngineConf, + struct dmmPATViewConfigLstT *patViewCOnf, + struct dmmPATViewMapConfigLstT *patViewMapConf, + struct dmmPATStatusLstT *patAreaStatus, + unsigned long *dmmSysConfig); + +/* ========================================================================== */ +/** + * dmm_pat_irq_config_set() + * + * @brief Configures PAT interrupt masks. + * + * @param irqMaskConf - dmmPATIrqConfigLstT* - [in] A NULL termintated linked + * list of all interrupt masks. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmPATIrqConfigLstT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_pat_irq_config_set(struct dmmPATIrqConfigLstT *irqMaskConf); + +/* ========================================================================== */ +/** + * dmm_pat_irq_config_get() + * + * @brief Configures PAT interrupt masks. + * + * @param irqMaskConf - dmmPATIrqConfigLstT* - [in/out] A NULL termintated + * linked list of all interrupt masks. + * + * @param irqStatusConf - dmmPATIrqConfigLstT* - [in/out] A NULL termintated + * linked list of all interrupt statuses to read. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmPATIrqConfigLstT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_pat_irq_config_get(struct dmmPATIrqConfigLstT *irqMaskConf, + struct dmmPATIrqConfigLstT *irqStatusConf); + +/* ========================================================================== */ +/** + * dmm_instance_init() + * + * @brief Initializes the Tiler cotnext. + * + * @param dmmInstanceCtxPtr - void * - [in] Tiler context instance. + * + * @param contXSize - signed long - [in] Tiler container width. + * + * @param contYSize - signed long - [in] Tiler container height. + * + * @param hMSP - MSP_HANDLE - [in] MSP handle related to this dmm_drv cotnext. + * + * @param usrAppData - void * - [in] Pointer to user specific data structure. + * + * @param usrCallback - MSP_usrCallback - [in] Pointer to callback supplied by + * the user for notificiation events (interupts). + * + * @return int True if operation succeded. + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see dmmTILERContCtxT for further detail. + */ +/* ========================================================================== */ +int dmm_instance_init(void *dmmInstanceCtxPtr, + signed long contXSize, + signed long contYSize, + void *hMSP, + void *usrAppData); + +/* ========================================================================== */ +/** + * dmm_instance_deinit() + * + * @brief Deinitializes the Tiler cotnext. + * + * @param dmmInstanceCtxPtr - void * - [in] Tiler context instance. + * + * @return int True if operation succeded. + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see dmmTILERContCtxT for further detail. + */ +/* ========================================================================== */ +int dmm_instance_deinit(void *dmmInstanceCtxPtr); + +/* ========================================================================== */ +/** + * dmm_copy2tiler_alias_view() + * + * @brief Auxiliary function for copying data to the Tiler alias view. + * + * @param destPtr - void * - [in] Destination pointer in Tiler alias view. + * + * @param srcPtr - void * - [in] Data source pointer. + * + * @param width - signed long - [in] Data width. + * + * @param height - signed long - [in] Data height. + * + * @param stride - signed long - [in] Data stride. + * + * @param accType - dmmMemoryAccessT - [in] Tiler memory view access type. + * + * @return errorCodeT error if event can't be signaled. + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see dmmTILERContCtxT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_copy2tiler_alias_view(void *destPtr, + void *srcPtr, + signed long width, + signed long height, + signed long stride, + enum dmmMemoryAccessT accType); + +/* ========================================================================== */ +/** + * dmm_virtual_buffer_manipulations() + * + * @brief Manipulates virtual buffers. + * + * @param dmmInstanceCtxPtr - void * - [in] Dmm context instance. + * + * @param sysPtr - void * - [in] Tiler system pointer to a 2D area. + * + * @param patOp - MSP_Dmm_Phy2VirtOpsT - [in] Refill operaion to perform. + * + * @param affectedArea - PATAreaT* - [in] Area that will be affected. + * + * @param destinationArea - PATAreaT* - [in] Destination coordinates. + * + * @return void * pointer to the area targeted by the operation. + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see dmmTILERContPageAreaT for further detail. + */ +/* ========================================================================== */ +void *dmm_virtual_buffer_manipulations(void *dmmInstanceCtxPtr, + void *sysPtr, + struct PATAreaT *affectedArea, + struct PATAreaT *destinationArea); + +#endif /* _DMM_DRV_H */ + diff --git a/drivers/media/video/tiler/dmm_hl_drv.c b/drivers/media/video/tiler/dmm_hl_drv.c new file mode 100644 index 000000000000..d7e315befce3 --- /dev/null +++ b/drivers/media/video/tiler/dmm_hl_drv.c @@ -0,0 +1,1210 @@ +/* + * dmm_hl_drv.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/vmalloc.h> +#include <linux/mm.h> /* vmalloc_to_page */ +#include <linux/mmzone.h> /* __page_to_phys */ +#include "dmm_def.h" +#include "dmm_2d_alloc.h" +#include "dmm_prv.h" +#include "dmm.h" + +unsigned long *va; + +/* ========================================================================== */ +/** + * dmm_get_context_pointer() + * + * @brief Returns a pointer to the Tiler context structure. + * + * @return void * Pointer to the Tiler context structure + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see dmmInstanceCtxT for further detail. + */ +/* ========================================================================== */ +void *dmm_get_context_pointer() +{ + return &dmmInstanceCtxStatic; +} + +/* ========================================================================== */ +/** + * dmm_module_config() + * + * @brief Configure selected DMM modules. + * + * @param tilerConf - dmmTILERConfigLstT* - [in] A NULL termintated linked list + * of all configurations for the specific DMM module or NULL if not to be + * configured. + * + * @param pegConf - dmmPEGConfigLstT* - [in] A NULL termintated linked list + * of all configurations for the specific DMM module or NULL if not to be + * configured. + * + * @param lisaConf - dmmLISAConfigLstT* - [in] A NULL termintated linked list + * of all configurations for the specific DMM module or NULL if not to be + * configured. + * + * @param patEngineConf - dmmPATEngineConfigLstT* - [in] A NULL termintated + * linked list + * of all configurations for the specific DMM module or NULL if not to be + * configured. + * + * @param patViewCOnf - dmmPATViewConfigLstT* - [in] A NULL termintated + * linked list of all configurations for the specific DMM module or NULL if + * not to be configured. + * + * @param patViewMapConf - dmmPATViewMapConfigLstT* - [in] A NULL + * termintated linked list of all configurations for the specific DMM module + * or NULL if not to be configured. + * + * @param dmmSysConfig - unsigned long* - [in] Clock configuration of DMM, + * NULL if not to be set. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmTILERConfigLstT, dmmPEGConfigLstT, + * dmmLISAConfigLstT, dmmPATEngineConfigLstT, dmmPATViewConfigLstT, + * dmmPATViewMapConfigLstT for further detail. + */ +/* ========================================================================== */ +/* DHS */ +enum errorCodeT dmm_module_config(struct dmmTILERConfigLstT *tilerConf, + struct dmmPEGConfigLstT *pegConf, + struct dmmLISAConfigLstT *lisaConf, + struct dmmPATEngineConfigLstT *patEngineConf, + struct dmmPATViewConfigLstT *patViewCOnf, + struct dmmPATViewMapConfigLstT *patViewMapConf, + unsigned long *dmmSysConfig) +{ + enum errorCodeT eCode = DMM_NO_ERROR; + + while (tilerConf != NULL && eCode == DMM_NO_ERROR) { + eCode = dmm_tiler_alias_orientation_set( + tilerConf->aliasConf.initiatorId, + tilerConf->aliasConf.orient); + tilerConf = tilerConf->nextConf; + } + + while (pegConf != NULL && eCode == DMM_NO_ERROR) { + eCode = dmm_peg_priority_set(pegConf->prioConf.initiatorId, + pegConf->prioConf.prio); + pegConf = pegConf->nextConf; + } + + while (lisaConf != NULL && eCode == DMM_NO_ERROR) { + eCode = dmm_lisa_memory_map_config( + lisaConf->mapConf.lisaMemMapIndx, + lisaConf->mapConf.sysAddr, + lisaConf->mapConf.sysSize, + lisaConf->mapConf.sdrcIntl, + lisaConf->mapConf.sdrcAddrspc, + lisaConf->mapConf.sdrcMap, + lisaConf->mapConf.sdrcAddr); + lisaConf = lisaConf->nextConf; + } + + while (patEngineConf != NULL && eCode == DMM_NO_ERROR) { + eCode = dmm_pat_refill_engine_config( + patEngineConf->engineConf.dmmPatEngineSel, + patEngineConf->engineConf.engineMode); + patEngineConf = patEngineConf->nextConf; + } + + while (patViewCOnf != NULL && eCode == DMM_NO_ERROR) { + eCode = dmm_pat_view_set(patViewCOnf->aliasViewConf.initiatorId, + patViewCOnf->aliasViewConf.viewIndex); + patViewCOnf = patViewCOnf->nextConf; + } + + while (patViewMapConf != NULL && eCode == DMM_NO_ERROR) { + eCode = dmm_pat_view_map_config( + patViewMapConf->viewConf.patViewMapIndx, + patViewMapConf->viewConf.memoryAccessMode, + patViewMapConf->viewConf.contX, + patViewMapConf->viewConf.transType, + patViewMapConf->viewConf.dmmPATViewBase); + patViewMapConf = patViewMapConf->nextConf; + } + + if (dmmSysConfig != NULL && eCode == DMM_NO_ERROR) + eCode = dmm_sys_config_set(*dmmSysConfig); + + return eCode; +} + +/* ========================================================================== */ +/** + * dmm_module_get_config() + * + * @brief Read the configuration of selected DMM modules. + * + * @param tilerConf - dmmTILERConfigLstT* - [out] A NULL termintated linked list + * of all configurations for the specific DMM module to be read to. + * + * @param pegConf - dmmPEGConfigLstT* - [out] A NULL termintated linked list + * of all configurations for the specific DMM module to be read to. + * + * @param lisaConf - dmmLISAConfigLstT* - [out] A NULL termintated linked list + * of all configurations for the specific DMM module to be read to. + * + * @param patEngineConf - dmmPATEngineConfigLstT* - [out] A NULL termintated + * linked list of all configurations for the specific DMM module to be read to. + * + * @param patViewCOnf - dmmPATViewConfigLstT* - [out] A NULL termintated + * linked list of all configurations for the specific DMM module to be read to. + * + * @param patViewMapConf - dmmPATViewMapConfigLstT* - [out] A NULL + * termintated linked list of all configurations for the specific DMM module + * to be read to. + * + * @param patAreaStatus - dmmPATStatusLstT* - [out] A NULL termintated + * linked list of all PAT area status' to be read. + * + * @param dmmSysConfig - unsigned long* - [in] Clock configuration of + * DMM, NULL if not to be read. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmTILERConfigLstT, dmmPEGConfigLstT, + * dmmLISAConfigLstT, dmmPATEngineConfigLstT, dmmPATViewConfigLstT, + * dmmPATViewMapConfigLstT for further detail. + */ +/* ========================================================================== */ +/* DHS */ +enum errorCodeT dmm_module_get_config(struct dmmTILERConfigLstT *tilerConf, + struct dmmPEGConfigLstT *pegConf, + struct dmmLISAConfigLstT *lisaConf, + struct dmmPATEngineConfigLstT *patEngineConf, + struct dmmPATViewConfigLstT *patViewCOnf, + struct dmmPATViewMapConfigLstT *patViewMapConf, + struct dmmPATStatusLstT *patAreaStatus, + unsigned long *dmmSysConfig) +{ + enum errorCodeT eCode = DMM_NO_ERROR; + + while (tilerConf != NULL && eCode == DMM_NO_ERROR) { + eCode = dmm_tiler_alias_orientation_get( + tilerConf->aliasConf.initiatorId, + &(tilerConf->aliasConf.orient)); + tilerConf = tilerConf->nextConf; + } + + while (pegConf != NULL && eCode == DMM_NO_ERROR) { + eCode = dmm_peg_priority_get(pegConf->prioConf.initiatorId, + &(pegConf->prioConf.prio)); + pegConf = pegConf->nextConf; + } + + while (lisaConf != NULL && eCode == DMM_NO_ERROR) { + eCode = dmm_lisa_memory_map_config_get( + lisaConf->mapConf.lisaMemMapIndx, + &(lisaConf->mapConf.sysAddr), + &(lisaConf->mapConf.sysSize), + &(lisaConf->mapConf.sdrcIntl), + &(lisaConf->mapConf.sdrcAddrspc), + &(lisaConf->mapConf.sdrcMap), + &(lisaConf->mapConf.sdrcAddr)); + lisaConf = lisaConf->nextConf; + } + + while (patEngineConf != NULL && eCode == DMM_NO_ERROR) { + eCode = dmm_pat_refill_engine_config_get( + patEngineConf->engineConf.dmmPatEngineSel, + &(patEngineConf->engineConf.engineMode)); + patEngineConf = patEngineConf->nextConf; + } + + while (patViewCOnf != NULL && eCode == DMM_NO_ERROR) { + eCode = dmm_pat_view_get( + patViewCOnf->aliasViewConf.initiatorId, + &(patViewCOnf->aliasViewConf.viewIndex)); + patViewCOnf = patViewCOnf->nextConf; + } + + while (patViewMapConf != NULL && eCode == DMM_NO_ERROR) { + eCode = dmm_pat_view_map_config_get( + patViewMapConf->viewConf.patViewMapIndx, + patViewMapConf->viewConf.memoryAccessMode, + &(patViewMapConf->viewConf.contX), + &(patViewMapConf->viewConf.transType), + &(patViewMapConf->viewConf.dmmPATViewBase)); + patViewMapConf = patViewMapConf->nextConf; + } + + while (patAreaStatus != NULL && eCode == DMM_NO_ERROR) { + eCode = dmm_pat_refill_area_status_get( + patAreaStatus->areaSelect, + &(patAreaStatus->patAreaStatus)); + + patAreaStatus = patAreaStatus->nextConf; + } + + if (dmmSysConfig != NULL && eCode == DMM_NO_ERROR) + eCode = dmm_sys_config_get(dmmSysConfig); + + return eCode; +} + +/* ========================================================================== */ +/** + * dmm_pat_irq_config_set() + * + * @brief Configures PAT interrupt masks. + * + * @param irqMaskConf - dmmPATIrqConfigLstT* - [in] A NULL termintated linked + * list of all interrupt masks. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmPATIrqConfigLstT for further detail. + */ +/* ========================================================================== */ +/* DHS */ +enum errorCodeT dmm_pat_irq_config_set(struct dmmPATIrqConfigLstT *irqMaskConf) +{ + enum errorCodeT eCode = DMM_NO_ERROR; + + while (irqMaskConf != NULL && eCode == DMM_NO_ERROR) { + eCode = dmm_pat_irq_mode_set(&(irqMaskConf->irqConf.irqEvnts)); + irqMaskConf = irqMaskConf->nextConf; + } + + return eCode; +} + +/* ========================================================================== */ +/** + * dmm_pat_irq_config_get() + * + * @brief Configures PAT interrupt masks. + * + * @param irqMaskConf - dmmPATIrqConfigLstT* - [in/out] A NULL termintated + * linked list of all interrupt masks. + * + * @param irqStatusConf - dmmPATIrqConfigLstT* - [in/out] A NULL termintated + * linked list of all interrupt statuses to read. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmPATIrqConfigLstT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_pat_irq_config_get(struct dmmPATIrqConfigLstT *irqMaskConf, + struct dmmPATIrqConfigLstT *irqStatusConf) +{ + enum errorCodeT eCode = DMM_NO_ERROR; + + while (irqMaskConf != NULL && eCode == DMM_NO_ERROR) { + eCode = dmm_pat_irq_mode_get(&(irqMaskConf->irqConf.irqEvnts)); + irqMaskConf = irqMaskConf->nextConf; + } + + while (irqStatusConf != NULL && eCode == DMM_NO_ERROR) { + eCode = dmm_pat_irq_status_get( + &(irqStatusConf->irqConf.irqEvnts), + irqStatusConf->irqConf.clrEvents); + irqStatusConf = irqStatusConf->nextConf; + } + + return eCode; +} + +/* ========================================================================== */ +/** + * dmm_pat_start_refill() + * + * @param dmmInstanceCtxPtr - void * - [in] Tiler context instance. + * + * @param bufferMappedZone - dmmTILERContPageAreaT* - [in] The tiled buffer + * descriptor. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmTILERContPageAreaT for further detail. + */ +/* ========================================================================== */ +/* DHS */ +enum errorCodeT dmm_pat_start_refill( + struct dmmTILERContPageAreaT *bufferMappedZone) +{ + struct PATDescrT areaDesc; + + areaDesc.area.x0 = bufferMappedZone->x0 + bufferMappedZone->xPageOfst; + areaDesc.area.y0 = bufferMappedZone->y0 + bufferMappedZone->yPageOfst; + areaDesc.area.x1 = bufferMappedZone->x0 + bufferMappedZone->xPageOfst + + bufferMappedZone->xPageCount - 1; + areaDesc.area.y1 = bufferMappedZone->y0 + bufferMappedZone->yPageOfst + + bufferMappedZone->yPageCount - 1; + + areaDesc.ctrl.direction = 0; + areaDesc.ctrl.initiator = 0; + areaDesc.ctrl.lutID = 0; + areaDesc.ctrl.start = 1; + areaDesc.ctrl.sync = 0; + + areaDesc.nextPatEntry = NULL; + + areaDesc.data = (unsigned long)(bufferMappedZone->patPageEntries); + + return dmm_pat_area_refill(&areaDesc, 0, MANUAL, 0); +} + +/* ========================================================================== */ +/** + * dmm_pat_phy2virt_mapping() + * + * @brief Mapping physical memory pages to virtual containers. + * + * @param bufferMappedZone - dmmTILERContPageAreaT* - [in] The tiled buffer + * descriptor. + * + * @param custmPagesPtr - void * - [in] Pointer to the custom supplied physical + * pages. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmTILERContPageAreaT for further detail. + */ +/* ========================================================================== */ +/* DHS */ +enum errorCodeT dmm_pat_phy2virt_mapping( + struct dmmTILERContPageAreaT *bufferMappedZone, + void *custmPagesPtr) +{ + unsigned long bfrPages; + enum errorCodeT eCode = DMM_NO_ERROR; + + bfrPages = + (bufferMappedZone->xPageCount)*(bufferMappedZone->yPageCount); + + if (bfrPages == 0) { + eCode = DMM_SYS_ERROR; + } else { + + if (dmm_tiler_populate_pat_page_entry_data(bfrPages, + &(bufferMappedZone->patPageEntries), + &(bufferMappedZone->patPageEntriesSpace), + custmPagesPtr) != DMM_NO_ERROR) { + eCode = DMM_SYS_ERROR; + return eCode; + } + + if (custmPagesPtr != NULL) + bufferMappedZone->patCustomPages = 1; + else + bufferMappedZone->patCustomPages = 0; + + eCode = dmm_pat_start_refill(bufferMappedZone); + } + + return eCode; +} + +/* ========================================================================== */ +/** + * dmm_tiler_populate_pat_page_entry_data() + * + * @brief Populates an aray with PAT page address entries. + * + * @param bfrSize - unsigned long - [in] Size of the buffer which will be used + * to generate page entries for. + * + * @param pageEntries - unsigned long** - [out] The address to the allocated + * page entry data array, aligned due to hardware specification. + * + * @param pageEntriesSpace - unsigned long** - [out] The address to the + * allocated page entry data array for deallocation purposes. + * + * @param custmPagesPtr - void * - [in] Pointer to a custom created memory + * pages list. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT for further detail. + */ +/* ========================================================================== */ +/* DHS */ +enum errorCodeT dmm_tiler_populate_pat_page_entry_data(unsigned long numPages, + unsigned long **pageEntries, + unsigned long **pageEntriesSpace, + void *custmPagesPtr) +{ + signed long iter; + unsigned long *tmpva = NULL; + + unsigned long *patAreaEntries = + (unsigned long *)vmalloc(numPages*4 + 16); + + va = (unsigned long *)vmalloc((numPages/4)*4096); + memset(va, 0x0, (numPages/4)*4096); + tmpva = va; + + + *pageEntriesSpace = patAreaEntries; + + patAreaEntries = + (unsigned long *)((((unsigned long)patAreaEntries) + 15) & ~15); + + if (custmPagesPtr == NULL) { + unsigned int *pa = NULL; + struct page *pg = NULL; + pg = kmalloc(sizeof(struct page), GFP_KERNEL); + memset(pg, 0x0, sizeof(struct page)); + pg = vmalloc_to_page(va); + pa = page_to_phys(pg); + patAreaEntries[0] = pa; + + va += 1024; + for (iter = 1; iter < numPages/4; iter++) { + pg = vmalloc_to_page(va); + pa = page_to_phys(pg); + patAreaEntries[iter] = pa; + va += 1024; + } + va = tmpva; + } else { + for (iter = 0; iter < numPages; iter++) { + patAreaEntries[iter] = + (unsigned long)(((unsigned long *)custmPagesPtr)[iter]); + } + } + + *pageEntries = patAreaEntries; + + return DMM_NO_ERROR; +} + +/* ========================================================================== */ +/** + * dmm_tiler_swap_pat_page_entry_data() + * + * @brief Swaps entries in an aray with PAT page address entries. + * + * @param bfrSize - unsigned long - [in] Size of the buffer which will be used + * to generate page entries for. + * + * @param pageEntries - unsigned long* - [in] The address to the allocated page + * entry data array, aligned due to hardware specification. + * + * @param affectedArea - PATAreaT* - [in] Area that will be affected. + * + * @param destX - unsigned char - [in] Destination coordinate X. + * + * @param destY - unsigned char - [in] Destination coordinate Y. + * + * @param stride - unsigned char - [in] Stride of the area. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_tiler_swap_pat_page_entry_data(unsigned long numPages, + unsigned long *pageEntries, + struct PATAreaT *affectedArea, + unsigned char destX, + unsigned char destY, + unsigned char stride) +{ + unsigned char row; + unsigned char column; + unsigned long entrySwap; + + unsigned char startX = affectedArea->x0; + unsigned char startY = affectedArea->y0; + + unsigned char endX = affectedArea->x1 + 1; + unsigned char enxY = affectedArea->y1 + 1; + + signed short ofstX = destX - startX; + signed short ofstY = destY - startY; + + for (row = startY; row < enxY; row++) { + for (column = startX; column < endX; column++) { + if (row*stride+column > numPages || + (row+ofstY)*stride+(column+ofstX) > numPages) + return DMM_WRONG_PARAM; + entrySwap = pageEntries[row*stride+column]; + pageEntries[row*stride+column] = + pageEntries[(row+ofstY)*stride+(column+ofstX)]; + pageEntries[(row+ofstY)*stride+(column+ofstX)] = + entrySwap; + } + } + + return DMM_NO_ERROR; +} + +/* ========================================================================== */ +/** + * dmm_tiler_container_map_area() + * + * @brief Allocates a 2D TILER buffer - virtual 2D allocation, + * descriptor and TILER system pointer updating. + * + * @param dmmTilerCtx - dmmTILERContCtxT* - [in] Tiler context instance. + * + * @param sizeWidth - unsigned short - [in] Width of buffer (in container + * elements). + * + * @param sizeHeight - unsigned short - [in] Height of buffer + * (in container elements). + * + * @param contMod - dmmMemoryAccessT - [in] Container access mode - for element + * sizes. + * + * @param allocedPtr - void ** - [out] The allocated buffer system pointer is + * provided through this double pointer. If no buffer is available this pointer + * is set to NULL. + * + * @param bufferMappedZone - dmmTILERContPageAreaT** - [out] Description of the + * 2D + * area that is mapped in the TILER container is provided in this structure. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmMemoryAccessT, dmmTILERContPageAreaT for further detail. + */ +/* ========================================================================== */ +/* DHS */ +enum errorCodeT dmm_tiler_container_map_area( + struct dmmTILERContCtxT *dmmTilerCtx, + unsigned short sizeWidth, + unsigned short sizeHeight, + enum dmmMemoryAccessT contMod, + void **allocedPtr, + struct dmmTILERContPageAreaT **bufferMappedZone) +{ + struct dmmTILERContPageAreaT areaRequest; + + enum errorCodeT eCode = DMM_NO_ERROR; + signed long pageDimmensionX = 0; + signed long pageDimmensionY = 0; + unsigned long accessMode = 0; + unsigned long addrShiftAlign = 0; + + switch (contMod) { + case MODE_8_BIT: + accessMode = 0; + pageDimmensionX = DMM_PAGE_DIMM_X_MODE_8; + pageDimmensionY = DMM_PAGE_DIMM_Y_MODE_8; + addrShiftAlign = DMM_HOR_Y_ADDRSHIFT_8; + break; + case MODE_16_BIT: + accessMode = 1; + pageDimmensionX = DMM_PAGE_DIMM_X_MODE_16; + pageDimmensionY = DMM_PAGE_DIMM_Y_MODE_16; + addrShiftAlign = DMM_HOR_Y_ADDRSHIFT_16; + break; + case MODE_32_BIT: + accessMode = 2; + pageDimmensionX = DMM_PAGE_DIMM_X_MODE_32; + pageDimmensionY = DMM_PAGE_DIMM_Y_MODE_32; + addrShiftAlign = DMM_HOR_Y_ADDRSHIFT_32; + break; + case MODE_PAGE: + accessMode = 3; + pageDimmensionX = DMM_PAGE_DIMM_X_MODE_8; + pageDimmensionY = DMM_PAGE_DIMM_Y_MODE_8; + sizeHeight = DMM_PAGE_DIMM_Y_MODE_8; + sizeWidth = + ((sizeWidth + DMM_4KiB_SIZE - 1)/DMM_4KiB_SIZE)* + DMM_PAGE_DIMM_X_MODE_8; + addrShiftAlign = DMM_HOR_Y_ADDRSHIFT_8; + break; + default: + eCode = DMM_WRONG_PARAM; + break; + } + + areaRequest.x1 = (sizeWidth + pageDimmensionX - 1)/pageDimmensionX - 1; + areaRequest.y1 = (sizeHeight + pageDimmensionY - 1)/pageDimmensionY - 1; + + *bufferMappedZone = alloc_2d_area(dmmTilerCtx, &areaRequest); + + DBG_OVERLAP_TEST(dmmTilerCtx); + + if (eCode == DMM_NO_ERROR) { + *allocedPtr = + DMM_COMPOSE_TILER_ALIAS_PTR( + ((*bufferMappedZone)->x0*pageDimmensionX) | + (((*bufferMappedZone)->y0*pageDimmensionY)<< + addrShiftAlign), accessMode); + } else { + *allocedPtr = NULL; + } + + return eCode; +} + +/* ========================================================================== */ +/** + * dmm_tiler_container_unmap_area() + * + * @brief Frees a 2D virtual TILER container buffer. \ + * + * @param dmmTilerCtx - dmmTILERContCtxT* - [in] Tiler context instance. + * + * @param bufferMappedZone - dmmTILERContPageAreaT* - [in] Description of the 2D + * area that is mapped in the TILER container is provided in this structure. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmTILERContPageAreaT for further detail. + */ +/* ========================================================================== */ +/* DHS */ +enum errorCodeT dmm_tiler_container_unmap_area( + struct dmmTILERContCtxT *dmmTilerCtx, + struct dmmTILERContPageAreaT *bufferMappedZone) +{ + if (dealloc_2d_area(dmmTilerCtx, bufferMappedZone) != 1) + return DMM_WRONG_PARAM; + else + return DMM_NO_ERROR; +} + +/* ========================================================================== */ +/** + * dmm_tiler_get_area_from_sysptr() + * + * @brief Gets a 2D area descriptor from the Tiler system pointer. + * + * @param dmmTilerCtx - dmmTILERContCtxT* - [in] Tiler context instance. + * + * @param sysPtr - void * - [in] Tiler system pointer to a 2D area. + * + * @return dmmTILERContPageAreaT* Pointer to the 2D area descriptor, NULL if + * error is encountered during extraction. + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see dmmTILERContPageAreaT for further detail. + */ +/* ========================================================================== */ +/* DHS */ +struct dmmTILERContPageAreaT *dmm_tiler_get_area_from_sysptr( + struct dmmTILERContCtxT *dmmTilerCtx, void *sysPtr) { + unsigned long X; + unsigned long Y; + enum dmmMemoryAccessT accessModeM; + + accessModeM = DMM_GET_ACC_MODE(sysPtr); + + if (DMM_GET_ROTATED(sysPtr) == 0) { + if (accessModeM == MODE_8_BIT || accessModeM == MODE_PAGE) { + X = DMM_HOR_X_PAGE_COOR_GET_8(sysPtr); + Y = DMM_HOR_Y_PAGE_COOR_GET_8(sysPtr); + } else if (accessModeM == MODE_16_BIT) { + X = DMM_HOR_X_PAGE_COOR_GET_16(sysPtr); + Y = DMM_HOR_Y_PAGE_COOR_GET_16(sysPtr); + } else if (accessModeM == MODE_32_BIT) { + X = DMM_HOR_X_PAGE_COOR_GET_32(sysPtr); + Y = DMM_HOR_Y_PAGE_COOR_GET_32(sysPtr); + } + } else { + if (accessModeM == MODE_8_BIT || accessModeM == MODE_PAGE) { + X = DMM_VER_X_PAGE_COOR_GET_8(sysPtr); + Y = DMM_VER_Y_PAGE_COOR_GET_8(sysPtr); + } else if (accessModeM == MODE_16_BIT) { + X = DMM_VER_X_PAGE_COOR_GET_16(sysPtr); + Y = DMM_VER_Y_PAGE_COOR_GET_16(sysPtr); + } else if (accessModeM == MODE_32_BIT) { + X = DMM_VER_X_PAGE_COOR_GET_32(sysPtr); + Y = DMM_VER_Y_PAGE_COOR_GET_32(sysPtr); + } + } + + return search_2d_area(dmmTilerCtx, X, Y, DMM_GET_X_INVERTED(sysPtr), + DMM_GET_Y_INVERTED(sysPtr)); +} + +/* ========================================================================== */ +/** + * dmm_instance_init() + * + * @brief Initializes the Tiler cotnext. + * + * @param dmmInstanceCtxPtr - void * - [in] Tiler context instance. + * + * @param contXSize - signed long - [in] Tiler container width. + * + * @param contYSize - signed long - [in] Tiler container height. + * + * @param hMSP - void * - [in] MSP handle related to this dmm_drv cotnext. + * + * @param usrAppData - void * - [in] Pointer to user specific data structure. + * + * @param usrCallback - MSP_usrCallback - [in] Pointer to callback supplied by + * the user for notificiation events (interupts). + * + * @return int True if operation succeded. + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see dmmTILERContCtxT for further detail. + */ +/* ========================================================================== */ +/* DHS */ +int dmm_instance_init(void *dmmInstanceCtxPtr, + signed long contXSize, + signed long contYSize, + void *hMSP, + void *usrAppData) +{ + struct dmmTILERContCtxT *dmmTilerCtx = + &((struct dmmInstanceCtxT *)dmmInstanceCtxPtr)->dmmTilerCtx; + struct dmmHwdCtxT *dmmHwdCtx = + &((struct dmmInstanceCtxT *)dmmInstanceCtxPtr)->dmmHwdCtx; + struct MSP_Dmm_eventNotificationT *dmmMspCtx = + &((struct dmmInstanceCtxT *)dmmInstanceCtxPtr)->dmmMspCtx; + + if (contXSize > 256 || contYSize > 128) + return 0; + + if (dmmHwdCtx->dmmOpenInstances == 0) { + + dmmTilerCtx->usdArList = NULL; + + dmmTilerCtx->tmpArSelect.plmntAr.x0 = 0; + dmmTilerCtx->tmpArSelect.plmntAr.y0 = 0; + dmmTilerCtx->tmpArSelect.plmntAr.x1 = 0; + dmmTilerCtx->tmpArSelect.plmntAr.y1 = 0; + dmmTilerCtx->tmpArSelect.anchrAr = NULL; + + dmmTilerCtx->contSizeX = contXSize; + dmmTilerCtx->contSizeY = contYSize; + + dmmHwdCtx->patIrqEvnt0.irqAreaSelect = 0; + dmmHwdCtx->patIrqEvnt1.irqAreaSelect = 1; + dmmHwdCtx->patIrqEvnt2.irqAreaSelect = 2; + dmmHwdCtx->patIrqEvnt3.irqAreaSelect = 3; + + dmmMspCtx->hMSP = hMSP; + dmmMspCtx->usrAppData = usrAppData; + } + + dmmHwdCtx->dmmOpenInstances++; + + return 1; +} + +/* ========================================================================== */ +/** + * dmm_instance_deinit() + * + * @brief Deinitializes the Tiler cotnext. + * + * @param dmmInstanceCtxPtr - void * - [in] Tiler context instance. + * + * @return int True if operation succeded. + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see dmmTILERContCtxT for further detail. + */ +/* ========================================================================== */ +int dmm_instance_deinit(void *dmmInstanceCtxPtr) +{ + struct dmmTILERContCtxT *dmmTilerCtx = + &((struct dmmInstanceCtxT *)dmmInstanceCtxPtr)->dmmTilerCtx; + struct dmmHwdCtxT *dmmHwdCtx = + &((struct dmmInstanceCtxT *)dmmInstanceCtxPtr)->dmmHwdCtx; + struct MSP_Dmm_eventNotificationT *dmmMspCtx = + &((struct dmmInstanceCtxT *)dmmInstanceCtxPtr)->dmmMspCtx; + + dmmHwdCtx->dmmOpenInstances--; + + if (dmmHwdCtx->dmmOpenInstances < 0) + return 0; + + if (dmmHwdCtx->dmmOpenInstances == 0) { + + while (dmmTilerCtx->usdArList != NULL) { + if (dmm_tiler_container_unmap_area( + dmmTilerCtx, &(dmmTilerCtx->usdArList->pgAr)) != + DMM_NO_ERROR) + return 0; + } + + dmmTilerCtx->usdArList = NULL; + + dmmTilerCtx->tmpArSelect.plmntAr.x0 = 0; + dmmTilerCtx->tmpArSelect.plmntAr.y0 = 0; + dmmTilerCtx->tmpArSelect.plmntAr.x1 = 0; + dmmTilerCtx->tmpArSelect.plmntAr.y1 = 0; + dmmTilerCtx->tmpArSelect.anchrAr = NULL; + + dmmTilerCtx->contSizeX = 0; + dmmTilerCtx->contSizeY = 0; + + dmmMspCtx->hMSP = NULL; + dmmMspCtx->usrAppData = NULL; + } + + return 1; +} + +/* ========================================================================== */ +/** +* dmm_pat_irq_handler() +* +* @brief Interrupt handler for PAT area status updates. +* +* @param data - UArg - +* +* @return none +* +* @pre There is no pre conditions. +* +* @post There is no post conditions. +* +* @see +* +*/ +/* ========================================================================== */ +void dmm_pat_irq_handler(unsigned long data) +{ +} + +/* ========================================================================== */ +/** + * dmm_copy2tiler_alias_view() + * + * @brief Auxiliary function for copying data to the Tiler alias view. + * + * @param destPtr - void * - [in] Destination pointer in Tiler alias view. + * + * @param srcPtr - void * - [in] Data source pointer. + * + * @param width - signed long - [in] Data width. + * + * @param height - signed long - [in] Data height. + * + * @param stride - signed long - [in] Data stride. + * + * @param accType - dmmMemoryAccessT - [in] Tiler memory view access type. + * + * @return errorCodeT error if event can't be signaled. + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see dmmTILERContCtxT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_copy2tiler_alias_view(void *destPtr, + void *srcPtr, + signed long width, + signed long height, + signed long stride, + enum dmmMemoryAccessT accType) +{ + signed long row; + + switch (accType) { + case MODE_8_BIT: { + unsigned char *destPtr8 = (unsigned char *)destPtr; + unsigned char *srcPtr8 = (unsigned char *)srcPtr; + for (row = 0; row < height; row++) { + memcpy(&destPtr8[row*DMM_TILER_CONT_WIDTH_8], + srcPtr8, width); + srcPtr8 += stride; + } + } + break; + case MODE_16_BIT: { + unsigned short *destPtr16 = (unsigned short *)destPtr; + unsigned short *srcPtr16 = (unsigned short *)srcPtr; + for (row = 0; row < height; row++) { + memcpy(&destPtr16[row*DMM_TILER_CONT_WIDTH_16], + srcPtr16, width*2); + srcPtr16 += stride; + } + } + break; + case MODE_32_BIT: { + unsigned long *destPtr32 = (unsigned long *)destPtr; + unsigned long *srcPtr32 = (unsigned long *)srcPtr; + for (row = 0; row < height; row++) { + memcpy(&destPtr32[row*DMM_TILER_CONT_WIDTH_32], + srcPtr32, width*4); + srcPtr32 += stride; + } + } + break; + case MODE_PAGE: { + unsigned char *destPtr8 = (unsigned char *)destPtr; + unsigned char *srcPtr8 = (unsigned char *)srcPtr; + for (row = 0; row < stride*height; row++) { + memcpy(&destPtr8[row], srcPtr8, stride); + srcPtr8 += stride; + } + } + break; + default: + return DMM_SYS_ERROR; + } + + return DMM_NO_ERROR; +} + +/* ========================================================================== */ +/** + * dmm_copy_from_tiler_alias_view() + * + * @brief Auxiliary function for copying data to the Tiler alias view. + * + * @param destPtr - void * - [in] Destination pointer in Tiler alias view. + * + * @param srcPtr - void * - [in] Data source pointer. + * + * @param width - signed long - [in] Data width. + * + * @param height - signed long - [in] Data height. + * + * @param stride - signed long - [in] Data stride. + * + * @param accType - dmmMemoryAccessT - [in] Tiler memory view access type. + * + * @return errorCodeT error if event can't be signaled. + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see dmmTILERContCtxT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_copy_from_tiler_alias_view(void *destPtr, + void *srcPtr, + signed long width, + signed long height, + signed long stride, + enum dmmMemoryAccessT accType) +{ + signed long row; + + switch (accType) { + case MODE_8_BIT: { + unsigned char *destPtr8 = (unsigned char *)destPtr; + unsigned char *srcPtr8 = (unsigned char *)srcPtr; + for (row = 0; row < height; row++) { + memcpy(destPtr8, &srcPtr8[row*DMM_TILER_CONT_WIDTH_8], + width); + destPtr8 += stride; + } + } + break; + case MODE_16_BIT: { + unsigned short *destPtr16 = (unsigned short *)destPtr; + unsigned short *srcPtr16 = (unsigned short *)srcPtr; + for (row = 0; row < height; row++) { + memcpy(destPtr16, + &srcPtr16[row*DMM_TILER_CONT_WIDTH_16], + width*2); + destPtr16 += stride; + } + } + break; + case MODE_32_BIT: { + unsigned long *destPtr32 = (unsigned long *)destPtr; + unsigned long *srcPtr32 = (unsigned long *)srcPtr; + for (row = 0; row < height; row++) { + memcpy(destPtr32, + &srcPtr32[row*DMM_TILER_CONT_WIDTH_32], + width*4); + destPtr32 += stride; + } + } + break; + case MODE_PAGE: { + unsigned char *destPtr8 = (unsigned char *)destPtr; + unsigned char *srcPtr8 = (unsigned char *)srcPtr; + for (row = 0; row < stride*height; row++) { + memcpy(destPtr8, &srcPtr8[row], stride); + destPtr8 += stride; + } + } + break; + default: + return DMM_SYS_ERROR; + } + + return DMM_NO_ERROR; +} + +/* ========================================================================== */ +/** + * dmmVirtualBufferManipulations() + * + * @brief Manipulates virtual buffers. + * + * @param dmmInstanceCtxPtr - void * - [in] Dmm context instance. + * + * @param sysPtr - void * - [in] Tiler system pointer to a 2D area. + * + * @param patOp - MSP_Dmm_Phy2VirtOpsT - [in] Refill operaion to perform. + * + * @param affectedArea - PATAreaT* - [in] Area that will be affected. + * + * @param destinationArea - PATAreaT* - [in] Destination coordinates. + * + * @return void * pointer to the area targeted by the operation. + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see dmmTILERContPageAreaT for further detail. + */ +/* ========================================================================== */ +void *dmm_virtual_buffer_manipulations(void *dmmInstanceCtxPtr, + void *sysPtr, + struct PATAreaT *affectedArea, + struct PATAreaT *destinationArea) +{ + unsigned long bfrPages; + struct dmmTILERContPageAreaT *bufferMappedZone; + enum errorCodeT eCode = DMM_NO_ERROR; + struct dmmTILERContCtxT *dmmTilerCtx = + &((struct dmmInstanceCtxT *)dmmInstanceCtxPtr)->dmmTilerCtx; + + enum dmmMemoryAccessT accessModeM; + struct dmmViewOrientT orient; + unsigned long addrAlignment; + unsigned long contWidth; + unsigned long contHeight; + + bufferMappedZone = dmm_tiler_get_area_from_sysptr(dmmTilerCtx, sysPtr); + bfrPages = + (bufferMappedZone->xPageCount)*(bufferMappedZone->yPageCount); + + eCode = dmm_tiler_swap_pat_page_entry_data(bfrPages, + bufferMappedZone->patPageEntries, affectedArea, + destinationArea->x0, destinationArea->y0, + bufferMappedZone->xPageCount); + + eCode = dmm_pat_start_refill(bufferMappedZone); + + if (eCode != DMM_NO_ERROR) + return NULL; + + accessModeM = DMM_GET_ACC_MODE(sysPtr); + orient.dmm90Rotate = (unsigned char)DMM_GET_ROTATED(sysPtr); + orient.dmmXInvert = (unsigned char)DMM_GET_X_INVERTED(sysPtr); + orient.dmmYInvert = (unsigned char)DMM_GET_Y_INVERTED(sysPtr); + + switch (accessModeM) { + case MODE_8_BIT: + case MODE_PAGE: + if (orient.dmm90Rotate) { + contWidth = DMM_TILER_CONT_HEIGHT_8; + contHeight = DMM_TILER_CONT_WIDTH_8; + } else { + contWidth = DMM_TILER_CONT_WIDTH_8; + contHeight = DMM_TILER_CONT_HEIGHT_8; + } + addrAlignment = 0; + break; + case MODE_16_BIT: + if (orient.dmm90Rotate) { + contWidth = DMM_TILER_CONT_HEIGHT_16; + contHeight = DMM_TILER_CONT_WIDTH_16; + } else { + contWidth = DMM_TILER_CONT_WIDTH_16; + contHeight = DMM_TILER_CONT_HEIGHT_16; + } + addrAlignment = 1; + break; + case MODE_32_BIT: + if (orient.dmm90Rotate) { + contWidth = DMM_TILER_CONT_HEIGHT_32; + contHeight = DMM_TILER_CONT_WIDTH_32; + } else { + contWidth = DMM_TILER_CONT_WIDTH_32; + contHeight = DMM_TILER_CONT_HEIGHT_32; + } + addrAlignment = 2; + break; + } + + if (orient.dmm90Rotate) { + sysPtr = (void *)((destinationArea->x0*contHeight + + destinationArea->y0) << ((unsigned long)addrAlignment)); + } else { + sysPtr = (void *)((destinationArea->y0*contWidth + + destinationArea->x0) << ((unsigned long)addrAlignment)); + } + sysPtr = DMM_COMPOSE_TILER_PTR(sysPtr, orient.dmm90Rotate, + orient.dmmYInvert, orient.dmmXInvert, accessModeM); + + return sysPtr; +} + diff --git a/drivers/media/video/tiler/dmm_ll_drv.c b/drivers/media/video/tiler/dmm_ll_drv.c new file mode 100644 index 000000000000..f95883be798b --- /dev/null +++ b/drivers/media/video/tiler/dmm_ll_drv.c @@ -0,0 +1,678 @@ +/* + * dmm_ll_drv.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/io.h> +#include "dmm_def.h" +#include "dmm_2d_alloc.h" +#include "dmm_prv.h" +#include "dmm_reg.h" +MODULE_LICENSE("GPL v2"); + +/* ========================================================================== */ +/** + * dmm_tiler_alias_orientation_set() + * + * @brief Set specific TILER alias orientation setting per initiator ID + * (alias view). + * + * @param initiatorID - signed long - [in] OCP id of DMM transfer initiator which + * alias view will be editted. + * + * @param viewOrientation - dmmViewOrientT - [in] New alias view orientation + * setting. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmViewOrientT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_tiler_alias_orientation_set(signed long initiatorID, + struct dmmViewOrientT viewOrientation) +{ + enum errorCodeT eCode = DMM_NO_ERROR; + unsigned long *reg = NULL; + + reg = (unsigned long)dmmvabase | (0x220ul); + __raw_writel(0x88888888, reg); + + reg = (unsigned long)dmmvabase | (0x220ul+0x4); + __raw_writel(0x88888888, reg); + + return eCode; +} + +/* ========================================================================== */ +/** + * dmm_tiler_alias_orientation_get() + * + * @brief Get specific TILER alias orientation setting per initiator ID + * (alias view). + * + * @param initiatorID - signed long - [in] OCP id of DMM transfer initiator + * which alias view will be editted. + * + * @param viewOrientation - dmmViewOrientT* - [out] Pointer to write alias view + * orientation setting to. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmViewOrientT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_tiler_alias_orientation_get(signed long initiatorID, + struct dmmViewOrientT *viewOrientation) +{ + enum errorCodeT eCode = DMM_NO_ERROR; + return eCode; +} + +/* ========================================================================== */ +/** + * dmm_peg_priority_set() + * + * @brief Set specific PEG priority setting per initiator ID. + * + * @param initiatorID - signed long - [in] OCP id of DMM transfer initiator + * which priority will be editted. + * + * @param prio - unsigned long - [in] New priority setting. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_peg_priority_set(signed long initiatorID, + unsigned long prio) +{ + enum errorCodeT eCode = DMM_NO_ERROR; + return eCode; +} + +/* ========================================================================== */ +/** + * dmm_peg_priority_get() + * + * @brief Get specific PEG priority setting per initiator ID. + * + * @param initiatorID - signed long - [in] OCP id of DMM transfer initiator + * which priority will be editted. + * + * @param prio - unsigned long* - [out] Poitner to write the priority setting. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_peg_priority_get(signed long initiatorID, + unsigned long *prio) +{ + enum errorCodeT eCode = DMM_NO_ERROR; + return eCode; +} + +/* ========================================================================== */ +/** + * dmm_pat_area_refill() + * + * @brief Initiate a PAT area refill (or terminate an ongoing - consult + * documentation). + * + * @param patDesc - PATDescrT* - [in] Pointer to a PAT area descriptor that's + * needed to extract settings from for the refill procedure initation. + * + * @param dmmPatAreaSel - signed long - [in] Selects which PAT area will be + * configured for a area refill procedure. + * + * @param refillType - dmmPATRefillMethodT - [in] Selects the refill method - + * manual or automatic. + * + * @param forcedRefill - int - [in] Selects if forced refill should be used + * effectively terminating any ongoing area refills related to the selected area + * + * @return errorCodeT + * + * @pre If forced mode is not used, no refills should be ongoing for the + * selected area - error status returned if this occurs. + * + * @post If non valid data is provided for patDesc and the refill engines fail + * to perform the request, an error status is returned. + * + * @see errorCodeT, PATDescrT, dmmPATRefillMethodT, int for further detail + */ +/* ========================================================================== */ +enum errorCodeT dmm_pat_area_refill(struct PATDescrT *patDesc, + signed long dmmPatAreaSel, + enum dmmPATRefillMethodT refillType, + int forcedRefill) +{ + enum errorCodeT eCode = DMM_NO_ERROR; + unsigned long *reg = NULL; + unsigned long regval = 0xffffffff; + unsigned long writeval = 0xffffffff; + unsigned long f = 0xffffffff; /* field */ + unsigned long fp = 0xffffffff; /* field position */ + + struct dmmPATStatusT areaStat; + + if (forcedRefill == 0) { + eCode = dmm_pat_refill_area_status_get( + dmmPatAreaSel, &areaStat); + + if (eCode == DMM_NO_ERROR) { + if (areaStat.ready == 0 || areaStat.engineRunning) { + printk(KERN_ALERT "hw not ready\n"); + eCode = DMM_HRDW_NOT_READY; + } + } + } + + if (dmmPatAreaSel < 0 || dmmPatAreaSel > 3) { + eCode = DMM_WRONG_PARAM; + } else if (eCode == DMM_NO_ERROR) { + if (refillType == AUTO) { + reg = (unsigned long)dmmvabase | (0x500ul + 0x0); + regval = __raw_readl(reg); + f = BITFIELD(31, 4); + fp = 4; + writeval = regval & (~(f)) | + ((((unsigned long)patDesc) << fp) & f); + __raw_writel(writeval, reg); + } else if (refillType == MANUAL) { + reg = (unsigned long)dmmvabase | (0x500ul + 0x0); + regval = __raw_readl(reg); + f = BITFIELD(31, 4); + fp = 4; + writeval = regval & (~(f)) | + ((((unsigned long)NULL) << fp) & f); + __raw_writel(writeval, reg); + + reg = (unsigned long)dmmvabase | (0x500ul + 0x4); + regval = __raw_readl(reg); + f = BITFIELD(30, 24); + fp = 24; + writeval = regval & (~(f)) | + (((patDesc->area.y1) << fp) & f); + __raw_writel(writeval, reg); + + f = BITFIELD(23, 16); + fp = 16; + writeval = regval & (~(f)) | + (((patDesc->area.x1) << fp) & f); + __raw_writel(writeval, reg); + + f = BITFIELD(14, 8); + fp = 8; + writeval = regval & (~(f)) | + (((patDesc->area.y0) << fp) & f); + __raw_writel(writeval, reg); + + f = BITFIELD(7, 0); + fp = 0; + writeval = regval & (~(f)) | + (((patDesc->area.x0) << fp) & f); + __raw_writel(writeval, reg); + + /* Apply 4 bit lft shft to counter the 4 bit rt shft */ + reg = (unsigned long)dmmvabase | (0x500ul + 0xc); + regval = __raw_readl(reg); + f = BITFIELD(31, 4); + fp = 4; + writeval = regval & (~(f)) | + ((((unsigned long)(patDesc->data >> 4)) << fp) & f); + __raw_writel(writeval, reg); + + reg = (unsigned long)dmmvabase | (0x500ul + 0x8); + regval = __raw_readl(reg); + f = BITFIELD(31, 28); + fp = 28; + writeval = regval & (~(f)) | + (((patDesc->ctrl.initiator) << fp) & f); + __raw_writel(writeval, reg); + + f = BITFIELD(16, 16); + fp = 16; + writeval = regval & (~(f)) | + (((patDesc->ctrl.sync) << fp) & f); + __raw_writel(writeval, reg); + + f = BITFIELD(6, 4); + fp = 4; + writeval = regval & (~(f)) | + (((patDesc->ctrl.direction) << fp) & f); + __raw_writel(writeval, reg); + + f = BITFIELD(0, 0); + fp = 0; + writeval = regval & (~(f)) | + (((patDesc->ctrl.start) << fp) & f); + __raw_writel(writeval, reg); + } else { + eCode = DMM_WRONG_PARAM; + } + if (eCode == DMM_NO_ERROR) { + eCode = dmm_pat_refill_area_status_get(dmmPatAreaSel, + &areaStat); + + if (eCode == DMM_NO_ERROR) { + if (areaStat.validDescriptor == 0) { + eCode = DMM_HRDW_CONFIG_FAILED; + printk(KERN_ALERT "hw config fail\n"); + } + } + + while (!areaStat.done && !areaStat.ready && + eCode == DMM_NO_ERROR) { + eCode = dmm_pat_refill_area_status_get( + dmmPatAreaSel, + &areaStat); + } + + if (areaStat.error) { + eCode = DMM_HRDW_CONFIG_FAILED; + printk(KERN_ALERT "hw config fail\n"); + } + } + } + return eCode; +} + +/* ========================================================================== */ +/** + * dmm_pat_refill_area_status_get() + * + * @brief Gets the status for the selected PAT area. + * + * @param dmmPatAreaSel - signed long - [in] Selects which PAT area status will + * be queried. + * + * @param areaStatus - dmmPATStatusT* - [out] Structure containing the PAT area + * status that will be filled by dmmPatRefillAreaStatusGet(). + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post If the query fails the provided areaStatus structure is not updated + * at all! + * + * @see errorCodeT, dmmPATStatusT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_pat_refill_area_status_get(signed long dmmPatAreaStatSel, + struct dmmPATStatusT *areaStatus) +{ + enum errorCodeT eCode = DMM_NO_ERROR; + + unsigned long stat = 0xffffffff; + unsigned long *statreg = NULL; + + if (dmmPatAreaStatSel >= 0 && dmmPatAreaStatSel <= 3) { + statreg = (unsigned long)dmmvabase | 0x4c0ul; + stat = __raw_readl(statreg); + + areaStatus->remainingLinesCounter = stat & BITFIELD(24, 16); + areaStatus->error = (enum dmmPATStatusErrT) + (stat & BITFIELD(15, 10)); + areaStatus->linkedReconfig = stat & BITFIELD(4, 4); + areaStatus->done = stat & BITFIELD(3, 3); + areaStatus->engineRunning = stat & BITFIELD(2, 2); + areaStatus->validDescriptor = stat & BITFIELD(1, 1); + areaStatus->ready = stat & BITFIELD(0, 0); + + } else { + eCode = DMM_WRONG_PARAM; + printk(KERN_ALERT "wrong parameter\n"); + } + + return eCode; +} + +/* ========================================================================== */ +/** + * dmm_pat_refill_engine_config() + * + * @brief Configure the selected PAT refill engine. + * + * @param dmmPatEngineSel - signed long - [in] Selects which PAT engine will be + * configured. + * + * @param engineMode - dmmPATEngineAccessT - [in] New engine mode. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmPATEngineAccessT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_pat_refill_engine_config(signed long dmmPatEngineSel, + enum dmmPATEngineAccessT engineMode) +{ + enum errorCodeT eCode = DMM_NO_ERROR; + unsigned long *reg = NULL; + + reg = (unsigned long)dmmvabase | (0x410ul); + __raw_writel(0x00000000, reg); + + return eCode; +} + +/* ========================================================================== */ +/** + * dmm_pat_refill_engine_config_get() + * + * @brief Get the selected PAT refill engine configuration. + * + * @param dmmPatEngineSel - signed long - [in] Selects which PAT engine will be + * configured. + * + * @param engineMode - dmmPATEngineAccessT* - [out] Pointer to write the engine + * mode. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmPATEngineAccessT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_pat_refill_engine_config_get(signed long dmmPatEngineSel, + enum dmmPATEngineAccessT *engineMode) +{ + enum errorCodeT eCode = DMM_NO_ERROR; + return eCode; +} + +/* ========================================================================== */ +/** + * dmm_pat_view_set() + * + * @brief Set specific PAT initiator view settings. + * + * @param initiatorID - signed long - [in] OCP id of DMM transfer initiator + * which PAT view will be editted. + * + * @param patViewIndx - signed long - [in] New view map setting. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_pat_view_set(signed long initiatorID, + signed long patViewIndx) +{ + enum errorCodeT eCode = DMM_NO_ERROR; + unsigned long *reg = NULL; + + if (patViewIndx < 0 || patViewIndx > 3) { + eCode = DMM_WRONG_PARAM; + } else { + reg = (unsigned long)dmmvabase | (0x420ul); + __raw_writel(0xDDDDDDDD, reg); + + reg = (unsigned long)dmmvabase | (0x420ul+0x4); + __raw_writel(0xDDDDDDDD, reg); + } + + return eCode; +} + +/* ========================================================================== */ +/** + * dmm_pat_view_get() + * + * @brief Get specific PAT initiator view settings. + * + * @param initiatorID - signed long - [in] OCP id of DMM transfer initiator + * which PAT view will be editted. + * + * @param patViewIndx - signed long* - [out] Pointer to write the view map + * setting. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_pat_view_get( + signed long initiatorID, signed long *patViewIndx) +{ + enum errorCodeT eCode = DMM_NO_ERROR; + return eCode; +} + +/* ========================================================================== */ +/** + * dmm_pat_view_map_config() + * + * @brief Configure selected PAT view map. + * + * @param patViewMapIndx - signed long - [in] Index of the selected PAT view + * map. + * + * @param memoryAccessMode - dmmMemoryAccessT - [in] Type of memory access to + * perform through this view. + * + * @param contX - unsigned long - [in] CONT_x register value. + * + * @param transType - dmmPATTranslationT - [in] Address translation schemes. + * + * @param dmmPATViewBase - unsigned long - [in] View map base address + * (31-bit only considered). + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmMemoryAccessT, dmmPATTranslationT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_pat_view_map_config(signed long patViewMapIndx, + enum dmmMemoryAccessT memoryAccessMode, + unsigned long contX, + enum dmmPATTranslationT transType, + unsigned long dmmPATViewBase) +{ + enum errorCodeT eCode = DMM_NO_ERROR; + unsigned long *reg = NULL; + unsigned long regval = 0xffffffff; + + reg = (unsigned long)dmmvabase | (0x460ul); + regval = __raw_readl(reg); + __raw_writel(0xFFFFFFFF, reg); + + reg = (unsigned long)dmmvabase | (0x440ul); + regval = __raw_readl(reg); + __raw_writel(0x80808080, reg); + + return eCode; +} + +enum errorCodeT dmm_pat_view_map_config_get(signed long patViewMapIndx, + enum dmmMemoryAccessT memoryAccessMode, + unsigned long *contX, + enum dmmPATTranslationT *transType, + unsigned long *dmmPATViewBase) +{ + enum errorCodeT eCode = DMM_NO_ERROR; + return eCode; +} + +/* ========================================================================== */ +/** + * dmm_lisa_memory_map_config() + * + * @brief Configure selected LISA memory map. + * + * @param lisaMemMapIndx - signed long - [in] Index of the selected LISA memory + * map. + * + * @param sysSize - dmmMemSectionSizeT - [in] Size of the memory section. + * + * @param sdrcIntl - dmmMemSdrcIntlModeT - [in] SDRAM controller interleaving + * mode + * + * @param sdrcAddrspc - unsigned long - [in] SDRAM controller address space. + * + * @param sdrcMap - dmmMemSectionMappingT - [in] SDRAM controller mapping. + * + * @param sdrcAddr - unsigned long - [in] SDRAM controller address MSB. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmMemSectionSizeT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_lisa_memory_map_config(signed long lisaMemMapIndx, + unsigned long sysAddr, + enum dmmMemSectionSizeT sysSize, + enum dmmMemSdrcIntlModeT sdrcIntl, + unsigned long sdrcAddrspc, + enum dmmMemSectionMappingT sdrcMap, + unsigned long sdrcAddr) +{ + enum errorCodeT eCode = DMM_NO_ERROR; + unsigned long *reg = NULL; + + if (lisaMemMapIndx != 0) + printk(KERN_WARNING "lisaMemMapIndx != 0\n"); + + reg = (unsigned long)dmmvabase | (0x40ul + (0x4*lisaMemMapIndx)); + __raw_writel(0x80710100, reg); + + return eCode; +} + +enum errorCodeT dmm_lisa_memory_map_config_get(signed long lisaMemMapIndx, + unsigned long *sysAddr, + enum dmmMemSectionSizeT *sysSize, + enum dmmMemSdrcIntlModeT *sdrcIntl, + unsigned long *sdrcAddrspc, + enum dmmMemSectionMappingT *sdrcMap, + unsigned long *sdrcAddr) +{ + enum errorCodeT eCode = DMM_NO_ERROR; + return eCode; +} + +/* ========================================================================== */ +/** + * dmm_engage_lisa_lock() + * + * @brief Sets the LISA lock register preventing further writting to the + * LISA memory map registers. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post Only a software reset of the DMM module can clear the lock bit. + * + * @see errorCodeT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_engage_lisa_lock() +{ + unsigned long *reg = NULL; + unsigned long regval = 0xffffffff; + unsigned long writeval = 0xffffffff; + unsigned long f = 0xffffffff; /* field */ + unsigned long fp = 0xffffffff; /* field position */ + + reg = (unsigned long)dmmvabase | (0x1cul); + regval = __raw_readl(reg); + + f = BITFIELD(0, 0); + fp = 0; + writeval = regval & (~(f)) | (((0x1ul) << fp) & f); + __raw_writel(writeval, reg); + + return DMM_NO_ERROR; +} + +enum errorCodeT dmm_sys_config_set(unsigned long dmmIdleMode) +{ + enum errorCodeT eCode = DMM_NO_ERROR; + return eCode; +} + +enum errorCodeT dmm_sys_config_get(unsigned long *dmmIdleMode) +{ + enum errorCodeT eCode = DMM_NO_ERROR; + return eCode; +} + +enum errorCodeT dmm_pat_irq_mode_set(struct dmmPATIrqEventsT *patIrqEvnt) +{ + enum errorCodeT eCode = DMM_NO_ERROR; + unsigned long *reg = NULL; + + reg = (unsigned long)dmmvabase | (0x4a0ul); + + __raw_writel(0x0000FFFF, reg); /* clr all irq registers */ + return eCode; +} + +enum errorCodeT dmm_pat_irq_mode_get(struct dmmPATIrqEventsT *patIrqEvnt) +{ + enum errorCodeT eCode = DMM_NO_ERROR; + return eCode; +} + +enum errorCodeT dmm_pat_irq_status_get(struct dmmPATIrqEventsT *patIrqEvnt, + int clrEvents) +{ + enum errorCodeT eCode = DMM_NO_ERROR; + return eCode; +} diff --git a/drivers/media/video/tiler/dmm_prv.h b/drivers/media/video/tiler/dmm_prv.h new file mode 100644 index 000000000000..9e7117f081ee --- /dev/null +++ b/drivers/media/video/tiler/dmm_prv.h @@ -0,0 +1,724 @@ +/* + * dmm_prv.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_PRV_H +#define _DMM_PRV_H + +#include "dmm_2d_alloc.h" +#include "dmm_drv.h" +#include "dmm_reg.h" + +#define DMM__DMM DMM__DMM +#define DMM_PAT_AREA_IRQ (0) + +#define DMM_MNGD_PHYS_PAGES (5) + +#define DMM_TILE_DIMM_X_MODE_8 (32) +#define DMM_TILE_DIMM_Y_MODE_8 (32) + +#define DMM_TILE_DIMM_X_MODE_16 (32) +#define DMM_TILE_DIMM_Y_MODE_16 (16) + +#define DMM_TILE_DIMM_X_MODE_32 (16) +#define DMM_TILE_DIMM_Y_MODE_32 (16) + +#define DMM_PAGE_DIMM_X_MODE_8 (DMM_TILE_DIMM_X_MODE_8*2) +#define DMM_PAGE_DIMM_Y_MODE_8 (DMM_TILE_DIMM_Y_MODE_8*2) + +#define DMM_PAGE_DIMM_X_MODE_16 (DMM_TILE_DIMM_X_MODE_16*2) +#define DMM_PAGE_DIMM_Y_MODE_16 (DMM_TILE_DIMM_Y_MODE_16*2) + +#define DMM_PAGE_DIMM_X_MODE_32 (DMM_TILE_DIMM_X_MODE_32*2) +#define DMM_PAGE_DIMM_Y_MODE_32 (DMM_TILE_DIMM_Y_MODE_32*2) + +#define DMM_HOR_X_ADDRSHIFT_8 (0) +#define DMM_HOR_X_ADDRMASK_8 (0x3FFF) +#define DMM_HOR_X_COOR_GET_8(x) (((unsigned long)x >> DMM_HOR_X_ADDRSHIFT_8) & \ + DMM_HOR_X_ADDRMASK_8) +#define DMM_HOR_X_PAGE_COOR_GET_8(x) (DMM_HOR_X_COOR_GET_8(x) / \ + DMM_PAGE_DIMM_X_MODE_8) + +#define DMM_HOR_Y_ADDRSHIFT_8 (14) +#define DMM_HOR_Y_ADDRMASK_8 (0x1FFF) +#define DMM_HOR_Y_COOR_GET_8(x) (((unsigned long)x >> DMM_HOR_Y_ADDRSHIFT_8) & \ + DMM_HOR_Y_ADDRMASK_8) +#define DMM_HOR_Y_PAGE_COOR_GET_8(x) (DMM_HOR_Y_COOR_GET_8(x) / \ + DMM_PAGE_DIMM_Y_MODE_8) + +#define DMM_HOR_X_ADDRSHIFT_16 (0) +#define DMM_HOR_X_ADDRMASK_16 (0x7FFF) +#define DMM_HOR_X_COOR_GET_16(x) (((unsigned long)x >> \ + DMM_HOR_X_ADDRSHIFT_16) & DMM_HOR_X_ADDRMASK_16) +#define DMM_HOR_X_PAGE_COOR_GET_16(x) (DMM_HOR_X_COOR_GET_16(x) / \ + DMM_PAGE_DIMM_X_MODE_16) + +#define DMM_HOR_Y_ADDRSHIFT_16 (15) +#define DMM_HOR_Y_ADDRMASK_16 (0xFFF) +#define DMM_HOR_Y_COOR_GET_16(x) (((unsigned long)x >> \ + DMM_HOR_Y_ADDRSHIFT_16) & DMM_HOR_Y_ADDRMASK_16) +#define DMM_HOR_Y_PAGE_COOR_GET_16(x) (DMM_HOR_Y_COOR_GET_16(x) / \ + DMM_PAGE_DIMM_Y_MODE_16) + +#define DMM_HOR_X_ADDRSHIFT_32 (0) +#define DMM_HOR_X_ADDRMASK_32 (0x7FFF) +#define DMM_HOR_X_COOR_GET_32(x) (((unsigned long)x >> \ + DMM_HOR_X_ADDRSHIFT_32) & DMM_HOR_X_ADDRMASK_32) +#define DMM_HOR_X_PAGE_COOR_GET_32(x) (DMM_HOR_X_COOR_GET_32(x) / \ + DMM_PAGE_DIMM_X_MODE_32) + +#define DMM_HOR_Y_ADDRSHIFT_32 (15) +#define DMM_HOR_Y_ADDRMASK_32 (0xFFF) +#define DMM_HOR_Y_COOR_GET_32(x) (((unsigned long)x >> \ + DMM_HOR_Y_ADDRSHIFT_32) & DMM_HOR_Y_ADDRMASK_32) +#define DMM_HOR_Y_PAGE_COOR_GET_32(x) (DMM_HOR_Y_COOR_GET_32(x) / \ + DMM_PAGE_DIMM_Y_MODE_32) + +#define DMM_VER_X_ADDRSHIFT_8 (14) +#define DMM_VER_X_ADDRMASK_8 (0x1FFF) +#define DMM_VER_X_COOR_GET_8(x) (((unsigned long)x >> \ + DMM_VER_X_ADDRSHIFT_8) & DMM_VER_X_ADDRMASK_8) +#define DMM_VER_X_PAGE_COOR_GET_8(x) (DMM_VER_X_COOR_GET_8(x) / \ + DMM_PAGE_DIMM_X_MODE_8) + +#define DMM_VER_Y_ADDRSHIFT_8 (0) +#define DMM_VER_Y_ADDRMASK_8 (0x3FFF) +#define DMM_VER_Y_COOR_GET_8(x) (((unsigned long)x >> \ + DMM_VER_Y_ADDRSHIFT_8) & DMM_VER_Y_ADDRMASK_8) +#define DMM_VER_Y_PAGE_COOR_GET_8(x) (DMM_VER_Y_COOR_GET_8(x) / \ + DMM_PAGE_DIMM_Y_MODE_8) + +#define DMM_VER_X_ADDRSHIFT_16 (14) +#define DMM_VER_X_ADDRMASK_16 (0x1FFF) +#define DMM_VER_X_COOR_GET_16(x) (((unsigned long)x >> \ + DMM_VER_X_ADDRSHIFT_16) & DMM_VER_X_ADDRMASK_16) +#define DMM_VER_X_PAGE_COOR_GET_16(x) (DMM_VER_X_COOR_GET_16(x) / \ + DMM_PAGE_DIMM_X_MODE_16) + +#define DMM_VER_Y_ADDRSHIFT_16 (0) +#define DMM_VER_Y_ADDRMASK_16 (0x3FFF) +#define DMM_VER_Y_COOR_GET_16(x) (((unsigned long)x >> \ + DMM_VER_Y_ADDRSHIFT_16) & DMM_VER_Y_ADDRMASK_16) +#define DMM_VER_Y_PAGE_COOR_GET_16(x) (DMM_VER_Y_COOR_GET_16(x) / \ + DMM_PAGE_DIMM_Y_MODE_16) + +#define DMM_VER_X_ADDRSHIFT_32 (15) +#define DMM_VER_X_ADDRMASK_32 (0xFFF) +#define DMM_VER_X_COOR_GET_32(x) (((unsigned long)x >> \ + DMM_VER_X_ADDRSHIFT_32) & DMM_VER_X_ADDRMASK_32) +#define DMM_VER_X_PAGE_COOR_GET_32(x) (DMM_VER_X_COOR_GET_32(x) / \ + DMM_PAGE_DIMM_X_MODE_32) + +#define DMM_VER_Y_ADDRSHIFT_32 (0) +#define DMM_VER_Y_ADDRMASK_32 (0x7FFF) +#define DMM_VER_Y_COOR_GET_32(x) (((unsigned long)x >> \ + DMM_VER_Y_ADDRSHIFT_32) & DMM_VER_Y_ADDRMASK_32) +#define DMM_VER_Y_PAGE_COOR_GET_32(x) (DMM_VER_Y_COOR_GET_32(x) / \ + DMM_PAGE_DIMM_Y_MODE_32) + +#define DMM_TILER_ALIAS_BASE (0x60000000) +#define DMM_ALIAS_VIEW_CLEAR (~0xE0000000) + +#define DMM_ACC_MODE_SHIFT (27) +#define DMM_ACC_MODE_MASK (3) +#define DMM_GET_ACC_MODE(x) ((enum dmmMemoryAccessT)(((unsigned long)x &\ + (DMM_ACC_MODE_MASK<<DMM_ACC_MODE_SHIFT))>>DMM_ACC_MODE_SHIFT)) + +#define DMM_X_INVERT_SHIFT (29) +#define DMM_GET_X_INVERTED(x) ((((unsigned long)x & \ + (1<<DMM_X_INVERT_SHIFT)) > 0) ? 1 : 0) + +#define DMM_Y_INVERT_SHIFT (30) +#define DMM_GET_Y_INVERTED(x) ((((unsigned long)x & \ + (1<<DMM_Y_INVERT_SHIFT)) > 0) ? 1 : 0) + +#define DMM_ROTATION_SHIFT (31) +#define DMM_GET_ROTATED(x) ((((unsigned long)x & \ + ((unsigned long)1<<DMM_ROTATION_SHIFT)) > 0) ? 1 : 0) + +#define DMM_COMPOSE_TILER_ALIAS_PTR(x, accM) ((void *)(DMM_TILER_ALIAS_BASE | \ + (unsigned long)x | (accM << DMM_ACC_MODE_SHIFT))) +#define DMM_COMPOSE_TILER_PTR(x, rot, yInv, xInv, accM) \ + ((void *)((unsigned long)x | (rot << DMM_ROTATION_SHIFT) | \ + (yInv << DMM_Y_INVERT_SHIFT) | (xInv << DMM_X_INVERT_SHIFT) | \ + (accM << DMM_ACC_MODE_SHIFT))) + +/*--------data declarations -----------------------------------*/ +extern struct dmmInstanceCtxT dmmInstanceCtxStatic; + +/** @struc dmmPhysPgLLT +* Structure defining Dmm physical memory pages managment linked list. */ +struct dmmPhysPgLLT { + struct dmmPhysPgLLT *nextPhysPg; + struct dmmPhysPgLLT *prevPhysPg; + unsigned long *physPgPtr; +}; + +/** @struc dmmHwdCtxT +* Structure defining Dmm driver hardware context. */ +struct dmmHwdCtxT { + signed long dmmOpenInstances; + struct dmmPATIrqEventsT patIrqEvnt0; + struct dmmPATIrqEventsT patIrqEvnt1; + struct dmmPATIrqEventsT patIrqEvnt2; + struct dmmPATIrqEventsT patIrqEvnt3; +}; + +/** @struc dmmInstanceCtxT +* Structure defining Dmm driver context. */ +struct dmmInstanceCtxT { + struct dmmHwdCtxT dmmHwdCtx; + struct MSP_Dmm_eventNotificationT dmmMspCtx; + struct dmmTILERContCtxT dmmTilerCtx; +}; + +/** @struc dmmPatRefillManip +* Enumeration of possible area refill manipulations. */ +enum dmmPatRefillManipT { + DMMP_REMAP, + DMMP_SWAP, + DMMP_MOVE +}; + +#ifdef __DMM_DEBUG_BUILD__ +#define DBG_OVERLAP_TEST(x) overlappingTest(x) + +struct DMM_rStruct_t { + unsigned long DMM_REVISION; + unsigned long DMM_HWINFO; + unsigned long DMM_LISA_HWINFO; + unsigned long DMM_SYSCONFIG; + unsigned long DMM_LISA_LOCK; + unsigned char filler1[32]; + unsigned long DMM_LISA_MAP__0; + unsigned long DMM_LISA_MAP__1; + unsigned long DMM_LISA_MAP__2; + unsigned long DMM_LISA_MAP__3; + unsigned char filler2[440]; + unsigned long DMM_TILER_HWINFO; + unsigned char filler3[20]; + unsigned long DMM_TILER_OR0; + unsigned long DMM_TILER_OR1; + unsigned char filler4[476]; + unsigned long DMM_PAT_HWINFO; + unsigned long DMM_PAT_GEOMETRY; + unsigned char filler5[16]; + unsigned long DMM_PAT_VIEW0; + unsigned long DMM_PAT_VIEW1; + unsigned char filler6[24]; + unsigned long DMM_PAT_VIEW_MAP__0; + unsigned long DMM_PAT_VIEW_MAP__1; + unsigned long DMM_PAT_VIEW_MAP__2; + unsigned long DMM_PAT_VIEW_MAP__3; + unsigned char filler7[16]; + unsigned long DMM_PAT_VIEW_MAP_BASE; + unsigned char filler8[28]; + unsigned long DMM_PAT_STATUS__0; + unsigned long DMM_PAT_STATUS__1; + unsigned long DMM_PAT_STATUS__2; + unsigned long DMM_PAT_STATUS__3; + unsigned char filler9[48]; + unsigned long DMM_PAT_IRQSTATUS_RAW; + unsigned char filler10[12]; + unsigned long DMM_PAT_IRQSTATUS; + unsigned char filler11[12]; + unsigned long DMM_PAT_IRQENABLE_SET; + unsigned char filler12[12]; + unsigned long DMM_PAT_IRQENABLE_CLR; + unsigned char filler13[12]; + unsigned long DMM_PAT_DESCR__0; + unsigned long DMM_PAT_AREA__0; + unsigned long DMM_PAT_CTRL__0; + unsigned long DMM_PAT_DATA__0; + unsigned long DMM_PAT_DESCR__1; + unsigned long DMM_PAT_AREA__1; + unsigned long DMM_PAT_CTRL__1; + unsigned long DMM_PAT_DATA__1; + unsigned long DMM_PAT_DESCR__2; + unsigned long DMM_PAT_AREA__2; + unsigned long DMM_PAT_CTRL__2; + unsigned long DMM_PAT_DATA__2; + unsigned long DMM_PAT_DESCR__3; + unsigned long DMM_PAT_AREA__3; + unsigned long DMM_PAT_CTRL__3; + unsigned long DMM_PAT_DATA__3; + unsigned char filler14[200]; + unsigned long DMM_PEG_HWINFO; + unsigned char filler15[20]; + unsigned long DMM_PEG_PRIO0; + unsigned long DMM_PEG_PRIO1; + unsigned char filler16[24]; + unsigned long DMM_PEG_PRIO_PAT; +}; + +#else + +#define DBG_OVERLAP_TEST(x) + +#endif /* __DMM_DEBUG_BUILD__ */ + +/*--------function prototypes ---------------------------------*/ +/* ========================================================================== */ +/** + * dmm_get_context_pointer() + * + * @brief Returns a pointer to the Tiler context structure. + * + * @return void * Pointer to the Tiler context structure + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see dmmInstanceCtxT for further detail. + */ +/* ========================================================================== */ +void *dmm_get_context_pointer(); + +/* ========================================================================== */ +/** + * dmm_tiler_container_map_area() + * + * @brief Allocates a 2D TILER buffer - virtual 2D allocation, + * descriptor and TILER system pointer updating. + * + * @param dmmTilerCtx - dmmTILERContCtxT* - [in] Tiler context instance. + * + * @param sizeWidth - unsigned short - [in] Width of buffer + * (in container elements). + * + * @param sizeHeight - unsigned short - [in] Height of buffer (in container + * elements). + * + * @param contMod - dmmMemoryAccessT - [in] Container access mode - for element + * sizes. + * + * @param allocedPtr - void ** - [out] The allocated buffer system pointer is + * provided through this double pointer. If no buffer is available this pointer + * is set to NULL. + * + * @param bufferMappedZone - dmmTILERContPageAreaT** - [out] Description of the + * 2D area that is mapped in the TILER container is provided in this structure. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmMemoryAccessT, dmmTILERContPageAreaT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_tiler_container_map_area( + struct dmmTILERContCtxT *dmmTilerCtx, + unsigned short sizeWidth, + unsigned short sizeHeight, + enum dmmMemoryAccessT contMod, + void **allocedPtr, + struct dmmTILERContPageAreaT **bufferMappedZone); + +/* ========================================================================== */ +/** + * dmm_tiler_populate_pat_page_entry_data() + * + * @brief Populates an aray with PAT page address entries. + * + * @param bfrSize - unsigned long - [in] Size of the buffer which will be used + * to generate page entries for. + * + * @param pageEntries - unsigned long** - [out] The address to the allocated + * page entry data array, aligned due to hardware specification. + * + * @param pageEntriesSpace - unsigned long** - [out] The address to the + * allocated page entry data array for deallocation purposes. + * + * @param custmPagesPtr - void * - [in] Pointer to a custom created memory + * pages list. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_tiler_populate_pat_page_entry_data(unsigned long bfrSize, + unsigned long **pageEntries, + unsigned long **pageEntriesSpace, + void *custmPagesPtr); + +/* ========================================================================== */ +/** + * dmm_tiler_swap_pat_page_entry_data() + * + * @brief Swaps entries in an aray with PAT page address entries. + * + * @param bfrSize - unsigned long - [in] Size of the buffer which will be used + * to generate page entries for. + * + * @param pageEntries - unsigned long* - [in] The address to the allocated + * page entry data array, aligned due to hardware specification. + * + * @param affectedArea - PATAreaT* - [in] Area that will be affected. + * + * @param destX - unsigned char - [in] Destination coordinate X. + * + * @param destY - unsigned char - [in] Destination coordinate Y. + * + * @param stride - unsigned char - [in] Stride of the area. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_tiler_swap_pat_page_entry_data(unsigned long numPages, + unsigned long *pageEntries, + struct PATAreaT *affectedArea, + unsigned char destX, + unsigned char destY, + unsigned char stride); + +/* ========================================================================== */ +/** + * dmm_tiler_container_unmap_area() + * + * @brief Frees a 2D virtual TILER container buffer. \ + * + * @param dmmTilerCtx - dmmTILERContCtxT* - [in] Tiler context instance. + * + * @param bufferMappedZone - dmmTILERContPageAreaT* - [in] Description of the 2D + * area that is mapped in the TILER container is provided in this structure. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmTILERContPageAreaT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_tiler_container_unmap_area( + struct dmmTILERContCtxT *dmmTilerCtx, + struct dmmTILERContPageAreaT *bufferMappedZone); + +/* ========================================================================== */ +/** + * dmm_tiler_get_area_from_sysptr() + * + * @brief Gets a 2D area descriptor from the Tiler system pointer. + * + * @param dmmTilerCtx - dmmTILERContCtxT* - [in] Tiler context instance. + * + * @param sysPtr - void * - [in] Tiler system pointer to a 2D area. + * + * @return dmmTILERContPageAreaT* Pointer to the 2D area descriptor, NULL if + * error is encountered during extraction. + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see dmmTILERContPageAreaT for further detail. + */ +/* ========================================================================== */ +struct dmmTILERContPageAreaT *dmm_tiler_get_area_from_sysptr( + struct dmmTILERContCtxT *dmmTilerCtx, void *sysPtr); + +/* ========================================================================== */ +/** + * dmmEventReport() + * + * @brief Signal events to the user modules (wrapper to the user supplied + * callback). + * + * @param dmmInstanceCtxPtr - void * - [in] Dmm context instance. + * + * @param mspEvent - MSP_EVENT_TYPE - [in] MSP event type. + * + * @param eData - void * - [in] MSP event data pointer. + * + * @return errorCodeT error if event can't be signaled. + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see dmmTILERContCtxT for further detail. + */ +/* ========================================================================== */ +/* enum errorCodeT dmmEventReport(void * dmmInstanceCtxPtr, + MSP_EVENT_TYPE mspEvent, void * eData); */ + +/* ========================================================================== */ +/** +* dmmPatIrqHandler() +* +* @brief Interrupt handler for PAT area status updates. +* +* @param data - UArg - +* +* @return none +* +* @pre There is no pre conditions. +* +* @post There is no post conditions. +* +* @see +* +*/ +/* ========================================================================== */ +/* Void dmmPatIrqHandler(UArg data); */ + +/* ========================================================================== */ +/** + * dmm_phys_page_rep_init() + * + * @brief Initializes the physical memory page repository instance. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_phys_page_rep_init(); + +/* ========================================================================== */ +/** + * dmmPhysPageRepDeinit() + * + * @brief Releases all resources held by the physical memory page repository + * instance. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT for further detail. + */ +/* ========================================================================== */ +/* enum errorCodeT dmmPhysPageRepDeinit(); */ + +/* ========================================================================== */ +/** + * dmm_get_phys_pages() + * + * @brief Return a pointer to a physical memory page and mark it as used. + * + * @return unsigned long* pointer to a physical memory page, NULL if error + * occurs. + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see + */ +/* ========================================================================== */ +unsigned long *dmm_get_phys_page(); + +/* ========================================================================== */ +/** + * dmm_free_phys_page() + * + * @brief Frees a specified physical memory page. + * + * @param physPgPtr - unsigned long* - [in] The address of the allocated + * physical page that should be freed. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_free_phys_page(unsigned long *physPgPtr); + +/* ========================================================================== */ +/** + * dmm_pat_phy2virt_mapping() + * + * @brief Mapping physical memory pages to virtual containers. + * + * @param bufferMappedZone - dmmTILERContPageAreaT* - [in] The tiled buffer + * descriptor. + * + * @param custmPagesPtr - void * - [in] Pointer to the custom supplied + * physical pages. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmTILERContPageAreaT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_pat_phy2virt_mapping( + struct dmmTILERContPageAreaT *bufferMappedZone, + void *custmPagesPtr); + +/* ========================================================================== */ +/** + * dmm_pat_start_refill() + * + * @brief Creates a PAT area descriptor and starts the refill. + * + * @param bufferMappedZone - dmmTILERContPageAreaT* - [in] The tiled buffer + * descriptor. + * + * @return errorCodeT + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see errorCodeT, dmmTILERContPageAreaT for further detail. + */ +/* ========================================================================== */ +enum errorCodeT dmm_pat_start_refill( + struct dmmTILERContPageAreaT *bufferMappedZone); + +/*--------function prototypes ---------------------------------*/ + +/* ========================================================================== */ +/** + * dmm_enter_critical_section() + * + * @brief Enter a critical code execution section. + * + * @return none + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see + */ +/* ========================================================================== */ +void dmm_enter_critical_section(); + +/* ========================================================================== */ +/** + * dmm_leave_critical_section() + * + * @brief Exit a critical code execution section. + * + * @return none + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see + */ +/* ========================================================================== */ +void dmm_leave_critical_section(); + +/* ========================================================================== */ +/** + * dmm_memory_size_alloc() + * + * @brief Allocates a physical memory page. + * + * @param pageNum - unsigned long - [in] Number of physical pages to allocate. + * + * @return void * pointer to the physical memory. + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see + */ +/* ========================================================================== */ +void *dmm_memory_size_alloc(unsigned long memSize); + +/* ========================================================================== */ +/** + * dmm_memory_page_alloc() + * + * @brief Allocates a physical memory page. + * + * @param pageNum - unsigned long - [in] Number of physical pages to allocate. + * + * @return void * pointer to the physical memory. + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see + */ +/* ========================================================================== */ +void *dmm_memory_page_alloc(unsigned long pageNum); + +/* ========================================================================== */ +/** + * dmm_memory_page_free() + * + * @brief Frees a physical memory page. + * + * @param pagePtr - void * - [in] Pointer to the physical pages to free. + * + * @return none + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see + */ +/* ========================================================================== */ +void dmm_memory_page_free(void *pagePtr); + +/* ========================================================================== */ +/** + * overlapping_test() + * + * @brief Performs an area overlap test for errors. Debug only. + * + * @param tlrCtx - dmmTILERContCtxT* - [in] TILER context structure. + * + * @return int: 1 if overlapping is detected. + * + * @pre There is no pre conditions. + * + * @post There is no post conditions. + * + * @see + */ +/* ========================================================================== */ +void overlapping_test(struct dmmTILERContCtxT *dmmTilerCtx); + +#endif /* _DMM_PRV_H */ + diff --git a/drivers/media/video/tiler/dmm_reg.h b/drivers/media/video/tiler/dmm_reg.h new file mode 100644 index 000000000000..9d974e6aa39e --- /dev/null +++ b/drivers/media/video/tiler/dmm_reg.h @@ -0,0 +1,29 @@ +/* + * dmm_reg.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_REG_H +#define DMM_REG_H + +#define BITS_32(in_NbBits) \ + ((((int)1 << in_NbBits) - 1) | ((int)1 << in_NbBits)) + +#define BITFIELD_32(in_UpBit, in_LowBit) \ + (BITS_32(in_UpBit) & ~((BITS_32(in_LowBit)) >> 1)) + +#define BITFIELD BITFIELD_32 + +extern unsigned long *dmmvabase; +#endif + diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index b91d66a767d7..3579a0a887ad 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c @@ -421,6 +421,8 @@ const char *v4l2_ctrl_get_name(u32 id) case V4L2_CID_CHROMA_AGC: return "Chroma AGC"; case V4L2_CID_COLOR_KILLER: return "Color Killer"; case V4L2_CID_COLORFX: return "Color Effects"; + case V4L2_CID_ROTATE: return "Rotate"; + case V4L2_CID_BG_COLOR: return "Background color"; /* MPEG controls */ case V4L2_CID_MPEG_CLASS: return "MPEG Encoder Controls"; @@ -546,6 +548,13 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; min = max = step = def = 0; break; + case V4L2_CID_BG_COLOR: + qctrl->type = V4L2_CTRL_TYPE_INTEGER; + step = 1; + min = 0; + /* Max is calculated as RGB888 that is 2^12*/ + max = 0xFFFFFF; + break; default: qctrl->type = V4L2_CTRL_TYPE_INTEGER; break; diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index be64a502ea27..df2611651151 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c @@ -277,6 +277,10 @@ static const char *v4l2_ioctls[] = { [_IOC_NR(VIDIOC_DBG_G_CHIP_IDENT)] = "VIDIOC_DBG_G_CHIP_IDENT", [_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK", + + [_IOC_NR(VIDIOC_S_COL_SPC_CONV)] = "VIDIOC_S_COL_SPC_CONV", + [_IOC_NR(VIDIOC_G_COL_SPC_CONV)] = "VIDIOC_G_COL_SPC_CONV", + #endif }; #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) @@ -1775,6 +1779,26 @@ static long __video_do_ioctl(struct file *file, break; } + /*---------------Color space conversion------------------------------*/ + case VIDIOC_S_COL_SPC_CONV: + { + struct v4l2_color_space_conversion *p = arg; + if (!ops->vidioc_s_color_space_conv) + break; + + ret = ops->vidioc_s_color_space_conv(file, fh, p); + break; + } + + case VIDIOC_G_COL_SPC_CONV: + { + struct v4l2_color_space_conversion *p = arg; + if (!ops->vidioc_g_color_space_conv) + break; + ret = ops->vidioc_g_color_space_conv(file, fh, p); + break; + } + default: { if (!ops->vidioc_default) diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 491ac0f800d2..3eec1ac2a48e 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -108,6 +108,19 @@ config TWL4030_CORE high speed USB OTG transceiver, an audio codec (on most versions) and many other features. +config TWL6030_CORE + bool "Texas Instruments TWL6030 Support" + depends on I2C=y && GENERIC_HARDIRQS + depends on !TWL4030_CORE + help + Say yes here if you have TWL6030 family chip on your board. + This core driver provides register access and IRQ handling + facilities, and registers devices for the various functions + so that function-specific drivers can bind to them. + + These multi-function chips are meant for OMAP4 processors, + providing power management, RTC, a USB transciever and a GPADC. + config MFD_TMIO bool default n diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 6f8a9a1af20b..17c533d83d8f 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -22,7 +22,8 @@ obj-$(CONFIG_MFD_WM8350_I2C) += wm8350-i2c.o obj-$(CONFIG_TPS65010) += tps65010.o obj-$(CONFIG_MENELAUS) += menelaus.o -obj-$(CONFIG_TWL4030_CORE) += twl4030-core.o twl4030-irq.o +obj-$(CONFIG_TWL4030_CORE) += twl-core.o twl4030-irq.o +obj-$(CONFIG_TWL6030_CORE) += twl-core.o twl6030-irq.o obj-$(CONFIG_MFD_CORE) += mfd-core.o diff --git a/drivers/mfd/twl4030-core.c b/drivers/mfd/twl-core.c index ca54996ffd0e..af4cf4726ac8 100644 --- a/drivers/mfd/twl4030-core.c +++ b/drivers/mfd/twl-core.c @@ -36,7 +36,7 @@ #include <linux/regulator/machine.h> #include <linux/i2c.h> -#include <linux/i2c/twl4030.h> +#include <linux/i2c/twl.h> #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) #include <mach/cpu.h> @@ -55,7 +55,7 @@ * (and associated registers). */ -#define DRIVER_NAME "twl4030" +#define DRIVER_NAME "twl" #if defined(CONFIG_TWL4030_BCI_BATTERY) || \ defined(CONFIG_TWL4030_BCI_BATTERY_MODULE) @@ -76,11 +76,18 @@ #define twl_has_gpio() false #endif -#if defined(CONFIG_REGULATOR_TWL4030) \ - || defined(CONFIG_REGULATOR_TWL4030_MODULE) -#define twl_has_regulator() true +#if defined(CONFIG_REGULATOR_TWL) \ + || defined(CONFIG_REGULATOR_TWL_MODULE) +#ifdef CONFIG_TWL4030_CORE +#define twl_has_4030regulator() true +#define twl_has_6030regulator() false +#elif CONFIG_TWL6030_CORE +#define twl_has_6030regulator() true +#define twl_has_4030regulator() false +#endif #else -#define twl_has_regulator() false +#define twl_has_4030regulator() false +#define twl_has_6030regulator() false #endif #if defined(CONFIG_TWL4030_MADC) || defined(CONFIG_TWL4030_MADC_MODULE) @@ -89,12 +96,18 @@ #define twl_has_madc() false #endif -#if defined(CONFIG_RTC_DRV_TWL4030) || defined(CONFIG_RTC_DRV_TWL4030_MODULE) +#if defined(CONFIG_RTC_DRV_TWL) || defined(CONFIG_RTC_DRV_TWL_MODULE) #define twl_has_rtc() true #else #define twl_has_rtc() false #endif +#if defined(CONFIG_TWL6030_CORE) /* FIXME add MMC CONFIG*/ +#define twl_has_mmc() true +#else +#define twl_has_mmc() false +#endif + #if defined(CONFIG_TWL4030_USB) || defined(CONFIG_TWL4030_USB_MODULE) #define twl_has_usb() true #else @@ -110,13 +123,27 @@ /* Triton Core internal information (BEGIN) */ -/* Last - for index max*/ -#define TWL4030_MODULE_LAST TWL4030_MODULE_SECURED_REG +#define TWL_NUM_SLAVES 4 + +#define SUB_CHIP_ID0 0 +#define SUB_CHIP_ID1 1 +#define SUB_CHIP_ID2 2 +#define SUB_CHIP_ID3 3 -#define TWL4030_NUM_SLAVES 4 +#ifdef CONFIG_TWL4030_CORE +#define USB_SUB_CHIP_ID SUB_CHIP_ID0 +#define GPIO_SUB_CHIP_ID SUB_CHIP_ID1 +#define MADC_SUB_CHIP_ID SUB_CHIP_ID2 +#define KEYPAD_SUB_CHIP_ID SUB_CHIP_ID2 +#define BCI_SUB_CHIP_ID SUB_CHIP_ID3 +#define RTC_SUB_CHIP_ID SUB_CHIP_ID3 +#define REG_SUB_CHIP_ID SUB_CHIP_ID3 +/* Last - for index max*/ +#define TWL4030_MODULE_LAST TWL4030_MODULE_SECURED_REG +#define TWL_MODULE_LAST TWL4030_MODULE_LAST -/* Base Address defns for twl4030_map[] */ +/* Base Address defns for twl_map[] */ /* subchip/slave 0 - USB ID */ #define TWL4030_BASEADD_USB 0x0000 @@ -147,10 +174,52 @@ #define TWL4030_BASEADD_PM_RECEIVER 0x005B #define TWL4030_BASEADD_RTC 0x001C #define TWL4030_BASEADD_SECURED_REG 0x0000 - +#endif /* CONFIG_TWL4030_CORE */ /* Triton Core internal information (END) */ +#ifdef CONFIG_TWL6030_CORE +#define TWL6030_MODULE_LAST TWL6030_MODULE_AUDIO +#define TWL_MODULE_LAST TWL6030_MODULE_LAST + +#define RTC_SUB_CHIP_ID SUB_CHIP_ID0 +#define REG_SUB_CHIP_ID SUB_CHIP_ID0 +#define MMC_SUB_CHIP_ID SUB_CHIP_ID0 +#define USB_SUB_CHIP_ID SUB_CHIP_ID1 +#define MADC_SUB_CHIP_ID SUB_CHIP_ID1 +#define BCI_SUB_CHIP_ID SUB_CHIP_ID1 +#define GPIO_SUB_CHIP_ID 0 /* NOT SUPPORTED IN TWL6030 */ +#define KEYPAD_SUB_CHIP_ID 0 /* ADDED FOR COMPILATION ONLY */ + +/* subchip/slave 0 0x48 - POWER */ +#define TWL6030_BASEADD_RTC 0x0000 +#define TWL6030_BASEADD_MEM 0x0017 +#define TWL6030_BASEADD_PM_MASTER 0x001F +#define TWL6030_BASEADD_PM_SLAVE_MISC 0x0030 +#define TWL6030_BASEADD_PM_SLAVE_SMPS 0x0040 +#define TWL6030_BASEADD_PM_SLAVE_LDO 0x0080 +#define TWL6030_BASEADD_PM_SLAVE_RES 0x00AD +#define TWL6030_BASEADD_PM_MISC 0x00E2 +#define TWL6030_BASEADD_PM_PUPD 0x00F0 + +/* subchip/slave 1 0x49 - FEATURE */ +#define TWL6030_BASEADD_USB 0x0000 +#define TWL6030_BASEADD_GPADC_CTRL 0x0030 +#define TWL6030_BASEADD_GPADC_RT 0x0035 +#define TWL6030_BASEADD_GPADC 0x005D +#define TWL6030_BASEADD_AUX 0x0090 +#define TWL6030_BASEADD_PWM 0x00BA +#define TWL6030_BASEADD_GASGAUGE 0x00C0 +#define TWL6030_BASEADD_PIH 0x00D0 +#define TWL6030_BASEADD_CHARGER 0x00E0 + +/* subchip/slave 2 0x4A - DFT */ +#define TWL6030_BASEADD_DIEID 0x00C0 + +/* subchip/slave 3 0x4B - AUDIO */ +#define TWL6030_BASEADD_AUDIO 0x0000 +#endif /* CONFIG_TWL6030_CORE */ + /* Few power values */ #define R_CFG_BOOT 0x05 #define R_PROTECT_KEY 0x0E @@ -176,8 +245,8 @@ /* is driver active, bound to a chip? */ static bool inuse; -/* Structure for each TWL4030 Slave */ -struct twl4030_client { +/* Structure for each TWL4030/TWL6030 Slave */ +struct twl_client { struct i2c_client *client; u8 address; @@ -188,16 +257,17 @@ struct twl4030_client { struct mutex xfer_lock; }; -static struct twl4030_client twl4030_modules[TWL4030_NUM_SLAVES]; +static struct twl_client twl_modules[TWL_NUM_SLAVES]; /* mapping the module id to slave id and base address */ -struct twl4030mapping { +struct twl_mapping { unsigned char sid; /* Slave ID */ unsigned char base; /* base address */ }; -static struct twl4030mapping twl4030_map[TWL4030_MODULE_LAST + 1] = { +#ifdef CONFIG_TWL4030_CORE +static struct twl_mapping twl_map[TWL4030_MODULE_LAST + 1] = { /* * NOTE: don't change this table without updating the * <linux/i2c/twl4030.h> defines for TWL4030_MODULE_* @@ -230,13 +300,47 @@ static struct twl4030mapping twl4030_map[TWL4030_MODULE_LAST + 1] = { { 3, TWL4030_BASEADD_RTC }, { 3, TWL4030_BASEADD_SECURED_REG }, }; +#endif + +#ifdef CONFIG_TWL6030_CORE +static struct twl_mapping twl_map[TWL6030_MODULE_LAST + 1] = { + /* + * NOTE: don't change this table without updating the + * <linux/i2c/twl6030.h> defines for TWL6030_MODULE_* + * so they continue to match the order in this table. + */ + { SUB_CHIP_ID0, TWL6030_BASEADD_RTC }, + { SUB_CHIP_ID0, TWL6030_BASEADD_MEM }, + { SUB_CHIP_ID0, TWL6030_BASEADD_PM_MASTER }, + { SUB_CHIP_ID0, TWL6030_BASEADD_PM_SLAVE_MISC }, + { SUB_CHIP_ID0, TWL6030_BASEADD_PM_SLAVE_SMPS }, + { SUB_CHIP_ID0, TWL6030_BASEADD_PM_SLAVE_LDO }, + { SUB_CHIP_ID0, TWL6030_BASEADD_PM_SLAVE_RES }, + { SUB_CHIP_ID0, TWL6030_BASEADD_PM_MISC }, + { SUB_CHIP_ID0, TWL6030_BASEADD_PM_PUPD }, + + { SUB_CHIP_ID1, TWL6030_BASEADD_USB }, + { SUB_CHIP_ID1, TWL6030_BASEADD_GPADC_CTRL }, + { SUB_CHIP_ID1, TWL6030_BASEADD_GPADC_RT }, + { SUB_CHIP_ID1, TWL6030_BASEADD_GPADC }, + { SUB_CHIP_ID1, TWL6030_BASEADD_AUX }, + { SUB_CHIP_ID1, TWL6030_BASEADD_PWM }, + { SUB_CHIP_ID1, TWL6030_BASEADD_GASGAUGE }, + { SUB_CHIP_ID1, TWL6030_BASEADD_PIH }, + { SUB_CHIP_ID1, TWL6030_BASEADD_CHARGER }, + + { SUB_CHIP_ID2, TWL6030_BASEADD_DIEID }, + + { SUB_CHIP_ID3, TWL6030_BASEADD_AUDIO }, +}; +#endif /*----------------------------------------------------------------------*/ /* Exported Functions */ /** - * twl4030_i2c_write - Writes a n bit register in TWL4030 + * twl_i2c_write - Writes a n bit register in TWL4030/TWL6030 * @mod_no: module number * @value: an array of num_bytes+1 containing data to write * @reg: register address (just offset will do) @@ -247,19 +351,19 @@ static struct twl4030mapping twl4030_map[TWL4030_MODULE_LAST + 1] = { * * Returns the result of operation - 0 is success */ -int twl4030_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) +int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) { int ret; int sid; - struct twl4030_client *twl; + struct twl_client *twl; struct i2c_msg *msg; - if (unlikely(mod_no > TWL4030_MODULE_LAST)) { + if (unlikely(mod_no > TWL_MODULE_LAST)) { pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no); return -EPERM; } - sid = twl4030_map[mod_no].sid; - twl = &twl4030_modules[sid]; + sid = twl_map[mod_no].sid; + twl = &twl_modules[sid]; if (unlikely(!inuse)) { pr_err("%s: client %d is not initialized\n", DRIVER_NAME, sid); @@ -276,7 +380,7 @@ int twl4030_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) msg->flags = 0; msg->buf = value; /* over write the first byte of buffer with the register address */ - *value = twl4030_map[mod_no].base + reg; + *value = twl_map[mod_no].base + reg; ret = i2c_transfer(twl->client->adapter, twl->xfer_msg, 1); mutex_unlock(&twl->xfer_lock); @@ -285,10 +389,10 @@ int twl4030_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) ret = 0; return ret; } -EXPORT_SYMBOL(twl4030_i2c_write); +EXPORT_SYMBOL(twl_i2c_write); /** - * twl4030_i2c_read - Reads a n bit register in TWL4030 + * twl_i2c_read - Reads a n bit register in TWL4030/TWL6030 * @mod_no: module number * @value: an array of num_bytes containing data to be read * @reg: register address (just offset will do) @@ -296,20 +400,20 @@ EXPORT_SYMBOL(twl4030_i2c_write); * * Returns result of operation - num_bytes is success else failure. */ -int twl4030_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) +int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) { int ret; u8 val; int sid; - struct twl4030_client *twl; + struct twl_client *twl; struct i2c_msg *msg; - if (unlikely(mod_no > TWL4030_MODULE_LAST)) { + if (unlikely(mod_no > TWL_MODULE_LAST)) { pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no); return -EPERM; } - sid = twl4030_map[mod_no].sid; - twl = &twl4030_modules[sid]; + sid = twl_map[mod_no].sid; + twl = &twl_modules[sid]; if (unlikely(!inuse)) { pr_err("%s: client %d is not initialized\n", DRIVER_NAME, sid); @@ -321,7 +425,7 @@ int twl4030_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) msg->addr = twl->address; msg->len = 1; msg->flags = 0; /* Read the register value */ - val = twl4030_map[mod_no].base + reg; + val = twl_map[mod_no].base + reg; msg->buf = &val; /* [MSG2] fill the data rx buffer */ msg = &twl->xfer_msg[1]; @@ -337,40 +441,40 @@ int twl4030_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) ret = 0; return ret; } -EXPORT_SYMBOL(twl4030_i2c_read); +EXPORT_SYMBOL(twl_i2c_read); /** - * twl4030_i2c_write_u8 - Writes a 8 bit register in TWL4030 + * twl_i2c_write_u8 - Writes a 8 bit register in TWL4030/TWL6030 * @mod_no: module number * @value: the value to be written 8 bit * @reg: register address (just offset will do) * * Returns result of operation - 0 is success */ -int twl4030_i2c_write_u8(u8 mod_no, u8 value, u8 reg) +int twl_i2c_write_u8(u8 mod_no, u8 value, u8 reg) { /* 2 bytes offset 1 contains the data offset 0 is used by i2c_write */ u8 temp_buffer[2] = { 0 }; /* offset 1 contains the data */ temp_buffer[1] = value; - return twl4030_i2c_write(mod_no, temp_buffer, reg, 1); + return twl_i2c_write(mod_no, temp_buffer, reg, 1); } -EXPORT_SYMBOL(twl4030_i2c_write_u8); +EXPORT_SYMBOL(twl_i2c_write_u8); /** - * twl4030_i2c_read_u8 - Reads a 8 bit register from TWL4030 + * twl_i2c_read_u8 - Reads a 8 bit register from TWL4030/TWL6030 * @mod_no: module number * @value: the value read 8 bit * @reg: register address (just offset will do) * * Returns result of operation - 0 is success */ -int twl4030_i2c_read_u8(u8 mod_no, u8 *value, u8 reg) +int twl_i2c_read_u8(u8 mod_no, u8 *value, u8 reg) { - return twl4030_i2c_read(mod_no, value, reg, 1); + return twl_i2c_read(mod_no, value, reg, 1); } -EXPORT_SYMBOL(twl4030_i2c_read_u8); +EXPORT_SYMBOL(twl_i2c_read_u8); /*----------------------------------------------------------------------*/ @@ -380,7 +484,7 @@ add_numbered_child(unsigned chip, const char *name, int num, bool can_wakeup, int irq0, int irq1) { struct platform_device *pdev; - struct twl4030_client *twl = &twl4030_modules[chip]; + struct twl_client *twl = &twl_modules[chip]; int status; pdev = platform_device_alloc(name, num); @@ -448,7 +552,7 @@ add_regulator_linked(int num, struct regulator_init_data *pdata, } /* NOTE: we currently ignore regulator IRQs, e.g. for short circuits */ - return add_numbered_child(3, "twl4030_reg", num, + return add_numbered_child(REG_SUB_CHIP_ID, "twl_reg", num, pdata, sizeof(*pdata), false, 0, 0); } @@ -465,41 +569,42 @@ add_regulator(int num, struct regulator_init_data *pdata) */ static int -add_children(struct twl4030_platform_data *pdata, unsigned long features) +add_children(struct twl_platform_data *pdata, unsigned long features) { struct device *child; struct device *usb_transceiver = NULL; if (twl_has_bci() && pdata->bci && !(features & TPS_SUBSET)) { - child = add_child(3, "twl4030_bci", + child = add_child(BCI_SUB_CHIP_ID, "twl4030_bci", pdata->bci, sizeof(*pdata->bci), false, /* irq0 = CHG_PRES, irq1 = BCI */ - pdata->irq_base + 8 + 1, pdata->irq_base + 2); + pdata->irq_base + BCI_PRES_INTR_OFFSET, + pdata->irq_base + BCI_INTR_OFFSET); if (IS_ERR(child)) return PTR_ERR(child); } if (twl_has_gpio() && pdata->gpio) { - child = add_child(1, "twl4030_gpio", + child = add_child(GPIO_SUB_CHIP_ID, "twl4030_gpio", pdata->gpio, sizeof(*pdata->gpio), - false, pdata->irq_base + 0, 0); + false, pdata->irq_base + GPIO_INTR_OFFSET, 0); if (IS_ERR(child)) return PTR_ERR(child); } if (twl_has_keypad() && pdata->keypad) { - child = add_child(2, "twl4030_keypad", + child = add_child(KEYPAD_SUB_CHIP_ID, "twl4030_keypad", pdata->keypad, sizeof(*pdata->keypad), - true, pdata->irq_base + 1, 0); + true, pdata->irq_base + KEYPAD_INTR_OFFSET, 0); if (IS_ERR(child)) return PTR_ERR(child); } if (twl_has_madc() && pdata->madc) { - child = add_child(2, "twl4030_madc", + child = add_child(MADC_SUB_CHIP_ID, "twl4030_madc", pdata->madc, sizeof(*pdata->madc), - true, pdata->irq_base + 3, 0); + true, pdata->irq_base + MADC_INTR_OFFSET, 0); if (IS_ERR(child)) return PTR_ERR(child); } @@ -512,19 +617,30 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) * Eventually, Linux might become more aware of such * HW security concerns, and "least privilege". */ - child = add_child(3, "twl4030_rtc", + child = add_child(RTC_SUB_CHIP_ID, "twl_rtc", NULL, 0, - true, pdata->irq_base + 8 + 3, 0); + true, pdata->irq_base + RTC_INTR_OFFSET, 0); + if (IS_ERR(child)) + return PTR_ERR(child); + } + +#ifdef CONFIG_TWL6030_CORE + if (twl_has_mmc()) { + child = add_child(MMC_SUB_CHIP_ID, "twl_mmc", + NULL, 0, true, + pdata->irq_base + MMCDETECT_INTR_OFFSET, 0); if (IS_ERR(child)) return PTR_ERR(child); } +#endif if (twl_has_usb() && pdata->usb) { - child = add_child(0, "twl4030_usb", + child = add_child(USB_SUB_CHIP_ID, "twl4030_usb", pdata->usb, sizeof(*pdata->usb), true, /* irq0 = USB_PRES, irq1 = USB */ - pdata->irq_base + 8 + 2, pdata->irq_base + 4); + pdata->irq_base + USB_PRES_INTR_OFFSET, + pdata->irq_base + USB_INTR_OFFSET); if (IS_ERR(child)) return PTR_ERR(child); @@ -538,7 +654,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) return PTR_ERR(child); } - if (twl_has_regulator()) { + if (twl_has_4030regulator()) { /* child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1); if (IS_ERR(child)) @@ -561,7 +677,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) return PTR_ERR(child); } - if (twl_has_regulator() && usb_transceiver) { + if (twl_has_4030regulator() && usb_transceiver) { static struct regulator_consumer_supply usb1v5 = { .supply = "usb1v5", }; @@ -603,7 +719,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) } /* maybe add LDOs that are omitted on cost-reduced parts */ - if (twl_has_regulator() && !(features & TPS_SUBSET)) { + if (twl_has_4030regulator() && !(features & TPS_SUBSET)) { child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2); if (IS_ERR(child)) return PTR_ERR(child); @@ -629,6 +745,49 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) return PTR_ERR(child); } + /* twl6030 regulators */ + if (twl_has_6030regulator()) { + child = add_regulator(TWL6030_REG_VMMC, pdata->vmmc); + if (IS_ERR(child)) + return PTR_ERR(child); + + child = add_regulator(TWL6030_REG_VPP, pdata->vpp); + if (IS_ERR(child)) + return PTR_ERR(child); + + child = add_regulator(TWL6030_REG_VUSIM, pdata->vusim); + if (IS_ERR(child)) + return PTR_ERR(child); + + child = add_regulator(TWL6030_REG_VANA, pdata->vana); + if (IS_ERR(child)) + return PTR_ERR(child); + + child = add_regulator(TWL6030_REG_VCXIO, pdata->vcxio); + if (IS_ERR(child)) + return PTR_ERR(child); + + child = add_regulator(TWL6030_REG_VDAC, pdata->vdac); + if (IS_ERR(child)) + return PTR_ERR(child); + + child = add_regulator(TWL6030_REG_VUSB, pdata->vusb); + if (IS_ERR(child)) + return PTR_ERR(child); + + child = add_regulator(TWL6030_REG_VAUX1_6030, pdata->vaux1); + if (IS_ERR(child)) + return PTR_ERR(child); + + child = add_regulator(TWL6030_REG_VAUX2_6030, pdata->vaux2); + if (IS_ERR(child)) + return PTR_ERR(child); + + child = add_regulator(TWL6030_REG_VAUX3_6030, pdata->vaux3); + if (IS_ERR(child)) + return PTR_ERR(child); + } + return 0; } @@ -643,7 +802,7 @@ static inline int __init protect_pm_master(void) { int e = 0; - e = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, KEY_LOCK, + e = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, KEY_LOCK, R_PROTECT_KEY); return e; } @@ -652,9 +811,9 @@ static inline int __init unprotect_pm_master(void) { int e = 0; - e |= twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, KEY_UNLOCK1, + e |= twl_i2c_write_u8(TWL_MODULE_PM_MASTER, KEY_UNLOCK1, R_PROTECT_KEY); - e |= twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, KEY_UNLOCK2, + e |= twl_i2c_write_u8(TWL_MODULE_PM_MASTER, KEY_UNLOCK2, R_PROTECT_KEY); return e; } @@ -673,7 +832,7 @@ static void clocks_init(struct device *dev) osc = clk_get(dev, "osc_sys_ck"); if (IS_ERR(osc)) { - printk(KERN_WARNING "Skipping twl4030 internal clock init and " + printk(KERN_WARNING "Skipping twl internal clock init and " "using bootloader value (unknown osc rate)\n"); return; } @@ -687,7 +846,7 @@ static void clocks_init(struct device *dev) */ osc = ERR_PTR(-EIO); - printk(KERN_WARNING "Skipping twl4030 internal clock init and " + printk(KERN_WARNING "Skipping twl internal clock init and " "using bootloader value (unknown osc rate)\n"); return; @@ -708,7 +867,7 @@ static void clocks_init(struct device *dev) ctrl |= HIGH_PERF_SQ; e |= unprotect_pm_master(); /* effect->MADC+USB ck en */ - e |= twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, ctrl, R_CFG_BOOT); + e |= twl_i2c_write_u8(TWL_MODULE_PM_MASTER, ctrl, R_CFG_BOOT); e |= protect_pm_master(); if (e < 0) @@ -717,10 +876,7 @@ static void clocks_init(struct device *dev) /*----------------------------------------------------------------------*/ -int twl_init_irq(int irq_num, unsigned irq_base, unsigned irq_end); -int twl_exit_irq(void); - -static int twl4030_remove(struct i2c_client *client) +static int twl_remove(struct i2c_client *client) { unsigned i; int status; @@ -729,12 +885,12 @@ static int twl4030_remove(struct i2c_client *client) if (status < 0) return status; - for (i = 0; i < TWL4030_NUM_SLAVES; i++) { - struct twl4030_client *twl = &twl4030_modules[i]; + for (i = 0; i < TWL_NUM_SLAVES; i++) { + struct twl_client *twl = &twl_modules[i]; if (twl->client && twl->client != client) i2c_unregister_device(twl->client); - twl4030_modules[i].client = NULL; + twl_modules[i].client = NULL; } inuse = false; return 0; @@ -742,11 +898,11 @@ static int twl4030_remove(struct i2c_client *client) /* NOTE: this driver only handles a single twl4030/tps659x0 chip */ static int -twl4030_probe(struct i2c_client *client, const struct i2c_device_id *id) +twl_probe(struct i2c_client *client, const struct i2c_device_id *id) { int status; unsigned i; - struct twl4030_platform_data *pdata = client->dev.platform_data; + struct twl_platform_data *pdata = client->dev.platform_data; if (!pdata) { dev_dbg(&client->dev, "no platform data?\n"); @@ -763,8 +919,8 @@ twl4030_probe(struct i2c_client *client, const struct i2c_device_id *id) return -EBUSY; } - for (i = 0; i < TWL4030_NUM_SLAVES; i++) { - struct twl4030_client *twl = &twl4030_modules[i]; + for (i = 0; i < TWL_NUM_SLAVES; i++) { + struct twl_client *twl = &twl_modules[i]; twl->address = client->addr + i; if (i == 0) @@ -792,7 +948,8 @@ twl4030_probe(struct i2c_client *client, const struct i2c_device_id *id) if (client->irq && pdata->irq_base && pdata->irq_end > pdata->irq_base) { - status = twl_init_irq(client->irq, pdata->irq_base, pdata->irq_end); + status = twl_init_irq(client->irq, pdata->irq_base, + pdata->irq_end); if (status < 0) goto fail; } @@ -800,40 +957,41 @@ twl4030_probe(struct i2c_client *client, const struct i2c_device_id *id) status = add_children(pdata, id->driver_data); fail: if (status < 0) - twl4030_remove(client); + twl_remove(client); return status; } -static const struct i2c_device_id twl4030_ids[] = { +static const struct i2c_device_id twl_ids[] = { { "twl4030", TWL4030_VAUX2 }, /* "Triton 2" */ { "twl5030", 0 }, /* T2 updated */ { "tps65950", 0 }, /* catalog version of twl5030 */ { "tps65930", TPS_SUBSET }, /* fewer LDOs and DACs; no charger */ { "tps65920", TPS_SUBSET }, /* fewer LDOs; no codec or charger */ + { "twl6030", 0 }, /* "Phoenix power chip" */ { /* end of list */ }, }; -MODULE_DEVICE_TABLE(i2c, twl4030_ids); +MODULE_DEVICE_TABLE(i2c, twl_ids); /* One Client Driver , 4 Clients */ -static struct i2c_driver twl4030_driver = { +static struct i2c_driver twl_driver = { .driver.name = DRIVER_NAME, - .id_table = twl4030_ids, - .probe = twl4030_probe, - .remove = twl4030_remove, + .id_table = twl_ids, + .probe = twl_probe, + .remove = twl_remove, }; -static int __init twl4030_init(void) +static int __init twl_init(void) { - return i2c_add_driver(&twl4030_driver); + return i2c_add_driver(&twl_driver); } -subsys_initcall(twl4030_init); +subsys_initcall(twl_init); -static void __exit twl4030_exit(void) +static void __exit twl_exit(void) { - i2c_del_driver(&twl4030_driver); + i2c_del_driver(&twl_driver); } -module_exit(twl4030_exit); +module_exit(twl_exit); MODULE_AUTHOR("Texas Instruments, Inc."); -MODULE_DESCRIPTION("I2C Core interface for TWL4030"); +MODULE_DESCRIPTION("I2C Core interface for TWL"); MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c index bae61b22501c..6e55da46a336 100644 --- a/drivers/mfd/twl4030-irq.c +++ b/drivers/mfd/twl4030-irq.c @@ -32,7 +32,7 @@ #include <linux/irq.h> #include <linux/kthread.h> -#include <linux/i2c/twl4030.h> +#include <linux/i2c/twl.h> /* @@ -199,7 +199,7 @@ static int twl4030_irq_thread(void *data) /* Wait for IRQ, then read PIH irq status (also blocking) */ wait_for_completion_interruptible(&irq_event); - ret = twl4030_i2c_read_u8(TWL4030_MODULE_PIH, &pih_isr, + ret = twl_i2c_read_u8(TWL4030_MODULE_PIH, &pih_isr, REG_PIH_ISR_P1); if (ret) { pr_warning("twl4030: I2C error %d reading PIH ISR\n", @@ -307,7 +307,7 @@ static int twl4030_init_sih_modules(unsigned line) if (!sih->bytes_ixr) continue; - status = twl4030_i2c_write(sih->module, buf, + status = twl_i2c_write(sih->module, buf, sih->mask[line].imr_offset, sih->bytes_ixr); if (status < 0) pr_err("twl4030: err %d initializing %s %s\n", @@ -321,7 +321,7 @@ static int twl4030_init_sih_modules(unsigned line) * And for PWR_INT it's not documented... */ if (sih->set_cor) { - status = twl4030_i2c_write_u8(sih->module, + status = twl_i2c_write_u8(sih->module, TWL4030_SIH_CTRL_COR_MASK, sih->control_offset); if (status < 0) @@ -345,14 +345,14 @@ static int twl4030_init_sih_modules(unsigned line) * uncommon with PWR_INT.PWRON. */ for (j = 0; j < 2; j++) { - status = twl4030_i2c_read(sih->module, rxbuf, + status = twl_i2c_read(sih->module, rxbuf, sih->mask[line].isr_offset, sih->bytes_ixr); if (status < 0) pr_err("twl4030: err %d initializing %s %s\n", status, sih->name, "ISR"); if (!sih->set_cor) - status = twl4030_i2c_write(sih->module, buf, + status = twl_i2c_write(sih->module, buf, sih->mask[line].isr_offset, sih->bytes_ixr); /* else COR=1 means read sufficed. @@ -421,7 +421,7 @@ static void twl4030_sih_do_mask(struct work_struct *work) return; /* write the whole mask ... simpler than subsetting it */ - status = twl4030_i2c_write(sih->module, imr.bytes, + status = twl_i2c_write(sih->module, imr.bytes, sih->mask[irq_line].imr_offset, sih->bytes_ixr); if (status) pr_err("twl4030: %s, %s --> %d\n", __func__, @@ -452,7 +452,7 @@ static void twl4030_sih_do_edge(struct work_struct *work) * any processor on the other IRQ line, EDR registers are * shared. */ - status = twl4030_i2c_read(sih->module, bytes + 1, + status = twl_i2c_read(sih->module, bytes + 1, sih->edr_offset, sih->bytes_edr); if (status) { pr_err("twl4030: %s, %s --> %d\n", __func__, @@ -486,7 +486,7 @@ static void twl4030_sih_do_edge(struct work_struct *work) } /* Write */ - status = twl4030_i2c_write(sih->module, bytes, + status = twl_i2c_write(sih->module, bytes, sih->edr_offset, sih->bytes_edr); if (status) pr_err("twl4030: %s, %s --> %d\n", __func__, @@ -571,7 +571,7 @@ static inline int sih_read_isr(const struct sih *sih) /* FIXME need retry-on-error ... */ isr.word = 0; - status = twl4030_i2c_read(sih->module, isr.bytes, + status = twl_i2c_read(sih->module, isr.bytes, sih->mask[irq_line].isr_offset, sih->bytes_ixr); return (status < 0) ? status : le32_to_cpu(isr.word); diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c new file mode 100644 index 000000000000..6738f17938b9 --- /dev/null +++ b/drivers/mfd/twl6030-irq.c @@ -0,0 +1,303 @@ +/* + * twl6030-irq.c - TWL6030 irq support + * + * Copyright (C) 2005-2009 Texas Instruments, Inc. + * + * Modifications to defer interrupt handling to a kernel thread: + * Copyright (C) 2006 MontaVista Software, Inc. + * + * Based on tlv320aic23.c: + * Copyright (c) by Kai Svahn <kai.svahn@nokia.com> + * + * Code cleanup and modifications to IRQ handler. + * by syed khasim <x0khasim@ti.com> + * + * TWL6030 specific code and IRQ handling changes by + * Jagadeesh Bhaskar Pakaravoor <j-pakaravoor@ti.com> + * Balaji T K <balajitk@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/init.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/kthread.h> +#include <linux/i2c/twl.h> + +/* + * TWL6030 (unlike its predecessors, which had two level interrupt handling) + * three interrupt registers INT_STS_A, INT_STS_B and INT_STS_C. + * It exposes status bits saying who has raised an interrupt. There are + * three mask registers that corresponds to these status registers, that + * enables/disables these interrupts. + * + * We set up IRQs starting at a platform-specified base. An interrupt map table, + * specifies mapping between interrupt number and the associated module. + * + */ + +static int twl6030_interrupt_mapping[24] = { + PWR_INTR_OFFSET, /* Bit 0 PWRON */ + PWR_INTR_OFFSET, /* Bit 1 RPWRON */ + PWR_INTR_OFFSET, /* Bit 2 BAT_VLOW */ + PWR_INTR_OFFSET, /* Bit 3 VBAT */ + RTC_INTR_OFFSET, /* Bit 4 RTC_ALARM */ + RTC_INTR_OFFSET, /* Bit 5 RTC_PERIOD */ + HOTDIE_INTR_OFFSET, /* Bit 6 HOT_DIE */ + SMPSLDO_INTR_OFFSET, /* Bit 7 VXXX_SHORT */ + + SMPSLDO_INTR_OFFSET, /* Bit 8 VMMC_SHORT */ + SMPSLDO_INTR_OFFSET, /* Bit 9 VUSIM_SHORT */ + SIMDETECT_INTR_OFFSET, /* Bit 10 SIM */ + MMCDETECT_INTR_OFFSET, /* Bit 11 MMC */ + RSV_INTR_OFFSET, /* Bit 12 Reserved */ + GPADC_INTR_OFFSET, /* Bit 13 GPADC_RT_EOC */ + GPADC_INTR_OFFSET, /* Bit 14 GPADC_SW_EOC */ + GASGAUGE_INTR_OFFSET, /* Bit 15 CC_AUTOCAL */ + + USBOTG_INTR_OFFSET, /* Bit 16 ID_WKUP */ + USBOTG_INTR_OFFSET, /* Bit 17 VBUS_WKUP */ + USBOTG_INTR_OFFSET, /* Bit 18 ID */ + USBOTG_INTR_OFFSET, /* Bit 19 VBUS */ + CHARGER_INTR_OFFSET, /* Bit 20 CHRG_CTRL */ + CHARGER_INTR_OFFSET, /* Bit 21 EXT_CHRG */ + CHARGER_INTR_OFFSET, /* Bit 22 INT_CHRG */ + CHARGER_INTR_OFFSET, /* Bit 23 BAT_OVT */ +}; +/*----------------------------------------------------------------------*/ + +static unsigned twl6030_irq_base; + +static struct completion irq_event; + +/* + * This thread processes interrupts reported by the Primary Interrupt Handler. + */ +static int twl6030_irq_thread(void *data) +{ + long irq = (long)data; + static unsigned i2c_errors; + static const unsigned max_i2c_errors = 100; + int ret; + + current->flags |= PF_NOFREEZE; + + while (!kthread_should_stop()) { + int i; + union { + u8 bytes[4]; + u32 int_sts; + } sts; + + /* Wait for IRQ, then read PIH irq status (also blocking) */ + wait_for_completion_interruptible(&irq_event); + + /* read INT_STS_A, B and C in one shot using a burst read */ + ret = twl_i2c_read(TWL6030_MODULE_PIH, sts.bytes, + REG_INT_STS_A, 3); + if (ret) { + pr_warning("twl6030: I2C error %d reading PIH ISR\n", + ret); + if (++i2c_errors >= max_i2c_errors) { + printk(KERN_ERR "Maximum I2C error count" + " exceeded. Terminating %s.\n", + __func__); + break; + } + complete(&irq_event); + continue; + } + + + + sts.bytes[3] = 0; /* Only 24 bits are valid*/ + + for (i = 0; sts.int_sts; sts.int_sts >>= 1, i++) { + local_irq_disable(); + if (sts.int_sts & 0x1) { + int module_irq = TWL6030_IRQ_BASE + + twl6030_interrupt_mapping[i]; + struct irq_desc *d = irq_to_desc(module_irq); + + if (!d) { + pr_err("twl6030: Invalid SIH IRQ: %d\n", + module_irq); + return -EINVAL; + } + + /* These can't be masked ... always warn + * if we get any surprises. + */ + if (d->status & IRQ_DISABLED) + note_interrupt(module_irq, d, + IRQ_NONE); + else + d->handle_irq(module_irq, d); + + } + local_irq_enable(); + } + ret = twl_i2c_write(TWL6030_MODULE_PIH, sts.bytes, + REG_INT_STS_A, 3); /* clear INT_STS_A */ + if (ret) + pr_warning("twl6030: I2C error in clearing PIH ISR\n"); + + enable_irq(irq); + } + + return 0; +} + +/* + * handle_twl6030_int() is the desc->handle method for the twl6030 interrupt. + * This is a chained interrupt, so there is no desc->action method for it. + * Now we need to query the interrupt controller in the twl6030 to determine + * which module is generating the interrupt request. However, we can't do i2c + * transactions in interrupt context, so we must defer that work to a kernel + * thread. All we do here is acknowledge and mask the interrupt and wakeup + * the kernel thread. + */ +static irqreturn_t handle_twl6030_pih(int irq, void *devid) +{ + disable_irq_nosync(irq); + complete(devid); + return IRQ_HANDLED; +} + +/*----------------------------------------------------------------------*/ + +static inline void activate_irq(int irq) +{ +#ifdef CONFIG_ARM + /* ARM requires an extra step to clear IRQ_NOREQUEST, which it + * sets on behalf of every irq_chip. Also sets IRQ_NOPROBE. + */ + set_irq_flags(irq, IRQF_VALID); +#else + /* same effect on other architectures */ + set_irq_noprobe(irq); +#endif +} + +/*----------------------------------------------------------------------*/ + +static unsigned twl6030_irq_next; + +/*----------------------------------------------------------------------*/ +int twl_int_mask_reset(u8 bit_mask, u8 offset) +{ + int ret; + u8 unmask_value; + ret = twl_i2c_read_u8(TWL6030_MODULE_PIH, &unmask_value, + REG_INT_STS_A + offset); + unmask_value &= (~(bit_mask)); + ret |= twl_i2c_write_u8(TWL6030_MODULE_PIH, unmask_value, + REG_INT_STS_A + offset); /* unmask INT_MSK_A/B/C */ + return ret; +} + +int twl_int_mask_set(u8 bit_mask, u8 offset) +{ + int ret; + u8 mask_value; + ret = twl_i2c_read_u8(TWL6030_MODULE_PIH, &mask_value, + REG_INT_STS_A + offset); + mask_value |= (bit_mask); + ret |= twl_i2c_write_u8(TWL6030_MODULE_PIH, mask_value, + REG_INT_STS_A + offset); /* mask INT_MSK_A/B/C */ + return ret; +} + +int twl_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) +{ + + int status = 0; + int i; + struct task_struct *task; + int ret; + u8 mask[4]; + + static struct irq_chip twl6030_irq_chip; + mask[1] = 0xFF; + mask[2] = 0xFF; + mask[3] = 0xFF; + ret = twl_i2c_write(TWL6030_MODULE_PIH, &mask[0], + REG_INT_MSK_LINE_A, 3); /* MASK ALL INT LINES*/ + + mask[1] = 0; + mask[2] = 0; + mask[3] = 0; + ret = twl_i2c_write(TWL6030_MODULE_PIH, &mask[0], + REG_INT_STS_A, 3); /* clear INT_STS_A,B,C */ + + ret |= twl_int_mask_reset(TWL6030_RTC_INT_MASK, REG_INT_MSK_LINE_A); + ret |= twl_int_mask_reset(TWL6030_MMCDETECT_INT_MASK, \ + REG_INT_MSK_LINE_B); + + twl6030_irq_base = irq_base; + + /* install an irq handler for each of the modules; + * clone dummy irq_chip since PIH can't *do* anything + */ + twl6030_irq_chip = dummy_irq_chip; + twl6030_irq_chip.name = "twl6030"; + twl6030_irq_chip.set_type = NULL; + + for (i = irq_base; i < irq_end; i++) { + set_irq_chip_and_handler(i, &twl6030_irq_chip, + handle_simple_irq); + activate_irq(i); + } + + twl6030_irq_next = i; + pr_info("twl6030: %s (irq %d) chaining IRQs %d..%d\n", "PIH", + irq_num, irq_base, twl6030_irq_next - 1); + + /* install an irq handler to demultiplex the TWL6030 interrupt */ + init_completion(&irq_event); + task = kthread_run(twl6030_irq_thread, (void *)irq_num, "twl6030-irq"); + if (IS_ERR(task)) { + pr_err("twl6030: could not create irq %d thread!\n", irq_num); + status = PTR_ERR(task); + goto fail_kthread; + } + + status = request_irq(irq_num, handle_twl6030_pih, IRQF_DISABLED, + "TWL6030-PIH", &irq_event); + if (status < 0) { + pr_err("twl6030: could not claim irq%d: %d\n", irq_num, status); + goto fail; + } + return status; +fail_kthread: + free_irq(irq_num, &irq_event); + +fail: + for (i = irq_base; i < irq_end; i++) + set_irq_chip_and_handler(i, NULL, NULL); + return status; +} + +int twl_exit_irq(void) +{ + + if (twl6030_irq_base) { + pr_err("twl6030: can't yet clean up IRQs?\n"); + return -ENOSYS; + } + return 0; +} + diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 891ef18bd77b..8a9bc885a868 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -132,7 +132,7 @@ config MMC_OMAP config MMC_OMAP_HS tristate "TI OMAP High Speed Multimedia Card Interface support" - depends on ARCH_OMAP2430 || ARCH_OMAP3 + depends on ARCH_OMAP2430 || ARCH_OMAP3 || ARCH_OMAP4 help This selects the TI OMAP High Speed Multimedia card Interface. If you have an OMAP2430 or OMAP3 board with a Multimedia Card slot, diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 1cf9cfb3b64f..215728814152 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -32,6 +32,8 @@ #include <mach/board.h> #include <mach/mmc.h> #include <mach/cpu.h> +#include <linux/proc_fs.h> +#include <linux/slab.h> /* OMAP HSMMC Host Controller Registers */ #define OMAP_HSMMC_SYSCONFIG 0x0010 @@ -101,6 +103,8 @@ #define OMAP_MMC1_DEVID 0 #define OMAP_MMC2_DEVID 1 #define OMAP_MMC3_DEVID 2 +#define OMAP_MMC4_DEVID 3 +#define OMAP_MMC5_DEVID 4 #define MMC_TIMEOUT_MS 20 #define OMAP_MMC_MASTER_CLOCK 96000000 @@ -152,6 +156,8 @@ struct mmc_omap_host { struct omap_mmc_platform_data *pdata; }; +struct mmc_omap_host *test_mmc_omap4_host; + /* * Stop clock to the card */ @@ -341,6 +347,9 @@ mmc_omap_cmd_done(struct mmc_omap_host *host, struct mmc_command *cmd) cmd->resp[0] = OMAP_HSMMC_READ(host->base, RSP10); } } + /* TO FIX :Hack for MMC SWITCH COMMAND which makes card go busy*/ + if (cmd->opcode == 6) + host->response_busy = 0; if ((host->data == NULL && !host->response_busy) || cmd->error) { host->mrq = NULL; mmc_request_done(host->mmc, cmd->mrq); @@ -527,23 +536,30 @@ static int omap_mmc_switch_opcond(struct mmc_omap_host *host, int vdd) int ret; /* Disable the clocks */ - clk_disable(host->fclk); - clk_disable(host->iclk); - clk_disable(host->dbclk); + if (!cpu_is_omap44xx()) { + clk_disable(host->fclk); + clk_disable(host->iclk); + clk_disable(host->dbclk); + } /* Turn the power off */ - ret = mmc_slot(host).set_power(host->dev, host->slot_id, 0, 0); - if (ret != 0) - goto err; - - /* Turn the power ON with given VDD 1.8 or 3.0v */ - ret = mmc_slot(host).set_power(host->dev, host->slot_id, 1, vdd); - if (ret != 0) - goto err; - - clk_enable(host->fclk); - clk_enable(host->iclk); - clk_enable(host->dbclk); + if (!cpu_is_omap44xx()) { + ret = mmc_slot(host).set_power + (host->dev, host->slot_id, 0, 0); + if (ret != 0) + goto err; + + /* Turn the power ON with given VDD 1.8 or 3.0v */ + ret = mmc_slot(host).set_power + (host->dev, host->slot_id, 1, vdd); + if (ret != 0) + goto err; + } + if (!cpu_is_omap44xx()) { + clk_enable(host->fclk); + clk_enable(host->iclk); + clk_enable(host->dbclk); + } OMAP_HSMMC_WRITE(host->base, HCTL, OMAP_HSMMC_READ(host->base, HCTL) & SDVSCLR); @@ -587,11 +603,13 @@ static void mmc_omap_detect(struct work_struct *work) mmc_carddetect_work); struct omap_mmc_slot_data *slot = &mmc_slot(host); - if (mmc_slot(host).card_detect) - host->carddetect = slot->card_detect(slot->card_detect_irq); - else - host->carddetect = -ENOSYS; - + if (!cpu_is_omap44xx()) { + if (mmc_slot(host).card_detect) + host->carddetect = + slot->card_detect(slot->card_detect_irq); + else + host->carddetect = -ENOSYS; + } sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch"); if (host->carddetect) { mmc_detect_change(host->mmc, (HZ * 200) / 1000); @@ -600,6 +618,90 @@ static void mmc_omap_detect(struct work_struct *work) mmc_detect_change(host->mmc, (HZ * 50) / 1000); } } +#if 1 +/* Dummy Card detect Enable/disable */ +static struct proc_dir_entry *mmc_dir, *mmc_irq_file; + +static int +read_proc_entries(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + int len = 0; + char *p = page; + struct mmc_omap_host *host = test_mmc_omap4_host; + + if (off != 0) + goto readproc_end; + p += sprintf(p, "host->carddetect =%d", host->carddetect); + + +readproc_end: + len = (p - page); + *eof = 1; + if (off >= len) + return 0; + *start = page + off; + return min(count, len - (int) off); +} + +static int +write_proc_entries(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + int len, i; + char val[10]; + struct mmc_omap_host *host = test_mmc_omap4_host; + if (!buffer || (count == 0)) + return 0; + + len = (count > 3) ? 3 : count; + for (i = 0; i < len; i++) + val[i] = buffer[i]; + val[i] = '\0'; + + + if (strncmp(val, "ON", 2) == 0) { + host->carddetect = 0; + schedule_work(&host->mmc_carddetect_work); + } else if (strncmp(val, "OFF", 3) == 0) { + host->carddetect = 1; + schedule_work(&host->mmc_carddetect_work); + } else + return -EINVAL; + + return count; + +} + +/*PROC interface Implementation */ +#define MMC_DIR "driver/mmc" +#define MMC_ROOT NULL +static int file_type[1] = {1}; +static int +create_proc_file_entries(void) +{ + + if (!(mmc_dir = proc_mkdir(MMC_DIR, MMC_ROOT))) + return -ENOMEM; + + if (!(mmc_irq_file = create_proc_entry("mmc_irq", 0644, mmc_dir))) + goto no_mmc_irq; + + mmc_irq_file->data = &file_type[0]; + + mmc_irq_file->read_proc = read_proc_entries; + mmc_irq_file->write_proc = write_proc_entries; +/* + mmc_dir->owner = THIS_MODULE; + mmc_irq_file->owner = THIS_MODULE; +*/ + return 0; + +no_mmc_irq: + remove_proc_entry(MMC_DIR, MMC_ROOT); + return -ENOMEM; +} +#endif /* * ISR for handling card insertion and removal @@ -751,6 +853,11 @@ static void set_data_timeout(struct mmc_omap_host *host, unsigned int timeout, cycle_ns; uint32_t reg, clkd, dto = 0; + if (cpu_is_omap44xx()) { + reg = 0xe00c7; + OMAP_HSMMC_WRITE(host->base, SYSCTL, reg); + return; + } reg = OMAP_HSMMC_READ(host->base, SYSCTL); clkd = (reg & CLKD_MASK) >> CLKD_SHIFT; if (clkd == 0) @@ -1022,46 +1129,48 @@ static int __init omap_mmc_probe(struct platform_device *pdev) mmc->f_max = 52000000; sema_init(&host->sem, 1); + if (!cpu_is_omap44xx()) { + host->iclk = clk_get(&pdev->dev, "ick"); + if (IS_ERR(host->iclk)) { + ret = PTR_ERR(host->iclk); + host->iclk = NULL; + goto err1; + } + host->fclk = clk_get(&pdev->dev, "fck"); + if (IS_ERR(host->fclk)) { + ret = PTR_ERR(host->fclk); + host->fclk = NULL; + clk_put(host->iclk); + goto err1; + } - host->iclk = clk_get(&pdev->dev, "ick"); - if (IS_ERR(host->iclk)) { - ret = PTR_ERR(host->iclk); - host->iclk = NULL; - goto err1; - } - host->fclk = clk_get(&pdev->dev, "fck"); - if (IS_ERR(host->fclk)) { - ret = PTR_ERR(host->fclk); - host->fclk = NULL; - clk_put(host->iclk); - goto err1; - } - - if (clk_enable(host->fclk) != 0) { - clk_put(host->iclk); - clk_put(host->fclk); - goto err1; - } + if (clk_enable(host->fclk) != 0) { + clk_put(host->iclk); + clk_put(host->fclk); + goto err1; + } - if (clk_enable(host->iclk) != 0) { - clk_disable(host->fclk); - clk_put(host->iclk); - clk_put(host->fclk); - goto err1; - } + if (clk_enable(host->iclk) != 0) { + clk_disable(host->fclk); + clk_put(host->iclk); + clk_put(host->fclk); + goto err1; + } - host->dbclk = clk_get(&pdev->dev, "mmchsdb_fck"); - /* - * MMC can still work without debounce clock. - */ - if (IS_ERR(host->dbclk)) - dev_warn(mmc_dev(host->mmc), "Failed to get debounce clock\n"); - else - if (clk_enable(host->dbclk) != 0) - dev_dbg(mmc_dev(host->mmc), "Enabling debounce" - " clk failed\n"); + host->dbclk = clk_get(&pdev->dev, "mmchsdb_fck"); + /* + * MMC can still work without debounce clock. + */ + if (IS_ERR(host->dbclk)) + dev_warn(mmc_dev(host->mmc), "Failed to get debounce\ + clock\n"); else - host->dbclk_enabled = 1; + if (clk_enable(host->dbclk) != 0) + dev_dbg(mmc_dev(host->mmc), "Enabling debounce\ + clk failed\n"); + else + host->dbclk_enabled = 1; + } /* Since we do only SG emulation, we can have as many segs * as we want. */ @@ -1096,6 +1205,14 @@ static int __init omap_mmc_probe(struct platform_device *pdev) host->dma_line_tx = OMAP34XX_DMA_MMC3_TX; host->dma_line_rx = OMAP34XX_DMA_MMC3_RX; break; + case OMAP_MMC4_DEVID: + host->dma_line_tx = OMAP44XX_DMA_MMC4_DMA_TX; + host->dma_line_rx = OMAP44XX_DMA_MMC4_DMA_RX; + break; + case OMAP_MMC5_DEVID: + host->dma_line_tx = OMAP44XX_DMA_MMC5_DMA_TX; + host->dma_line_rx = OMAP44XX_DMA_MMC5_DMA_RX; + break; default: dev_err(mmc_dev(host->mmc), "Invalid MMC id\n"); goto err_irq; @@ -1117,21 +1234,20 @@ static int __init omap_mmc_probe(struct platform_device *pdev) } } mmc->ocr_avail = mmc_slot(host).ocr_mask; - - /* Request IRQ for card detect */ - if ((mmc_slot(host).card_detect_irq)) { - ret = request_irq(mmc_slot(host).card_detect_irq, - omap_mmc_cd_handler, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING - | IRQF_DISABLED, - mmc_hostname(mmc), host); - if (ret) { - dev_dbg(mmc_dev(host->mmc), - "Unable to grab MMC CD IRQ\n"); - goto err_irq_cd; + if (!cpu_is_omap44xx()) { + /* Request IRQ for card detect */ + if ((mmc_slot(host).card_detect_irq)) { + ret = request_irq(mmc_slot(host).card_detect_irq, + omap_mmc_cd_handler, IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING | IRQF_DISABLED, + mmc_hostname(mmc), host); + if (ret) { + dev_dbg(mmc_dev(host->mmc), + "Unable to grab MMC CD IRQ\n"); + goto err_irq_cd; + } } } - OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK); OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK); @@ -1149,7 +1265,12 @@ static int __init omap_mmc_probe(struct platform_device *pdev) if (ret < 0) goto err_cover_switch; } - +#if 1 + if ((cpu_is_omap44xx()) && (host->id == OMAP_MMC1_DEVID)) { + create_proc_file_entries(); + test_mmc_omap4_host = host; + } +#endif return 0; err_cover_switch: @@ -1157,17 +1278,19 @@ err_cover_switch: err_slot_name: mmc_remove_host(mmc); err_irq_cd: - free_irq(mmc_slot(host).card_detect_irq, host); +free_irq(mmc_slot(host).card_detect_irq, host); err_irq_cd_init: free_irq(host->irq, host); err_irq: - clk_disable(host->fclk); - clk_disable(host->iclk); - clk_put(host->fclk); - clk_put(host->iclk); - if (host->dbclk_enabled) { - clk_disable(host->dbclk); - clk_put(host->dbclk); + if (!cpu_is_omap44xx()) { + clk_disable(host->fclk); + clk_disable(host->iclk); + clk_put(host->fclk); + clk_put(host->iclk); + if (host->dbclk_enabled) { + clk_disable(host->dbclk); + clk_put(host->dbclk); + } } err1: @@ -1193,14 +1316,15 @@ static int omap_mmc_remove(struct platform_device *pdev) if (mmc_slot(host).card_detect_irq) free_irq(mmc_slot(host).card_detect_irq, host); flush_scheduled_work(); - - clk_disable(host->fclk); - clk_disable(host->iclk); - clk_put(host->fclk); - clk_put(host->iclk); - if (host->dbclk_enabled) { - clk_disable(host->dbclk); - clk_put(host->dbclk); + if (!cpu_is_omap44xx()) { + clk_disable(host->fclk); + clk_disable(host->iclk); + clk_put(host->fclk); + clk_put(host->iclk); + if (host->dbclk_enabled) { + clk_disable(host->dbclk); + clk_put(host->dbclk); + } } mmc_free_host(host->mmc); @@ -1243,9 +1367,11 @@ static int omap_mmc_suspend(struct platform_device *pdev, pm_message_t state) OMAP_HSMMC_WRITE(host->base, HCTL, OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP); - clk_disable(host->fclk); - clk_disable(host->iclk); - clk_disable(host->dbclk); + if (!cpu_is_omap44xx()) { + clk_disable(host->fclk); + clk_disable(host->iclk); + clk_disable(host->dbclk); + } } } @@ -1262,21 +1388,22 @@ static int omap_mmc_resume(struct platform_device *pdev) return 0; if (host) { + if (!cpu_is_omap44xx()) { + ret = clk_enable(host->fclk); + if (ret) + goto clk_en_err; - ret = clk_enable(host->fclk); - if (ret) - goto clk_en_err; - - ret = clk_enable(host->iclk); - if (ret) { - clk_disable(host->fclk); - clk_put(host->fclk); - goto clk_en_err; - } + ret = clk_enable(host->iclk); + if (ret) { + clk_disable(host->fclk); + clk_put(host->fclk); + goto clk_en_err; + } - if (clk_enable(host->dbclk) != 0) - dev_dbg(mmc_dev(host->mmc), + if (clk_enable(host->dbclk) != 0) + dev_dbg(mmc_dev(host->mmc), "Enabling debounce clk failed\n"); + } omap_hsmmc_init(host); diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index f4317798e47c..9e989a4d550a 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -75,9 +75,9 @@ config REGULATOR_MAX1586 regulator via I2C bus. The provided regulator is suitable for PXA27x chips to control VCC_CORE and VCC_USIM voltages. -config REGULATOR_TWL4030 +config REGULATOR_TWL bool "TI TWL4030/TWL5030/TPS695x0 PMIC" - depends on TWL4030_CORE + depends on TWL4030_CORE || TWL6030_CORE help This driver supports the voltage regulators provided by this family of companion chips. diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 4d762c4cccfd..712f733af6b9 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -11,7 +11,7 @@ obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o -obj-$(CONFIG_REGULATOR_TWL4030) += twl4030-regulator.o +obj-$(CONFIG_REGULATOR_TWL) += twl-regulator.o obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o obj-$(CONFIG_REGULATOR_DA903X) += da903x.o diff --git a/drivers/regulator/twl4030-regulator.c b/drivers/regulator/twl-regulator.c index e2032fb60b55..4152f2c9ae30 100644 --- a/drivers/regulator/twl4030-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -1,5 +1,5 @@ /* - * twl4030-regulator.c -- support regulators in twl4030 family chips + * twl-regulator.c -- support regulators in twl4030/twl6030 family chips * * Copyright (C) 2008 David Brownell * @@ -15,11 +15,11 @@ #include <linux/platform_device.h> #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> -#include <linux/i2c/twl4030.h> +#include <linux/i2c/twl.h> /* - * The TWL4030/TW5030/TPS659x0 family chips include power management, a + * The TWL4030/TW5030/TPS659x0/TWL6030 family chips include power management, a * USB OTG transceiver, an RTC, ADC, PWM, and lots more. Some versions * include an audio codec, battery charger, and more voltage regulators. * These chips are often used in OMAP-based systems. @@ -33,7 +33,7 @@ struct twlreg_info { /* start of regulator's PM_RECEIVER control register bank */ u8 base; - /* twl4030 resource ID, for resource control state machine */ + /* twl resource ID, for resource control state machine */ u8 id; /* voltage in mV = table[VSEL]; table_len must be a power-of-two */ @@ -52,27 +52,38 @@ struct twlreg_info { * The first three registers of all power resource banks help hardware to * manage the various resource groups. */ +/* Common offset in TWL4030/6030 */ #define VREG_GRP 0 +/* TWL4030 register offsets */ #define VREG_TYPE 1 #define VREG_REMAP 2 -#define VREG_DEDICATED 3 /* LDO control */ - +#define VREG_DEDICATED 3 +/* TWL6030 register offsets */ +#define VREG_TRANS 1 +#define VREG_STATE 2 +#define VREG_VOLTAGE 3 +/* TWL6030 Misc register offsets */ +#define VREG_BC_ALL 1 +#define VREG_BC_REF 2 +#define VREG_BC_PROC 3 +#define VREG_BC_CLK_RST 4 static inline int -twl4030reg_read(struct twlreg_info *info, unsigned offset) +twlreg_read(struct twlreg_info *info, unsigned slave_subgp, unsigned offset) { u8 value; int status; - status = twl4030_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, + status = twl_i2c_read_u8(slave_subgp, &value, info->base + offset); return (status < 0) ? status : value; } static inline int -twl4030reg_write(struct twlreg_info *info, unsigned offset, u8 value) +twlreg_write(struct twlreg_info *info, unsigned slave_subgp, unsigned offset, + u8 value) { - return twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, + return twl_i2c_write_u8(slave_subgp, value, info->base + offset); } @@ -80,23 +91,29 @@ twl4030reg_write(struct twlreg_info *info, unsigned offset, u8 value) /* generic power resource operations, which work on all regulators */ -static int twl4030reg_grp(struct regulator_dev *rdev) +static int twlreg_grp(struct regulator_dev *rdev) { - return twl4030reg_read(rdev_get_drvdata(rdev), VREG_GRP); + return twlreg_read(rdev_get_drvdata(rdev), TWL_MODULE_PM_SLAVE_LDO, + VREG_GRP); } /* * Enable/disable regulators by joining/leaving the P1 (processor) group. * We assume nobody else is updating the DEV_GRP registers. */ - +#ifdef CONFIG_TWL4030_CORE #define P3_GRP BIT(7) /* "peripherals" */ #define P2_GRP BIT(6) /* secondary processor, modem, etc */ #define P1_GRP BIT(5) /* CPU/Linux */ +#elif CONFIG_TWL6030_CORE +#define P3_GRP BIT(2) /* secondary processor, modem, etc */ +#define P2_GRP BIT(1) /* "peripherals" */ +#define P1_GRP BIT(0) /* CPU/Linux */ +#endif -static int twl4030reg_is_enabled(struct regulator_dev *rdev) +static int twlreg_is_enabled(struct regulator_dev *rdev) { - int state = twl4030reg_grp(rdev); + int state = twlreg_grp(rdev); if (state < 0) return state; @@ -104,35 +121,35 @@ static int twl4030reg_is_enabled(struct regulator_dev *rdev) return (state & P1_GRP) != 0; } -static int twl4030reg_enable(struct regulator_dev *rdev) +static int twlreg_enable(struct regulator_dev *rdev) { struct twlreg_info *info = rdev_get_drvdata(rdev); int grp; - grp = twl4030reg_read(info, VREG_GRP); + grp = twlreg_read(info, TWL_MODULE_PM_SLAVE_LDO, VREG_GRP); if (grp < 0) return grp; grp |= P1_GRP; - return twl4030reg_write(info, VREG_GRP, grp); + return twlreg_write(info, TWL_MODULE_PM_SLAVE_LDO, VREG_GRP, grp); } -static int twl4030reg_disable(struct regulator_dev *rdev) +static int twlreg_disable(struct regulator_dev *rdev) { struct twlreg_info *info = rdev_get_drvdata(rdev); int grp; - grp = twl4030reg_read(info, VREG_GRP); + grp = twlreg_read(info, TWL_MODULE_PM_SLAVE_LDO, VREG_GRP); if (grp < 0) return grp; grp &= ~P1_GRP; - return twl4030reg_write(info, VREG_GRP, grp); + return twlreg_write(info, TWL_MODULE_PM_SLAVE_LDO, VREG_GRP, grp); } -static int twl4030reg_get_status(struct regulator_dev *rdev) +static int twlreg_get_status(struct regulator_dev *rdev) { - int state = twl4030reg_grp(rdev); + int state = twlreg_grp(rdev); if (state < 0) return state; @@ -146,7 +163,7 @@ static int twl4030reg_get_status(struct regulator_dev *rdev) : REGULATOR_STATUS_STANDBY; } -static int twl4030reg_set_mode(struct regulator_dev *rdev, unsigned mode) +static int twlreg_set_mode(struct regulator_dev *rdev, unsigned mode) { struct twlreg_info *info = rdev_get_drvdata(rdev); unsigned message; @@ -165,19 +182,19 @@ static int twl4030reg_set_mode(struct regulator_dev *rdev, unsigned mode) } /* Ensure the resource is associated with some group */ - status = twl4030reg_grp(rdev); + status = twlreg_grp(rdev); if (status < 0) return status; if (!(status & (P3_GRP | P2_GRP | P1_GRP))) return -EACCES; - status = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, - message >> 8, 0x15 /* PB_WORD_MSB */ ); + status = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, + message >> 8, 0x15/* PB_WORD_MSB */); if (status >= 0) return status; - return twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, - message, 0x16 /* PB_WORD_LSB */ ); + return twl_i2c_write_u8(TWL_MODULE_PM_MASTER, + message, 0x16/* PB_WORD_LSB */); } /*----------------------------------------------------------------------*/ @@ -197,7 +214,7 @@ static int twl4030reg_set_mode(struct regulator_dev *rdev, unsigned mode) * VAUX3 at 3V is incorrectly listed in some TI manuals as unsupported. * TI are revising the twl5030/tps659x0 specs to support that 3.0V setting. */ -#ifdef CONFIG_TWL4030_ALLOW_UNSUPPORTED +#ifdef CONFIG_TWL_ALLOW_UNSUPPORTED #define UNSUP_MASK 0x0000 #else #define UNSUP_MASK 0x8000 @@ -260,9 +277,31 @@ static const u16 VSIM_VSEL_table[] = { static const u16 VDAC_VSEL_table[] = { 1200, 1300, 1800, 1800, }; +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 twl4030ldo_list_voltage(struct regulator_dev *rdev, unsigned index) +static int twlldo_list_voltage(struct regulator_dev *rdev, unsigned index) { struct twlreg_info *info = rdev_get_drvdata(rdev); int mV = info->table[index]; @@ -271,7 +310,7 @@ static int twl4030ldo_list_voltage(struct regulator_dev *rdev, unsigned index) } static int -twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) +twlldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) { struct twlreg_info *info = rdev_get_drvdata(rdev); int vsel; @@ -288,16 +327,18 @@ twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) /* use the first in-range value */ if (min_uV <= uV && uV <= max_uV) - return twl4030reg_write(info, VREG_DEDICATED, vsel); + return twlreg_write(info, TWL_MODULE_PM_SLAVE_LDO, + VREG_VOLTAGE, vsel); } return -EDOM; } -static int twl4030ldo_get_voltage(struct regulator_dev *rdev) +static int twlldo_get_voltage(struct regulator_dev *rdev) { struct twlreg_info *info = rdev_get_drvdata(rdev); - int vsel = twl4030reg_read(info, VREG_DEDICATED); + int vsel = twlreg_read(info, TWL_MODULE_PM_SLAVE_LDO, + VREG_VOLTAGE); if (vsel < 0) return vsel; @@ -306,19 +347,20 @@ static int twl4030ldo_get_voltage(struct regulator_dev *rdev) return LDO_MV(info->table[vsel]) * 1000; } -static struct regulator_ops twl4030ldo_ops = { - .list_voltage = twl4030ldo_list_voltage, +static struct regulator_ops twlldo_ops = { + .list_voltage = twlldo_list_voltage, - .set_voltage = twl4030ldo_set_voltage, - .get_voltage = twl4030ldo_get_voltage, + .set_voltage = twlldo_set_voltage, + .get_voltage = twlldo_get_voltage, - .enable = twl4030reg_enable, - .disable = twl4030reg_disable, - .is_enabled = twl4030reg_is_enabled, + .enable = twlreg_enable, + .disable = twlreg_disable, + .is_enabled = twlreg_is_enabled, - .set_mode = twl4030reg_set_mode, - - .get_status = twl4030reg_get_status, +#ifdef CONFIG_TWL4030_CORE + .set_mode = twlreg_set_mode, + .get_status = twlreg_get_status, +#endif }; /*----------------------------------------------------------------------*/ @@ -326,60 +368,70 @@ static struct regulator_ops twl4030ldo_ops = { /* * Fixed voltage LDOs don't have a VSEL field to update. */ -static int twl4030fixed_list_voltage(struct regulator_dev *rdev, unsigned index) +static int twlfixed_list_voltage(struct regulator_dev *rdev, unsigned index) { struct twlreg_info *info = rdev_get_drvdata(rdev); return info->min_mV * 1000; } -static int twl4030fixed_get_voltage(struct regulator_dev *rdev) +static int twlfixed_get_voltage(struct regulator_dev *rdev) { struct twlreg_info *info = rdev_get_drvdata(rdev); return info->min_mV * 1000; } -static struct regulator_ops twl4030fixed_ops = { - .list_voltage = twl4030fixed_list_voltage, +static struct regulator_ops twlfixed_ops = { + .list_voltage = twlfixed_list_voltage, - .get_voltage = twl4030fixed_get_voltage, + .get_voltage = twlfixed_get_voltage, - .enable = twl4030reg_enable, - .disable = twl4030reg_disable, - .is_enabled = twl4030reg_is_enabled, + .enable = twlreg_enable, + .disable = twlreg_disable, + .is_enabled = twlreg_is_enabled, - .set_mode = twl4030reg_set_mode, - - .get_status = twl4030reg_get_status, +#ifdef CONFIG_TWL4030_CORE + .set_mode = twlreg_set_mode, + .get_status = twlreg_get_status, +#endif }; /*----------------------------------------------------------------------*/ -#define TWL_ADJUSTABLE_LDO(label, offset, num) { \ +#define TWL4030_ADJUSTABLE_LDO(label, offset, num) \ + TWL_ADJUSTABLE_LDO(label, offset, num, TWL4030) +#define TWL4030_FIXED_LDO(label, offset, mVolts, num) \ + TWL_FIXED_LDO(label, offset, mVolts, num, TWL4030) +#define TWL6030_ADJUSTABLE_LDO(label, offset, num) \ + TWL_ADJUSTABLE_LDO(label, offset, num, TWL6030) +#define TWL6030_FIXED_LDO(label, offset, mVolts, num) \ + TWL_FIXED_LDO(label, offset, mVolts, num, TWL6030) + +#define TWL_ADJUSTABLE_LDO(label, offset, num, family) { \ .base = offset, \ .id = num, \ .table_len = ARRAY_SIZE(label##_VSEL_table), \ .table = label##_VSEL_table, \ .desc = { \ .name = #label, \ - .id = TWL4030_REG_##label, \ + .id = family##_REG_##label, \ .n_voltages = ARRAY_SIZE(label##_VSEL_table), \ - .ops = &twl4030ldo_ops, \ + .ops = &twlldo_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ }, \ } -#define TWL_FIXED_LDO(label, offset, mVolts, num) { \ +#define TWL_FIXED_LDO(label, offset, mVolts, num, family) { \ .base = offset, \ .id = num, \ .min_mV = mVolts, \ .desc = { \ .name = #label, \ - .id = TWL4030_REG_##label, \ + .id = family##_REG_##label, \ .n_voltages = 1, \ - .ops = &twl4030fixed_ops, \ + .ops = &twlfixed_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ }, \ @@ -389,35 +441,60 @@ static struct regulator_ops twl4030fixed_ops = { * We list regulators here if systems need some level of * software control over them after boot. */ -static struct twlreg_info twl4030_regs[] = { - TWL_ADJUSTABLE_LDO(VAUX1, 0x17, 1), - TWL_ADJUSTABLE_LDO(VAUX2_4030, 0x1b, 2), - TWL_ADJUSTABLE_LDO(VAUX2, 0x1b, 2), - TWL_ADJUSTABLE_LDO(VAUX3, 0x1f, 3), - TWL_ADJUSTABLE_LDO(VAUX4, 0x23, 4), - TWL_ADJUSTABLE_LDO(VMMC1, 0x27, 5), - TWL_ADJUSTABLE_LDO(VMMC2, 0x2b, 6), +static struct twlreg_info twl_regs[] = { +#ifdef CONFIG_TWL4030_CORE + TWL4030_ADJUSTABLE_LDO(VAUX1, 0x17, 1), + TWL4030_ADJUSTABLE_LDO(VAUX2_4030, 0x1b, 2), + TWL4030_ADJUSTABLE_LDO(VAUX2, 0x1b, 2), + TWL4030_ADJUSTABLE_LDO(VAUX3, 0x1f, 3), + TWL4030_ADJUSTABLE_LDO(VAUX4, 0x23, 4), + TWL4030_ADJUSTABLE_LDO(VMMC1, 0x27, 5), + TWL4030_ADJUSTABLE_LDO(VMMC2, 0x2b, 6), /* - TWL_ADJUSTABLE_LDO(VPLL1, 0x2f, 7), + TWL4030_ADJUSTABLE_LDO(VPLL1, 0x2f, 7), */ - TWL_ADJUSTABLE_LDO(VPLL2, 0x33, 8), - TWL_ADJUSTABLE_LDO(VSIM, 0x37, 9), - TWL_ADJUSTABLE_LDO(VDAC, 0x3b, 10), + TWL4030_ADJUSTABLE_LDO(VPLL2, 0x33, 8), + TWL4030_ADJUSTABLE_LDO(VSIM, 0x37, 9), + TWL4030_ADJUSTABLE_LDO(VDAC, 0x3b, 10), /* - TWL_ADJUSTABLE_LDO(VINTANA1, 0x3f, 11), - TWL_ADJUSTABLE_LDO(VINTANA2, 0x43, 12), - TWL_ADJUSTABLE_LDO(VINTDIG, 0x47, 13), - TWL_SMPS(VIO, 0x4b, 14), - TWL_SMPS(VDD1, 0x55, 15), - TWL_SMPS(VDD2, 0x63, 16), + TWL4030_ADJUSTABLE_LDO(VINTANA1, 0x3f, 11), + TWL4030_ADJUSTABLE_LDO(VINTANA2, 0x43, 12), + TWL4030_ADJUSTABLE_LDO(VINTDIG, 0x47, 13), + TWL4030_SMPS(VIO, 0x4b, 14), + TWL4030_SMPS(VDD1, 0x55, 15), + TWL4030_SMPS(VDD2, 0x63, 16), */ - TWL_FIXED_LDO(VUSB1V5, 0x71, 1500, 17), - TWL_FIXED_LDO(VUSB1V8, 0x74, 1800, 18), - TWL_FIXED_LDO(VUSB3V1, 0x77, 3100, 19), + TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17), + TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18), + TWL4030_FIXED_LDO(VUSB3V1, 0x77, 3100, 19), /* VUSBCP is managed *only* by the USB subchip */ +#elif CONFIG_TWL6030_CORE + TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x84, 1), + TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x88, 2), + TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x8c, 3), + TWL6030_ADJUSTABLE_LDO(VMMC, 0x98, 4), + TWL6030_ADJUSTABLE_LDO(VPP, 0x9c, 5), + /* + TWL6030_ADJUSTABLE_LDO(VRTC, 0x00, 6), + */ + TWL6030_ADJUSTABLE_LDO(VUSIM, 0xa4, 7), + /* SMPS + TWL6030_SMPS(VDD1, 0x4b, 8), + TWL6030_SMPS(VDD2, 0x55, 9), + TWL6030_SMPS(VDD3, 0x63, 10), + TWL6030_SMPS(VMEM, 0x00, 11), + TWL6030_SMPS(V1V29, 0x00, 12), + TWL6030_SMPS(V1V8, 0x00, 13), + TWL6030_SMPS(V2V1, 0x00, 14), + */ + TWL6030_FIXED_LDO(VANA, 0x80, 2100, 15), + TWL6030_FIXED_LDO(VCXIO, 0x90, 1800, 16), + TWL6030_FIXED_LDO(VDAC, 0x94, 1800, 17), + TWL6030_FIXED_LDO(VUSB, 0xa0, 3300, 18) +#endif }; -static int twl4030reg_probe(struct platform_device *pdev) +static int twlreg_probe(struct platform_device *pdev) { int i; struct twlreg_info *info; @@ -425,10 +502,10 @@ static int twl4030reg_probe(struct platform_device *pdev) struct regulation_constraints *c; struct regulator_dev *rdev; - for (i = 0, info = NULL; i < ARRAY_SIZE(twl4030_regs); i++) { - if (twl4030_regs[i].desc.id != pdev->id) + for (i = 0, info = NULL; i < ARRAY_SIZE(twl_regs); i++) { + if (twl_regs[i].desc.id != pdev->id) continue; - info = twl4030_regs + i; + info = twl_regs + i; break; } if (!info) @@ -466,35 +543,35 @@ static int twl4030reg_probe(struct platform_device *pdev) return 0; } -static int __devexit twl4030reg_remove(struct platform_device *pdev) +static int __devexit twlreg_remove(struct platform_device *pdev) { regulator_unregister(platform_get_drvdata(pdev)); return 0; } -MODULE_ALIAS("platform:twl4030_reg"); +MODULE_ALIAS("platform:twl_reg"); -static struct platform_driver twl4030reg_driver = { - .probe = twl4030reg_probe, - .remove = __devexit_p(twl4030reg_remove), +static struct platform_driver twlreg_driver = { + .probe = twlreg_probe, + .remove = __devexit_p(twlreg_remove), /* NOTE: short name, to work around driver model truncation of - * "twl4030_regulator.12" (and friends) to "twl4030_regulator.1". + * "twl_regulator.12" (and friends) to "twl_regulator.1". */ - .driver.name = "twl4030_reg", + .driver.name = "twl_reg", .driver.owner = THIS_MODULE, }; -static int __init twl4030reg_init(void) +static int __init twlreg_init(void) { - return platform_driver_register(&twl4030reg_driver); + return platform_driver_register(&twlreg_driver); } -subsys_initcall(twl4030reg_init); +subsys_initcall(twlreg_init); -static void __exit twl4030reg_exit(void) +static void __exit twlreg_exit(void) { - platform_driver_unregister(&twl4030reg_driver); + platform_driver_unregister(&twlreg_driver); } -module_exit(twl4030reg_exit) +module_exit(twlreg_exit) -MODULE_DESCRIPTION("TWL4030 regulator driver"); +MODULE_DESCRIPTION("TWL regulator driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 81adbdbd5042..89ccc9359531 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -257,15 +257,15 @@ config RTC_DRV_TWL92330 platforms. The support is integrated with the rest of the Menelaus driver; it's not separate module. -config RTC_DRV_TWL4030 - tristate "TI TWL4030/TWL5030/TPS659x0" - depends on RTC_CLASS && TWL4030_CORE +config RTC_DRV_TWL + tristate "TI TWL4030/TWL5030/TWL6030/TPS659x0" + depends on RTC_CLASS && (TWL4030_CORE || TWL6030_CORE) help If you say yes here you get support for the RTC on the TWL4030 family chips, used mostly with OMAP3 platforms. This driver can also be built as a module. If so, the module - will be called rtc-twl4030. + will be called twl-rtc. config RTC_DRV_S35390A tristate "Seiko Instruments S-35390A" diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 3c0f2b2ac927..c32e21d7f66d 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -70,7 +70,7 @@ obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o -obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl4030.o +obj-$(CONFIG_RTC_DRV_TWL) += rtc-twl.o obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o diff --git a/drivers/rtc/rtc-twl4030.c b/drivers/rtc/rtc-twl.c index 9c8c70c497dc..ff3842d9eec0 100644 --- a/drivers/rtc/rtc-twl4030.c +++ b/drivers/rtc/rtc-twl.c @@ -28,7 +28,7 @@ #include <linux/platform_device.h> #include <linux/interrupt.h> -#include <linux/i2c/twl4030.h> +#include <linux/i2c/twl.h> /* @@ -42,6 +42,7 @@ #define REG_YEARS_REG 0x05 #define REG_WEEKS_REG 0x06 +#ifdef CONFIG_TWL4030_CORE #define REG_ALARM_SECONDS_REG 0x07 #define REG_ALARM_MINUTES_REG 0x08 #define REG_ALARM_HOURS_REG 0x09 @@ -55,6 +56,26 @@ #define REG_RTC_COMP_LSB_REG 0x10 #define REG_RTC_COMP_MSB_REG 0x11 +#endif + +#ifdef CONFIG_TWL6030_CORE +#define REG_ALARM_SECONDS_REG 0x08 +#define REG_ALARM_MINUTES_REG 0x09 +#define REG_ALARM_HOURS_REG 0x0A +#define REG_ALARM_DAYS_REG 0x0B +#define REG_ALARM_MONTHS_REG 0x0C +#define REG_ALARM_YEARS_REG 0x0D + +#define REG_RTC_CTRL_REG 0x10 +#define REG_RTC_STATUS_REG 0x11 +#define REG_RTC_INTERRUPTS_REG 0x12 + +#define REG_RTC_COMP_LSB_REG 0x13 +#define REG_RTC_COMP_MSB_REG 0x14 +#define REG_RTC_RESET_STATUS_REG 0x16 + +#define TWL_MODULE_RTC TWL6030_MODULE_RTC +#endif /* RTC_CTRL_REG bitfields */ #define BIT_RTC_CTRL_REG_STOP_RTC_M 0x01 @@ -88,13 +109,13 @@ /* * Supports 1 byte read from TWL4030 RTC register. */ -static int twl4030_rtc_read_u8(u8 *data, u8 reg) +static int twl_rtc_read_u8(u8 *data, u8 reg) { int ret; - ret = twl4030_i2c_read_u8(TWL4030_MODULE_RTC, data, reg); + ret = twl_i2c_read_u8(TWL_MODULE_RTC, data, reg); if (ret < 0) - pr_err("twl4030_rtc: Could not read TWL4030" + pr_err("twl_rtc: Could not read TWL4030" "register %X - error %d\n", reg, ret); return ret; } @@ -102,13 +123,13 @@ static int twl4030_rtc_read_u8(u8 *data, u8 reg) /* * Supports 1 byte write to TWL4030 RTC registers. */ -static int twl4030_rtc_write_u8(u8 data, u8 reg) +static int twl_rtc_write_u8(u8 data, u8 reg) { int ret; - ret = twl4030_i2c_write_u8(TWL4030_MODULE_RTC, data, reg); + ret = twl_i2c_write_u8(TWL_MODULE_RTC, data, reg); if (ret < 0) - pr_err("twl4030_rtc: Could not write TWL4030" + pr_err("twl_rtc: Could not write TWL4030" "register %X - error %d\n", reg, ret); return ret; } @@ -129,7 +150,7 @@ static int set_rtc_irq_bit(unsigned char bit) val = rtc_irq_bits | bit; val &= ~BIT_RTC_INTERRUPTS_REG_EVERY_M; - ret = twl4030_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG); + ret = twl_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG); if (ret == 0) rtc_irq_bits = val; @@ -145,14 +166,14 @@ static int mask_rtc_irq_bit(unsigned char bit) int ret; val = rtc_irq_bits & ~bit; - ret = twl4030_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG); + ret = twl_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG); if (ret == 0) rtc_irq_bits = val; return ret; } -static int twl4030_rtc_alarm_irq_enable(struct device *dev, unsigned enabled) +static int twl_rtc_alarm_irq_enable(struct device *dev, unsigned enabled) { int ret; @@ -164,7 +185,7 @@ static int twl4030_rtc_alarm_irq_enable(struct device *dev, unsigned enabled) return ret; } -static int twl4030_rtc_update_irq_enable(struct device *dev, unsigned enabled) +static int twl_rtc_update_irq_enable(struct device *dev, unsigned enabled) { int ret; @@ -185,23 +206,23 @@ static int twl4030_rtc_update_irq_enable(struct device *dev, unsigned enabled) * - Months are 1..12 vs Linux 0-11 * - Years are 0..99 vs Linux 1900..N (we assume 21st century) */ -static int twl4030_rtc_read_time(struct device *dev, struct rtc_time *tm) +static int twl_rtc_read_time(struct device *dev, struct rtc_time *tm) { unsigned char rtc_data[ALL_TIME_REGS + 1]; int ret; u8 save_control; - ret = twl4030_rtc_read_u8(&save_control, REG_RTC_CTRL_REG); + ret = twl_rtc_read_u8(&save_control, REG_RTC_CTRL_REG); if (ret < 0) return ret; save_control |= BIT_RTC_CTRL_REG_GET_TIME_M; - ret = twl4030_rtc_write_u8(save_control, REG_RTC_CTRL_REG); + ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG); if (ret < 0) return ret; - ret = twl4030_i2c_read(TWL4030_MODULE_RTC, rtc_data, + ret = twl_i2c_read(TWL_MODULE_RTC, rtc_data, REG_SECONDS_REG, ALL_TIME_REGS); if (ret < 0) { @@ -219,7 +240,7 @@ static int twl4030_rtc_read_time(struct device *dev, struct rtc_time *tm) return ret; } -static int twl4030_rtc_set_time(struct device *dev, struct rtc_time *tm) +static int twl_rtc_set_time(struct device *dev, struct rtc_time *tm) { unsigned char save_control; unsigned char rtc_data[ALL_TIME_REGS + 1]; @@ -233,17 +254,17 @@ static int twl4030_rtc_set_time(struct device *dev, struct rtc_time *tm) rtc_data[6] = bin2bcd(tm->tm_year - 100); /* Stop RTC while updating the TC registers */ - ret = twl4030_rtc_read_u8(&save_control, REG_RTC_CTRL_REG); + ret = twl_rtc_read_u8(&save_control, REG_RTC_CTRL_REG); if (ret < 0) goto out; save_control &= ~BIT_RTC_CTRL_REG_STOP_RTC_M; - twl4030_rtc_write_u8(save_control, REG_RTC_CTRL_REG); + twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG); if (ret < 0) goto out; /* update all the time registers in one shot */ - ret = twl4030_i2c_write(TWL4030_MODULE_RTC, rtc_data, + ret = twl_i2c_write(TWL_MODULE_RTC, rtc_data, REG_SECONDS_REG, ALL_TIME_REGS); if (ret < 0) { dev_err(dev, "rtc_set_time error %d\n", ret); @@ -252,7 +273,7 @@ static int twl4030_rtc_set_time(struct device *dev, struct rtc_time *tm) /* Start back RTC */ save_control |= BIT_RTC_CTRL_REG_STOP_RTC_M; - ret = twl4030_rtc_write_u8(save_control, REG_RTC_CTRL_REG); + ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG); out: return ret; @@ -261,12 +282,12 @@ out: /* * Gets current TWL4030 RTC alarm time. */ -static int twl4030_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) +static int twl_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) { unsigned char rtc_data[ALL_TIME_REGS + 1]; int ret; - ret = twl4030_i2c_read(TWL4030_MODULE_RTC, rtc_data, + ret = twl_i2c_read(TWL_MODULE_RTC, rtc_data, REG_ALARM_SECONDS_REG, ALL_TIME_REGS); if (ret < 0) { dev_err(dev, "rtc_read_alarm error %d\n", ret); @@ -288,12 +309,12 @@ static int twl4030_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) return ret; } -static int twl4030_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) +static int twl_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) { unsigned char alarm_data[ALL_TIME_REGS + 1]; int ret; - ret = twl4030_rtc_alarm_irq_enable(dev, 0); + ret = twl_rtc_alarm_irq_enable(dev, 0); if (ret) goto out; @@ -305,7 +326,7 @@ static int twl4030_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) alarm_data[6] = bin2bcd(alm->time.tm_year - 100); /* update all the alarm registers in one shot */ - ret = twl4030_i2c_write(TWL4030_MODULE_RTC, alarm_data, + ret = twl_i2c_write(TWL_MODULE_RTC, alarm_data, REG_ALARM_SECONDS_REG, ALL_TIME_REGS); if (ret) { dev_err(dev, "rtc_set_alarm error %d\n", ret); @@ -313,12 +334,12 @@ static int twl4030_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) } if (alm->enabled) - ret = twl4030_rtc_alarm_irq_enable(dev, 1); + ret = twl_rtc_alarm_irq_enable(dev, 1); out: return ret; } -static irqreturn_t twl4030_rtc_interrupt(int irq, void *rtc) +static irqreturn_t twl_rtc_interrupt(int irq, void *rtc) { unsigned long events = 0; int ret = IRQ_NONE; @@ -333,7 +354,7 @@ static irqreturn_t twl4030_rtc_interrupt(int irq, void *rtc) local_irq_enable(); #endif - res = twl4030_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG); + res = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG); if (res) goto out; /* @@ -347,14 +368,15 @@ static irqreturn_t twl4030_rtc_interrupt(int irq, void *rtc) else events |= RTC_IRQF | RTC_UF; - res = twl4030_rtc_write_u8(rd_reg | BIT_RTC_STATUS_REG_ALARM_M, + res = twl_rtc_write_u8(rd_reg | BIT_RTC_STATUS_REG_ALARM_M, REG_RTC_STATUS_REG); if (res) goto out; +#ifdef CONFIG_TWL4030_CORE /* Clear on Read enabled. RTC_IT bit of TWL4030_INT_PWR_ISR1 * needs 2 reads to clear the interrupt. One read is done in - * do_twl4030_pwrirq(). Doing the second read, to clear + * do_twl_pwrirq(). Doing the second read, to clear * the bit. * * FIXME the reason PWR_ISR1 needs an extra read is that @@ -363,10 +385,11 @@ static irqreturn_t twl4030_rtc_interrupt(int irq, void *rtc) * risk wrongly clearing status for some other IRQ (losing * the interrupt). Be smarter about handling RTC_UF ... */ - res = twl4030_i2c_read_u8(TWL4030_MODULE_INT, + res = twl_i2c_read_u8(TWL_MODULE_INT, &rd_reg, TWL4030_INT_PWR_ISR1); if (res) goto out; +#endif /* Notify RTC core on event */ rtc_update_irq(rtc, 1, events); @@ -376,18 +399,18 @@ out: return ret; } -static struct rtc_class_ops twl4030_rtc_ops = { - .read_time = twl4030_rtc_read_time, - .set_time = twl4030_rtc_set_time, - .read_alarm = twl4030_rtc_read_alarm, - .set_alarm = twl4030_rtc_set_alarm, - .alarm_irq_enable = twl4030_rtc_alarm_irq_enable, - .update_irq_enable = twl4030_rtc_update_irq_enable, +static struct rtc_class_ops twl_rtc_ops = { + .read_time = twl_rtc_read_time, + .set_time = twl_rtc_set_time, + .read_alarm = twl_rtc_read_alarm, + .set_alarm = twl_rtc_set_alarm, + .alarm_irq_enable = twl_rtc_alarm_irq_enable, + .update_irq_enable = twl_rtc_update_irq_enable, }; /*----------------------------------------------------------------------*/ -static int __devinit twl4030_rtc_probe(struct platform_device *pdev) +static int __devinit twl_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc; int ret = 0; @@ -398,7 +421,7 @@ static int __devinit twl4030_rtc_probe(struct platform_device *pdev) return -EINVAL; rtc = rtc_device_register(pdev->name, - &pdev->dev, &twl4030_rtc_ops, THIS_MODULE); + &pdev->dev, &twl_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) { ret = PTR_ERR(rtc); dev_err(&pdev->dev, "can't register RTC device, err %ld\n", @@ -409,7 +432,7 @@ static int __devinit twl4030_rtc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, rtc); - ret = twl4030_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG); + ret = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG); if (ret < 0) goto out1; @@ -420,11 +443,11 @@ static int __devinit twl4030_rtc_probe(struct platform_device *pdev) dev_warn(&pdev->dev, "Pending Alarm interrupt detected.\n"); /* Clear RTC Power up reset and pending alarm interrupts */ - ret = twl4030_rtc_write_u8(rd_reg, REG_RTC_STATUS_REG); + ret = twl_rtc_write_u8(rd_reg, REG_RTC_STATUS_REG); if (ret < 0) goto out1; - ret = request_irq(irq, twl4030_rtc_interrupt, + ret = request_irq(irq, twl_rtc_interrupt, IRQF_TRIGGER_RISING, dev_name(&rtc->dev), rtc); if (ret < 0) { @@ -433,20 +456,20 @@ static int __devinit twl4030_rtc_probe(struct platform_device *pdev) } /* Check RTC module status, Enable if it is off */ - ret = twl4030_rtc_read_u8(&rd_reg, REG_RTC_CTRL_REG); + ret = twl_rtc_read_u8(&rd_reg, REG_RTC_CTRL_REG); if (ret < 0) goto out2; if (!(rd_reg & BIT_RTC_CTRL_REG_STOP_RTC_M)) { dev_info(&pdev->dev, "Enabling TWL4030-RTC.\n"); rd_reg = BIT_RTC_CTRL_REG_STOP_RTC_M; - ret = twl4030_rtc_write_u8(rd_reg, REG_RTC_CTRL_REG); + ret = twl_rtc_write_u8(rd_reg, REG_RTC_CTRL_REG); if (ret < 0) goto out2; } /* init cached IRQ enable bits */ - ret = twl4030_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG); + ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG); if (ret < 0) goto out2; @@ -464,7 +487,7 @@ out0: * Disable all TWL4030 RTC module interrupts. * Sets status flag to free. */ -static int __devexit twl4030_rtc_remove(struct platform_device *pdev) +static int __devexit twl_rtc_remove(struct platform_device *pdev) { /* leave rtc running, but disable irqs */ struct rtc_device *rtc = platform_get_drvdata(pdev); @@ -480,7 +503,7 @@ static int __devexit twl4030_rtc_remove(struct platform_device *pdev) return 0; } -static void twl4030_rtc_shutdown(struct platform_device *pdev) +static void twl_rtc_shutdown(struct platform_device *pdev) { /* mask timer interrupts, but leave alarm interrupts on to enable power-on when alarm is triggered */ @@ -491,7 +514,7 @@ static void twl4030_rtc_shutdown(struct platform_device *pdev) static unsigned char irqstat; -static int twl4030_rtc_suspend(struct platform_device *pdev, pm_message_t state) +static int twl_rtc_suspend(struct platform_device *pdev, pm_message_t state) { irqstat = rtc_irq_bits; @@ -499,42 +522,42 @@ static int twl4030_rtc_suspend(struct platform_device *pdev, pm_message_t state) return 0; } -static int twl4030_rtc_resume(struct platform_device *pdev) +static int twl_rtc_resume(struct platform_device *pdev) { set_rtc_irq_bit(irqstat); return 0; } #else -#define twl4030_rtc_suspend NULL -#define twl4030_rtc_resume NULL +#define twl_rtc_suspend NULL +#define twl_rtc_resume NULL #endif -MODULE_ALIAS("platform:twl4030_rtc"); +MODULE_ALIAS("platform:twl_rtc"); static struct platform_driver twl4030rtc_driver = { - .probe = twl4030_rtc_probe, - .remove = __devexit_p(twl4030_rtc_remove), - .shutdown = twl4030_rtc_shutdown, - .suspend = twl4030_rtc_suspend, - .resume = twl4030_rtc_resume, + .probe = twl_rtc_probe, + .remove = __devexit_p(twl_rtc_remove), + .shutdown = twl_rtc_shutdown, + .suspend = twl_rtc_suspend, + .resume = twl_rtc_resume, .driver = { .owner = THIS_MODULE, - .name = "twl4030_rtc", + .name = "twl_rtc", }, }; -static int __init twl4030_rtc_init(void) +static int __init twl_rtc_init(void) { return platform_driver_register(&twl4030rtc_driver); } -module_init(twl4030_rtc_init); +module_init(twl_rtc_init); -static void __exit twl4030_rtc_exit(void) +static void __exit twl_rtc_exit(void) { platform_driver_unregister(&twl4030rtc_driver); } -module_exit(twl4030_rtc_exit); +module_exit(twl_rtc_exit); MODULE_AUTHOR("Texas Instruments, MontaVista Software"); MODULE_LICENSE("GPL"); diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 2c733c27db2f..c2564689acd2 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -157,10 +157,10 @@ config SPI_OMAP_UWIRE This hooks up to the MicroWire controller on OMAP1 chips. config SPI_OMAP24XX - tristate "McSPI driver for OMAP24xx/OMAP34xx" - depends on ARCH_OMAP24XX || ARCH_OMAP34XX + tristate "McSPI driver for OMAP24xx/OMAP34xx/OMAP4" + depends on ARCH_OMAP24XX || ARCH_OMAP34XX || ARCH_OMAP4 help - SPI master controller for OMAP24xx/OMAP34xx Multichannel SPI + SPI master controller for OMAP24xx/OMAP34xx/OMAP4 Multichannel SPI (McSPI) modules. config SPI_ORION diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c index 9b80ad36dbba..afb3a2b5bb58 100644 --- a/drivers/spi/omap2_mcspi.c +++ b/drivers/spi/omap2_mcspi.c @@ -42,21 +42,38 @@ #define OMAP2_MCSPI_MAX_FREQ 48000000 #define OMAP2_MCSPI_REVISION 0x00 -#define OMAP2_MCSPI_SYSCONFIG 0x10 -#define OMAP2_MCSPI_SYSSTATUS 0x14 -#define OMAP2_MCSPI_IRQSTATUS 0x18 -#define OMAP2_MCSPI_IRQENABLE 0x1c -#define OMAP2_MCSPI_WAKEUPENABLE 0x20 -#define OMAP2_MCSPI_SYST 0x24 -#define OMAP2_MCSPI_MODULCTRL 0x28 +#ifdef CONFIG_ARCH_OMAP4 +#define OMAP2_MCSPI_SYSCONFIG 0x110 +#define OMAP2_MCSPI_SYSSTATUS 0x114 +#define OMAP2_MCSPI_IRQSTATUS 0x118 +#define OMAP2_MCSPI_IRQENABLE 0x11c +#define OMAP2_MCSPI_WAKEUPENABLE 0x120 +#define OMAP2_MCSPI_SYST 0x124 +#define OMAP2_MCSPI_MODULCTRL 0x128 /* per-channel banks, 0x14 bytes each, first is: */ -#define OMAP2_MCSPI_CHCONF0 0x2c -#define OMAP2_MCSPI_CHSTAT0 0x30 -#define OMAP2_MCSPI_CHCTRL0 0x34 -#define OMAP2_MCSPI_TX0 0x38 -#define OMAP2_MCSPI_RX0 0x3c +#define OMAP2_MCSPI_CHCONF0 0x12c +#define OMAP2_MCSPI_CHSTAT0 0x130 +#define OMAP2_MCSPI_CHCTRL0 0x134 +#define OMAP2_MCSPI_TX0 0x138 +#define OMAP2_MCSPI_RX0 0x13c +#else +#define OMAP2_MCSPI_REVISION 0x00 +#define OMAP2_MCSPI_SYSCONFIG 0x10 +#define OMAP2_MCSPI_SYSSTATUS 0x14 +#define OMAP2_MCSPI_IRQSTATUS 0x18 +#define OMAP2_MCSPI_IRQENABLE 0x1c +#define OMAP2_MCSPI_WAKEUPENABLE 0x20 +#define OMAP2_MCSPI_SYST 0x24 +#define OMAP2_MCSPI_MODULCTRL 0x28 +/* per-channel banks, 0x14 bytes each, first is: */ +#define OMAP2_MCSPI_CHCONF0 0x2c +#define OMAP2_MCSPI_CHSTAT0 0x30 +#define OMAP2_MCSPI_CHCTRL0 0x34 +#define OMAP2_MCSPI_TX0 0x38 +#define OMAP2_MCSPI_RX0 0x3c +#endif /* per-register bitmasks: */ #define OMAP2_MCSPI_SYSCONFIG_SMARTIDLE (2 << 3) @@ -933,7 +950,8 @@ static u8 __initdata spi2_txdma_id[] = { OMAP24XX_DMA_SPI2_TX1, }; -#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX) +#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX) ||\ +defined(CONFIG_ARCH_OMAP4) static u8 __initdata spi3_rxdma_id[] = { OMAP24XX_DMA_SPI3_RX0, OMAP24XX_DMA_SPI3_RX1, @@ -945,7 +963,7 @@ static u8 __initdata spi3_txdma_id[] = { }; #endif -#ifdef CONFIG_ARCH_OMAP3 +#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) static u8 __initdata spi4_rxdma_id[] = { OMAP34XX_DMA_SPI4_RX0, }; @@ -975,14 +993,15 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev) txdma_id = spi2_txdma_id; num_chipselect = 2; break; -#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) +#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) ||\ +defined(CONFIG_ARCH_OMAP4) case 3: rxdma_id = spi3_rxdma_id; txdma_id = spi3_txdma_id; num_chipselect = 2; break; #endif -#ifdef CONFIG_ARCH_OMAP3 +#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) case 4: rxdma_id = spi4_rxdma_id; txdma_id = spi4_txdma_id; @@ -1038,20 +1057,24 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev) spin_lock_init(&mcspi->lock); INIT_LIST_HEAD(&mcspi->msg_queue); - - mcspi->ick = clk_get(&pdev->dev, "ick"); - if (IS_ERR(mcspi->ick)) { - dev_dbg(&pdev->dev, "can't get mcspi_ick\n"); - status = PTR_ERR(mcspi->ick); - goto err1a; - } - mcspi->fck = clk_get(&pdev->dev, "fck"); - if (IS_ERR(mcspi->fck)) { - dev_dbg(&pdev->dev, "can't get mcspi_fck\n"); - status = PTR_ERR(mcspi->fck); - goto err2; + /* + * FIX-ME: Replace with correct clk node when clk + * framework is available + */ + if (!cpu_is_omap44xx()) { + mcspi->ick = clk_get(&pdev->dev, "ick"); + if (IS_ERR(mcspi->ick)) { + dev_dbg(&pdev->dev, "can't get mcspi_ick\n"); + status = PTR_ERR(mcspi->ick); + goto err1a; + } + mcspi->fck = clk_get(&pdev->dev, "fck"); + if (IS_ERR(mcspi->fck)) { + dev_dbg(&pdev->dev, "can't get mcspi_fck\n"); + status = PTR_ERR(mcspi->fck); + goto err2; + } } - mcspi->dma_channels = kcalloc(master->num_chipselect, sizeof(struct omap2_mcspi_dma), GFP_KERNEL); diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c index 9e3e7a5c258b..60fbf469eb39 100644 --- a/drivers/usb/otg/twl4030-usb.c +++ b/drivers/usb/otg/twl4030-usb.c @@ -33,7 +33,7 @@ #include <linux/io.h> #include <linux/delay.h> #include <linux/usb/otg.h> -#include <linux/i2c/twl4030.h> +#include <linux/i2c/twl.h> #include <linux/regulator/consumer.h> #include <linux/err.h> @@ -258,7 +258,7 @@ struct twl4030_usb { spinlock_t lock; /* pin configuration */ - enum twl4030_usb_mode usb_mode; + enum twl_usb_mode usb_mode; int irq; u8 linkstat; @@ -276,16 +276,16 @@ static int twl4030_i2c_write_u8_verify(struct twl4030_usb *twl, { u8 check; - if ((twl4030_i2c_write_u8(module, data, address) >= 0) && - (twl4030_i2c_read_u8(module, &check, address) >= 0) && + if ((twl_i2c_write_u8(module, data, address) >= 0) && + (twl_i2c_read_u8(module, &check, address) >= 0) && (check == data)) return 0; dev_dbg(twl->dev, "Write%d[%d,0x%x] wrote %02x but read %02x\n", 1, module, address, check, data); /* Failed once: Try again */ - if ((twl4030_i2c_write_u8(module, data, address) >= 0) && - (twl4030_i2c_read_u8(module, &check, address) >= 0) && + if ((twl_i2c_write_u8(module, data, address) >= 0) && + (twl_i2c_read_u8(module, &check, address) >= 0) && (check == data)) return 0; dev_dbg(twl->dev, "Write%d[%d,0x%x] wrote %02x but read %02x\n", @@ -303,7 +303,7 @@ static inline int twl4030_usb_write(struct twl4030_usb *twl, { int ret = 0; - ret = twl4030_i2c_write_u8(TWL4030_MODULE_USB, data, address); + ret = twl_i2c_write_u8(TWL4030_MODULE_USB, data, address); if (ret < 0) dev_dbg(twl->dev, "TWL4030:USB:Write[0x%x] Error %d\n", address, ret); @@ -315,7 +315,7 @@ static inline int twl4030_readb(struct twl4030_usb *twl, u8 module, u8 address) u8 data; int ret = 0; - ret = twl4030_i2c_read_u8(module, &data, address); + ret = twl_i2c_read_u8(module, &data, address); if (ret >= 0) ret = data; else @@ -462,7 +462,7 @@ static void twl4030_phy_power(struct twl4030_usb *twl, int on) * SLEEP. We work around this by clearing the bit after usv3v1 * is re-activated. This ensures that VUSB3V1 is really active. */ - twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, + twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2); regulator_enable(twl->usb1v5); pwr &= ~PHY_PWR_PHYPWD; @@ -505,44 +505,44 @@ static void twl4030_phy_resume(struct twl4030_usb *twl) static int twl4030_usb_ldo_init(struct twl4030_usb *twl) { /* Enable writing to power configuration registers */ - twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0xC0, PROTECT_KEY); - twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0x0C, PROTECT_KEY); + twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0xC0, PROTECT_KEY); + twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0x0C, PROTECT_KEY); /* put VUSB3V1 LDO in active state */ - twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2); + twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2); /* input to VUSB3V1 LDO is from VBAT, not VBUS */ - twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x14, VUSB_DEDICATED1); + twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x14, VUSB_DEDICATED1); /* Initialize 3.1V regulator */ - twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB3V1_DEV_GRP); + twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB3V1_DEV_GRP); twl->usb3v1 = regulator_get(twl->dev, "usb3v1"); if (IS_ERR(twl->usb3v1)) return -ENODEV; - twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB3V1_TYPE); + twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB3V1_TYPE); /* Initialize 1.5V regulator */ - twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V5_DEV_GRP); + twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V5_DEV_GRP); twl->usb1v5 = regulator_get(twl->dev, "usb1v5"); if (IS_ERR(twl->usb1v5)) goto fail1; - twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V5_TYPE); + twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V5_TYPE); /* Initialize 1.8V regulator */ - twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V8_DEV_GRP); + twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V8_DEV_GRP); twl->usb1v8 = regulator_get(twl->dev, "usb1v8"); if (IS_ERR(twl->usb1v8)) goto fail2; - twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V8_TYPE); + twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V8_TYPE); /* disable access to power configuration registers */ - twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, PROTECT_KEY); + twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, PROTECT_KEY); return 0; @@ -655,7 +655,7 @@ static int twl4030_set_host(struct otg_transceiver *x, struct usb_bus *host) static int __devinit twl4030_usb_probe(struct platform_device *pdev) { - struct twl4030_usb_data *pdata = pdev->dev.platform_data; + struct twl_usb_data *pdata = pdev->dev.platform_data; struct twl4030_usb *twl; int status, err; diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 3b54b3940178..e09367a60446 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -2149,6 +2149,7 @@ config FB_BROADSHEET a bridge adapter. source "drivers/video/omap/Kconfig" +source "drivers/video/omap2/Kconfig" source "drivers/video/backlight/Kconfig" source "drivers/video/display/Kconfig" diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 01a819f47371..01bf7a50ec12 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -123,6 +123,7 @@ obj-$(CONFIG_FB_SM501) += sm501fb.o obj-$(CONFIG_FB_XILINX) += xilinxfb.o obj-$(CONFIG_FB_SH_MOBILE_LCDC) += sh_mobile_lcdcfb.o obj-$(CONFIG_FB_OMAP) += omap/ +obj-$(CONFIG_OMAP2_DSS) += omap2/ obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o obj-$(CONFIG_FB_CARMINE) += carminefb.o obj-$(CONFIG_FB_MB862XX) += mb862xx/ diff --git a/drivers/video/omap/Kconfig b/drivers/video/omap/Kconfig index 44408850e2eb..0c8f3a52865e 100644 --- a/drivers/video/omap/Kconfig +++ b/drivers/video/omap/Kconfig @@ -1,6 +1,7 @@ config FB_OMAP tristate "OMAP frame buffer support (EXPERIMENTAL)" - depends on FB && ARCH_OMAP + depends on FB && ARCH_OMAP && (OMAP2_DSS = "n") + select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT @@ -9,7 +10,7 @@ config FB_OMAP config FB_OMAP_BOOTLOADER_INIT bool "Check bootloader initialization" - depends on FB_OMAP + depends on FB_OMAP || FB_OMAP2 help Say Y here if you want to enable checking if the bootloader has already initialized the display controller. In this case the diff --git a/drivers/video/omap/Makefile b/drivers/video/omap/Makefile index ed13889c1162..af0c9534d938 100644 --- a/drivers/video/omap/Makefile +++ b/drivers/video/omap/Makefile @@ -8,6 +8,7 @@ objs-yy := omapfb_main.o objs-y$(CONFIG_ARCH_OMAP1) += lcdc.o objs-y$(CONFIG_ARCH_OMAP2) += dispc.o +objs-y$(CONFIG_ARCH_OMAP4) += dispc.o objs-$(CONFIG_ARCH_OMAP1)$(CONFIG_FB_OMAP_LCDC_EXTERNAL) += sossi.o objs-$(CONFIG_ARCH_OMAP2)$(CONFIG_FB_OMAP_LCDC_EXTERNAL) += rfbi.o @@ -23,6 +24,7 @@ objs-y$(CONFIG_MACH_OMAP_PALMZ71) += lcd_palmz71.o objs-$(CONFIG_ARCH_OMAP16XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1610.o objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1510.o objs-y$(CONFIG_MACH_OMAP_OSK) += lcd_osk.o +objs-y$(CONFIG_MACH_OMAP_4430SDP) += lcd_4430sdp.o omapfb-objs := $(objs-yy) diff --git a/drivers/video/omap/blizzard.c b/drivers/video/omap/blizzard.c index 9dfcf39d3367..782b48843a7d 100644 --- a/drivers/video/omap/blizzard.c +++ b/drivers/video/omap/blizzard.c @@ -25,9 +25,9 @@ #include <linux/fb.h> #include <linux/delay.h> #include <linux/clk.h> +#include <linux/omapfb.h> #include <mach/dma.h> -#include <mach/omapfb.h> #include <mach/blizzard.h> #include "dispc.h" diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c index 148cbcc39602..f8e2b948df12 100644 --- a/drivers/video/omap/dispc.c +++ b/drivers/video/omap/dispc.c @@ -24,19 +24,29 @@ #include <linux/vmalloc.h> #include <linux/clk.h> #include <linux/io.h> +#include <linux/omapfb.h> #include <mach/sram.h> -#include <mach/omapfb.h> #include <mach/board.h> #include "dispc.h" #define MODULE_NAME "dispc" -#define DSS_BASE 0x48050000 -#define DSS_SYSCONFIG 0x0010 +#ifndef CONFIG_ARCH_OMAP4 + /* DSS */ + #define DSS_BASE 0x48050000 + /* DISPLAY CONTROLLER */ + #define DISPC_BASE 0x48050400 +#else + /* DSS */ + #define DSS_BASE 0x48042000 + /* DISPLAY CONTROLLER */ + #define DISPC_BASE 0x48043000 +#endif -#define DISPC_BASE 0x48050400 +#define DSS_SYSCONFIG 0x0010 +#define DSS_REG_SIZE 0x00001000 /* DISPC common */ #define DISPC_REVISION 0x0000 @@ -436,6 +446,9 @@ static inline int _setup_plane(int plane, int channel_out, dispc_write_reg(ri_reg[plane], (screen_width - width) * bpp / 8 + 1); + /* Enabling GO-LCD bit in DISPC_CONTROL */ + MOD_REG_FLD(DISPC_CONTROL, 0x1<<05, 0x1<<05); + return height * screen_width * bpp / 8; } @@ -856,6 +869,7 @@ void omap_dispc_free_irq(void) } EXPORT_SYMBOL(omap_dispc_free_irq); +#ifndef CONFIG_ARCH_OMAP4 static irqreturn_t omap_dispc_irq_handler(int irq, void *dev) { u32 stat = dispc_read_reg(DISPC_IRQSTATUS); @@ -877,30 +891,32 @@ static irqreturn_t omap_dispc_irq_handler(int irq, void *dev) return IRQ_HANDLED; } +#endif static int get_dss_clocks(void) { - dispc.dss_ick = clk_get(dispc.fbdev->dev, "ick"); - if (IS_ERR(dispc.dss_ick)) { - dev_err(dispc.fbdev->dev, "can't get ick\n"); - return PTR_ERR(dispc.dss_ick); - } + if (!cpu_is_omap44xx()) { + dispc.dss_ick = clk_get(dispc.fbdev->dev, "ick"); + if (IS_ERR(dispc.dss_ick)) { + dev_err(dispc.fbdev->dev, "can't get ick\n"); + return PTR_ERR(dispc.dss_ick); + } - dispc.dss1_fck = clk_get(dispc.fbdev->dev, "dss1_fck"); - if (IS_ERR(dispc.dss1_fck)) { - dev_err(dispc.fbdev->dev, "can't get dss1_fck\n"); - clk_put(dispc.dss_ick); - return PTR_ERR(dispc.dss1_fck); - } + dispc.dss1_fck = clk_get(dispc.fbdev->dev, "dss1_fck"); + if (IS_ERR(dispc.dss1_fck)) { + dev_err(dispc.fbdev->dev, "can't get dss1_fck\n"); + clk_put(dispc.dss_ick); + return PTR_ERR(dispc.dss1_fck); + } - dispc.dss_54m_fck = clk_get(dispc.fbdev->dev, "tv_fck"); - if (IS_ERR(dispc.dss_54m_fck)) { - dev_err(dispc.fbdev->dev, "can't get tv_fck\n"); - clk_put(dispc.dss_ick); - clk_put(dispc.dss1_fck); - return PTR_ERR(dispc.dss_54m_fck); + dispc.dss_54m_fck = clk_get(dispc.fbdev->dev, "tv_fck"); + if (IS_ERR(dispc.dss_54m_fck)) { + dev_err(dispc.fbdev->dev, "can't get tv_fck\n"); + clk_put(dispc.dss_ick); + clk_put(dispc.dss1_fck); + return PTR_ERR(dispc.dss_54m_fck); + } } - return 0; } @@ -1413,7 +1429,7 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode, /* Enable those that we handle always */ omap_dispc_enable_irqs(DISPC_IRQ_FRAMEMASK); - +#ifndef CONFIG_ARCH_OMAP4 if ((r = request_irq(INT_24XX_DSS_IRQ, omap_dispc_irq_handler, 0, MODULE_NAME, fbdev)) < 0) { dev_err(dispc.fbdev->dev, "can't get DSS IRQ\n"); @@ -1422,7 +1438,7 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode, /* L3 firewall setting: enable access to OCM RAM */ __raw_writel(0x402000b0, IO_ADDRESS(0x680050a0)); - +#endif if ((r = alloc_palette_ram()) < 0) goto fail2; diff --git a/drivers/video/omap/hwa742.c b/drivers/video/omap/hwa742.c index 5d4f34887a22..d865b55b8269 100644 --- a/drivers/video/omap/hwa742.c +++ b/drivers/video/omap/hwa742.c @@ -25,9 +25,9 @@ #include <linux/fb.h> #include <linux/delay.h> #include <linux/clk.h> +#include <linux/omapfb.h> #include <mach/dma.h> -#include <mach/omapfb.h> #include <mach/hwa742.h> #define HWA742_REV_CODE_REG 0x0 diff --git a/drivers/video/omap/lcd_4430sdp.c b/drivers/video/omap/lcd_4430sdp.c new file mode 100644 index 000000000000..1065d2acfbef --- /dev/null +++ b/drivers/video/omap/lcd_4430sdp.c @@ -0,0 +1,128 @@ +/* + * LCD panel support for the TI 4430SDP board + * + * Copyright (C) 2007 MontaVista + * Author: Hunyue Yau <hyau@mvista.com> + * + * Derived from drivers/video/omap/lcd-apollon.c + * + * 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/module.h> +#include <linux/platform_device.h> +#include <linux/omapfb.h> + +#include <mach/mux.h> +#include <asm/mach-types.h> + +#define LCD_PIXCLOCK_MAX 5400 /* freq 5.4 MHz */ + +static int sdp4430_panel_init(struct lcd_panel *panel, + struct omapfb_device *fbdev) +{ + return 0; +} + +static void sdp4430_panel_cleanup(struct lcd_panel *panel) +{ + return; +} + +static int sdp4430_panel_enable(struct lcd_panel *panel) +{ + return 0; +} + +static void sdp4430_panel_disable(struct lcd_panel *panel) +{ + return; +} + +static unsigned long sdp4430_panel_get_caps(struct lcd_panel *panel) +{ + return 0; +} + +struct lcd_panel sdp4430_panel = { + .name = "sdp4430", + .config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC | + OMAP_LCDC_INV_HSYNC, + .bpp = 16, + .data_lines = 16, + .x_res = 240, + .y_res = 320, + .hsw = 3, /* hsync_len (4) - 1 */ + .hfp = 3, /* right_margin (4) - 1 */ + .hbp = 39, /* left_margin (40) - 1 */ + .vsw = 1, /* vsync_len (2) - 1 */ + .vfp = 2, /* lower_margin */ + .vbp = 7, /* upper_margin (8) - 1 */ + + .pixel_clock = LCD_PIXCLOCK_MAX, + + .init = sdp4430_panel_init, + .cleanup = sdp4430_panel_cleanup, + .enable = sdp4430_panel_enable, + .disable = sdp4430_panel_disable, + .get_caps = sdp4430_panel_get_caps, +}; + +static int sdp4430_panel_probe(struct platform_device *pdev) +{ + omapfb_register_panel(&sdp4430_panel); + return 0; +} + +static int sdp4430_panel_remove(struct platform_device *pdev) +{ + return 0; +} +static int sdp4430_panel_suspend(struct platform_device *pdev, + pm_message_t mesg) +{ + return 0; +} + +static int sdp4430_panel_resume(struct platform_device *pdev) +{ + return 0; +} + +struct platform_driver sdp4430_panel_driver = { + .probe = sdp4430_panel_probe, + .remove = sdp4430_panel_remove, + .suspend = sdp4430_panel_suspend, + .resume = sdp4430_panel_resume, + + .driver = { + .name = "sdp4430_lcd", + .owner = THIS_MODULE, + }, +}; + +static int __init sdp4430_panel_drv_init(void) +{ + return platform_driver_register(&sdp4430_panel_driver); +} + +static void __exit sdp4430_panel_drv_exit(void) +{ + platform_driver_unregister(&sdp4430_panel_driver); + return; +} + +module_init(sdp4430_panel_drv_init); +module_exit(sdp4430_panel_drv_exit); diff --git a/drivers/video/omap/lcd_h3.c b/drivers/video/omap/lcd_h3.c index 2486237ebba5..f7264ea35d35 100644 --- a/drivers/video/omap/lcd_h3.c +++ b/drivers/video/omap/lcd_h3.c @@ -22,9 +22,9 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/i2c/tps65010.h> +#include <linux/omapfb.h> #include <mach/gpio.h> -#include <mach/omapfb.h> #define MODULE_NAME "omapfb-lcd_h3" diff --git a/drivers/video/omap/lcd_h4.c b/drivers/video/omap/lcd_h4.c index 6ff56430341b..d72df0c16d79 100644 --- a/drivers/video/omap/lcd_h4.c +++ b/drivers/video/omap/lcd_h4.c @@ -21,8 +21,7 @@ #include <linux/module.h> #include <linux/platform_device.h> - -#include <mach/omapfb.h> +#include <linux/omapfb.h> static int h4_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) { diff --git a/drivers/video/omap/lcd_inn1510.c b/drivers/video/omap/lcd_inn1510.c index 6953ed4b5820..f6e05d7f080b 100644 --- a/drivers/video/omap/lcd_inn1510.c +++ b/drivers/video/omap/lcd_inn1510.c @@ -22,9 +22,9 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/io.h> +#include <linux/omapfb.h> #include <mach/fpga.h> -#include <mach/omapfb.h> static int innovator1510_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) diff --git a/drivers/video/omap/lcd_inn1610.c b/drivers/video/omap/lcd_inn1610.c index 4c4f7ee6d733..c599e41f9a42 100644 --- a/drivers/video/omap/lcd_inn1610.c +++ b/drivers/video/omap/lcd_inn1610.c @@ -21,9 +21,9 @@ #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/omapfb.h> #include <mach/gpio.h> -#include <mach/omapfb.h> #define MODULE_NAME "omapfb-lcd_h3" diff --git a/drivers/video/omap/lcd_osk.c b/drivers/video/omap/lcd_osk.c index 379c96d36da5..d6b193ec6a82 100644 --- a/drivers/video/omap/lcd_osk.c +++ b/drivers/video/omap/lcd_osk.c @@ -22,10 +22,10 @@ #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/omapfb.h> #include <mach/gpio.h> #include <mach/mux.h> -#include <mach/omapfb.h> static int osk_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) { diff --git a/drivers/video/omap/lcd_palmte.c b/drivers/video/omap/lcd_palmte.c index 218317366e6e..dcb456c39959 100644 --- a/drivers/video/omap/lcd_palmte.c +++ b/drivers/video/omap/lcd_palmte.c @@ -22,9 +22,9 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/io.h> +#include <linux/omapfb.h> #include <mach/fpga.h> -#include <mach/omapfb.h> static int palmte_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) diff --git a/drivers/video/omap/lcd_palmtt.c b/drivers/video/omap/lcd_palmtt.c index 57b0f6cf6a5a..e8adab8a76fa 100644 --- a/drivers/video/omap/lcd_palmtt.c +++ b/drivers/video/omap/lcd_palmtt.c @@ -28,9 +28,9 @@ GPIO13 - screen blanking #include <linux/platform_device.h> #include <linux/module.h> #include <linux/io.h> +#include <linux/omapfb.h> #include <mach/gpio.h> -#include <mach/omapfb.h> static int palmtt_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) diff --git a/drivers/video/omap/lcd_palmz71.c b/drivers/video/omap/lcd_palmz71.c index d33d78b11723..d5b3f82b26a2 100644 --- a/drivers/video/omap/lcd_palmz71.c +++ b/drivers/video/omap/lcd_palmz71.c @@ -23,8 +23,7 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/io.h> - -#include <mach/omapfb.h> +#include <linux/omapfb.h> static int palmz71_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) diff --git a/drivers/video/omap/lcdc.c b/drivers/video/omap/lcdc.c index ab3949256677..633e33ce54a6 100644 --- a/drivers/video/omap/lcdc.c +++ b/drivers/video/omap/lcdc.c @@ -28,9 +28,9 @@ #include <linux/dma-mapping.h> #include <linux/vmalloc.h> #include <linux/clk.h> +#include <linux/omapfb.h> #include <mach/dma.h> -#include <mach/omapfb.h> #include <asm/mach-types.h> diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c index 8862233d57b6..30e1f0412777 100644 --- a/drivers/video/omap/omapfb_main.c +++ b/drivers/video/omap/omapfb_main.c @@ -27,9 +27,9 @@ #include <linux/platform_device.h> #include <linux/mm.h> #include <linux/uaccess.h> +#include <linux/omapfb.h> #include <mach/dma.h> -#include <mach/omapfb.h> #include "lcdc.h" #include "dispc.h" @@ -577,7 +577,11 @@ static int set_fb_var(struct fb_info *fbi, var->grayscale = 0; /* pixclock in ps, the rest in pixclock */ +#ifndef CONFIG_MACH_OMAP_4430SDP var->pixclock = 10000000 / (panel->pixel_clock / 100); +#else + var->pixclock = 0; +#endif var->left_margin = panel->hfp; var->right_margin = panel->hbp; var->upper_margin = panel->vfp; diff --git a/drivers/video/omap/rfbi.c b/drivers/video/omap/rfbi.c index 9332d6ca6456..690a48bbc6de 100644 --- a/drivers/video/omap/rfbi.c +++ b/drivers/video/omap/rfbi.c @@ -26,8 +26,7 @@ #include <linux/interrupt.h> #include <linux/clk.h> #include <linux/io.h> - -#include <mach/omapfb.h> +#include <linux/omapfb.h> #include "dispc.h" diff --git a/drivers/video/omap/sossi.c b/drivers/video/omap/sossi.c index a76946220249..cab398f81ecc 100644 --- a/drivers/video/omap/sossi.c +++ b/drivers/video/omap/sossi.c @@ -23,9 +23,9 @@ #include <linux/clk.h> #include <linux/irq.h> #include <linux/io.h> +#include <linux/omapfb.h> #include <mach/dma.h> -#include <mach/omapfb.h> #include "lcdc.h" diff --git a/drivers/video/omap2/Kconfig b/drivers/video/omap2/Kconfig new file mode 100644 index 000000000000..89bf2107bb2a --- /dev/null +++ b/drivers/video/omap2/Kconfig @@ -0,0 +1,3 @@ +source "drivers/video/omap2/dss/Kconfig" +source "drivers/video/omap2/displays/Kconfig" +source "drivers/video/omap2/omapfb/Kconfig" diff --git a/drivers/video/omap2/Makefile b/drivers/video/omap2/Makefile new file mode 100644 index 000000000000..93e90e20e9ad --- /dev/null +++ b/drivers/video/omap2/Makefile @@ -0,0 +1,5 @@ +# OMAP2/3 Display Subsystem +obj-y += dss/ +obj-y += displays/ +obj-y += omapfb/ + diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig new file mode 100644 index 000000000000..0be61486880c --- /dev/null +++ b/drivers/video/omap2/displays/Kconfig @@ -0,0 +1,43 @@ +menu "OMAP2/3 Display Device Drivers" + depends on OMAP2_DSS + +config PANEL_GENERIC + tristate "Generic Panel" + help + Generic panel driver. + Used for DVI output for Beagle and OMAP3 SDP. + +config PANEL_SAMSUNG_LTE430WQ_F0C + tristate "Samsung LTE430WQ-F0C LCD Panel" + depends on OMAP2_DSS + help + LCD Panel used on Overo Palo43 + +config PANEL_SHARP_LS037V7DW01 + tristate "Sharp LS037V7DW01 LCD Panel" + depends on OMAP2_DSS + help + LCD Panel used in TI's SDP3430 and EVM boards + +config PANEL_N800 + tristate "Panel N8x0" + help + N8x0 LCD (hack) + +config CTRL_BLIZZARD + tristate "Blizzard Controller" + help + Blizzard Controller (hack) + +config PANEL_ACX565AKM + tristate "ACX565AKM LCD Panel" + depends on OMAP2_DSS_SDI + select BACKLIGHT_CLASS_DEVICE + help + LCD Panel used in RX51 + +config LCD_4430SDP + tristate "OMAP4 LCD Panel" + help + LCD Panel used in OMAP4 +endmenu diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile new file mode 100644 index 000000000000..dc382ed0ba1b --- /dev/null +++ b/drivers/video/omap2/displays/Makefile @@ -0,0 +1,9 @@ +obj-$(CONFIG_PANEL_GENERIC) += panel-generic.o +obj-$(CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C) += panel-samsung-lte430wq-f0c.o +obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o + +obj-$(CONFIG_CTRL_BLIZZARD) += ctrl-blizzard.o +obj-$(CONFIG_PANEL_N800) += panel-n800.o + +obj-$(CONFIG_PANEL_ACX565AKM) += panel-acx565akm.o +obj-$(CONFIG_LCD_4430SDP) += lcd_4430sdp.o diff --git a/drivers/video/omap2/displays/ctrl-blizzard.c b/drivers/video/omap2/displays/ctrl-blizzard.c new file mode 100644 index 000000000000..6698e4df8368 --- /dev/null +++ b/drivers/video/omap2/displays/ctrl-blizzard.c @@ -0,0 +1,279 @@ + +//#define DEBUG + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/err.h> + +#include <mach/display.h> +#include <mach/dma.h> + +#ifdef DEBUG +#define DBG(format, ...) printk(KERN_DEBUG "Blizzard: " format, ## __VA_ARGS__) +#else +#define DBG(format, ...) +#endif + +#define BLIZZARD_REV_CODE 0x00 +#define BLIZZARD_CONFIG 0x02 +#define BLIZZARD_PLL_DIV 0x04 +#define BLIZZARD_PLL_LOCK_RANGE 0x06 +#define BLIZZARD_PLL_CLOCK_SYNTH_0 0x08 +#define BLIZZARD_PLL_CLOCK_SYNTH_1 0x0a +#define BLIZZARD_PLL_MODE 0x0c +#define BLIZZARD_CLK_SRC 0x0e +#define BLIZZARD_MEM_BANK0_ACTIVATE 0x10 +#define BLIZZARD_MEM_BANK0_STATUS 0x14 +#define BLIZZARD_PANEL_CONFIGURATION 0x28 +#define BLIZZARD_HDISP 0x2a +#define BLIZZARD_HNDP 0x2c +#define BLIZZARD_VDISP0 0x2e +#define BLIZZARD_VDISP1 0x30 +#define BLIZZARD_VNDP 0x32 +#define BLIZZARD_HSW 0x34 +#define BLIZZARD_VSW 0x38 +#define BLIZZARD_DISPLAY_MODE 0x68 +#define BLIZZARD_INPUT_WIN_X_START_0 0x6c +#define BLIZZARD_DATA_SOURCE_SELECT 0x8e +#define BLIZZARD_DISP_MEM_DATA_PORT 0x90 +#define BLIZZARD_DISP_MEM_READ_ADDR0 0x92 +#define BLIZZARD_POWER_SAVE 0xE6 +#define BLIZZARD_NDISP_CTRL_STATUS 0xE8 + +/* Data source select */ +/* For S1D13745 */ +#define BLIZZARD_SRC_WRITE_LCD_BACKGROUND 0x00 +#define BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE 0x01 +#define BLIZZARD_SRC_WRITE_OVERLAY_ENABLE 0x04 +#define BLIZZARD_SRC_DISABLE_OVERLAY 0x05 +/* For S1D13744 */ +#define BLIZZARD_SRC_WRITE_LCD 0x00 +#define BLIZZARD_SRC_BLT_LCD 0x06 + +#define BLIZZARD_COLOR_RGB565 0x01 +#define BLIZZARD_COLOR_YUV420 0x09 + +#define BLIZZARD_VERSION_S1D13745 0x01 /* Hailstorm */ +#define BLIZZARD_VERSION_S1D13744 0x02 /* Blizzard */ + +#define BLIZZARD_AUTO_UPDATE_TIME (HZ / 20) + + + +static struct { + int version; +} blizzard; + + +static inline void blizzard_cmd(u8 cmd) +{ + omap_rfbi_write_command(&cmd, 1); +} + +static inline void blizzard_write(u8 cmd, const u8 *buf, int len) +{ + omap_rfbi_write_command(&cmd, 1); + omap_rfbi_write_data(buf, len); +} + +static inline void blizzard_read(u8 cmd, u8 *buf, int len) +{ + omap_rfbi_write_command(&cmd, 1); + omap_rfbi_read_data(buf, len); +} + +static u8 blizzard_read_reg(u8 cmd) +{ + u8 data; + blizzard_read(cmd, &data, 1); + return data; +} + +static int blizzard_ctrl_init(struct omap_display *display) +{ + DBG("blizzard_ctrl_init\n"); + + return 0; +} + + +static int blizzard_ctrl_enable(struct omap_display *display) +{ + int r = 0; + u8 rev, conf; + + DBG("blizzard_ctrl_enable\n"); + + if (display->hw_config.ctrl_enable) { + r = display->hw_config.ctrl_enable(display); + if (r) + return r; + } + + msleep(100); + + rev = blizzard_read_reg(BLIZZARD_CLK_SRC); + printk("CLK_SRC %x\n", rev); + + rev = blizzard_read_reg(BLIZZARD_PLL_DIV); + printk("PLLDIV %x\n", rev); + + rev = blizzard_read_reg(BLIZZARD_REV_CODE); + conf = blizzard_read_reg(BLIZZARD_CONFIG); + + printk("rev %x, conf %x\n", rev, conf); + + switch (rev & 0xfc) { + case 0x9c: + blizzard.version = BLIZZARD_VERSION_S1D13744; + pr_info("omapfb: s1d13744 LCD controller rev %d " + "initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07); + break; + case 0xa4: + blizzard.version = BLIZZARD_VERSION_S1D13745; + pr_info("omapfb: s1d13745 LCD controller rev %d " + "initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07); + break; + default: + printk("invalid s1d1374x revision %02x\n", + rev); + r = -ENODEV; + } + + return r; +} + +static void blizzard_ctrl_disable(struct omap_display *display) +{ + DBG("blizzard_ctrl_disable\n"); + + if (display->hw_config.ctrl_disable) + display->hw_config.ctrl_disable(display); +} + +int rfbi_configure(int rfbi_module, int bpp, int lines); + +static void blizzard_ctrl_setup_update(struct omap_display *display, + u16 x, u16 y, u16 w, u16 h) +{ + u8 tmp[18]; + int x_end, y_end; + + DBG("blizzard_ctrl_setup_update\n"); + + x_end = x + w - 1; + y_end = y + h - 1; + + tmp[0] = x; + tmp[1] = x >> 8; + tmp[2] = y; + tmp[3] = y >> 8; + tmp[4] = x_end; + tmp[5] = x_end >> 8; + tmp[6] = y_end; + tmp[7] = y_end >> 8; + + /* scaling? */ + tmp[8] = x; + tmp[9] = x >> 8; + tmp[10] = y; + tmp[11] = y >> 8; + tmp[12] = x_end; + tmp[13] = x_end >> 8; + tmp[14] = y_end; + tmp[15] = y_end >> 8; + + tmp[16] = BLIZZARD_COLOR_RGB565; //color_mode; + + if (blizzard.version == BLIZZARD_VERSION_S1D13745) + tmp[17] = BLIZZARD_SRC_WRITE_LCD_BACKGROUND; + else + tmp[17] = blizzard.version == BLIZZARD_VERSION_S1D13744 ? + BLIZZARD_SRC_WRITE_LCD : + BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE; + + rfbi_configure(display->hw_config.u.rfbi.channel, + 16, + 8); + + blizzard_write(BLIZZARD_INPUT_WIN_X_START_0, tmp, 18); + + rfbi_configure(display->hw_config.u.rfbi.channel, + 16, + 16); +} + +static int blizzard_ctrl_enable_te(struct omap_display *display, bool enable) +{ + return 0; +} + +static int blizzard_ctrl_rotate(struct omap_display *display, u8 rotate) +{ + return 0; +} + +static int blizzard_ctrl_mirror(struct omap_display *display, bool enable) +{ + return 0; +} + +static int blizzard_run_test(struct omap_display *display, int test_num) +{ + return 0; +} + +static struct omap_ctrl blizzard_ctrl = { + .owner = THIS_MODULE, + .name = "ctrl-blizzard", + .init = blizzard_ctrl_init, + .enable = blizzard_ctrl_enable, + .disable = blizzard_ctrl_disable, + .setup_update = blizzard_ctrl_setup_update, + .enable_te = blizzard_ctrl_enable_te, + .set_rotate = blizzard_ctrl_rotate, + .set_mirror = blizzard_ctrl_mirror, + .run_test = blizzard_run_test, + .pixel_size = 16, + + .timings = { + .cs_on_time = 0, + + .we_on_time = 9000, + .we_off_time = 18000, + .we_cycle_time = 36000, + + .re_on_time = 9000, + .re_off_time = 27000, + .re_cycle_time = 36000, + + .access_time = 27000, + .cs_off_time = 36000, + + .cs_pulse_width = 0, + }, +}; + + +static int __init blizzard_init(void) +{ + DBG("blizzard_init\n"); + omap_dss_register_ctrl(&blizzard_ctrl); + return 0; +} + +static void __exit blizzard_exit(void) +{ + DBG("blizzard_exit\n"); + + omap_dss_unregister_ctrl(&blizzard_ctrl); +} + +module_init(blizzard_init); +module_exit(blizzard_exit); + +MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>"); +MODULE_DESCRIPTION("Blizzard Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/omap2/displays/lcd_4430sdp.c b/drivers/video/omap2/displays/lcd_4430sdp.c new file mode 100644 index 000000000000..a878d6c19ac2 --- /dev/null +++ b/drivers/video/omap2/displays/lcd_4430sdp.c @@ -0,0 +1,125 @@ +/* + * lcd4430_sdp panel support + * + * Copyright (C) 2009 Texas Instruments + * Author: Mayuresh Janorkar <mayur@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, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/module.h> +#include <linux/delay.h> +#include <linux/platform_device.h> +#include <linux/i2c/twl.h> +#include <linux/spi/spi.h> + +#include <mach/gpio.h> +#include <mach/gpio.h> +#include <mach/mux.h> +#include <asm/mach-types.h> +#include <mach/control.h> + +#include <mach/display.h> + +#define LCD_XRES 800 +#define LCD_YRES 480 +#define LCD_PIXCLOCK_MAX 21625 + +/*NEC NL8048HL11-01B Manual + * defines HFB, HSW, HBP, VFP, VSW, VBP as shown below + */ + +static struct omap_video_timings lcd_4430_sdp_panel_timings = { + /* 800 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */ + .x_res = LCD_XRES, + .y_res = LCD_YRES, + .pixel_clock = LCD_PIXCLOCK_MAX, + .hfp = 6, + .hsw = 1, + .hbp = 4, + .vfp = 3, + .vsw = 1, + .vbp = 4, +}; + +static int lcd_4430_sdp_panel_probe(struct omap_dss_device *dssdev) +{ + dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | + OMAP_DSS_LCD_IHS; + dssdev->panel.timings = lcd_4430_sdp_panel_timings; + + return 0; +} + +static void lcd_4430_sdp_panel_remove(struct omap_dss_device *dssdev) +{ +} + +static int lcd_4430_sdp_panel_enable(struct omap_dss_device *dssdev) +{ + int r = 0; + mdelay(4); + if (dssdev->platform_enable) + r = dssdev->platform_enable(dssdev); + /* Enable LCD-Enable bit in DISPC_CONTROL */ + omap_writel((omap_readl(0x48043040) | 0x1), 0x48043040); + return r; +} + +static void lcd_4430_sdp_panel_disable(struct omap_dss_device *dssdev) +{ + if (dssdev->platform_disable) + dssdev->platform_disable(dssdev); + mdelay(4); +} + +static int lcd_4430_sdp_panel_suspend(struct omap_dss_device *dssdev) +{ + lcd_4430_sdp_panel_disable(dssdev); + return 0; +} + +static int lcd_4430_sdp_panel_resume(struct omap_dss_device *dssdev) +{ + return lcd_4430_sdp_panel_enable(dssdev); +} + +static struct omap_dss_driver lcd_4430_sdp_driver = { + .probe = lcd_4430_sdp_panel_probe, + .remove = lcd_4430_sdp_panel_remove, + + .enable = lcd_4430_sdp_panel_enable, + .disable = lcd_4430_sdp_panel_disable, + .suspend = lcd_4430_sdp_panel_suspend, + .resume = lcd_4430_sdp_panel_resume, + + .driver = { + .name = "sdp4430_panel", + .owner = THIS_MODULE, + }, +}; + +static int __init lcd_4430_sdp_lcd_init(void) +{ + + return omap_dss_register_driver(&lcd_4430_sdp_driver); +} + +static void __exit lcd_4430_sdp_lcd_exit(void) +{ + return omap_dss_unregister_driver(&lcd_4430_sdp_driver); +} + +module_init(lcd_4430_sdp_lcd_init); +module_exit(lcd_4430_sdp_lcd_exit); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c new file mode 100644 index 000000000000..2679d6c2a6dc --- /dev/null +++ b/drivers/video/omap2/displays/panel-acx565akm.c @@ -0,0 +1,712 @@ +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/clk.h> +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/spi/spi.h> +#include <linux/jiffies.h> +#include <linux/sched.h> +#include <linux/backlight.h> +#include <linux/fb.h> + +#include <mach/display.h> +#include <mach/dma.h> + +#include "panel-acx565akm.h" + +#define MIPID_CMD_READ_DISP_ID 0x04 +#define MIPID_CMD_READ_RED 0x06 +#define MIPID_CMD_READ_GREEN 0x07 +#define MIPID_CMD_READ_BLUE 0x08 +#define MIPID_CMD_READ_DISP_STATUS 0x09 +#define MIPID_CMD_RDDSDR 0x0F +#define MIPID_CMD_SLEEP_IN 0x10 +#define MIPID_CMD_SLEEP_OUT 0x11 +#define MIPID_CMD_DISP_OFF 0x28 +#define MIPID_CMD_DISP_ON 0x29 +#define MIPID_CMD_WRITE_DISP_BRIGHTNESS 0x51 +#define MIPID_CMD_READ_DISP_BRIGHTNESS 0x52 +#define MIPID_CMD_WRITE_CTRL_DISP 0x53 + +#define CTRL_DISP_BRIGHTNESS_CTRL_ON (1 << 5) +#define CTRL_DISP_AMBIENT_LIGHT_CTRL_ON (1 << 4) +#define CTRL_DISP_BACKLIGHT_ON (1 << 2) +#define CTRL_DISP_AUTO_BRIGHTNESS_ON (1 << 1) + +#define MIPID_CMD_READ_CTRL_DISP 0x54 +#define MIPID_CMD_WRITE_CABC 0x55 +#define MIPID_CMD_READ_CABC 0x56 + +#define MIPID_VER_LPH8923 3 +#define MIPID_VER_LS041Y3 4 +#define MIPID_VER_L4F00311 8 +#define MIPID_VER_ACX565AKM 9 + +struct acx565akm_device { + struct backlight_device *bl_dev; + int enabled; + int model; + int revision; + u8 display_id[3]; + int has_bc:1; + int has_cabc:1; + unsigned int saved_bklight_level; + unsigned long hw_guard_end; /* next value of jiffies + when we can issue the + next sleep in/out command */ + unsigned long hw_guard_wait; /* max guard time in jiffies */ + + struct spi_device *spi; + struct mutex mutex; + struct omap_panel panel; + struct omap_display *display; +}; + +static int acx565akm_bl_update_status(struct backlight_device *dev); + +static void acx565akm_transfer(struct acx565akm_device *md, int cmd, + const u8 *wbuf, int wlen, u8 *rbuf, int rlen) +{ + struct spi_message m; + struct spi_transfer *x, xfer[5]; + int r; + + BUG_ON(md->spi == NULL); + + spi_message_init(&m); + + memset(xfer, 0, sizeof(xfer)); + x = &xfer[0]; + + cmd &= 0xff; + x->tx_buf = &cmd; + x->bits_per_word = 9; + x->len = 2; + + if (rlen > 1 && wlen == 0) { + /* + * Between the command and the response data there is a + * dummy clock cycle. Add an extra bit after the command + * word to account for this. + */ + x->bits_per_word = 10; + cmd <<= 1; + } + spi_message_add_tail(x, &m); + + if (wlen) { + x++; + x->tx_buf = wbuf; + x->len = wlen; + x->bits_per_word = 9; + spi_message_add_tail(x, &m); + } + + if (rlen) { + x++; + x->rx_buf = rbuf; + x->len = rlen; + spi_message_add_tail(x, &m); + } + + r = spi_sync(md->spi, &m); + if (r < 0) + dev_dbg(&md->spi->dev, "spi_sync %d\n", r); +} + +static inline void acx565akm_cmd(struct acx565akm_device *md, int cmd) +{ + acx565akm_transfer(md, cmd, NULL, 0, NULL, 0); +} + +static inline void acx565akm_write(struct acx565akm_device *md, + int reg, const u8 *buf, int len) +{ + acx565akm_transfer(md, reg, buf, len, NULL, 0); +} + +static inline void acx565akm_read(struct acx565akm_device *md, + int reg, u8 *buf, int len) +{ + acx565akm_transfer(md, reg, NULL, 0, buf, len); +} + +static void hw_guard_start(struct acx565akm_device *md, int guard_msec) +{ + md->hw_guard_wait = msecs_to_jiffies(guard_msec); + md->hw_guard_end = jiffies + md->hw_guard_wait; +} + +static void hw_guard_wait(struct acx565akm_device *md) +{ + unsigned long wait = md->hw_guard_end - jiffies; + + if ((long)wait > 0 && wait <= md->hw_guard_wait) { + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(wait); + } +} + +static void set_sleep_mode(struct acx565akm_device *md, int on) +{ + int cmd, sleep_time = 50; + + if (on) + cmd = MIPID_CMD_SLEEP_IN; + else + cmd = MIPID_CMD_SLEEP_OUT; + hw_guard_wait(md); + acx565akm_cmd(md, cmd); + hw_guard_start(md, 120); + /* + * When we enable the panel, it seems we _have_ to sleep + * 120 ms before sending the init string. When disabling the + * panel we'll sleep for the duration of 2 frames, so that the + * controller can still provide the PCLK,HS,VS signals. */ + if (!on) + sleep_time = 120; + msleep(sleep_time); +} + +static void set_display_state(struct acx565akm_device *md, int enabled) +{ + int cmd = enabled ? MIPID_CMD_DISP_ON : MIPID_CMD_DISP_OFF; + + acx565akm_cmd(md, cmd); +} + +static int panel_enabled(struct acx565akm_device *md) +{ + u32 disp_status; + int enabled; + + acx565akm_read(md, MIPID_CMD_READ_DISP_STATUS, (u8 *)&disp_status, 4); + disp_status = __be32_to_cpu(disp_status); + enabled = (disp_status & (1 << 17)) && (disp_status & (1 << 10)); + dev_dbg(&md->spi->dev, + "LCD panel %senabled by bootloader (status 0x%04x)\n", + enabled ? "" : "not ", disp_status); + return enabled; +} + +static void enable_backlight_ctrl(struct acx565akm_device *md, int enable) +{ + u16 ctrl; + + acx565akm_read(md, MIPID_CMD_READ_CTRL_DISP, (u8 *)&ctrl, 1); + if (enable) { + ctrl |= CTRL_DISP_BRIGHTNESS_CTRL_ON | + CTRL_DISP_BACKLIGHT_ON; + } else { + ctrl &= ~(CTRL_DISP_BRIGHTNESS_CTRL_ON | + CTRL_DISP_BACKLIGHT_ON); + } + + ctrl |= 1 << 8; + acx565akm_write(md, MIPID_CMD_WRITE_CTRL_DISP, (u8 *)&ctrl, 2); +} + +static void set_cabc_mode(struct acx565akm_device *md, int mode) +{ + u16 cabc_ctrl; + + cabc_ctrl = 0; + acx565akm_read(md, MIPID_CMD_READ_CABC, (u8 *)&cabc_ctrl, 1); + cabc_ctrl &= ~3; + cabc_ctrl |= (1 << 8) | (mode & 3); + acx565akm_write(md, MIPID_CMD_WRITE_CABC, (u8 *)&cabc_ctrl, 2); +} + +static int get_cabc_mode(struct acx565akm_device *md) +{ + u8 cabc_ctrl; + + acx565akm_read(md, MIPID_CMD_READ_CABC, &cabc_ctrl, 1); + return cabc_ctrl & 3; +} + +static int panel_detect(struct acx565akm_device *md) +{ + acx565akm_read(md, MIPID_CMD_READ_DISP_ID, md->display_id, 3); + dev_dbg(&md->spi->dev, "MIPI display ID: %02x%02x%02x\n", + md->display_id[0], md->display_id[1], md->display_id[2]); + + switch (md->display_id[0]) { + case 0x10: + md->model = MIPID_VER_ACX565AKM; + md->panel.name = "acx565akm"; + md->has_bc = 1; + md->has_cabc = 1; + break; + case 0x29: + md->model = MIPID_VER_L4F00311; + md->panel.name = "l4f00311"; + break; + case 0x45: + md->model = MIPID_VER_LPH8923; + md->panel.name = "lph8923"; + break; + case 0x83: + md->model = MIPID_VER_LS041Y3; + md->panel.name = "ls041y3"; + break; + default: + md->panel.name = "unknown"; + dev_err(&md->spi->dev, "invalid display ID\n"); + return -ENODEV; + } + + md->revision = md->display_id[1]; + + pr_info("omapfb: %s rev %02x LCD detected\n", + md->panel.name, md->revision); + + return 0; +} + +static int acx565akm_panel_enable(struct omap_display *display) +{ + struct acx565akm_device *md = + (struct acx565akm_device *)display->panel->priv; + + dev_dbg(&md->spi->dev, "%s\n", __func__); + + mutex_lock(&md->mutex); + + if (display->hw_config.panel_enable) + display->hw_config.panel_enable(display); + + md->enabled = panel_enabled(md); + + if (md->enabled) { + dev_dbg(&md->spi->dev, "panel already enabled\n"); + mutex_unlock(&md->mutex); + return 0; + } + + set_sleep_mode(md, 0); + md->enabled = 1; + set_display_state(md, 1); + + mutex_unlock(&md->mutex); + + return acx565akm_bl_update_status(md->bl_dev); +} + +static void acx565akm_panel_disable(struct omap_display *display) +{ + struct acx565akm_device *md = + (struct acx565akm_device *)display->panel->priv; + + dev_dbg(&md->spi->dev, "%s\n", __func__); + + mutex_lock(&md->mutex); + + if (!md->enabled) { + mutex_unlock(&md->mutex); + return; + } + set_display_state(md, 0); + set_sleep_mode(md, 1); + md->enabled = 0; + + if (display->hw_config.panel_disable) + display->hw_config.panel_disable(display); + + mutex_unlock(&md->mutex); +} + +#if 0 +static void acx565akm_set_mode(struct omap_display *display, + int x_res, int y_res, int bpp) +{ + struct acx565akm_device *md = + (struct acx565akm_device *)display->panel->priv; + u16 par; + + switch (bpp) { + case 16: + par = 0x150; + break; + case 18: + par = 0x160; + break; + case 24: + par = 0x170; + break; + } + + acx565akm_write(md, 0x3a, (u8 *)&par, 2); +} +#endif + +static int acx565akm_panel_suspend(struct omap_display *display) +{ + acx565akm_panel_disable(display); + return 0; +} + +static int acx565akm_panel_resume(struct omap_display *display) +{ + return acx565akm_panel_enable(display); +} + +static void acx565akm_set_brightness(struct acx565akm_device *md, int level) +{ + int bv; + + bv = level | (1 << 8); + acx565akm_write(md, MIPID_CMD_WRITE_DISP_BRIGHTNESS, (u8 *)&bv, 2); + + if (level) + enable_backlight_ctrl(md, 1); + else + enable_backlight_ctrl(md, 0); +} + +static int acx565akm_get_actual_brightness(struct acx565akm_device *md) +{ + u8 bv; + + acx565akm_read(md, MIPID_CMD_READ_DISP_BRIGHTNESS, &bv, 1); + + return bv; +} + +static int acx565akm_bl_update_status(struct backlight_device *dev) +{ + struct acx565akm_device *md = dev_get_drvdata(&dev->dev); + struct omap_display *display = md->display; + int r; + int level; + + dev_dbg(&md->spi->dev, "%s\n", __func__); + + if (display->hw_config.set_backlight == NULL) + return -ENODEV; + + mutex_lock(&md->mutex); + + if (dev->props.fb_blank == FB_BLANK_UNBLANK && + dev->props.power == FB_BLANK_UNBLANK) + level = dev->props.brightness; + else + level = 0; + + r = 0; + if (md->has_bc) + acx565akm_set_brightness(md, level); + else + if (display->hw_config.set_backlight != NULL) + r = display->hw_config.set_backlight(display, level); + else + r = -ENODEV; + + mutex_unlock(&md->mutex); + + return r; +} + +static int acx565akm_bl_get_intensity(struct backlight_device *dev) +{ + struct acx565akm_device *md = dev_get_drvdata(&dev->dev); + struct omap_display *display = md->display; + + dev_dbg(&dev->dev, "%s\n", __func__); + + if (md->has_bc && display->hw_config.set_backlight == NULL) + return -ENODEV; + + if (dev->props.fb_blank == FB_BLANK_UNBLANK && + dev->props.power == FB_BLANK_UNBLANK) { + if (md->has_bc) + return acx565akm_get_actual_brightness(md); + else + return dev->props.brightness; + } + + return 0; +} + +static struct backlight_ops acx565akm_bl_ops = { + .get_brightness = acx565akm_bl_get_intensity, + .update_status = acx565akm_bl_update_status, +}; + +static const char *cabc_modes[] = { + "off", /* used also always when CABC is not supported */ + "ui", + "still-image", + "moving-image", +}; + +static ssize_t show_cabc_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct acx565akm_device *md = dev_get_drvdata(dev); + const char *mode_str; + int mode; + int len; + + if (!md->has_cabc) + mode = 0; + else + mode = get_cabc_mode(md); + mode_str = "unknown"; + if (mode >= 0 && mode < ARRAY_SIZE(cabc_modes)) + mode_str = cabc_modes[mode]; + len = snprintf(buf, PAGE_SIZE, "%s\n", mode_str); + + return len < PAGE_SIZE - 1 ? len : PAGE_SIZE - 1; +} + +static ssize_t store_cabc_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct acx565akm_device *md = dev_get_drvdata(dev); + int i; + + for (i = 0; i < ARRAY_SIZE(cabc_modes); i++) { + const char *mode_str = cabc_modes[i]; + int cmp_len = strlen(mode_str); + + if (count > 0 && buf[count - 1] == '\n') + count--; + if (count != cmp_len) + continue; + + if (strncmp(buf, mode_str, cmp_len) == 0) + break; + } + + if (i == ARRAY_SIZE(cabc_modes)) + return -EINVAL; + + if (!md->has_cabc && i != 0) + return -EINVAL; + + mutex_lock(&md->mutex); + set_cabc_mode(md, i); + mutex_unlock(&md->mutex); + + return count; +} + +static ssize_t show_cabc_available_modes(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct acx565akm_device *md = dev_get_drvdata(dev); + int len; + int i; + + if (!md->has_cabc) + return snprintf(buf, PAGE_SIZE, "%s\n", cabc_modes[0]); + + for (i = 0, len = 0; + len < PAGE_SIZE && i < ARRAY_SIZE(cabc_modes); i++) + len += snprintf(&buf[len], PAGE_SIZE - len, "%s%s%s", + i ? " " : "", cabc_modes[i], + i == ARRAY_SIZE(cabc_modes) - 1 ? "\n" : ""); + + return len < PAGE_SIZE ? len : PAGE_SIZE - 1; +} + +static DEVICE_ATTR(cabc_mode, S_IRUGO | S_IWUSR, + show_cabc_mode, store_cabc_mode); +static DEVICE_ATTR(cabc_available_modes, S_IRUGO, + show_cabc_available_modes, NULL); + +static struct attribute *bldev_attrs[] = { + &dev_attr_cabc_mode.attr, + &dev_attr_cabc_available_modes.attr, + NULL, +}; + +static struct attribute_group bldev_attr_group = { + .attrs = bldev_attrs, +}; + +static int acx565akm_panel_init(struct omap_display *display) +{ + struct omap_panel *panel = display->panel; + struct acx565akm_panel_data *panel_data = display->hw_config.panel_data; + struct acx565akm_device *md = (struct acx565akm_device *)panel->priv; + + struct backlight_device *bldev; + int brightness; + int max_brightness; + int r; + + dev_dbg(&md->spi->dev, "%s\n", __func__); + + if (!panel_data) { + dev_err(&md->spi->dev, "no panel data\n"); + return -ENODEV; + } + + mutex_init(&md->mutex); + md->display = display; + + if (display->hw_config.panel_enable) + display->hw_config.panel_enable(display); + + md->enabled = panel_enabled(md); + + r = panel_detect(md); + if (r) { + if (!md->enabled && display->hw_config.panel_disable) + display->hw_config.panel_disable(display); + mutex_unlock(&md->mutex); + return r; + } + + if (!panel_data->bc_connected) { + md->has_bc = 0; + md->has_cabc = 0; + } + +#if 0 + acx565akm_set_mode(display, panel->timings.x_res, panel->timings.y_res, + panel->bpp); +#endif + + if (!md->enabled) + display->hw_config.panel_disable(display); + + bldev = backlight_device_register("acx565akm", &md->spi->dev, + md, &acx565akm_bl_ops); + md->bl_dev = bldev; + + if (md->has_cabc) { + r = sysfs_create_group(&bldev->dev.kobj, &bldev_attr_group); + if (r) { + dev_err(&bldev->dev, "failed to create sysfs files\n"); + backlight_device_unregister(bldev); + return r; + } + } + + bldev->props.fb_blank = FB_BLANK_UNBLANK; + bldev->props.power = FB_BLANK_UNBLANK; + + if (md->has_bc) + max_brightness = 255; + else + max_brightness = display->hw_config.max_backlight_level; + + if (md->has_bc) + brightness = acx565akm_get_actual_brightness(md); + else { + if (display->hw_config.get_backlight != NULL) + brightness = display->hw_config.get_backlight(display); + else + brightness = 0; + } + + bldev->props.max_brightness = max_brightness; + bldev->props.brightness = brightness; + acx565akm_bl_update_status(bldev); + + return 0; +} + +static struct omap_panel acx565akm_panel = { + .name = "panel-acx565akm", + .init = acx565akm_panel_init, + .suspend = acx565akm_panel_suspend, + .resume = acx565akm_panel_resume, + .enable = acx565akm_panel_enable, + .disable = acx565akm_panel_disable, + + .timings = { + .x_res = 800, + .y_res = 480, + + .pixel_clock = 24000, + + .hsw = 4, + .hfp = 16, + .hbp = 12, + + .vsw = 3, + .vfp = 3, + .vbp = 3, + }, + + .config = OMAP_DSS_LCD_TFT, + + .recommended_bpp = 16, + + /* + * supported modes: 12bpp(444), 16bpp(565), 18bpp(666), 24bpp(888) + * resolutions. + */ +}; + +static int acx565akm_spi_probe(struct spi_device *spi) +{ + struct acx565akm_device *md; + + dev_dbg(&md->spi->dev, "%s\n", __func__); + + md = kzalloc(sizeof(*md), GFP_KERNEL); + if (md == NULL) { + dev_err(&spi->dev, "out of memory\n"); + return -ENOMEM; + } + + spi->mode = SPI_MODE_3; + md->spi = spi; + dev_set_drvdata(&spi->dev, md); + md->panel = acx565akm_panel; + acx565akm_panel.priv = md; + + omap_dss_register_panel(&acx565akm_panel); + + return 0; +} + +static int acx565akm_spi_remove(struct spi_device *spi) +{ + struct acx565akm_device *md = dev_get_drvdata(&spi->dev); + + dev_dbg(&md->spi->dev, "%s\n", __func__); + + sysfs_remove_group(&md->bl_dev->dev.kobj, &bldev_attr_group); + backlight_device_unregister(md->bl_dev); + omap_dss_unregister_panel(&acx565akm_panel); + + kfree(md); + + return 0; +} + +static struct spi_driver acx565akm_spi_driver = { + .driver = { + .name = "acx565akm", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = acx565akm_spi_probe, + .remove = __devexit_p(acx565akm_spi_remove), +}; + +static int __init acx565akm_init(void) +{ + return spi_register_driver(&acx565akm_spi_driver); +} + +static void __exit acx565akm_exit(void) +{ + spi_unregister_driver(&acx565akm_spi_driver); +} + +module_init(acx565akm_init); +module_exit(acx565akm_exit); + +MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>"); +MODULE_DESCRIPTION("acx565akm LCD Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/omap2/displays/panel-acx565akm.h b/drivers/video/omap2/displays/panel-acx565akm.h new file mode 100644 index 000000000000..6d3727b4c7af --- /dev/null +++ b/drivers/video/omap2/displays/panel-acx565akm.h @@ -0,0 +1,9 @@ +#ifndef __DRIVERS_VIDEO_OMAP2_DISPLAYS_PANEL_ACX565AKM_H +#define __DRIVERS_VIDEO_OMAP2_DISPLAYS_PANEL_ACX565AKM_H + +struct acx565akm_panel_data { + unsigned bc_connected:1; +}; + +#endif + diff --git a/drivers/video/omap2/displays/panel-generic.c b/drivers/video/omap2/displays/panel-generic.c new file mode 100644 index 000000000000..738147eee49c --- /dev/null +++ b/drivers/video/omap2/displays/panel-generic.c @@ -0,0 +1,104 @@ +/* + * Generic panel support + * + * Copyright (C) 2008 Nokia Corporation + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.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, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/module.h> +#include <linux/delay.h> + +#include <mach/display.h> + +static struct omap_video_timings generic_panel_timings = { + /* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */ + .x_res = 640, + .y_res = 480, + .pixel_clock = 23500, + .hfp = 48, + .hsw = 32, + .hbp = 80, + .vfp = 3, + .vsw = 4, + .vbp = 7, +}; + +static int generic_panel_probe(struct omap_dss_device *dssdev) +{ + dssdev->panel.config = OMAP_DSS_LCD_TFT; + dssdev->panel.timings = generic_panel_timings; + + return 0; +} + +static void generic_panel_remove(struct omap_dss_device *dssdev) +{ +} + +static int generic_panel_enable(struct omap_dss_device *dssdev) +{ + int r = 0; + + if (dssdev->platform_enable) + r = dssdev->platform_enable(dssdev); + + return r; +} + +static void generic_panel_disable(struct omap_dss_device *dssdev) +{ + if (dssdev->platform_disable) + dssdev->platform_disable(dssdev); +} + +static int generic_panel_suspend(struct omap_dss_device *dssdev) +{ + generic_panel_disable(dssdev); + return 0; +} + +static int generic_panel_resume(struct omap_dss_device *dssdev) +{ + return generic_panel_enable(dssdev); +} + +static struct omap_dss_driver generic_driver = { + .probe = generic_panel_probe, + .remove = generic_panel_remove, + + .enable = generic_panel_enable, + .disable = generic_panel_disable, + .suspend = generic_panel_suspend, + .resume = generic_panel_resume, + + .driver = { + .name = "generic_panel", + .owner = THIS_MODULE, + }, +}; + +static int __init generic_panel_drv_init(void) +{ + return omap_dss_register_driver(&generic_driver); +} + +static void __exit generic_panel_drv_exit(void) +{ + omap_dss_unregister_driver(&generic_driver); +} + +module_init(generic_panel_drv_init); +module_exit(generic_panel_drv_exit); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/omap2/displays/panel-n800.c b/drivers/video/omap2/displays/panel-n800.c new file mode 100644 index 000000000000..91d3e37d6d4c --- /dev/null +++ b/drivers/video/omap2/displays/panel-n800.c @@ -0,0 +1,435 @@ + +/*#define DEBUG*/ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/clk.h> +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/spi/spi.h> +#include <linux/jiffies.h> +#include <linux/sched.h> +#include <linux/backlight.h> +#include <linux/fb.h> + +#include <mach/display.h> +#include <mach/dma.h> + +#define MIPID_CMD_READ_DISP_ID 0x04 +#define MIPID_CMD_READ_RED 0x06 +#define MIPID_CMD_READ_GREEN 0x07 +#define MIPID_CMD_READ_BLUE 0x08 +#define MIPID_CMD_READ_DISP_STATUS 0x09 +#define MIPID_CMD_RDDSDR 0x0F +#define MIPID_CMD_SLEEP_IN 0x10 +#define MIPID_CMD_SLEEP_OUT 0x11 +#define MIPID_CMD_DISP_OFF 0x28 +#define MIPID_CMD_DISP_ON 0x29 + +#define MIPID_VER_LPH8923 3 +#define MIPID_VER_LS041Y3 4 + +#define MIPID_ESD_CHECK_PERIOD msecs_to_jiffies(5000) + +#ifdef DEBUG +#define DBG(format, ...) printk(KERN_DEBUG "PN800: " format, ## __VA_ARGS__) +#else +#define DBG(format, ...) +#endif + +struct pn800_device { + struct backlight_device *bl_dev; + int enabled; + int model; + int revision; + u8 display_id[3]; + unsigned int saved_bklight_level; + unsigned long hw_guard_end; /* next value of jiffies + when we can issue the + next sleep in/out command */ + unsigned long hw_guard_wait; /* max guard time in jiffies */ + + struct spi_device *spi; + struct mutex mutex; + struct omap_panel panel; + struct omap_display *display; +}; + + +static void pn800_transfer(struct pn800_device *md, int cmd, + const u8 *wbuf, int wlen, u8 *rbuf, int rlen) +{ + struct spi_message m; + struct spi_transfer *x, xfer[4]; + u16 w; + int r; + + BUG_ON(md->spi == NULL); + + spi_message_init(&m); + + memset(xfer, 0, sizeof(xfer)); + x = &xfer[0]; + + cmd &= 0xff; + x->tx_buf = &cmd; + x->bits_per_word = 9; + x->len = 2; + spi_message_add_tail(x, &m); + + if (wlen) { + x++; + x->tx_buf = wbuf; + x->len = wlen; + x->bits_per_word = 9; + spi_message_add_tail(x, &m); + } + + if (rlen) { + x++; + x->rx_buf = &w; + x->len = 1; + spi_message_add_tail(x, &m); + + if (rlen > 1) { + /* Arrange for the extra clock before the first + * data bit. + */ + x->bits_per_word = 9; + x->len = 2; + + x++; + x->rx_buf = &rbuf[1]; + x->len = rlen - 1; + spi_message_add_tail(x, &m); + } + } + + r = spi_sync(md->spi, &m); + if (r < 0) + dev_dbg(&md->spi->dev, "spi_sync %d\n", r); + + if (rlen) + rbuf[0] = w & 0xff; +} + +static inline void pn800_cmd(struct pn800_device *md, int cmd) +{ + pn800_transfer(md, cmd, NULL, 0, NULL, 0); +} + +static inline void pn800_write(struct pn800_device *md, + int reg, const u8 *buf, int len) +{ + pn800_transfer(md, reg, buf, len, NULL, 0); +} + +static inline void pn800_read(struct pn800_device *md, + int reg, u8 *buf, int len) +{ + pn800_transfer(md, reg, NULL, 0, buf, len); +} + +static void set_data_lines(struct pn800_device *md, int data_lines) +{ + u16 par; + + switch (data_lines) { + case 16: + par = 0x150; + break; + case 18: + par = 0x160; + break; + case 24: + par = 0x170; + break; + } + pn800_write(md, 0x3a, (u8 *)&par, 2); +} + +static void send_init_string(struct pn800_device *md) +{ + u16 initpar[] = { 0x0102, 0x0100, 0x0100 }; + int data_lines; + + pn800_write(md, 0xc2, (u8 *)initpar, sizeof(initpar)); + + data_lines = (int)md->display->hw_config.panel_data; // XXX + + set_data_lines(md, data_lines); +} + +static void hw_guard_start(struct pn800_device *md, int guard_msec) +{ + md->hw_guard_wait = msecs_to_jiffies(guard_msec); + md->hw_guard_end = jiffies + md->hw_guard_wait; +} + +static void hw_guard_wait(struct pn800_device *md) +{ + unsigned long wait = md->hw_guard_end - jiffies; + + if ((long)wait > 0 && wait <= md->hw_guard_wait) { + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(wait); + } +} + +static void set_sleep_mode(struct pn800_device *md, int on) +{ + int cmd, sleep_time = 50; + + if (on) + cmd = MIPID_CMD_SLEEP_IN; + else + cmd = MIPID_CMD_SLEEP_OUT; + hw_guard_wait(md); + pn800_cmd(md, cmd); + hw_guard_start(md, 120); + /* + * When we enable the panel, it seems we _have_ to sleep + * 120 ms before sending the init string. When disabling the + * panel we'll sleep for the duration of 2 frames, so that the + * controller can still provide the PCLK,HS,VS signals. */ + if (!on) + sleep_time = 120; + msleep(sleep_time); +} + +static void set_display_state(struct pn800_device *md, int enabled) +{ + int cmd = enabled ? MIPID_CMD_DISP_ON : MIPID_CMD_DISP_OFF; + + pn800_cmd(md, cmd); +} + +static int panel_enabled(struct pn800_device *md) +{ + u32 disp_status; + int enabled; + + pn800_read(md, MIPID_CMD_READ_DISP_STATUS, (u8 *)&disp_status, 4); + disp_status = __be32_to_cpu(disp_status); + enabled = (disp_status & (1 << 17)) && (disp_status & (1 << 10)); + dev_dbg(&md->spi->dev, + "LCD panel %s enabled by bootloader (status 0x%04x)\n", + enabled ? "" : "not ", disp_status); + DBG("status %#08x\n", disp_status); + return enabled; +} + +static int panel_detect(struct pn800_device *md) +{ + pn800_read(md, MIPID_CMD_READ_DISP_ID, md->display_id, 3); + dev_dbg(&md->spi->dev, "MIPI display ID: %02x%02x%02x\n", + md->display_id[0], md->display_id[1], md->display_id[2]); + + switch (md->display_id[0]) { + case 0x45: + md->model = MIPID_VER_LPH8923; + md->panel.name = "lph8923"; + break; + case 0x83: + md->model = MIPID_VER_LS041Y3; + md->panel.name = "ls041y3"; + //md->esd_check = ls041y3_esd_check; + break; + default: + md->panel.name = "unknown"; + dev_err(&md->spi->dev, "invalid display ID\n"); + return -ENODEV; + } + + md->revision = md->display_id[1]; + pr_info("omapfb: %s rev %02x LCD detected\n", + md->panel.name, md->revision); + + return 0; +} + + + +static int pn800_panel_enable(struct omap_display *display) +{ + int r; + struct pn800_device *md = + (struct pn800_device *)display->panel->priv; + + DBG("pn800_panel_enable\n"); + + mutex_lock(&md->mutex); + + if (display->hw_config.panel_enable) + display->hw_config.panel_enable(display); + + msleep(50); // wait for power up + + r = panel_detect(md); + if (r) { + mutex_unlock(&md->mutex); + return r; + } + + md->enabled = panel_enabled(md); + + if (md->enabled) { + DBG("panel already enabled\n"); + ; /*pn800_esd_start_check(md);*/ + } else { + ; /*md->saved_bklight_level = pn800_get_bklight_level(panel);*/ + } + + + if (md->enabled) { + mutex_unlock(&md->mutex); + return 0; + } + + set_sleep_mode(md, 0); + md->enabled = 1; + send_init_string(md); + set_display_state(md, 1); + //mipid_set_bklight_level(panel, md->saved_bklight_level); + //mipid_esd_start_check(md); + + mutex_unlock(&md->mutex); + return 0; +} + +static void pn800_panel_disable(struct omap_display *display) +{ + struct pn800_device *md = + (struct pn800_device *)display->panel->priv; + + DBG("pn800_panel_disable\n"); + + mutex_lock(&md->mutex); + + if (!md->enabled) { + mutex_unlock(&md->mutex); + return; + } + /*md->saved_bklight_level = pn800_get_bklight_level(panel);*/ + /*pn800_set_bklight_level(panel, 0);*/ + + set_display_state(md, 0); + set_sleep_mode(md, 1); + md->enabled = 0; + + + if (display->hw_config.panel_disable) + display->hw_config.panel_disable(display); + + mutex_unlock(&md->mutex); +} + +static int pn800_panel_init(struct omap_display *display) +{ + struct pn800_device *md = + (struct pn800_device *)display->panel->priv; + + DBG("pn800_panel_init\n"); + + mutex_init(&md->mutex); + md->display = display; + + return 0; +} + +static int pn800_run_test(struct omap_display *display, int test_num) +{ + return 0; +} + +static struct omap_panel pn800_panel = { + .owner = THIS_MODULE, + .name = "panel-pn800", + .init = pn800_panel_init, + /*.remove = pn800_cleanup,*/ + .enable = pn800_panel_enable, + .disable = pn800_panel_disable, + //.set_mode = pn800_set_mode, + .run_test = pn800_run_test, + + .timings = { + .x_res = 800, + .y_res = 480, + + .pixel_clock = 21940, + .hsw = 50, + .hfp = 20, + .hbp = 15, + + .vsw = 2, + .vfp = 1, + .vbp = 3, + }, + .config = OMAP_DSS_LCD_TFT, +}; + +static int pn800_spi_probe(struct spi_device *spi) +{ + struct pn800_device *md; + + DBG("pn800_spi_probe\n"); + + md = kzalloc(sizeof(*md), GFP_KERNEL); + if (md == NULL) { + dev_err(&spi->dev, "out of memory\n"); + return -ENOMEM; + } + + spi->mode = SPI_MODE_0; + md->spi = spi; + dev_set_drvdata(&spi->dev, md); + md->panel = pn800_panel; + pn800_panel.priv = md; + + omap_dss_register_panel(&pn800_panel); + + return 0; +} + +static int pn800_spi_remove(struct spi_device *spi) +{ + struct pn800_device *md = dev_get_drvdata(&spi->dev); + + DBG("pn800_spi_remove\n"); + + omap_dss_unregister_panel(&pn800_panel); + + /*pn800_disable(&md->panel);*/ + kfree(md); + + return 0; +} + +static struct spi_driver pn800_spi_driver = { + .driver = { + .name = "panel-n800", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = pn800_spi_probe, + .remove = __devexit_p(pn800_spi_remove), +}; + +static int __init pn800_init(void) +{ + DBG("pn800_init\n"); + return spi_register_driver(&pn800_spi_driver); +} + +static void __exit pn800_exit(void) +{ + DBG("pn800_exit\n"); + spi_unregister_driver(&pn800_spi_driver); +} + +module_init(pn800_init); +module_exit(pn800_exit); + +MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>"); +MODULE_DESCRIPTION("N800 LCD Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/omap2/displays/panel-samsung-lte430wq-f0c.c b/drivers/video/omap2/displays/panel-samsung-lte430wq-f0c.c new file mode 100644 index 000000000000..eafe581b36ff --- /dev/null +++ b/drivers/video/omap2/displays/panel-samsung-lte430wq-f0c.c @@ -0,0 +1,113 @@ +/* + * LCD panel driver for Samsung LTE430WQ-F0C + * + * Author: Steve Sakoman <steve@sakoman.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, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/module.h> +#include <linux/delay.h> + +#include <mach/display.h> + +static struct omap_video_timings samsung_lte_timings = { + .x_res = 480, + .y_res = 272, + + .pixel_clock = 9200, + + .hsw = 41, + .hfp = 8, + .hbp = 45-41, + + .vsw = 10, + .vfp = 4, + .vbp = 12-10, +}; + +static int samsung_lte_panel_probe(struct omap_dss_device *dssdev) +{ + dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | + OMAP_DSS_LCD_IHS; + dssdev->panel.timings = samsung_lte_timings; + + return 0; +} + +static void samsung_lte_panel_remove(struct omap_dss_device *dssdev) +{ +} + +static int samsung_lte_panel_enable(struct omap_dss_device *dssdev) +{ + int r = 0; + + /* wait couple of vsyncs until enabling the LCD */ + msleep(50); + + if (dssdev->platform_enable) + r = dssdev->platform_enable(dssdev); + + return r; +} + +static void samsung_lte_panel_disable(struct omap_dss_device *dssdev) +{ + if (dssdev->platform_disable) + dssdev->platform_disable(dssdev); + + /* wait at least 5 vsyncs after disabling the LCD */ + + msleep(100); +} + +static int samsung_lte_panel_suspend(struct omap_dss_device *dssdev) +{ + samsung_lte_panel_disable(dssdev); + return 0; +} + +static int samsung_lte_panel_resume(struct omap_dss_device *dssdev) +{ + return samsung_lte_panel_enable(dssdev); +} + +static struct omap_dss_driver samsung_lte_driver = { + .probe = samsung_lte_panel_probe, + .remove = samsung_lte_panel_remove, + + .enable = samsung_lte_panel_enable, + .disable = samsung_lte_panel_disable, + .suspend = samsung_lte_panel_suspend, + .resume = samsung_lte_panel_resume, + + .driver = { + .name = "samsung_lte_panel", + .owner = THIS_MODULE, + }, +}; + +static int __init samsung_lte_panel_drv_init(void) +{ + return omap_dss_register_driver(&samsung_lte_driver); +} + +static void __exit samsung_lte_panel_drv_exit(void) +{ + omap_dss_unregister_driver(&samsung_lte_driver); +} + +module_init(samsung_lte_panel_drv_init); +module_exit(samsung_lte_panel_drv_exit); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c new file mode 100644 index 000000000000..2b6d8899441a --- /dev/null +++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c @@ -0,0 +1,153 @@ +/* + * LCD panel driver for Sharp LS037V7DW01 + * + * Copyright (C) 2008 Nokia Corporation + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.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, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/module.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/regulator/consumer.h> +#include <linux/err.h> + +#include <mach/display.h> + +struct sharp_data { + /* XXX This regulator should actually be in SDP board file, not here, + * as it doesn't actually power the LCD, but something else that + * affects the output to LCD (I think. Somebody clarify). It doesn't do + * harm here, as SDP is the only board using this currently */ + struct regulator *vdvi_reg; +}; + +static struct omap_video_timings sharp_ls_timings = { + .x_res = 480, + .y_res = 640, + + .pixel_clock = 19200, + + .hsw = 2, + .hfp = 1, + .hbp = 28, + + .vsw = 1, + .vfp = 1, + .vbp = 1, +}; + +static int sharp_ls_panel_probe(struct omap_dss_device *dssdev) +{ + struct sharp_data *sd; + + dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | + OMAP_DSS_LCD_IHS; + dssdev->panel.acb = 0x28; + dssdev->panel.timings = sharp_ls_timings; + + sd = kzalloc(sizeof(*sd), GFP_KERNEL); + if (!sd) + return -ENOMEM; + + dev_set_drvdata(&dssdev->dev, sd); + + sd->vdvi_reg = regulator_get(&dssdev->dev, "vdvi"); + if (IS_ERR(sd->vdvi_reg)) { + kfree(sd); + printk(KERN_INFO "failed to get VDVI regulator\n"); + return PTR_ERR(sd->vdvi_reg); + } + + return 0; +} + +static void sharp_ls_panel_remove(struct omap_dss_device *dssdev) +{ + struct sharp_data *sd = dev_get_drvdata(&dssdev->dev); + + regulator_put(sd->vdvi_reg); + + kfree(sd); +} + +static int sharp_ls_panel_enable(struct omap_dss_device *dssdev) +{ + struct sharp_data *sd = dev_get_drvdata(&dssdev->dev); + int r = 0; + + /* wait couple of vsyncs until enabling the LCD */ + msleep(50); + + regulator_enable(sd->vdvi_reg); + + if (dssdev->platform_enable) + r = dssdev->platform_enable(dssdev); + + return r; +} + +static void sharp_ls_panel_disable(struct omap_dss_device *dssdev) +{ + struct sharp_data *sd = dev_get_drvdata(&dssdev->dev); + + if (dssdev->platform_disable) + dssdev->platform_disable(dssdev); + + regulator_disable(sd->vdvi_reg); + + /* wait at least 5 vsyncs after disabling the LCD */ + + msleep(100); +} + +static int sharp_ls_panel_suspend(struct omap_dss_device *dssdev) +{ + sharp_ls_panel_disable(dssdev); + return 0; +} + +static int sharp_ls_panel_resume(struct omap_dss_device *dssdev) +{ + return sharp_ls_panel_enable(dssdev); +} + +static struct omap_dss_driver sharp_ls_driver = { + .probe = sharp_ls_panel_probe, + .remove = sharp_ls_panel_remove, + + .enable = sharp_ls_panel_enable, + .disable = sharp_ls_panel_disable, + .suspend = sharp_ls_panel_suspend, + .resume = sharp_ls_panel_resume, + + .driver = { + .name = "sharp_ls_panel", + .owner = THIS_MODULE, + }, +}; + +static int __init sharp_ls_panel_drv_init(void) +{ + return omap_dss_register_driver(&sharp_ls_driver); +} + +static void __exit sharp_ls_panel_drv_exit(void) +{ + omap_dss_unregister_driver(&sharp_ls_driver); +} + +module_init(sharp_ls_panel_drv_init); +module_exit(sharp_ls_panel_drv_exit); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig new file mode 100644 index 000000000000..ca098c6bb4f0 --- /dev/null +++ b/drivers/video/omap2/dss/Kconfig @@ -0,0 +1,90 @@ +menuconfig OMAP2_DSS + tristate "OMAP2/3 Display Subsystem support (EXPERIMENTAL)" + depends on ARCH_OMAP2 || ARCH_OMAP3 || ARCH_OMAP4 + default y + help + OMAP2/3/4 Display Subsystem support. + +if OMAP2_DSS + +config OMAP2_DSS_VRAM_SIZE + int "VRAM size (MB)" + range 0 32 + default 4 + help + The amount of SDRAM to reserve at boot time for video RAM use. + This VRAM will be used by omapfb and other drivers that need + large continuous RAM area for video use. + + You can also set this with "vram=<bytes>" kernel argument, or + in the board file. + +config OMAP2_DSS_DEBUG_SUPPORT + bool "Debug support" + default y + help + This enables debug messages. You need to enable printing + with 'debug' module parameter. + +config OMAP2_DSS_RFBI + bool "RFBI support" + default n + help + MIPI DBI, or RFBI (Remote Framebuffer Interface), support. + +config OMAP2_DSS_VENC + bool "VENC support" + default y + help + OMAP Video Encoder support. + +config OMAP2_DSS_SDI + bool "SDI support" + depends on ARCH_OMAP3 + default n + help + SDI (Serial Display Interface) support. + +config OMAP2_DSS_DSI + bool "DSI support" + depends on ARCH_OMAP3 + default n + help + MIPI DSI support. + +config OMAP2_DSS_USE_DSI_PLL + bool "Use DSI PLL for PCLK (EXPERIMENTAL)" + default n + depends on OMAP2_DSS_DSI + help + Use DSI PLL to generate pixel clock. Currently only for DPI output. + DSI PLL can be used to generate higher and more precise pixel clocks. + +config OMAP2_DSS_FAKE_VSYNC + bool "Fake VSYNC irq from manual update displays" + default n + help + If this is selected, DSI will generate a fake DISPC VSYNC interrupt + when DSI has sent a frame. This is only needed with DSI or RFBI + displays using manual mode, and you want VSYNC to, for example, + time animation. + +config OMAP2_DSS_MIN_FCK_PER_PCK + int "Minimum FCK/PCK ratio (for scaling)" + range 0 32 + default 0 + help + This can be used to adjust the minimum FCK/PCK ratio. + + With this you can make sure that DISPC FCK is at least + n x PCK. Video plane scaling requires higher FCK than + normally. + + If this is set to 0, there's no extra constraint on the + DISPC FCK. However, the FCK will at minimum be + 2xPCK (if active matrix) or 3xPCK (if passive matrix). + + Max FCK is 173MHz, so this doesn't work if your PCK + is very high. + +endif diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile new file mode 100644 index 000000000000..980c72c2db98 --- /dev/null +++ b/drivers/video/omap2/dss/Makefile @@ -0,0 +1,6 @@ +obj-$(CONFIG_OMAP2_DSS) += omapdss.o +omapdss-y := core.o dss.o dispc.o dpi.o display.o manager.o overlay.o +omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o +omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o +omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o +omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c new file mode 100644 index 000000000000..0fd57d6eae6b --- /dev/null +++ b/drivers/video/omap2/dss/core.c @@ -0,0 +1,925 @@ +/* + * linux/drivers/video/omap2/dss/core.c + * + * Copyright (C) 2009 Nokia Corporation + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> + * + * Some code and ideas taken from drivers/video/omap/ driver + * by Imre Deak. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#define DSS_SUBSYS_NAME "CORE" + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/platform_device.h> +#include <linux/seq_file.h> +#include <linux/debugfs.h> +#include <linux/io.h> +#include <linux/device.h> + +#include <mach/display.h> +#include <mach/clock.h> + +#include "dss.h" + +static struct { + struct platform_device *pdev; + int ctx_id; + + struct clk *dss_ick; + struct clk *dss1_fck; + struct clk *dss2_fck; + struct clk *dss_54m_fck; + struct clk *dss_96m_fck; + unsigned num_clks_enabled; +} core; + +static void dss_clk_enable_all_no_ctx(void); +static void dss_clk_disable_all_no_ctx(void); +static void dss_clk_enable_no_ctx(enum dss_clock clks); +static void dss_clk_disable_no_ctx(enum dss_clock clks); + +static char *def_disp_name; +module_param_named(def_disp, def_disp_name, charp, 0); +MODULE_PARM_DESC(def_disp_name, "default display name"); + +#ifdef DEBUG +unsigned int dss_debug; +module_param_named(debug, dss_debug, bool, 0644); +#endif + +/* CONTEXT */ +static int dss_get_ctx_id(void) +{ + struct omap_dss_board_info *pdata = core.pdev->dev.platform_data; + int r; + + if (!pdata->get_last_off_on_transaction_id) + return 0; + r = pdata->get_last_off_on_transaction_id(&core.pdev->dev); + if (r < 0) { + dev_err(&core.pdev->dev, "getting transaction ID failed, " + "will force context restore\n"); + r = -1; + } + return r; +} + +int dss_need_ctx_restore(void) +{ + int id = dss_get_ctx_id(); + + if (id < 0 || id != core.ctx_id) { + DSSDBG("ctx id %d -> id %d\n", + core.ctx_id, id); + core.ctx_id = id; + return 1; + } else { + return 0; + } +} + +static void save_all_ctx(void) +{ + DSSDBG("save context\n"); + + dss_clk_enable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1); + + dss_save_context(); + dispc_save_context(); +#ifdef CONFIG_OMAP2_DSS_DSI + dsi_save_context(); +#endif + + dss_clk_disable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1); +} + +static void restore_all_ctx(void) +{ + DSSDBG("restore context\n"); + + dss_clk_enable_all_no_ctx(); + + dss_restore_context(); + dispc_restore_context(); +#ifdef CONFIG_OMAP2_DSS_DSI + dsi_restore_context(); +#endif + + dss_clk_disable_all_no_ctx(); +} + +/* CLOCKS */ +void dss_dump_clocks(struct seq_file *s) +{ + int i; + struct clk *clocks[5] = { + core.dss_ick, + core.dss1_fck, + core.dss2_fck, + core.dss_54m_fck, + core.dss_96m_fck + }; + + seq_printf(s, "- dss -\n"); + + seq_printf(s, "internal clk count\t%u\n", core.num_clks_enabled); + + for (i = 0; i < 5; i++) { + if (!clocks[i]) + continue; + seq_printf(s, "%-15s\t%lu\t%d\n", + clocks[i]->name, + clk_get_rate(clocks[i]), + clocks[i]->usecount); + } +} + +static int dss_get_clock(struct clk **clock, const char *clk_name) +{ + struct clk *clk; + + clk = clk_get(&core.pdev->dev, clk_name); + + if (IS_ERR(clk)) { + DSSERR("can't get clock %s", clk_name); + return PTR_ERR(clk); + } + + *clock = clk; + + DSSDBG("clk %s, rate %ld\n", clk_name, clk_get_rate(clk)); + + return 0; +} + +static int dss_get_clocks(void) +{ + int r; + + core.dss_ick = NULL; + core.dss1_fck = NULL; + core.dss2_fck = NULL; + core.dss_54m_fck = NULL; + core.dss_96m_fck = NULL; + + r = dss_get_clock(&core.dss_ick, "ick"); + if (r) + goto err; + + r = dss_get_clock(&core.dss1_fck, "dss1_fck"); + if (r) + goto err; + + r = dss_get_clock(&core.dss2_fck, "dss2_fck"); + if (r) + goto err; + + r = dss_get_clock(&core.dss_54m_fck, "tv_fck"); + if (r) + goto err; + + r = dss_get_clock(&core.dss_96m_fck, "video_fck"); + if (r) + goto err; + + return 0; + +err: + if (core.dss_ick) + clk_put(core.dss_ick); + if (core.dss1_fck) + clk_put(core.dss1_fck); + if (core.dss2_fck) + clk_put(core.dss2_fck); + if (core.dss_54m_fck) + clk_put(core.dss_54m_fck); + if (core.dss_96m_fck) + clk_put(core.dss_96m_fck); + + return r; +} + +static void dss_put_clocks(void) +{ + if (core.dss_96m_fck) + clk_put(core.dss_96m_fck); + clk_put(core.dss_54m_fck); + clk_put(core.dss1_fck); + clk_put(core.dss2_fck); + clk_put(core.dss_ick); +} + +unsigned long dss_clk_get_rate(enum dss_clock clk) +{ + switch (clk) { + case DSS_CLK_ICK: + return clk_get_rate(core.dss_ick); + case DSS_CLK_FCK1: + return clk_get_rate(core.dss1_fck); + case DSS_CLK_FCK2: + return clk_get_rate(core.dss2_fck); + case DSS_CLK_54M: + return clk_get_rate(core.dss_54m_fck); + case DSS_CLK_96M: + return clk_get_rate(core.dss_96m_fck); + } + + BUG(); + return 0; +} + +static unsigned count_clk_bits(enum dss_clock clks) +{ + unsigned num_clks = 0; + + if (clks & DSS_CLK_ICK) + ++num_clks; + if (clks & DSS_CLK_FCK1) + ++num_clks; + if (clks & DSS_CLK_FCK2) + ++num_clks; + if (clks & DSS_CLK_54M) + ++num_clks; + if (clks & DSS_CLK_96M) + ++num_clks; + + return num_clks; +} + +static void dss_clk_enable_no_ctx(enum dss_clock clks) +{ + unsigned num_clks = count_clk_bits(clks); + + if (clks & DSS_CLK_ICK) + clk_enable(core.dss_ick); + if (clks & DSS_CLK_FCK1) + clk_enable(core.dss1_fck); + if (clks & DSS_CLK_FCK2) + clk_enable(core.dss2_fck); + if (clks & DSS_CLK_54M) + clk_enable(core.dss_54m_fck); + if (clks & DSS_CLK_96M) + clk_enable(core.dss_96m_fck); + + core.num_clks_enabled += num_clks; +} + +void dss_clk_enable(enum dss_clock clks) +{ + dss_clk_enable_no_ctx(clks); + + if (cpu_is_omap34xx() && dss_need_ctx_restore()) + restore_all_ctx(); + else if (cpu_is_omap44xx() && dss_need_ctx_restore()) + restore_all_ctx(); +} + +static void dss_clk_disable_no_ctx(enum dss_clock clks) +{ + unsigned num_clks = count_clk_bits(clks); + + if (clks & DSS_CLK_ICK) + clk_disable(core.dss_ick); + if (clks & DSS_CLK_FCK1) + clk_disable(core.dss1_fck); + if (clks & DSS_CLK_FCK2) + clk_disable(core.dss2_fck); + if (clks & DSS_CLK_54M) + clk_disable(core.dss_54m_fck); + if (clks & DSS_CLK_96M) + clk_disable(core.dss_96m_fck); + + core.num_clks_enabled -= num_clks; +} + +void dss_clk_disable(enum dss_clock clks) +{ + if (cpu_is_omap34xx() || cpu_is_omap44xx()) { + unsigned num_clks = count_clk_bits(clks); + + BUG_ON(core.num_clks_enabled < num_clks); + + if (core.num_clks_enabled == num_clks) + save_all_ctx(); + } + + dss_clk_disable_no_ctx(clks); +} + +static void dss_clk_enable_all_no_ctx(void) +{ + enum dss_clock clks; + + clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M; + if (cpu_is_omap34xx() || cpu_is_omap44xx()) + clks |= DSS_CLK_96M; + dss_clk_enable_no_ctx(clks); +} + +static void dss_clk_disable_all_no_ctx(void) +{ + enum dss_clock clks; + + clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M; + if (cpu_is_omap34xx() || cpu_is_omap44xx()) + clks |= DSS_CLK_96M; + dss_clk_disable_no_ctx(clks); +} + +static void dss_clk_disable_all(void) +{ + enum dss_clock clks; + + clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M; + if (cpu_is_omap34xx() || cpu_is_omap44xx()) + clks |= DSS_CLK_96M; + dss_clk_disable(clks); +} + +/* DEBUGFS */ +#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) +static void dss_debug_dump_clocks(struct seq_file *s) +{ + dss_dump_clocks(s); + dispc_dump_clocks(s); +#ifdef CONFIG_OMAP2_DSS_DSI + dsi_dump_clocks(s); +#endif +} + +static int dss_debug_show(struct seq_file *s, void *unused) +{ + void (*func)(struct seq_file *) = s->private; + func(s); + return 0; +} + +static int dss_debug_open(struct inode *inode, struct file *file) +{ + return single_open(file, dss_debug_show, inode->i_private); +} + +static const struct file_operations dss_debug_fops = { + .open = dss_debug_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static struct dentry *dss_debugfs_dir; + +static int dss_initialize_debugfs(void) +{ + dss_debugfs_dir = debugfs_create_dir("omapdss", NULL); + if (IS_ERR(dss_debugfs_dir)) { + int err = PTR_ERR(dss_debugfs_dir); + dss_debugfs_dir = NULL; + return err; + } + + debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir, + &dss_debug_dump_clocks, &dss_debug_fops); + + debugfs_create_file("dss", S_IRUGO, dss_debugfs_dir, + &dss_dump_regs, &dss_debug_fops); + debugfs_create_file("dispc", S_IRUGO, dss_debugfs_dir, + &dispc_dump_regs, &dss_debug_fops); +#ifdef CONFIG_OMAP2_DSS_RFBI + debugfs_create_file("rfbi", S_IRUGO, dss_debugfs_dir, + &rfbi_dump_regs, &dss_debug_fops); +#endif +#ifdef CONFIG_OMAP2_DSS_DSI + debugfs_create_file("dsi", S_IRUGO, dss_debugfs_dir, + &dsi_dump_regs, &dss_debug_fops); +#endif +#ifdef CONFIG_OMAP2_DSS_VENC + debugfs_create_file("venc", S_IRUGO, dss_debugfs_dir, + &venc_dump_regs, &dss_debug_fops); +#endif + return 0; +} + +static void dss_uninitialize_debugfs(void) +{ + if (dss_debugfs_dir) + debugfs_remove_recursive(dss_debugfs_dir); +} +#endif /* CONFIG_DEBUG_FS && CONFIG_OMAP2_DSS_DEBUG_SUPPORT */ + +/* PLATFORM DEVICE */ +static int omap_dss_probe(struct platform_device *pdev) +{ + struct omap_dss_board_info *pdata = pdev->dev.platform_data; + int skip_init = 0; + int r; + int i; + + core.pdev = pdev; + + dss_init_overlay_managers(pdev); + dss_init_overlays(pdev); + + /* + * FIX-ME: Replace with correct clk node when clk + * framework is available + */ + if (!cpu_is_omap44xx()) { + r = dss_get_clocks(); + if (r) + goto fail0; + } + + dss_clk_enable_all_no_ctx(); + + core.ctx_id = dss_get_ctx_id(); + DSSDBG("initial ctx id %u\n", core.ctx_id); + +#ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT + /* DISPC_CONTROL */ + if (omap_readl(0x48050440) & 1) /* LCD enabled? */ + skip_init = 1; +#endif + + r = dss_init(skip_init); + if (r) { + DSSERR("Failed to initialize DSS\n"); + goto fail0; + } + +#ifdef CONFIG_OMAP2_DSS_RFBI + r = rfbi_init(); + if (r) { + DSSERR("Failed to initialize rfbi\n"); + goto fail0; + } +#endif + + r = dpi_init(); + if (r) { + DSSERR("Failed to initialize dpi\n"); + goto fail0; + } + + r = dispc_init(); + if (r) { + DSSERR("Failed to initialize dispc\n"); + goto fail0; + } +#ifdef CONFIG_OMAP2_DSS_VENC + r = venc_init(pdev); + if (r) { + DSSERR("Failed to initialize venc\n"); + goto fail0; + } +#endif + if (cpu_is_omap34xx()) { +#ifdef CONFIG_OMAP2_DSS_SDI + r = sdi_init(skip_init); + if (r) { + DSSERR("Failed to initialize SDI\n"); + goto fail0; + } +#endif +#ifdef CONFIG_OMAP2_DSS_DSI + r = dsi_init(pdev); + if (r) { + DSSERR("Failed to initialize DSI\n"); + goto fail0; + } +#endif + } + +#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) + r = dss_initialize_debugfs(); + if (r) + goto fail0; +#endif + + for (i = 0; i < pdata->num_devices; ++i) { + struct omap_dss_device *dssdev = pdata->devices[i]; + + r = omap_dss_register_device(dssdev); + if (r) + DSSERR("device reg failed %d\n", i); + + if (def_disp_name && strcmp(def_disp_name, dssdev->name) == 0) + pdata->default_device = dssdev; + } + + dss_clk_disable_all(); + + return 0; + + /* XXX fail correctly */ +fail0: + return r; +} + +static int omap_dss_remove(struct platform_device *pdev) +{ + struct omap_dss_board_info *pdata = pdev->dev.platform_data; + int i; + int c; + +#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) + dss_uninitialize_debugfs(); +#endif + +#ifdef CONFIG_OMAP2_DSS_VENC + venc_exit(); +#endif + dispc_exit(); + dpi_exit(); +#ifdef CONFIG_OMAP2_DSS_RFBI + rfbi_exit(); +#endif + if (cpu_is_omap34xx()) { +#ifdef CONFIG_OMAP2_DSS_DSI + dsi_exit(); +#endif +#ifdef CONFIG_OMAP2_DSS_SDI + sdi_exit(); +#endif + } + + dss_exit(); + + /* these should be removed at some point */ + c = core.dss_ick->usecount; + if (c > 0) { + DSSERR("warning: dss_ick usecount %d, disabling\n", c); + while (c-- > 0) + clk_disable(core.dss_ick); + } + + c = core.dss1_fck->usecount; + if (c > 0) { + DSSERR("warning: dss1_fck usecount %d, disabling\n", c); + while (c-- > 0) + clk_disable(core.dss1_fck); + } + + c = core.dss2_fck->usecount; + if (c > 0) { + DSSERR("warning: dss2_fck usecount %d, disabling\n", c); + while (c-- > 0) + clk_disable(core.dss2_fck); + } + + c = core.dss_54m_fck->usecount; + if (c > 0) { + DSSERR("warning: dss_54m_fck usecount %d, disabling\n", c); + while (c-- > 0) + clk_disable(core.dss_54m_fck); + } + + if (core.dss_96m_fck) { + c = core.dss_96m_fck->usecount; + if (c > 0) { + DSSERR("warning: dss_96m_fck usecount %d, disabling\n", + c); + while (c-- > 0) + clk_disable(core.dss_96m_fck); + } + } + + dss_put_clocks(); + + dss_uninit_overlays(pdev); + dss_uninit_overlay_managers(pdev); + + for (i = 0; i < pdata->num_devices; ++i) + omap_dss_unregister_device(pdata->devices[i]); + + return 0; +} + +static void omap_dss_shutdown(struct platform_device *pdev) +{ + DSSDBG("shutdown\n"); +} + +static int omap_dss_suspend(struct platform_device *pdev, pm_message_t state) +{ + DSSDBG("suspend %d\n", state.event); + + return dss_suspend_all_devices(); +} + +static int omap_dss_resume(struct platform_device *pdev) +{ + DSSDBG("resume\n"); + + return dss_resume_all_devices(); +} + +static struct platform_driver omap_dss_driver = { + .probe = omap_dss_probe, + .remove = omap_dss_remove, + .shutdown = omap_dss_shutdown, + .suspend = omap_dss_suspend, + .resume = omap_dss_resume, + .driver = { + .name = "omapdss", + .owner = THIS_MODULE, + }, +}; + +/* BUS */ +static int dss_bus_match(struct device *dev, struct device_driver *driver) +{ + struct omap_dss_device *dssdev = to_dss_device(dev); + + DSSDBG("bus_match. dev %s/%s, drv %s\n", + dev_name(dev), dssdev->driver_name, driver->name); + + return strcmp(dssdev->driver_name, driver->name) == 0; +} + +static ssize_t device_name_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct omap_dss_device *dssdev = to_dss_device(dev); + return snprintf(buf, PAGE_SIZE, "%s\n", + dssdev->name ? + dssdev->name : ""); +} + +static struct device_attribute default_dev_attrs[] = { + __ATTR(name, S_IRUGO, device_name_show, NULL), + __ATTR_NULL, +}; + +static ssize_t driver_name_show(struct device_driver *drv, char *buf) +{ + struct omap_dss_driver *dssdrv = to_dss_driver(drv); + return snprintf(buf, PAGE_SIZE, "%s\n", + dssdrv->driver.name ? + dssdrv->driver.name : ""); +} +static struct driver_attribute default_drv_attrs[] = { + __ATTR(name, S_IRUGO, driver_name_show, NULL), + __ATTR_NULL, +}; + +static struct bus_type dss_bus_type = { + .name = "omapdss", + .match = dss_bus_match, + .dev_attrs = default_dev_attrs, + .drv_attrs = default_drv_attrs, +}; + +static void dss_bus_release(struct device *dev) +{ + DSSDBG("bus_release\n"); +} + +static struct device dss_bus = { + .release = dss_bus_release, +}; + +struct bus_type *dss_get_bus(void) +{ + return &dss_bus_type; +} + +/* DRIVER */ +static int dss_driver_probe(struct device *dev) +{ + int r; + struct omap_dss_driver *dssdrv = to_dss_driver(dev->driver); + struct omap_dss_device *dssdev = to_dss_device(dev); + struct omap_dss_board_info *pdata = core.pdev->dev.platform_data; + bool force; + + DSSDBG("driver_probe: dev %s/%s, drv %s\n", + dev_name(dev), dssdev->driver_name, + dssdrv->driver.name); + + dss_init_device(core.pdev, dssdev); + + /* skip this if the device is behind a ctrl */ + if (!dssdev->panel.ctrl) { + force = pdata->default_device == dssdev; + dss_recheck_connections(dssdev, force); + } + + r = dssdrv->probe(dssdev); + + if (r) { + DSSERR("driver probe failed: %d\n", r); + return r; + } + + DSSDBG("probe done for device %s\n", dev_name(dev)); + + dssdev->driver = dssdrv; + + return 0; +} + +static int dss_driver_remove(struct device *dev) +{ + struct omap_dss_driver *dssdrv = to_dss_driver(dev->driver); + struct omap_dss_device *dssdev = to_dss_device(dev); + + DSSDBG("driver_remove: dev %s/%s\n", dev_name(dev), + dssdev->driver_name); + + dssdrv->remove(dssdev); + + dss_uninit_device(core.pdev, dssdev); + + dssdev->driver = NULL; + + return 0; +} + +int omap_dss_register_driver(struct omap_dss_driver *dssdriver) +{ + dssdriver->driver.bus = &dss_bus_type; + dssdriver->driver.probe = dss_driver_probe; + dssdriver->driver.remove = dss_driver_remove; + return driver_register(&dssdriver->driver); +} +EXPORT_SYMBOL(omap_dss_register_driver); + +void omap_dss_unregister_driver(struct omap_dss_driver *dssdriver) +{ + driver_unregister(&dssdriver->driver); +} +EXPORT_SYMBOL(omap_dss_unregister_driver); + +/* DEVICE */ +static void reset_device(struct device *dev, int check) +{ + u8 *dev_p = (u8 *)dev; + u8 *dev_end = dev_p + sizeof(*dev); + void *saved_pdata; + + saved_pdata = dev->platform_data; + if (check) { + /* + * Check if there is any other setting than platform_data + * in struct device; warn that these will be reset by our + * init. + */ + dev->platform_data = NULL; + while (dev_p < dev_end) { + if (*dev_p) { + WARN("%s: struct device fields will be " + "discarded\n", + __func__); + break; + } + dev_p++; + } + } + memset(dev, 0, sizeof(*dev)); + dev->platform_data = saved_pdata; +} + + +static void omap_dss_dev_release(struct device *dev) +{ + reset_device(dev, 0); +} + +int omap_dss_register_device(struct omap_dss_device *dssdev) +{ + static int dev_num; + static int panel_num; + int r; + + WARN_ON(!dssdev->driver_name); + + reset_device(&dssdev->dev, 1); + dssdev->dev.bus = &dss_bus_type; + dssdev->dev.parent = &dss_bus; + dssdev->dev.release = omap_dss_dev_release; + dev_set_name(&dssdev->dev, "display%d", dev_num++); + r = device_register(&dssdev->dev); + if (r) + return r; + + if (dssdev->ctrl.panel) { + struct omap_dss_device *panel = dssdev->ctrl.panel; + + panel->panel.ctrl = dssdev; + + reset_device(&panel->dev, 1); + panel->dev.bus = &dss_bus_type; + panel->dev.parent = &dssdev->dev; + panel->dev.release = omap_dss_dev_release; + dev_set_name(&panel->dev, "panel%d", panel_num++); + r = device_register(&panel->dev); + if (r) + return r; + } + + return 0; +} + +void omap_dss_unregister_device(struct omap_dss_device *dssdev) +{ + device_unregister(&dssdev->dev); + + if (dssdev->ctrl.panel) { + struct omap_dss_device *panel = dssdev->ctrl.panel; + device_unregister(&panel->dev); + } +} + +/* BUS */ +static int omap_dss_bus_register(void) +{ + int r; + + r = bus_register(&dss_bus_type); + if (r) { + DSSERR("bus register failed\n"); + return r; + } + + dev_set_name(&dss_bus, "omapdss"); + r = device_register(&dss_bus); + if (r) { + DSSERR("bus driver register failed\n"); + bus_unregister(&dss_bus_type); + return r; + } + + return 0; +} + +/* INIT */ + +#ifdef CONFIG_OMAP2_DSS_MODULE +static void omap_dss_bus_unregister(void) +{ + device_unregister(&dss_bus); + + bus_unregister(&dss_bus_type); +} + +static int __init omap_dss_init(void) +{ + int r; + + r = omap_dss_bus_register(); + if (r) + return r; + + r = platform_driver_register(&omap_dss_driver); + if (r) { + omap_dss_bus_unregister(); + return r; + } + + return 0; +} + +static void __exit omap_dss_exit(void) +{ + platform_driver_unregister(&omap_dss_driver); + + omap_dss_bus_unregister(); +} + +module_init(omap_dss_init); +module_exit(omap_dss_exit); +#else +static int __init omap_dss_init(void) +{ + return omap_dss_bus_register(); +} + +static int __init omap_dss_init2(void) +{ + return platform_driver_register(&omap_dss_driver); +} + +core_initcall(omap_dss_init); +device_initcall(omap_dss_init2); +#endif + +MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>"); +MODULE_DESCRIPTION("OMAP2/3 Display Subsystem"); +MODULE_LICENSE("GPL v2"); + diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c new file mode 100644 index 000000000000..de8da84f9a5e --- /dev/null +++ b/drivers/video/omap2/dss/dispc.c @@ -0,0 +1,3230 @@ +/* + * linux/drivers/video/omap2/dss/dispc.c + * + * Copyright (C) 2009 Nokia Corporation + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> + * + * Some code and ideas taken from drivers/video/omap/ driver + * by Imre Deak. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#define DSS_SUBSYS_NAME "DISPC" + +#include <linux/kernel.h> +#include <linux/dma-mapping.h> +#include <linux/vmalloc.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/jiffies.h> +#include <linux/seq_file.h> +#include <linux/delay.h> +#include <linux/workqueue.h> + +#include <mach/sram.h> +#include <mach/board.h> +#include <mach/clock.h> + +#include <mach/display.h> + +#include "dss.h" + +#ifndef CONFIG_ARCH_OMAP4 + /* DSS */ + #define DSS_BASE 0x48050000 + /* DISPLAY CONTROLLER */ + #define DISPC_BASE 0x48050400 +#else + /* DSS */ + #define DSS_BASE 0x48042000 + /* DISPLAY CONTROLLER */ + #define DISPC_BASE 0x48043000 +#endif + +#define DISPC_SZ_REGS SZ_1K + +struct dispc_reg { u16 idx; }; + +#define DISPC_REG(idx) ((const struct dispc_reg) { idx }) + +/* DISPC common */ +#define DISPC_REVISION DISPC_REG(0x0000) +#define DISPC_SYSCONFIG DISPC_REG(0x0010) +#define DISPC_SYSSTATUS DISPC_REG(0x0014) +#define DISPC_IRQSTATUS DISPC_REG(0x0018) +#define DISPC_IRQENABLE DISPC_REG(0x001C) +#define DISPC_CONTROL DISPC_REG(0x0040) +#define DISPC_CONFIG DISPC_REG(0x0044) +#define DISPC_CAPABLE DISPC_REG(0x0048) +#define DISPC_DEFAULT_COLOR0 DISPC_REG(0x004C) +#define DISPC_DEFAULT_COLOR1 DISPC_REG(0x0050) +#define DISPC_TRANS_COLOR0 DISPC_REG(0x0054) +#define DISPC_TRANS_COLOR1 DISPC_REG(0x0058) +#define DISPC_LINE_STATUS DISPC_REG(0x005C) +#define DISPC_LINE_NUMBER DISPC_REG(0x0060) +#define DISPC_TIMING_H DISPC_REG(0x0064) +#define DISPC_TIMING_V DISPC_REG(0x0068) +#define DISPC_POL_FREQ DISPC_REG(0x006C) +#define DISPC_DIVISOR DISPC_REG(0x0070) +#define DISPC_GLOBAL_ALPHA DISPC_REG(0x0074) +#define DISPC_SIZE_DIG DISPC_REG(0x0078) +#define DISPC_SIZE_LCD DISPC_REG(0x007C) + +/* DISPC GFX plane */ +#define DISPC_GFX_BA0 DISPC_REG(0x0080) +#define DISPC_GFX_BA1 DISPC_REG(0x0084) +#define DISPC_GFX_POSITION DISPC_REG(0x0088) +#define DISPC_GFX_SIZE DISPC_REG(0x008C) +#define DISPC_GFX_ATTRIBUTES DISPC_REG(0x00A0) +#define DISPC_GFX_FIFO_THRESHOLD DISPC_REG(0x00A4) +#define DISPC_GFX_FIFO_SIZE_STATUS DISPC_REG(0x00A8) +#define DISPC_GFX_ROW_INC DISPC_REG(0x00AC) +#define DISPC_GFX_PIXEL_INC DISPC_REG(0x00B0) +#define DISPC_GFX_WINDOW_SKIP DISPC_REG(0x00B4) +#define DISPC_GFX_TABLE_BA DISPC_REG(0x00B8) + +#define DISPC_DATA_CYCLE1 DISPC_REG(0x01D4) +#define DISPC_DATA_CYCLE2 DISPC_REG(0x01D8) +#define DISPC_DATA_CYCLE3 DISPC_REG(0x01DC) + +#define DISPC_CPR_COEF_R DISPC_REG(0x0220) +#define DISPC_CPR_COEF_G DISPC_REG(0x0224) +#define DISPC_CPR_COEF_B DISPC_REG(0x0228) + +#define DISPC_GFX_PRELOAD DISPC_REG(0x022C) + +/* DISPC Video plane, n = 0 for VID1 and n = 1 for VID2 */ +#define DISPC_VID_REG(n, idx) DISPC_REG(0x00BC + (n)*0x90 + idx) + +#define DISPC_VID_BA0(n) DISPC_VID_REG(n, 0x0000) +#define DISPC_VID_BA1(n) DISPC_VID_REG(n, 0x0004) +#define DISPC_VID_POSITION(n) DISPC_VID_REG(n, 0x0008) +#define DISPC_VID_SIZE(n) DISPC_VID_REG(n, 0x000C) +#define DISPC_VID_ATTRIBUTES(n) DISPC_VID_REG(n, 0x0010) +#define DISPC_VID_FIFO_THRESHOLD(n) DISPC_VID_REG(n, 0x0014) +#define DISPC_VID_FIFO_SIZE_STATUS(n) DISPC_VID_REG(n, 0x0018) +#define DISPC_VID_ROW_INC(n) DISPC_VID_REG(n, 0x001C) +#define DISPC_VID_PIXEL_INC(n) DISPC_VID_REG(n, 0x0020) +#define DISPC_VID_FIR(n) DISPC_VID_REG(n, 0x0024) +#define DISPC_VID_PICTURE_SIZE(n) DISPC_VID_REG(n, 0x0028) +#define DISPC_VID_ACCU0(n) DISPC_VID_REG(n, 0x002C) +#define DISPC_VID_ACCU1(n) DISPC_VID_REG(n, 0x0030) + +/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */ +#define DISPC_VID_FIR_COEF_H(n, i) DISPC_REG(0x00F0 + (n)*0x90 + (i)*0x8) +/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */ +#define DISPC_VID_FIR_COEF_HV(n, i) DISPC_REG(0x00F4 + (n)*0x90 + (i)*0x8) +/* coef index i = {0, 1, 2, 3, 4} */ +#define DISPC_VID_CONV_COEF(n, i) DISPC_REG(0x0130 + (n)*0x90 + (i)*0x4) +/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */ +#define DISPC_VID_FIR_COEF_V(n, i) DISPC_REG(0x01E0 + (n)*0x20 + (i)*0x4) + +#define DISPC_VID_PRELOAD(n) DISPC_REG(0x230 + (n)*0x04) + + +#define DISPC_IRQ_MASK_ERROR (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \ + DISPC_IRQ_OCP_ERR | \ + DISPC_IRQ_VID1_FIFO_UNDERFLOW | \ + DISPC_IRQ_VID2_FIFO_UNDERFLOW | \ + DISPC_IRQ_SYNC_LOST | \ + DISPC_IRQ_SYNC_LOST_DIGIT) + +#define DISPC_MAX_NR_ISRS 8 + +struct omap_dispc_isr_data { + omap_dispc_isr_t isr; + void *arg; + u32 mask; +}; + +#define REG_GET(idx, start, end) \ + FLD_GET(dispc_read_reg(idx), start, end) + +#define REG_FLD_MOD(idx, val, start, end) \ + dispc_write_reg(idx, FLD_MOD(dispc_read_reg(idx), val, start, end)) + +static const struct dispc_reg dispc_reg_att[] = { DISPC_GFX_ATTRIBUTES, + DISPC_VID_ATTRIBUTES(0), + DISPC_VID_ATTRIBUTES(1) }; + +static struct { + void __iomem *base; + + struct clk *dpll4_m4_ck; + + unsigned long cache_req_pck; + unsigned long cache_prate; + struct dispc_clock_info cache_cinfo; + + u32 fifo_size[3]; + + spinlock_t irq_lock; + u32 irq_error_mask; + struct omap_dispc_isr_data registered_isr[DISPC_MAX_NR_ISRS]; + u32 error_irqs; + struct work_struct error_work; + + u32 ctx[DISPC_SZ_REGS / sizeof(u32)]; +} dispc; + +static void _omap_dispc_set_irqs(void); + +static inline void dispc_write_reg(const struct dispc_reg idx, u32 val) +{ + __raw_writel(val, dispc.base + idx.idx); +} + +static inline u32 dispc_read_reg(const struct dispc_reg idx) +{ + return __raw_readl(dispc.base + idx.idx); +} + +#define SR(reg) \ + dispc.ctx[(DISPC_##reg).idx / sizeof(u32)] = dispc_read_reg(DISPC_##reg) +#define RR(reg) \ + dispc_write_reg(DISPC_##reg, dispc.ctx[(DISPC_##reg).idx / sizeof(u32)]) + +void dispc_save_context(void) +{ + if (cpu_is_omap24xx()) + return; + + SR(SYSCONFIG); + SR(IRQENABLE); + SR(CONTROL); + SR(CONFIG); + SR(DEFAULT_COLOR0); + SR(DEFAULT_COLOR1); + SR(TRANS_COLOR0); + SR(TRANS_COLOR1); + SR(LINE_NUMBER); + SR(TIMING_H); + SR(TIMING_V); + SR(POL_FREQ); + SR(DIVISOR); + SR(GLOBAL_ALPHA); + SR(SIZE_DIG); + SR(SIZE_LCD); + + SR(GFX_BA0); + SR(GFX_BA1); + SR(GFX_POSITION); + SR(GFX_SIZE); + SR(GFX_ATTRIBUTES); + SR(GFX_FIFO_THRESHOLD); + SR(GFX_ROW_INC); + SR(GFX_PIXEL_INC); + SR(GFX_WINDOW_SKIP); + SR(GFX_TABLE_BA); + + SR(DATA_CYCLE1); + SR(DATA_CYCLE2); + SR(DATA_CYCLE3); + + SR(CPR_COEF_R); + SR(CPR_COEF_G); + SR(CPR_COEF_B); + + SR(GFX_PRELOAD); + + /* VID1 */ + SR(VID_BA0(0)); + SR(VID_BA1(0)); + SR(VID_POSITION(0)); + SR(VID_SIZE(0)); + SR(VID_ATTRIBUTES(0)); + SR(VID_FIFO_THRESHOLD(0)); + SR(VID_ROW_INC(0)); + SR(VID_PIXEL_INC(0)); + SR(VID_FIR(0)); + SR(VID_PICTURE_SIZE(0)); + SR(VID_ACCU0(0)); + SR(VID_ACCU1(0)); + + SR(VID_FIR_COEF_H(0, 0)); + SR(VID_FIR_COEF_H(0, 1)); + SR(VID_FIR_COEF_H(0, 2)); + SR(VID_FIR_COEF_H(0, 3)); + SR(VID_FIR_COEF_H(0, 4)); + SR(VID_FIR_COEF_H(0, 5)); + SR(VID_FIR_COEF_H(0, 6)); + SR(VID_FIR_COEF_H(0, 7)); + + SR(VID_FIR_COEF_HV(0, 0)); + SR(VID_FIR_COEF_HV(0, 1)); + SR(VID_FIR_COEF_HV(0, 2)); + SR(VID_FIR_COEF_HV(0, 3)); + SR(VID_FIR_COEF_HV(0, 4)); + SR(VID_FIR_COEF_HV(0, 5)); + SR(VID_FIR_COEF_HV(0, 6)); + SR(VID_FIR_COEF_HV(0, 7)); + + SR(VID_CONV_COEF(0, 0)); + SR(VID_CONV_COEF(0, 1)); + SR(VID_CONV_COEF(0, 2)); + SR(VID_CONV_COEF(0, 3)); + SR(VID_CONV_COEF(0, 4)); + + SR(VID_FIR_COEF_V(0, 0)); + SR(VID_FIR_COEF_V(0, 1)); + SR(VID_FIR_COEF_V(0, 2)); + SR(VID_FIR_COEF_V(0, 3)); + SR(VID_FIR_COEF_V(0, 4)); + SR(VID_FIR_COEF_V(0, 5)); + SR(VID_FIR_COEF_V(0, 6)); + SR(VID_FIR_COEF_V(0, 7)); + + SR(VID_PRELOAD(0)); + + /* VID2 */ + SR(VID_BA0(1)); + SR(VID_BA1(1)); + SR(VID_POSITION(1)); + SR(VID_SIZE(1)); + SR(VID_ATTRIBUTES(1)); + SR(VID_FIFO_THRESHOLD(1)); + SR(VID_ROW_INC(1)); + SR(VID_PIXEL_INC(1)); + SR(VID_FIR(1)); + SR(VID_PICTURE_SIZE(1)); + SR(VID_ACCU0(1)); + SR(VID_ACCU1(1)); + + SR(VID_FIR_COEF_H(1, 0)); + SR(VID_FIR_COEF_H(1, 1)); + SR(VID_FIR_COEF_H(1, 2)); + SR(VID_FIR_COEF_H(1, 3)); + SR(VID_FIR_COEF_H(1, 4)); + SR(VID_FIR_COEF_H(1, 5)); + SR(VID_FIR_COEF_H(1, 6)); + SR(VID_FIR_COEF_H(1, 7)); + + SR(VID_FIR_COEF_HV(1, 0)); + SR(VID_FIR_COEF_HV(1, 1)); + SR(VID_FIR_COEF_HV(1, 2)); + SR(VID_FIR_COEF_HV(1, 3)); + SR(VID_FIR_COEF_HV(1, 4)); + SR(VID_FIR_COEF_HV(1, 5)); + SR(VID_FIR_COEF_HV(1, 6)); + SR(VID_FIR_COEF_HV(1, 7)); + + SR(VID_CONV_COEF(1, 0)); + SR(VID_CONV_COEF(1, 1)); + SR(VID_CONV_COEF(1, 2)); + SR(VID_CONV_COEF(1, 3)); + SR(VID_CONV_COEF(1, 4)); + + SR(VID_FIR_COEF_V(1, 0)); + SR(VID_FIR_COEF_V(1, 1)); + SR(VID_FIR_COEF_V(1, 2)); + SR(VID_FIR_COEF_V(1, 3)); + SR(VID_FIR_COEF_V(1, 4)); + SR(VID_FIR_COEF_V(1, 5)); + SR(VID_FIR_COEF_V(1, 6)); + SR(VID_FIR_COEF_V(1, 7)); + + SR(VID_PRELOAD(1)); +} + +void dispc_restore_context(void) +{ + RR(SYSCONFIG); + RR(IRQENABLE); + /*RR(CONTROL);*/ + RR(CONFIG); + RR(DEFAULT_COLOR0); + RR(DEFAULT_COLOR1); + RR(TRANS_COLOR0); + RR(TRANS_COLOR1); + RR(LINE_NUMBER); + RR(TIMING_H); + RR(TIMING_V); + RR(POL_FREQ); + RR(DIVISOR); + RR(GLOBAL_ALPHA); + RR(SIZE_DIG); + RR(SIZE_LCD); + + RR(GFX_BA0); + RR(GFX_BA1); + RR(GFX_POSITION); + RR(GFX_SIZE); + RR(GFX_ATTRIBUTES); + RR(GFX_FIFO_THRESHOLD); + RR(GFX_ROW_INC); + RR(GFX_PIXEL_INC); + RR(GFX_WINDOW_SKIP); + RR(GFX_TABLE_BA); + + RR(DATA_CYCLE1); + RR(DATA_CYCLE2); + RR(DATA_CYCLE3); + + RR(CPR_COEF_R); + RR(CPR_COEF_G); + RR(CPR_COEF_B); + + RR(GFX_PRELOAD); + + /* VID1 */ + RR(VID_BA0(0)); + RR(VID_BA1(0)); + RR(VID_POSITION(0)); + RR(VID_SIZE(0)); + RR(VID_ATTRIBUTES(0)); + RR(VID_FIFO_THRESHOLD(0)); + RR(VID_ROW_INC(0)); + RR(VID_PIXEL_INC(0)); + RR(VID_FIR(0)); + RR(VID_PICTURE_SIZE(0)); + RR(VID_ACCU0(0)); + RR(VID_ACCU1(0)); + + RR(VID_FIR_COEF_H(0, 0)); + RR(VID_FIR_COEF_H(0, 1)); + RR(VID_FIR_COEF_H(0, 2)); + RR(VID_FIR_COEF_H(0, 3)); + RR(VID_FIR_COEF_H(0, 4)); + RR(VID_FIR_COEF_H(0, 5)); + RR(VID_FIR_COEF_H(0, 6)); + RR(VID_FIR_COEF_H(0, 7)); + + RR(VID_FIR_COEF_HV(0, 0)); + RR(VID_FIR_COEF_HV(0, 1)); + RR(VID_FIR_COEF_HV(0, 2)); + RR(VID_FIR_COEF_HV(0, 3)); + RR(VID_FIR_COEF_HV(0, 4)); + RR(VID_FIR_COEF_HV(0, 5)); + RR(VID_FIR_COEF_HV(0, 6)); + RR(VID_FIR_COEF_HV(0, 7)); + + RR(VID_CONV_COEF(0, 0)); + RR(VID_CONV_COEF(0, 1)); + RR(VID_CONV_COEF(0, 2)); + RR(VID_CONV_COEF(0, 3)); + RR(VID_CONV_COEF(0, 4)); + + RR(VID_FIR_COEF_V(0, 0)); + RR(VID_FIR_COEF_V(0, 1)); + RR(VID_FIR_COEF_V(0, 2)); + RR(VID_FIR_COEF_V(0, 3)); + RR(VID_FIR_COEF_V(0, 4)); + RR(VID_FIR_COEF_V(0, 5)); + RR(VID_FIR_COEF_V(0, 6)); + RR(VID_FIR_COEF_V(0, 7)); + + RR(VID_PRELOAD(0)); + + /* VID2 */ + RR(VID_BA0(1)); + RR(VID_BA1(1)); + RR(VID_POSITION(1)); + RR(VID_SIZE(1)); + RR(VID_ATTRIBUTES(1)); + RR(VID_FIFO_THRESHOLD(1)); + RR(VID_ROW_INC(1)); + RR(VID_PIXEL_INC(1)); + RR(VID_FIR(1)); + RR(VID_PICTURE_SIZE(1)); + RR(VID_ACCU0(1)); + RR(VID_ACCU1(1)); + + RR(VID_FIR_COEF_H(1, 0)); + RR(VID_FIR_COEF_H(1, 1)); + RR(VID_FIR_COEF_H(1, 2)); + RR(VID_FIR_COEF_H(1, 3)); + RR(VID_FIR_COEF_H(1, 4)); + RR(VID_FIR_COEF_H(1, 5)); + RR(VID_FIR_COEF_H(1, 6)); + RR(VID_FIR_COEF_H(1, 7)); + + RR(VID_FIR_COEF_HV(1, 0)); + RR(VID_FIR_COEF_HV(1, 1)); + RR(VID_FIR_COEF_HV(1, 2)); + RR(VID_FIR_COEF_HV(1, 3)); + RR(VID_FIR_COEF_HV(1, 4)); + RR(VID_FIR_COEF_HV(1, 5)); + RR(VID_FIR_COEF_HV(1, 6)); + RR(VID_FIR_COEF_HV(1, 7)); + + RR(VID_CONV_COEF(1, 0)); + RR(VID_CONV_COEF(1, 1)); + RR(VID_CONV_COEF(1, 2)); + RR(VID_CONV_COEF(1, 3)); + RR(VID_CONV_COEF(1, 4)); + + RR(VID_FIR_COEF_V(1, 0)); + RR(VID_FIR_COEF_V(1, 1)); + RR(VID_FIR_COEF_V(1, 2)); + RR(VID_FIR_COEF_V(1, 3)); + RR(VID_FIR_COEF_V(1, 4)); + RR(VID_FIR_COEF_V(1, 5)); + RR(VID_FIR_COEF_V(1, 6)); + RR(VID_FIR_COEF_V(1, 7)); + + RR(VID_PRELOAD(1)); + + /* enable last, because LCD & DIGIT enable are here */ + RR(CONTROL); +} + +#undef SR +#undef RR + +static inline void enable_clocks(bool enable) +{ + if (enable) + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + else + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); +} + +bool dispc_go_busy(enum omap_channel channel) +{ + int bit; + + if (channel == OMAP_DSS_CHANNEL_LCD) + bit = 5; /* GOLCD */ + else + bit = 6; /* GODIGIT */ + + return REG_GET(DISPC_CONTROL, bit, bit) == 1; +} + +void dispc_go(enum omap_channel channel) +{ + int bit; + + enable_clocks(1); + + if (channel == OMAP_DSS_CHANNEL_LCD) + bit = 0; /* LCDENABLE */ + else + bit = 1; /* DIGITALENABLE */ + REG_FLD_MOD(DISPC_CONTROL, 1, 0, 0); + + /* if the channel is not enabled, we don't need GO */ +/* if (REG_GET(DISPC_CONTROL, bit, bit) == 0) + goto end; + +*/ + if (channel == OMAP_DSS_CHANNEL_LCD) + bit = 5; /* GOLCD */ + else + bit = 6; /* GODIGIT */ + + if (REG_GET(DISPC_CONTROL, bit, bit) == 1) { + DSSERR("GO bit not down for channel %d\n", channel); + goto end; + } + + DSSDBG("GO %s\n", channel == OMAP_DSS_CHANNEL_LCD ? "LCD" : "DIGIT"); + + REG_FLD_MOD(DISPC_CONTROL, 1, bit, bit); +end: + enable_clocks(0); +} + +static void _dispc_write_firh_reg(enum omap_plane plane, int reg, u32 value) +{ + BUG_ON(plane == OMAP_DSS_GFX); + + dispc_write_reg(DISPC_VID_FIR_COEF_H(plane-1, reg), value); +} + +static void _dispc_write_firhv_reg(enum omap_plane plane, int reg, u32 value) +{ + BUG_ON(plane == OMAP_DSS_GFX); + + dispc_write_reg(DISPC_VID_FIR_COEF_HV(plane-1, reg), value); +} + +static void _dispc_write_firv_reg(enum omap_plane plane, int reg, u32 value) +{ + BUG_ON(plane == OMAP_DSS_GFX); + + dispc_write_reg(DISPC_VID_FIR_COEF_V(plane-1, reg), value); +} + +static void _dispc_set_scale_coef(enum omap_plane plane, int hscaleup, + int vscaleup, int five_taps) +{ + /* Coefficients for horizontal up-sampling */ + static const u32 coef_hup[8] = { + 0x00800000, + 0x0D7CF800, + 0x1E70F5FF, + 0x335FF5FE, + 0xF74949F7, + 0xF55F33FB, + 0xF5701EFE, + 0xF87C0DFF, + }; + + /* Coefficients for horizontal down-sampling */ + static const u32 coef_hdown[8] = { + 0x24382400, + 0x28371FFE, + 0x2C361BFB, + 0x303516F9, + 0x11343311, + 0x1635300C, + 0x1B362C08, + 0x1F372804, + }; + + /* Coefficients for horizontal and vertical up-sampling */ + static const u32 coef_hvup[2][8] = { + { + 0x00800000, + 0x037B02FF, + 0x0C6F05FE, + 0x205907FB, + 0x00404000, + 0x075920FE, + 0x056F0CFF, + 0x027B0300, + }, + { + 0x00800000, + 0x0D7CF8FF, + 0x1E70F5FE, + 0x335FF5FB, + 0xF7404000, + 0xF55F33FE, + 0xF5701EFF, + 0xF87C0D00, + }, + }; + + /* Coefficients for horizontal and vertical down-sampling */ + static const u32 coef_hvdown[2][8] = { + { + 0x24382400, + 0x28391F04, + 0x2D381B08, + 0x3237170C, + 0x123737F7, + 0x173732F9, + 0x1B382DFB, + 0x1F3928FE, + }, + { + 0x24382400, + 0x28371F04, + 0x2C361B08, + 0x3035160C, + 0x113433F7, + 0x163530F9, + 0x1B362CFB, + 0x1F3728FE, + }, + }; + + /* Coefficients for vertical up-sampling */ + static const u32 coef_vup[8] = { + 0x00000000, + 0x0000FF00, + 0x0000FEFF, + 0x0000FBFE, + 0x000000F7, + 0x0000FEFB, + 0x0000FFFE, + 0x000000FF, + }; + + + /* Coefficients for vertical down-sampling */ + static const u32 coef_vdown[8] = { + 0x00000000, + 0x000004FE, + 0x000008FB, + 0x00000CF9, + 0x0000F711, + 0x0000F90C, + 0x0000FB08, + 0x0000FE04, + }; + + const u32 *h_coef; + const u32 *hv_coef; + const u32 *hv_coef_mod; + const u32 *v_coef; + int i; + + if (hscaleup) + h_coef = coef_hup; + else + h_coef = coef_hdown; + + if (vscaleup) { + hv_coef = coef_hvup[five_taps]; + v_coef = coef_vup; + + if (hscaleup) + hv_coef_mod = NULL; + else + hv_coef_mod = coef_hvdown[five_taps]; + } else { + hv_coef = coef_hvdown[five_taps]; + v_coef = coef_vdown; + + if (hscaleup) + hv_coef_mod = coef_hvup[five_taps]; + else + hv_coef_mod = NULL; + } + + for (i = 0; i < 8; i++) { + u32 h, hv; + + h = h_coef[i]; + + hv = hv_coef[i]; + + if (hv_coef_mod) { + hv &= 0xffffff00; + hv |= (hv_coef_mod[i] & 0xff); + } + + _dispc_write_firh_reg(plane, i, h); + _dispc_write_firhv_reg(plane, i, hv); + } + + if (!five_taps) + return; + + for (i = 0; i < 8; i++) { + u32 v; + v = v_coef[i]; + _dispc_write_firv_reg(plane, i, v); + } +} + +static void _dispc_setup_color_conv_coef(void) +{ + const struct color_conv_coef { + int ry, rcr, rcb, gy, gcr, gcb, by, bcr, bcb; + int full_range; + } ctbl_bt601_5 = { + 298, 409, 0, 298, -208, -100, 298, 0, 517, 0, + }; + + const struct color_conv_coef *ct; + +#define CVAL(x, y) (FLD_VAL(x, 26, 16) | FLD_VAL(y, 10, 0)) + + ct = &ctbl_bt601_5; + + dispc_write_reg(DISPC_VID_CONV_COEF(0, 0), CVAL(ct->rcr, ct->ry)); + dispc_write_reg(DISPC_VID_CONV_COEF(0, 1), CVAL(ct->gy, ct->rcb)); + dispc_write_reg(DISPC_VID_CONV_COEF(0, 2), CVAL(ct->gcb, ct->gcr)); + dispc_write_reg(DISPC_VID_CONV_COEF(0, 3), CVAL(ct->bcr, ct->by)); + dispc_write_reg(DISPC_VID_CONV_COEF(0, 4), CVAL(0, ct->bcb)); + + dispc_write_reg(DISPC_VID_CONV_COEF(1, 0), CVAL(ct->rcr, ct->ry)); + dispc_write_reg(DISPC_VID_CONV_COEF(1, 1), CVAL(ct->gy, ct->rcb)); + dispc_write_reg(DISPC_VID_CONV_COEF(1, 2), CVAL(ct->gcb, ct->gcr)); + dispc_write_reg(DISPC_VID_CONV_COEF(1, 3), CVAL(ct->bcr, ct->by)); + dispc_write_reg(DISPC_VID_CONV_COEF(1, 4), CVAL(0, ct->bcb)); + +#undef CVAL + + REG_FLD_MOD(DISPC_VID_ATTRIBUTES(0), ct->full_range, 11, 11); + REG_FLD_MOD(DISPC_VID_ATTRIBUTES(1), ct->full_range, 11, 11); +} + + +static void _dispc_set_plane_ba0(enum omap_plane plane, u32 paddr) +{ + const struct dispc_reg ba0_reg[] = { DISPC_GFX_BA0, + DISPC_VID_BA0(0), + DISPC_VID_BA0(1) }; + + dispc_write_reg(ba0_reg[plane], paddr); +} + +static void _dispc_set_plane_ba1(enum omap_plane plane, u32 paddr) +{ + const struct dispc_reg ba1_reg[] = { DISPC_GFX_BA1, + DISPC_VID_BA1(0), + DISPC_VID_BA1(1) }; + + dispc_write_reg(ba1_reg[plane], paddr); +} + +static void _dispc_set_plane_pos(enum omap_plane plane, int x, int y) +{ + const struct dispc_reg pos_reg[] = { DISPC_GFX_POSITION, + DISPC_VID_POSITION(0), + DISPC_VID_POSITION(1) }; + + u32 val = FLD_VAL(y, 26, 16) | FLD_VAL(x, 10, 0); + dispc_write_reg(pos_reg[plane], val); +} + +static void _dispc_set_pic_size(enum omap_plane plane, int width, int height) +{ + const struct dispc_reg siz_reg[] = { DISPC_GFX_SIZE, + DISPC_VID_PICTURE_SIZE(0), + DISPC_VID_PICTURE_SIZE(1) }; + u32 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); + dispc_write_reg(siz_reg[plane], val); +} + +static void _dispc_set_vid_size(enum omap_plane plane, int width, int height) +{ + u32 val; + const struct dispc_reg vsi_reg[] = { DISPC_VID_SIZE(0), + DISPC_VID_SIZE(1) }; + + BUG_ON(plane == OMAP_DSS_GFX); + + val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); + dispc_write_reg(vsi_reg[plane-1], val); +} + +static void _dispc_setup_global_alpha(enum omap_plane plane, u8 global_alpha) +{ + + BUG_ON(plane == OMAP_DSS_VIDEO1); + + if (plane == OMAP_DSS_GFX) + REG_FLD_MOD(DISPC_GLOBAL_ALPHA, global_alpha, 7, 0); + else if (plane == OMAP_DSS_VIDEO2) + REG_FLD_MOD(DISPC_GLOBAL_ALPHA, global_alpha, 23, 16); +} + +static void _dispc_set_pix_inc(enum omap_plane plane, s32 inc) +{ + const struct dispc_reg ri_reg[] = { DISPC_GFX_PIXEL_INC, + DISPC_VID_PIXEL_INC(0), + DISPC_VID_PIXEL_INC(1) }; + + dispc_write_reg(ri_reg[plane], inc); +} + +static void _dispc_set_row_inc(enum omap_plane plane, s32 inc) +{ + const struct dispc_reg ri_reg[] = { DISPC_GFX_ROW_INC, + DISPC_VID_ROW_INC(0), + DISPC_VID_ROW_INC(1) }; + + dispc_write_reg(ri_reg[plane], inc); +} + +static void _dispc_set_color_mode(enum omap_plane plane, + enum omap_color_mode color_mode) +{ + u32 m = 0; + + switch (color_mode) { + case OMAP_DSS_COLOR_CLUT1: + m = 0x0; break; + case OMAP_DSS_COLOR_CLUT2: + m = 0x1; break; + case OMAP_DSS_COLOR_CLUT4: + m = 0x2; break; + case OMAP_DSS_COLOR_CLUT8: + m = 0x3; break; + case OMAP_DSS_COLOR_RGB12U: + m = 0x4; break; + case OMAP_DSS_COLOR_ARGB16: + m = 0x5; break; + case OMAP_DSS_COLOR_RGB16: + m = 0x6; break; + case OMAP_DSS_COLOR_RGB24U: + m = 0x8; break; + case OMAP_DSS_COLOR_RGB24P: + m = 0x9; break; + case OMAP_DSS_COLOR_YUV2: + m = 0xa; break; + case OMAP_DSS_COLOR_UYVY: + m = 0xb; break; + case OMAP_DSS_COLOR_ARGB32: + m = 0xc; break; + case OMAP_DSS_COLOR_RGBA32: + m = 0xd; break; + case OMAP_DSS_COLOR_RGBX32: + m = 0xe; break; + default: + BUG(); break; + } + + REG_FLD_MOD(dispc_reg_att[plane], m, 4, 1); +} + +static void _dispc_set_channel_out(enum omap_plane plane, + enum omap_channel channel) +{ + int shift; + u32 val; + + switch (plane) { + case OMAP_DSS_GFX: + shift = 8; + break; + case OMAP_DSS_VIDEO1: + case OMAP_DSS_VIDEO2: + shift = 16; + break; + default: + BUG(); + return; + } + + val = dispc_read_reg(dispc_reg_att[plane]); + val = FLD_MOD(val, channel, shift, shift); + dispc_write_reg(dispc_reg_att[plane], val); +} + +void dispc_set_burst_size(enum omap_plane plane, + enum omap_burst_size burst_size) +{ + int shift; + u32 val; + + enable_clocks(1); + + switch (plane) { + case OMAP_DSS_GFX: + shift = 6; + break; + case OMAP_DSS_VIDEO1: + case OMAP_DSS_VIDEO2: + shift = 14; + break; + default: + BUG(); + return; + } + + val = dispc_read_reg(dispc_reg_att[plane]); + val = FLD_MOD(val, burst_size, shift+1, shift); + dispc_write_reg(dispc_reg_att[plane], val); + + enable_clocks(0); +} + +static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable) +{ + u32 val; + + BUG_ON(plane == OMAP_DSS_GFX); + + val = dispc_read_reg(dispc_reg_att[plane]); + val = FLD_MOD(val, enable, 9, 9); + dispc_write_reg(dispc_reg_att[plane], val); +} + +void dispc_enable_replication(enum omap_plane plane, bool enable) +{ + int bit; + + if (plane == OMAP_DSS_GFX) + bit = 5; + else + bit = 10; + + enable_clocks(1); + REG_FLD_MOD(dispc_reg_att[plane], enable, bit, bit); + enable_clocks(0); +} + +void dispc_set_lcd_size(u16 width, u16 height) +{ + u32 val; + BUG_ON((width > (1 << 11)) || (height > (1 << 11))); + val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); + enable_clocks(1); + dispc_write_reg(DISPC_SIZE_LCD, val); + enable_clocks(0); +} + +void dispc_set_digit_size(u16 width, u16 height) +{ + u32 val; + BUG_ON((width > (1 << 11)) || (height > (1 << 11))); + val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); + enable_clocks(1); + dispc_write_reg(DISPC_SIZE_DIG, val); + enable_clocks(0); +} + +static void dispc_read_plane_fifo_sizes(void) +{ + const struct dispc_reg fsz_reg[] = { DISPC_GFX_FIFO_SIZE_STATUS, + DISPC_VID_FIFO_SIZE_STATUS(0), + DISPC_VID_FIFO_SIZE_STATUS(1) }; + u32 size; + int plane; + + enable_clocks(1); + + for (plane = 0; plane < ARRAY_SIZE(dispc.fifo_size); ++plane) { + if (cpu_is_omap24xx()) + size = FLD_GET(dispc_read_reg(fsz_reg[plane]), 8, 0); + else if (cpu_is_omap34xx()) + size = FLD_GET(dispc_read_reg(fsz_reg[plane]), 10, 0); + else if (cpu_is_omap44xx()) + size = FLD_GET(dispc_read_reg(fsz_reg[plane]), 15, 0); + else + BUG(); + dispc.fifo_size[plane] = size; + } + + enable_clocks(0); +} + +u32 dispc_get_plane_fifo_size(enum omap_plane plane) +{ + return dispc.fifo_size[plane]; +} + +void dispc_setup_plane_fifo(enum omap_plane plane, u32 low, u32 high) +{ + const struct dispc_reg ftrs_reg[] = { DISPC_GFX_FIFO_THRESHOLD, + DISPC_VID_FIFO_THRESHOLD(0), + DISPC_VID_FIFO_THRESHOLD(1) }; + enable_clocks(1); + + DSSDBG("fifo(%d) low/high old %u/%u, new %u/%u\n", + plane, + REG_GET(ftrs_reg[plane], 11, 0), + REG_GET(ftrs_reg[plane], 27, 16), + low, high); + + if (cpu_is_omap24xx()) + dispc_write_reg(ftrs_reg[plane], + FLD_VAL(high, 24, 16) | FLD_VAL(low, 8, 0)); + else if (cpu_is_omap34xx()) + dispc_write_reg(ftrs_reg[plane], + FLD_VAL(high, 27, 16) | FLD_VAL(low, 11, 0)); + else /* cpu is omap44xx */ + dispc_write_reg(ftrs_reg[plane], + FLD_VAL(high, 31, 16) | FLD_VAL(low, 15, 0)); + + enable_clocks(0); +} + +void dispc_enable_fifomerge(bool enable) +{ + enable_clocks(1); + + DSSDBG("FIFO merge %s\n", enable ? "enabled" : "disabled"); + REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14); + + enable_clocks(0); +} + +static void _dispc_set_fir(enum omap_plane plane, int hinc, int vinc) +{ + u32 val; + const struct dispc_reg fir_reg[] = { DISPC_VID_FIR(0), + DISPC_VID_FIR(1) }; + + BUG_ON(plane == OMAP_DSS_GFX); + + if (cpu_is_omap24xx()) + val = FLD_VAL(vinc, 27, 16) | FLD_VAL(hinc, 11, 0); + else + val = FLD_VAL(vinc, 28, 16) | FLD_VAL(hinc, 12, 0); + dispc_write_reg(fir_reg[plane-1], val); +} + +static void _dispc_set_vid_accu0(enum omap_plane plane, int haccu, int vaccu) +{ + u32 val; + const struct dispc_reg ac0_reg[] = { DISPC_VID_ACCU0(0), + DISPC_VID_ACCU0(1) }; + + BUG_ON(plane == OMAP_DSS_GFX); + + val = FLD_VAL(vaccu, 25, 16) | FLD_VAL(haccu, 9, 0); + dispc_write_reg(ac0_reg[plane-1], val); +} + +static void _dispc_set_vid_accu1(enum omap_plane plane, int haccu, int vaccu) +{ + u32 val; + const struct dispc_reg ac1_reg[] = { DISPC_VID_ACCU1(0), + DISPC_VID_ACCU1(1) }; + + BUG_ON(plane == OMAP_DSS_GFX); + + val = FLD_VAL(vaccu, 25, 16) | FLD_VAL(haccu, 9, 0); + dispc_write_reg(ac1_reg[plane-1], val); +} + + +static void _dispc_set_scaling(enum omap_plane plane, + u16 orig_width, u16 orig_height, + u16 out_width, u16 out_height, + bool ilace, bool five_taps, + bool fieldmode) +{ + int fir_hinc; + int fir_vinc; + int hscaleup, vscaleup; + int accu0 = 0; + int accu1 = 0; + u32 l; + + BUG_ON(plane == OMAP_DSS_GFX); + + hscaleup = orig_width <= out_width; + vscaleup = orig_height <= out_height; + + _dispc_set_scale_coef(plane, hscaleup, vscaleup, five_taps); + + if (!orig_width || orig_width == out_width) + fir_hinc = 0; + else + fir_hinc = 1024 * orig_width / out_width; + + if (!orig_height || orig_height == out_height) + fir_vinc = 0; + else + fir_vinc = 1024 * orig_height / out_height; + + _dispc_set_fir(plane, fir_hinc, fir_vinc); + + l = dispc_read_reg(dispc_reg_att[plane]); + l &= ~((0x0f << 5) | (0x3 << 21)); + + l |= fir_hinc ? (1 << 5) : 0; + l |= fir_vinc ? (1 << 6) : 0; + + l |= hscaleup ? 0 : (1 << 7); + l |= vscaleup ? 0 : (1 << 8); + + l |= five_taps ? (1 << 21) : 0; + l |= five_taps ? (1 << 22) : 0; + + dispc_write_reg(dispc_reg_att[plane], l); + + /* + * field 0 = even field = bottom field + * field 1 = odd field = top field + */ + if (ilace && !fieldmode) { + accu1 = 0; + accu0 = (fir_vinc / 2) & 0x3ff; + if (accu0 >= 1024/2) { + accu1 = 1024/2; + accu0 -= accu1; + } + } + + _dispc_set_vid_accu0(plane, 0, accu0); + _dispc_set_vid_accu1(plane, 0, accu1); +} + +static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation, + bool mirroring, enum omap_color_mode color_mode) +{ + if (color_mode == OMAP_DSS_COLOR_YUV2 || + color_mode == OMAP_DSS_COLOR_UYVY) { + int vidrot = 0; + + if (mirroring) { + switch (rotation) { + case 0: + vidrot = 2; + break; + case 1: + vidrot = 1; + break; + case 2: + vidrot = 0; + break; + case 3: + vidrot = 3; + break; + } + } else { + switch (rotation) { + case 0: + vidrot = 0; + break; + case 1: + vidrot = 1; + break; + case 2: + vidrot = 2; + break; + case 3: + vidrot = 3; + break; + } + } + + REG_FLD_MOD(dispc_reg_att[plane], vidrot, 13, 12); + + if (rotation == 1 || rotation == 3) + REG_FLD_MOD(dispc_reg_att[plane], 0x1, 18, 18); + else + REG_FLD_MOD(dispc_reg_att[plane], 0x0, 18, 18); + } else { + REG_FLD_MOD(dispc_reg_att[plane], 0, 13, 12); + REG_FLD_MOD(dispc_reg_att[plane], 0, 18, 18); + } +} + +static s32 pixinc(int pixels, u8 ps) +{ + if (pixels == 1) + return 1; + else if (pixels > 1) + return 1 + (pixels - 1) * ps; + else if (pixels < 0) + return 1 - (-pixels + 1) * ps; + else + BUG(); +} + +static void calc_vrfb_rotation_offset(u8 rotation, bool mirror, + u16 screen_width, + u16 width, u16 height, + enum omap_color_mode color_mode, bool fieldmode, + unsigned int field_offset, + unsigned *offset0, unsigned *offset1, + s32 *row_inc, s32 *pix_inc) +{ + u8 ps; + + switch (color_mode) { + case OMAP_DSS_COLOR_RGB16: + case OMAP_DSS_COLOR_ARGB16: + ps = 2; + break; + + case OMAP_DSS_COLOR_RGB24P: + ps = 3; + break; + + case OMAP_DSS_COLOR_RGB24U: + case OMAP_DSS_COLOR_ARGB32: + case OMAP_DSS_COLOR_RGBA32: + case OMAP_DSS_COLOR_RGBX32: + case OMAP_DSS_COLOR_YUV2: + case OMAP_DSS_COLOR_UYVY: + ps = 4; + break; + + default: + BUG(); + return; + } + + DSSDBG("calc_rot(%d): scrw %d, %dx%d\n", rotation, screen_width, + width, height); + + /* + * field 0 = even field = bottom field + * field 1 = odd field = top field + */ + switch (rotation + mirror * 4) { + case 0: + case 2: + /* + * If the pixel format is YUV or UYVY divide the width + * of the image by 2 for 0 and 180 degree rotation. + */ + if (color_mode == OMAP_DSS_COLOR_YUV2 || + color_mode == OMAP_DSS_COLOR_UYVY) + width = width >> 1; + case 1: + case 3: + *offset1 = 0; + if (field_offset) + *offset0 = field_offset * screen_width * ps; + else + *offset0 = 0; + + *row_inc = pixinc(1 + (screen_width - width) + + (fieldmode ? screen_width : 0), + ps); + *pix_inc = pixinc(1, ps); + break; + + case 4: + case 6: + /* If the pixel format is YUV or UYVY divide the width + * of the image by 2 for 0 degree and 180 degree + */ + if (color_mode == OMAP_DSS_COLOR_YUV2 || + color_mode == OMAP_DSS_COLOR_UYVY) + width = width >> 1; + case 5: + case 7: + *offset1 = 0; + if (field_offset) + *offset0 = field_offset * screen_width * ps; + else + *offset0 = 0; + *row_inc = pixinc(1 - (screen_width + width) - + (fieldmode ? screen_width : 0), + ps); + *pix_inc = pixinc(1, ps); + break; + + default: + BUG(); + } +} + +static void calc_dma_rotation_offset(u8 rotation, bool mirror, + u16 screen_width, + u16 width, u16 height, + enum omap_color_mode color_mode, bool fieldmode, + unsigned int field_offset, + unsigned *offset0, unsigned *offset1, + s32 *row_inc, s32 *pix_inc) +{ + u8 ps; + u16 fbw, fbh; + + switch (color_mode) { + case OMAP_DSS_COLOR_RGB16: + case OMAP_DSS_COLOR_ARGB16: + ps = 2; + break; + + case OMAP_DSS_COLOR_RGB24P: + ps = 3; + break; + + case OMAP_DSS_COLOR_RGB24U: + case OMAP_DSS_COLOR_ARGB32: + case OMAP_DSS_COLOR_RGBA32: + case OMAP_DSS_COLOR_RGBX32: + ps = 4; + break; + + case OMAP_DSS_COLOR_YUV2: + case OMAP_DSS_COLOR_UYVY: + ps = 2; + break; + default: + BUG(); + return; + } + + DSSDBG("calc_rot(%d): scrw %d, %dx%d\n", rotation, screen_width, + width, height); + + /* width & height are overlay sizes, convert to fb sizes */ + + if (rotation == 0 || rotation == 2) { + fbw = width; + fbh = height; + } else { + fbw = height; + fbh = width; + } + + /* + * field 0 = even field = bottom field + * field 1 = odd field = top field + */ + switch (rotation + mirror * 4) { + case 0: + *offset1 = 0; + if (field_offset) + *offset0 = *offset1 + field_offset * screen_width * ps; + else + *offset0 = *offset1; + *row_inc = pixinc(1 + (screen_width - fbw) + + (fieldmode ? screen_width : 0), + ps); + *pix_inc = pixinc(1, ps); + break; + case 1: + *offset1 = screen_width * (fbh - 1) * ps; + if (field_offset) + *offset0 = *offset1 + field_offset * ps; + else + *offset0 = *offset1; + *row_inc = pixinc(screen_width * (fbh - 1) + 1 + + (fieldmode ? 1 : 0), ps); + *pix_inc = pixinc(-screen_width, ps); + break; + case 2: + *offset1 = (screen_width * (fbh - 1) + fbw - 1) * ps; + if (field_offset) + *offset0 = *offset1 - field_offset * screen_width * ps; + else + *offset0 = *offset1; + *row_inc = pixinc(-1 - + (screen_width - fbw) - + (fieldmode ? screen_width : 0), + ps); + *pix_inc = pixinc(-1, ps); + break; + case 3: + *offset1 = (fbw - 1) * ps; + if (field_offset) + *offset0 = *offset1 - field_offset * ps; + else + *offset0 = *offset1; + *row_inc = pixinc(-screen_width * (fbh - 1) - 1 - + (fieldmode ? 1 : 0), ps); + *pix_inc = pixinc(screen_width, ps); + break; + + /* mirroring */ + case 0 + 4: + *offset1 = (fbw - 1) * ps; + if (field_offset) + *offset0 = *offset1 + field_offset * screen_width * ps; + else + *offset0 = *offset1; + *row_inc = pixinc(screen_width * 2 - 1 + + (fieldmode ? screen_width : 0), + ps); + *pix_inc = pixinc(-1, ps); + break; + + case 1 + 4: + *offset1 = 0; + if (field_offset) + *offset0 = *offset1 + field_offset * ps; + else + *offset0 = *offset1; + *row_inc = pixinc(-screen_width * (fbh - 1) + 1 + + (fieldmode ? 1 : 0), + ps); + *pix_inc = pixinc(screen_width, ps); + break; + + case 2 + 4: + *offset1 = screen_width * (fbh - 1) * ps; + if (field_offset) + *offset0 = *offset1 - field_offset * screen_width * ps; + else + *offset0 = *offset1; + *row_inc = pixinc(1 - screen_width * 2 - + (fieldmode ? screen_width : 0), + ps); + *pix_inc = pixinc(1, ps); + break; + + case 3 + 4: + *offset1 = (screen_width * (fbh - 1) + fbw - 1) * ps; + if (field_offset) + *offset0 = *offset1 - field_offset * ps; + else + *offset0 = *offset1; + *row_inc = pixinc(screen_width * (fbh - 1) - 1 - + (fieldmode ? 1 : 0), + ps); + *pix_inc = pixinc(-screen_width, ps); + break; + + default: + BUG(); + } +} + +static unsigned long calc_fclk_five_taps(u16 width, u16 height, + u16 out_width, u16 out_height, enum omap_color_mode color_mode) +{ + u32 fclk = 0; + /* FIXME venc pclk? */ + u64 tmp, pclk = dispc_pclk_rate(); + + if (height > out_height) { + /* FIXME get real display PPL */ + unsigned int ppl = 800; + + tmp = pclk * height * out_width; + do_div(tmp, 2 * out_height * ppl); + fclk = tmp; + + if (height > 2 * out_height && ppl != out_width) { + tmp = pclk * (height - 2 * out_height) * out_width; + do_div(tmp, 2 * out_height * (ppl - out_width)); + fclk = max(fclk, (u32) tmp); + } + } + + if (width > out_width) { + tmp = pclk * width; + do_div(tmp, out_width); + fclk = max(fclk, (u32) tmp); + + if (color_mode == OMAP_DSS_COLOR_RGB24U) + fclk <<= 1; + } + + return fclk; +} + +static unsigned long calc_fclk(u16 width, u16 height, + u16 out_width, u16 out_height) +{ + unsigned int hf, vf; + + /* + * FIXME how to determine the 'A' factor + * for the no downscaling case ? + */ + + if (width > 3 * out_width) + hf = 4; + else if (width > 2 * out_width) + hf = 3; + else if (width > out_width) + hf = 2; + else + hf = 1; + + if (height > out_height) + vf = 2; + else + vf = 1; + + /* FIXME venc pclk? */ + return dispc_pclk_rate() * vf * hf; +} + +void dispc_set_channel_out(enum omap_plane plane, enum omap_channel channel_out) +{ + enable_clocks(1); + _dispc_set_channel_out(plane, channel_out); + enable_clocks(0); +} + +static int _dispc_setup_plane(enum omap_plane plane, + u32 paddr, u16 screen_width, + u16 pos_x, u16 pos_y, + u16 width, u16 height, + u16 out_width, u16 out_height, + enum omap_color_mode color_mode, + bool ilace, + enum omap_dss_rotation_type rotation_type, + u8 rotation, int mirror, + u8 global_alpha) +{ + const int maxdownscale = cpu_is_omap34xx() ? 4 : 2; + bool five_taps = 0; + bool fieldmode = 0; + int cconv = 0; + unsigned offset0, offset1; + s32 row_inc; + s32 pix_inc; + u16 frame_height = height; + unsigned int field_offset = 0; + + if (paddr == 0) + return -EINVAL; + + if (ilace && height == out_height) + fieldmode = 1; + + if (ilace) { + if (fieldmode) + height /= 2; + pos_y /= 2; + out_height /= 2; + + DSSDBG("adjusting for ilace: height %d, pos_y %d, " + "out_height %d\n", + height, pos_y, out_height); + } + + if (plane == OMAP_DSS_GFX) { + if (width != out_width || height != out_height) + return -EINVAL; + + switch (color_mode) { + case OMAP_DSS_COLOR_ARGB16: + case OMAP_DSS_COLOR_RGB16: + case OMAP_DSS_COLOR_RGB24P: + case OMAP_DSS_COLOR_RGB24U: + case OMAP_DSS_COLOR_ARGB32: + case OMAP_DSS_COLOR_RGBA32: + case OMAP_DSS_COLOR_RGBX32: + break; + + default: + return -EINVAL; + } + } else { + /* video plane */ + + unsigned long fclk = 0; + + if (out_width < width / maxdownscale || + out_width > width * 8) + return -EINVAL; + + if (out_height < height / maxdownscale || + out_height > height * 8) + return -EINVAL; + + switch (color_mode) { + case OMAP_DSS_COLOR_RGB16: + case OMAP_DSS_COLOR_RGB24P: + case OMAP_DSS_COLOR_RGB24U: + case OMAP_DSS_COLOR_RGBX32: + break; + + case OMAP_DSS_COLOR_ARGB16: + case OMAP_DSS_COLOR_ARGB32: + case OMAP_DSS_COLOR_RGBA32: + if (plane == OMAP_DSS_VIDEO1) + return -EINVAL; + break; + + case OMAP_DSS_COLOR_YUV2: + case OMAP_DSS_COLOR_UYVY: + cconv = 1; + break; + + default: + return -EINVAL; + } + + /* Must use 5-tap filter? */ + five_taps = height > out_height * 2; + + if (!five_taps) { + fclk = calc_fclk(width, height, + out_width, out_height); + + /* Try 5-tap filter if 3-tap fclk is too high */ + if (cpu_is_omap34xx() && height > out_height && + fclk > dispc_fclk_rate()) + five_taps = true; + } + + if (width > (2048 >> five_taps)) + return -EINVAL; + + if (five_taps) + fclk = calc_fclk_five_taps(width, height, + out_width, out_height, color_mode); + + DSSDBG("required fclk rate = %lu Hz\n", fclk); + DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate()); + + if (fclk > dispc_fclk_rate()) + return -EINVAL; + } + + if (ilace && !fieldmode) { + /* + * when downscaling the bottom field may have to start several + * source lines below the top field. Unfortunately ACCUI + * registers will only hold the fractional part of the offset + * so the integer part must be added to the base address of the + * bottom field. + */ + if (!height || height == out_height) + field_offset = 0; + else + field_offset = height / out_height / 2; + } + + /* Fields are independent but interleaved in memory. */ + if (fieldmode) + field_offset = 1; + + if (rotation_type == OMAP_DSS_ROT_DMA) + calc_dma_rotation_offset(rotation, mirror, + screen_width, width, frame_height, color_mode, + fieldmode, field_offset, + &offset0, &offset1, &row_inc, &pix_inc); + else + calc_vrfb_rotation_offset(rotation, mirror, + screen_width, width, frame_height, color_mode, + fieldmode, field_offset, + &offset0, &offset1, &row_inc, &pix_inc); + + DSSDBG("offset0 %u, offset1 %u, row_inc %d, pix_inc %d\n", + offset0, offset1, row_inc, pix_inc); + + _dispc_set_color_mode(plane, color_mode); + + _dispc_set_plane_ba0(plane, paddr + offset0); + _dispc_set_plane_ba1(plane, paddr + offset1); + + _dispc_set_row_inc(plane, row_inc); + _dispc_set_pix_inc(plane, pix_inc); + + DSSDBG("%d,%d %dx%d -> %dx%d\n", pos_x, pos_y, width, height, + out_width, out_height); + + _dispc_set_plane_pos(plane, pos_x, pos_y); + + _dispc_set_pic_size(plane, width, height); + + if (plane != OMAP_DSS_GFX) { + _dispc_set_scaling(plane, width, height, + out_width, out_height, + ilace, five_taps, fieldmode); + _dispc_set_vid_size(plane, out_width, out_height); + _dispc_set_vid_color_conv(plane, cconv); + } + + _dispc_set_rotation_attrs(plane, rotation, mirror, color_mode); + + if (plane != OMAP_DSS_VIDEO1) + _dispc_setup_global_alpha(plane, global_alpha); + + return 0; +} + +static void _dispc_enable_plane(enum omap_plane plane, bool enable) +{ + REG_FLD_MOD(dispc_reg_att[plane], enable ? 1 : 0, 0, 0); +} + +static void dispc_disable_isr(void *data, u32 mask) +{ + struct completion *compl = data; + complete(compl); +} + +static void _enable_lcd_out(bool enable) +{ + REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0); +} + +void dispc_enable_lcd_out(bool enable) +{ + struct completion frame_done_completion; + bool is_on; + int r; + + enable_clocks(1); + + /* When we disable LCD output, we need to wait until frame is done. + * Otherwise the DSS is still working, and turning off the clocks + * prevents DSS from going to OFF mode */ + is_on = REG_GET(DISPC_CONTROL, 0, 0); + + if (!enable && is_on) { + init_completion(&frame_done_completion); + + r = omap_dispc_register_isr(dispc_disable_isr, + &frame_done_completion, + DISPC_IRQ_FRAMEDONE); + + if (r) + DSSERR("failed to register FRAMEDONE isr\n"); + } + + _enable_lcd_out(enable); + + if (!enable && is_on) { + if (!wait_for_completion_timeout(&frame_done_completion, + msecs_to_jiffies(100))) + DSSERR("timeout waiting for FRAME DONE\n"); + + r = omap_dispc_unregister_isr(dispc_disable_isr, + &frame_done_completion, + DISPC_IRQ_FRAMEDONE); + + if (r) + DSSERR("failed to unregister FRAMEDONE isr\n"); + } + + enable_clocks(0); +} + +static void _enable_digit_out(bool enable) +{ + REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 1, 1); +} + +void dispc_enable_digit_out(bool enable) +{ + struct completion frame_done_completion; + int r; + + enable_clocks(1); + + if (REG_GET(DISPC_CONTROL, 1, 1) == enable) { + enable_clocks(0); + return; + } + + if (enable) { + unsigned long flags; + /* When we enable digit output, we'll get an extra digit + * sync lost interrupt, that we need to ignore */ + spin_lock_irqsave(&dispc.irq_lock, flags); + dispc.irq_error_mask &= ~DISPC_IRQ_SYNC_LOST_DIGIT; + _omap_dispc_set_irqs(); + spin_unlock_irqrestore(&dispc.irq_lock, flags); + } + + /* When we disable digit output, we need to wait until fields are done. + * Otherwise the DSS is still working, and turning off the clocks + * prevents DSS from going to OFF mode. And when enabling, we need to + * wait for the extra sync losts */ + init_completion(&frame_done_completion); + + r = omap_dispc_register_isr(dispc_disable_isr, &frame_done_completion, + DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD); + if (r) + DSSERR("failed to register EVSYNC isr\n"); + + _enable_digit_out(enable); + + /* XXX I understand from TRM that we should only wait for the + * current field to complete. But it seems we have to wait + * for both fields */ + if (!wait_for_completion_timeout(&frame_done_completion, + msecs_to_jiffies(100))) + DSSERR("timeout waiting for EVSYNC\n"); + + if (!wait_for_completion_timeout(&frame_done_completion, + msecs_to_jiffies(100))) + DSSERR("timeout waiting for EVSYNC\n"); + + r = omap_dispc_unregister_isr(dispc_disable_isr, + &frame_done_completion, + DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD); + if (r) + DSSERR("failed to unregister EVSYNC isr\n"); + + if (enable) { + unsigned long flags; + spin_lock_irqsave(&dispc.irq_lock, flags); + dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR; + dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT); + _omap_dispc_set_irqs(); + spin_unlock_irqrestore(&dispc.irq_lock, flags); + } + + enable_clocks(0); +} + +void dispc_lcd_enable_signal_polarity(bool act_high) +{ + enable_clocks(1); + REG_FLD_MOD(DISPC_CONTROL, act_high ? 1 : 0, 29, 29); + enable_clocks(0); +} + +void dispc_lcd_enable_signal(bool enable) +{ + enable_clocks(1); + REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 28, 28); + enable_clocks(0); +} + +void dispc_pck_free_enable(bool enable) +{ + enable_clocks(1); + REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 27, 27); + enable_clocks(0); +} + +void dispc_enable_fifohandcheck(bool enable) +{ + enable_clocks(1); + REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 16, 16); + enable_clocks(0); +} + + +void dispc_set_lcd_display_type(enum omap_lcd_display_type type) +{ + int mode; + + switch (type) { + case OMAP_DSS_LCD_DISPLAY_STN: + mode = 0; + break; + + case OMAP_DSS_LCD_DISPLAY_TFT: + mode = 1; + break; + + default: + BUG(); + return; + } + + enable_clocks(1); + REG_FLD_MOD(DISPC_CONTROL, mode, 3, 3); + enable_clocks(0); +} + +void dispc_set_loadmode(enum omap_dss_load_mode mode) +{ + enable_clocks(1); + REG_FLD_MOD(DISPC_CONFIG, mode, 2, 1); + enable_clocks(0); +} + + +void dispc_set_default_color(enum omap_channel channel, u32 color) +{ + const struct dispc_reg def_reg[] = { DISPC_DEFAULT_COLOR0, + DISPC_DEFAULT_COLOR1 }; + + enable_clocks(1); + dispc_write_reg(def_reg[channel], color); + enable_clocks(0); +} + +u32 dispc_get_default_color(enum omap_channel channel) +{ + const struct dispc_reg def_reg[] = { DISPC_DEFAULT_COLOR0, + DISPC_DEFAULT_COLOR1 }; + u32 l; + + BUG_ON(channel != OMAP_DSS_CHANNEL_DIGIT && + channel != OMAP_DSS_CHANNEL_LCD); + + enable_clocks(1); + l = dispc_read_reg(def_reg[channel]); + enable_clocks(0); + + return l; +} + +void dispc_set_trans_key(enum omap_channel ch, + enum omap_dss_trans_key_type type, + u32 trans_key) +{ + const struct dispc_reg tr_reg[] = { + DISPC_TRANS_COLOR0, DISPC_TRANS_COLOR1 }; + + enable_clocks(1); + if (ch == OMAP_DSS_CHANNEL_LCD) + REG_FLD_MOD(DISPC_CONFIG, type, 11, 11); + else /* OMAP_DSS_CHANNEL_DIGIT */ + REG_FLD_MOD(DISPC_CONFIG, type, 13, 13); + + dispc_write_reg(tr_reg[ch], trans_key); + enable_clocks(0); +} + +void dispc_get_trans_key(enum omap_channel ch, + enum omap_dss_trans_key_type *type, + u32 *trans_key) +{ + const struct dispc_reg tr_reg[] = { + DISPC_TRANS_COLOR0, DISPC_TRANS_COLOR1 }; + + enable_clocks(1); + if (type) { + if (ch == OMAP_DSS_CHANNEL_LCD) + *type = REG_GET(DISPC_CONFIG, 11, 11); + else if (ch == OMAP_DSS_CHANNEL_DIGIT) + *type = REG_GET(DISPC_CONFIG, 13, 13); + else + BUG(); + } + + if (trans_key) + *trans_key = dispc_read_reg(tr_reg[ch]); + enable_clocks(0); +} + +void dispc_enable_trans_key(enum omap_channel ch, bool enable) +{ + enable_clocks(1); + if (ch == OMAP_DSS_CHANNEL_LCD) + REG_FLD_MOD(DISPC_CONFIG, enable, 10, 10); + else /* OMAP_DSS_CHANNEL_DIGIT */ + REG_FLD_MOD(DISPC_CONFIG, enable, 12, 12); + enable_clocks(0); +} +void dispc_enable_alpha_blending(enum omap_channel ch, bool enable) +{ + enable_clocks(1); + if (ch == OMAP_DSS_CHANNEL_LCD) + REG_FLD_MOD(DISPC_CONFIG, enable, 18, 18); + else /* OMAP_DSS_CHANNEL_DIGIT */ + REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19); + enable_clocks(0); +} +bool dispc_alpha_blending_enabled(enum omap_channel ch) +{ + bool enabled; + + enable_clocks(1); + if (ch == OMAP_DSS_CHANNEL_LCD) + enabled = REG_GET(DISPC_CONFIG, 18, 18); + else if (ch == OMAP_DSS_CHANNEL_DIGIT) + enabled = REG_GET(DISPC_CONFIG, 18, 18); + else + BUG(); + enable_clocks(0); + + return enabled; + +} + + +bool dispc_trans_key_enabled(enum omap_channel ch) +{ + bool enabled; + + enable_clocks(1); + if (ch == OMAP_DSS_CHANNEL_LCD) + enabled = REG_GET(DISPC_CONFIG, 10, 10); + else if (ch == OMAP_DSS_CHANNEL_DIGIT) + enabled = REG_GET(DISPC_CONFIG, 12, 12); + else + BUG(); + enable_clocks(0); + + return enabled; +} + + +void dispc_set_tft_data_lines(u8 data_lines) +{ + int code; + + switch (data_lines) { + case 12: + code = 0; + break; + case 16: + code = 1; + break; + case 18: + code = 2; + break; + case 24: + code = 3; + break; + default: + BUG(); + return; + } + + enable_clocks(1); + REG_FLD_MOD(DISPC_CONTROL, code, 9, 8); + enable_clocks(0); +} + +void dispc_set_parallel_interface_mode(enum omap_parallel_interface_mode mode) +{ + u32 l; + int stallmode; + int gpout0 = 1; + int gpout1; +#define VIRTIO_OMAP4 + switch (mode) { + case OMAP_DSS_PARALLELMODE_BYPASS: +#ifndef VIRTIO_OMAP4 + stallmode = 0; +#else /* This is needed for a quirk with virtio, to have RFBI enabled */ + stallmode = 1; +#endif + gpout1 = 1; + break; + + case OMAP_DSS_PARALLELMODE_RFBI: + stallmode = 1; + gpout1 = 0; + break; + + case OMAP_DSS_PARALLELMODE_DSI: + stallmode = 1; + gpout1 = 1; + break; + + default: + BUG(); + return; + } + + enable_clocks(1); + + l = dispc_read_reg(DISPC_CONTROL); + + printk(KERN_INFO "OMAP DISPCONTROL read (stallmode)%d\n", + FLD_GET(l, 11, 11)); + printk(KERN_INFO "OMAP DISPCONTROL read (gpout)%d\n", + FLD_GET(l, 15, 15)); + printk(KERN_INFO "OMAP DISPCONTROL read (stallmode)%d\n", + FLD_GET(l, 16, 16)); + + + l = FLD_MOD(l, stallmode, 11, 11); + l = FLD_MOD(l, gpout0, 15, 15); + l = FLD_MOD(l, gpout1, 16, 16); + + dispc_write_reg(DISPC_CONTROL, l); + + enable_clocks(0); +} + +static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp, + int vsw, int vfp, int vbp) +{ + if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) { + if (hsw < 1 || hsw > 64 || + hfp < 1 || hfp > 256 || + hbp < 1 || hbp > 256 || + vsw < 1 || vsw > 64 || + vfp < 0 || vfp > 255 || + vbp < 0 || vbp > 255) + return false; + } else { + if (hsw < 1 || hsw > 256 || + hfp < 1 || hfp > 4096 || + hbp < 1 || hbp > 4096 || + vsw < 1 || vsw > 256 || + vfp < 0 || vfp > 4095 || + vbp < 0 || vbp > 4095) + return false; + } + + return true; +} + +bool dispc_lcd_timings_ok(struct omap_video_timings *timings) +{ + return _dispc_lcd_timings_ok(timings->hsw, timings->hfp, + timings->hbp, timings->vsw, + timings->vfp, timings->vbp); +} + +static void _dispc_set_lcd_timings(int hsw, int hfp, int hbp, + int vsw, int vfp, int vbp) +{ + u32 timing_h, timing_v; + + if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) { + timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) | + FLD_VAL(hbp-1, 27, 20); + + timing_v = FLD_VAL(vsw-1, 5, 0) | FLD_VAL(vfp, 15, 8) | + FLD_VAL(vbp, 27, 20); + } else { + timing_h = FLD_VAL(hsw-1, 7, 0) | FLD_VAL(hfp-1, 19, 8) | + FLD_VAL(hbp-1, 31, 20); + + timing_v = FLD_VAL(vsw-1, 7, 0) | FLD_VAL(vfp, 19, 8) | + FLD_VAL(vbp, 31, 20); + } + + enable_clocks(1); + dispc_write_reg(DISPC_TIMING_H, timing_h); + dispc_write_reg(DISPC_TIMING_V, timing_v); + enable_clocks(0); +} + +/* change name to mode? */ +void dispc_set_lcd_timings(struct omap_video_timings *timings) +{ + unsigned xtot, ytot; + unsigned long ht, vt; + + if (!_dispc_lcd_timings_ok(timings->hsw, timings->hfp, + timings->hbp, timings->vsw, + timings->vfp, timings->vbp)) + BUG(); + + _dispc_set_lcd_timings(timings->hsw, timings->hfp, timings->hbp, + timings->vsw, timings->vfp, timings->vbp); + + dispc_set_lcd_size(timings->x_res, timings->y_res); + + xtot = timings->x_res + timings->hfp + timings->hsw + timings->hbp; + ytot = timings->y_res + timings->vfp + timings->vsw + timings->vbp; + + ht = (timings->pixel_clock * 1000) / xtot; + vt = (timings->pixel_clock * 1000) / xtot / ytot; + + DSSDBG("xres %u yres %u\n", timings->x_res, timings->y_res); + DSSDBG("pck %u\n", timings->pixel_clock); + DSSDBG("hsw %d hfp %d hbp %d vsw %d vfp %d vbp %d\n", + timings->hsw, timings->hfp, timings->hbp, + timings->vsw, timings->vfp, timings->vbp); + + DSSDBG("hsync %luHz, vsync %luHz\n", ht, vt); +} + +void dispc_set_lcd_divisor(u16 lck_div, u16 pck_div) +{ + BUG_ON(lck_div < 1); + BUG_ON(pck_div < 2); + + enable_clocks(1); + dispc_write_reg(DISPC_DIVISOR, + FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0)); + enable_clocks(0); +} + +static void dispc_get_lcd_divisor(int *lck_div, int *pck_div) +{ + u32 l; + l = dispc_read_reg(DISPC_DIVISOR); + *lck_div = FLD_GET(l, 23, 16); + *pck_div = FLD_GET(l, 7, 0); +} + +unsigned long dispc_fclk_rate(void) +{ + unsigned long r = 0; + + if (dss_get_dispc_clk_source() == 0) + r = dss_clk_get_rate(DSS_CLK_FCK1); + else +#ifdef CONFIG_OMAP2_DSS_DSI + r = dsi_get_dsi1_pll_rate(); +#else + BUG(); +#endif + return r; +} + +unsigned long dispc_lclk_rate(void) +{ + int lcd; + unsigned long r; + u32 l; + + l = dispc_read_reg(DISPC_DIVISOR); + + lcd = FLD_GET(l, 23, 16); + + r = dispc_fclk_rate(); + + return r / lcd; +} + +unsigned long dispc_pclk_rate(void) +{ + int lcd, pcd; + unsigned long r; + u32 l; + + l = dispc_read_reg(DISPC_DIVISOR); + + lcd = FLD_GET(l, 23, 16); + pcd = FLD_GET(l, 7, 0); + + r = dispc_fclk_rate(); + + return r / lcd / pcd; +} + +void dispc_dump_clocks(struct seq_file *s) +{ + int lcd, pcd; + + enable_clocks(1); + + dispc_get_lcd_divisor(&lcd, &pcd); + + seq_printf(s, "- dispc -\n"); + + seq_printf(s, "dispc fclk source = %s\n", + dss_get_dispc_clk_source() == 0 ? + "dss1_alwon_fclk" : "dsi1_pll_fclk"); + + seq_printf(s, "pixel clk = %lu / %d / %d = %lu\n", + dispc_fclk_rate(), + lcd, pcd, + dispc_pclk_rate()); + + enable_clocks(0); +} + +void dispc_dump_regs(struct seq_file *s) +{ +#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dispc_read_reg(r)) + + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + + DUMPREG(DISPC_REVISION); + DUMPREG(DISPC_SYSCONFIG); + DUMPREG(DISPC_SYSSTATUS); + DUMPREG(DISPC_IRQSTATUS); + DUMPREG(DISPC_IRQENABLE); + DUMPREG(DISPC_CONTROL); + DUMPREG(DISPC_CONFIG); + DUMPREG(DISPC_CAPABLE); + DUMPREG(DISPC_DEFAULT_COLOR0); + DUMPREG(DISPC_DEFAULT_COLOR1); + DUMPREG(DISPC_TRANS_COLOR0); + DUMPREG(DISPC_TRANS_COLOR1); + DUMPREG(DISPC_LINE_STATUS); + DUMPREG(DISPC_LINE_NUMBER); + DUMPREG(DISPC_TIMING_H); + DUMPREG(DISPC_TIMING_V); + DUMPREG(DISPC_POL_FREQ); + DUMPREG(DISPC_DIVISOR); + DUMPREG(DISPC_GLOBAL_ALPHA); + DUMPREG(DISPC_SIZE_DIG); + DUMPREG(DISPC_SIZE_LCD); + + DUMPREG(DISPC_GFX_BA0); + DUMPREG(DISPC_GFX_BA1); + DUMPREG(DISPC_GFX_POSITION); + DUMPREG(DISPC_GFX_SIZE); + DUMPREG(DISPC_GFX_ATTRIBUTES); + DUMPREG(DISPC_GFX_FIFO_THRESHOLD); + DUMPREG(DISPC_GFX_FIFO_SIZE_STATUS); + DUMPREG(DISPC_GFX_ROW_INC); + DUMPREG(DISPC_GFX_PIXEL_INC); + DUMPREG(DISPC_GFX_WINDOW_SKIP); + DUMPREG(DISPC_GFX_TABLE_BA); + + DUMPREG(DISPC_DATA_CYCLE1); + DUMPREG(DISPC_DATA_CYCLE2); + DUMPREG(DISPC_DATA_CYCLE3); + + DUMPREG(DISPC_CPR_COEF_R); + DUMPREG(DISPC_CPR_COEF_G); + DUMPREG(DISPC_CPR_COEF_B); + + DUMPREG(DISPC_GFX_PRELOAD); + + DUMPREG(DISPC_VID_BA0(0)); + DUMPREG(DISPC_VID_BA1(0)); + DUMPREG(DISPC_VID_POSITION(0)); + DUMPREG(DISPC_VID_SIZE(0)); + DUMPREG(DISPC_VID_ATTRIBUTES(0)); + DUMPREG(DISPC_VID_FIFO_THRESHOLD(0)); + DUMPREG(DISPC_VID_FIFO_SIZE_STATUS(0)); + DUMPREG(DISPC_VID_ROW_INC(0)); + DUMPREG(DISPC_VID_PIXEL_INC(0)); + DUMPREG(DISPC_VID_FIR(0)); + DUMPREG(DISPC_VID_PICTURE_SIZE(0)); + DUMPREG(DISPC_VID_ACCU0(0)); + DUMPREG(DISPC_VID_ACCU1(0)); + + DUMPREG(DISPC_VID_BA0(1)); + DUMPREG(DISPC_VID_BA1(1)); + DUMPREG(DISPC_VID_POSITION(1)); + DUMPREG(DISPC_VID_SIZE(1)); + DUMPREG(DISPC_VID_ATTRIBUTES(1)); + DUMPREG(DISPC_VID_FIFO_THRESHOLD(1)); + DUMPREG(DISPC_VID_FIFO_SIZE_STATUS(1)); + DUMPREG(DISPC_VID_ROW_INC(1)); + DUMPREG(DISPC_VID_PIXEL_INC(1)); + DUMPREG(DISPC_VID_FIR(1)); + DUMPREG(DISPC_VID_PICTURE_SIZE(1)); + DUMPREG(DISPC_VID_ACCU0(1)); + DUMPREG(DISPC_VID_ACCU1(1)); + + DUMPREG(DISPC_VID_FIR_COEF_H(0, 0)); + DUMPREG(DISPC_VID_FIR_COEF_H(0, 1)); + DUMPREG(DISPC_VID_FIR_COEF_H(0, 2)); + DUMPREG(DISPC_VID_FIR_COEF_H(0, 3)); + DUMPREG(DISPC_VID_FIR_COEF_H(0, 4)); + DUMPREG(DISPC_VID_FIR_COEF_H(0, 5)); + DUMPREG(DISPC_VID_FIR_COEF_H(0, 6)); + DUMPREG(DISPC_VID_FIR_COEF_H(0, 7)); + DUMPREG(DISPC_VID_FIR_COEF_HV(0, 0)); + DUMPREG(DISPC_VID_FIR_COEF_HV(0, 1)); + DUMPREG(DISPC_VID_FIR_COEF_HV(0, 2)); + DUMPREG(DISPC_VID_FIR_COEF_HV(0, 3)); + DUMPREG(DISPC_VID_FIR_COEF_HV(0, 4)); + DUMPREG(DISPC_VID_FIR_COEF_HV(0, 5)); + DUMPREG(DISPC_VID_FIR_COEF_HV(0, 6)); + DUMPREG(DISPC_VID_FIR_COEF_HV(0, 7)); + DUMPREG(DISPC_VID_CONV_COEF(0, 0)); + DUMPREG(DISPC_VID_CONV_COEF(0, 1)); + DUMPREG(DISPC_VID_CONV_COEF(0, 2)); + DUMPREG(DISPC_VID_CONV_COEF(0, 3)); + DUMPREG(DISPC_VID_CONV_COEF(0, 4)); + DUMPREG(DISPC_VID_FIR_COEF_V(0, 0)); + DUMPREG(DISPC_VID_FIR_COEF_V(0, 1)); + DUMPREG(DISPC_VID_FIR_COEF_V(0, 2)); + DUMPREG(DISPC_VID_FIR_COEF_V(0, 3)); + DUMPREG(DISPC_VID_FIR_COEF_V(0, 4)); + DUMPREG(DISPC_VID_FIR_COEF_V(0, 5)); + DUMPREG(DISPC_VID_FIR_COEF_V(0, 6)); + DUMPREG(DISPC_VID_FIR_COEF_V(0, 7)); + + DUMPREG(DISPC_VID_FIR_COEF_H(1, 0)); + DUMPREG(DISPC_VID_FIR_COEF_H(1, 1)); + DUMPREG(DISPC_VID_FIR_COEF_H(1, 2)); + DUMPREG(DISPC_VID_FIR_COEF_H(1, 3)); + DUMPREG(DISPC_VID_FIR_COEF_H(1, 4)); + DUMPREG(DISPC_VID_FIR_COEF_H(1, 5)); + DUMPREG(DISPC_VID_FIR_COEF_H(1, 6)); + DUMPREG(DISPC_VID_FIR_COEF_H(1, 7)); + DUMPREG(DISPC_VID_FIR_COEF_HV(1, 0)); + DUMPREG(DISPC_VID_FIR_COEF_HV(1, 1)); + DUMPREG(DISPC_VID_FIR_COEF_HV(1, 2)); + DUMPREG(DISPC_VID_FIR_COEF_HV(1, 3)); + DUMPREG(DISPC_VID_FIR_COEF_HV(1, 4)); + DUMPREG(DISPC_VID_FIR_COEF_HV(1, 5)); + DUMPREG(DISPC_VID_FIR_COEF_HV(1, 6)); + DUMPREG(DISPC_VID_FIR_COEF_HV(1, 7)); + DUMPREG(DISPC_VID_CONV_COEF(1, 0)); + DUMPREG(DISPC_VID_CONV_COEF(1, 1)); + DUMPREG(DISPC_VID_CONV_COEF(1, 2)); + DUMPREG(DISPC_VID_CONV_COEF(1, 3)); + DUMPREG(DISPC_VID_CONV_COEF(1, 4)); + DUMPREG(DISPC_VID_FIR_COEF_V(1, 0)); + DUMPREG(DISPC_VID_FIR_COEF_V(1, 1)); + DUMPREG(DISPC_VID_FIR_COEF_V(1, 2)); + DUMPREG(DISPC_VID_FIR_COEF_V(1, 3)); + DUMPREG(DISPC_VID_FIR_COEF_V(1, 4)); + DUMPREG(DISPC_VID_FIR_COEF_V(1, 5)); + DUMPREG(DISPC_VID_FIR_COEF_V(1, 6)); + DUMPREG(DISPC_VID_FIR_COEF_V(1, 7)); + + DUMPREG(DISPC_VID_PRELOAD(0)); + DUMPREG(DISPC_VID_PRELOAD(1)); + + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); +#undef DUMPREG +} + +static void _dispc_set_pol_freq(bool onoff, bool rf, bool ieo, bool ipc, + bool ihs, bool ivs, u8 acbi, u8 acb) +{ + u32 l = 0; + + DSSDBG("onoff %d rf %d ieo %d ipc %d ihs %d ivs %d acbi %d acb %d\n", + onoff, rf, ieo, ipc, ihs, ivs, acbi, acb); + + l |= FLD_VAL(onoff, 17, 17); + l |= FLD_VAL(rf, 16, 16); + l |= FLD_VAL(ieo, 15, 15); + l |= FLD_VAL(ipc, 14, 14); + l |= FLD_VAL(ihs, 13, 13); + l |= FLD_VAL(ivs, 12, 12); + l |= FLD_VAL(acbi, 11, 8); + l |= FLD_VAL(acb, 7, 0); + + enable_clocks(1); + dispc_write_reg(DISPC_POL_FREQ, l); + enable_clocks(0); +} + +void dispc_set_pol_freq(enum omap_panel_config config, u8 acbi, u8 acb) +{ + _dispc_set_pol_freq((config & OMAP_DSS_LCD_ONOFF) != 0, + (config & OMAP_DSS_LCD_RF) != 0, + (config & OMAP_DSS_LCD_IEO) != 0, + (config & OMAP_DSS_LCD_IPC) != 0, + (config & OMAP_DSS_LCD_IHS) != 0, + (config & OMAP_DSS_LCD_IVS) != 0, + acbi, acb); +} + +void find_lck_pck_divs(bool is_tft, unsigned long req_pck, unsigned long fck, + u16 *lck_div, u16 *pck_div) +{ + u16 pcd_min = is_tft ? 2 : 3; + unsigned long best_pck; + u16 best_ld, cur_ld; + u16 best_pd, cur_pd; + + best_pck = 0; + best_ld = 0; + best_pd = 0; + + for (cur_ld = 1; cur_ld <= 255; ++cur_ld) { + unsigned long lck = fck / cur_ld; + + for (cur_pd = pcd_min; cur_pd <= 255; ++cur_pd) { + unsigned long pck = lck / cur_pd; + long old_delta = abs(best_pck - req_pck); + long new_delta = abs(pck - req_pck); + + if (best_pck == 0 || new_delta < old_delta) { + best_pck = pck; + best_ld = cur_ld; + best_pd = cur_pd; + + if (pck == req_pck) + goto found; + } + + if (pck < req_pck) + break; + } + + if (lck / pcd_min < req_pck) + break; + } + +found: + *lck_div = best_ld; + *pck_div = best_pd; +} + +int dispc_calc_clock_div(bool is_tft, unsigned long req_pck, + struct dispc_clock_info *cinfo) +{ + unsigned long prate; + struct dispc_clock_info cur, best; + int match = 0; + int min_fck_per_pck; + unsigned long fck_rate = dss_clk_get_rate(DSS_CLK_FCK1); + + if (cpu_is_omap34xx()) + prate = clk_get_rate(clk_get_parent(dispc.dpll4_m4_ck)); + else + prate = 0; + + if (req_pck == dispc.cache_req_pck && + ((cpu_is_omap34xx() && prate == dispc.cache_prate) || + dispc.cache_cinfo.fck == fck_rate)) { + DSSDBG("dispc clock info found from cache.\n"); + *cinfo = dispc.cache_cinfo; + return 0; + } + + min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK; + + if (min_fck_per_pck && + req_pck * min_fck_per_pck > DISPC_MAX_FCK) { + DSSERR("Requested pixel clock not possible with the current " + "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning " + "the constraint off.\n"); + min_fck_per_pck = 0; + } + +retry: + memset(&cur, 0, sizeof(cur)); + memset(&best, 0, sizeof(best)); + + if (cpu_is_omap24xx()) { + /* XXX can we change the clock on omap2? */ + cur.fck = dss_clk_get_rate(DSS_CLK_FCK1); + cur.fck_div = 1; + + match = 1; + + find_lck_pck_divs(is_tft, req_pck, cur.fck, + &cur.lck_div, &cur.pck_div); + + cur.lck = cur.fck / cur.lck_div; + cur.pck = cur.lck / cur.pck_div; + + best = cur; + + goto found; + } else if (cpu_is_omap34xx()) { + for (cur.fck_div = 16; cur.fck_div > 0; --cur.fck_div) { + cur.fck = prate / cur.fck_div * 2; + + if (cur.fck > DISPC_MAX_FCK) + continue; + + if (min_fck_per_pck && + cur.fck < req_pck * min_fck_per_pck) + continue; + + match = 1; + + find_lck_pck_divs(is_tft, req_pck, cur.fck, + &cur.lck_div, &cur.pck_div); + + cur.lck = cur.fck / cur.lck_div; + cur.pck = cur.lck / cur.pck_div; + + if (abs(cur.pck - req_pck) < abs(best.pck - req_pck)) { + best = cur; + + if (cur.pck == req_pck) + goto found; + } + } + } else if (cpu_is_omap44xx()) { + for (cur.fck_div = 16; cur.fck_div > 0; --cur.fck_div) { + cur.fck = prate / cur.fck_div * 2; + + if (cur.fck > DISPC_MAX_FCK) + continue; + + if (min_fck_per_pck && + cur.fck < req_pck * min_fck_per_pck) + continue; + + match = 1; + + find_lck_pck_divs(is_tft, req_pck, cur.fck, + &cur.lck_div, &cur.pck_div); + + cur.lck = cur.fck / cur.lck_div; + cur.pck = cur.lck / cur.pck_div; + + if (abs(cur.pck - req_pck) < abs(best.pck - req_pck)) { + best = cur; + + if (cur.pck == req_pck) + goto found; + } + } + } else { + BUG(); + } + +found: + if (!match) { + if (min_fck_per_pck) { + DSSERR("Could not find suitable clock settings.\n" + "Turning FCK/PCK constraint off and" + "trying again.\n"); + min_fck_per_pck = 0; + goto retry; + } + + DSSERR("Could not find suitable clock settings.\n"); + + return -EINVAL; + } + + if (cinfo) + *cinfo = best; + + dispc.cache_req_pck = req_pck; + dispc.cache_prate = prate; + dispc.cache_cinfo = best; + + return 0; +} + +int dispc_set_clock_div(struct dispc_clock_info *cinfo) +{ + unsigned long prate; + int r; + + if (cpu_is_omap34xx()) { + prate = clk_get_rate(clk_get_parent(dispc.dpll4_m4_ck)); + DSSDBG("dpll4_m4 = %ld\n", prate); + } + + DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div); + DSSDBG("lck = %ld (%d)\n", cinfo->lck, cinfo->lck_div); + DSSDBG("pck = %ld (%d)\n", cinfo->pck, cinfo->pck_div); + + if (cpu_is_omap34xx()) { + r = clk_set_rate(dispc.dpll4_m4_ck, prate / cinfo->fck_div); + if (r) + return r; + } + + dispc_set_lcd_divisor(cinfo->lck_div, cinfo->pck_div); + + return 0; +} + +int dispc_get_clock_div(struct dispc_clock_info *cinfo) +{ + cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK1); + + if (cpu_is_omap34xx()) { + unsigned long prate; + prate = clk_get_rate(clk_get_parent(dispc.dpll4_m4_ck)); + cinfo->fck_div = prate / (cinfo->fck / 2); + } else { + cinfo->fck_div = 0; + } + + cinfo->lck_div = REG_GET(DISPC_DIVISOR, 23, 16); + cinfo->pck_div = REG_GET(DISPC_DIVISOR, 7, 0); + + cinfo->lck = cinfo->fck / cinfo->lck_div; + cinfo->pck = cinfo->lck / cinfo->pck_div; + + return 0; +} + +/* dispc.irq_lock has to be locked by the caller */ +static void _omap_dispc_set_irqs(void) +{ + u32 mask; + u32 old_mask; + int i; + struct omap_dispc_isr_data *isr_data; + + mask = dispc.irq_error_mask; + + for (i = 0; i < DISPC_MAX_NR_ISRS; i++) { + isr_data = &dispc.registered_isr[i]; + + if (isr_data->isr == NULL) + continue; + + mask |= isr_data->mask; + } + + enable_clocks(1); + + old_mask = dispc_read_reg(DISPC_IRQENABLE); + /* clear the irqstatus for newly enabled irqs */ + dispc_write_reg(DISPC_IRQSTATUS, (mask ^ old_mask) & mask); + + dispc_write_reg(DISPC_IRQENABLE, mask); + + enable_clocks(0); +} + +int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask) +{ + int i; + int ret; + unsigned long flags; + struct omap_dispc_isr_data *isr_data; + + if (isr == NULL) + return -EINVAL; + + spin_lock_irqsave(&dispc.irq_lock, flags); + + /* check for duplicate entry */ + for (i = 0; i < DISPC_MAX_NR_ISRS; i++) { + isr_data = &dispc.registered_isr[i]; + if (isr_data->isr == isr && isr_data->arg == arg && + isr_data->mask == mask) { + ret = -EINVAL; + goto err; + } + } + + isr_data = NULL; + ret = -EBUSY; + + for (i = 0; i < DISPC_MAX_NR_ISRS; i++) { + isr_data = &dispc.registered_isr[i]; + + if (isr_data->isr != NULL) + continue; + + isr_data->isr = isr; + isr_data->arg = arg; + isr_data->mask = mask; + ret = 0; + + break; + } + + _omap_dispc_set_irqs(); + + spin_unlock_irqrestore(&dispc.irq_lock, flags); + + return 0; +err: + spin_unlock_irqrestore(&dispc.irq_lock, flags); + + return ret; +} +EXPORT_SYMBOL(omap_dispc_register_isr); + +int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask) +{ + int i; + unsigned long flags; + int ret = -EINVAL; + struct omap_dispc_isr_data *isr_data; + + spin_lock_irqsave(&dispc.irq_lock, flags); + + for (i = 0; i < DISPC_MAX_NR_ISRS; i++) { + isr_data = &dispc.registered_isr[i]; + if (isr_data->isr != isr || isr_data->arg != arg || + isr_data->mask != mask) + continue; + + /* found the correct isr */ + + isr_data->isr = NULL; + isr_data->arg = NULL; + isr_data->mask = 0; + + ret = 0; + break; + } + + if (ret == 0) + _omap_dispc_set_irqs(); + + spin_unlock_irqrestore(&dispc.irq_lock, flags); + + return ret; +} +EXPORT_SYMBOL(omap_dispc_unregister_isr); + +#ifdef DEBUG +static void print_irq_status(u32 status) +{ + if ((status & dispc.irq_error_mask) == 0) + return; + + printk(KERN_DEBUG "DISPC IRQ: 0x%x: ", status); + +#define PIS(x) \ + if (status & DISPC_IRQ_##x) \ + printk(#x " "); + PIS(GFX_FIFO_UNDERFLOW); + PIS(OCP_ERR); + PIS(VID1_FIFO_UNDERFLOW); + PIS(VID2_FIFO_UNDERFLOW); + PIS(SYNC_LOST); + PIS(SYNC_LOST_DIGIT); +#undef PIS + + printk("\n"); +} +#endif + +/* Called from dss.c. Note that we don't touch clocks here, + * but we presume they are on because we got an IRQ. However, + * an irq handler may turn the clocks off, so we may not have + * clock later in the function. */ +void dispc_irq_handler(void) +{ + int i; + u32 irqstatus; + u32 handledirqs = 0; + u32 unhandled_errors; + struct omap_dispc_isr_data *isr_data; + struct omap_dispc_isr_data registered_isr[DISPC_MAX_NR_ISRS]; + + spin_lock(&dispc.irq_lock); + + irqstatus = dispc_read_reg(DISPC_IRQSTATUS); + +#ifdef DEBUG + if (dss_debug) + print_irq_status(irqstatus); +#endif + /* Ack the interrupt. Do it here before clocks are possibly turned + * off */ + dispc_write_reg(DISPC_IRQSTATUS, irqstatus); + + /* make a copy and unlock, so that isrs can unregister + * themselves */ + memcpy(registered_isr, dispc.registered_isr, + sizeof(registered_isr)); + + spin_unlock(&dispc.irq_lock); + + for (i = 0; i < DISPC_MAX_NR_ISRS; i++) { + isr_data = ®istered_isr[i]; + + if (!isr_data->isr) + continue; + + if (isr_data->mask & irqstatus) { + isr_data->isr(isr_data->arg, irqstatus); + handledirqs |= isr_data->mask; + } + } + + spin_lock(&dispc.irq_lock); + + unhandled_errors = irqstatus & ~handledirqs & dispc.irq_error_mask; + + if (unhandled_errors) { + dispc.error_irqs |= unhandled_errors; + + dispc.irq_error_mask &= ~unhandled_errors; + _omap_dispc_set_irqs(); + + schedule_work(&dispc.error_work); + } + + spin_unlock(&dispc.irq_lock); +} + +static void dispc_error_worker(struct work_struct *work) +{ + int i; + u32 errors; + unsigned long flags; + + spin_lock_irqsave(&dispc.irq_lock, flags); + errors = dispc.error_irqs; + dispc.error_irqs = 0; + spin_unlock_irqrestore(&dispc.irq_lock, flags); + + if (errors & DISPC_IRQ_GFX_FIFO_UNDERFLOW) { + DSSERR("GFX_FIFO_UNDERFLOW, disabling GFX\n"); + for (i = 0; i < omap_dss_get_num_overlays(); ++i) { + struct omap_overlay *ovl; + ovl = omap_dss_get_overlay(i); + + if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC)) + continue; + + if (ovl->id == 0) { + dispc_enable_plane(ovl->id, 0); + dispc_go(ovl->manager->id); + mdelay(50); + break; + } + } + } + + if (errors & DISPC_IRQ_VID1_FIFO_UNDERFLOW) { + DSSERR("VID1_FIFO_UNDERFLOW, disabling VID1\n"); + for (i = 0; i < omap_dss_get_num_overlays(); ++i) { + struct omap_overlay *ovl; + ovl = omap_dss_get_overlay(i); + + if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC)) + continue; + + if (ovl->id == 1) { + dispc_enable_plane(ovl->id, 0); + dispc_go(ovl->manager->id); + mdelay(50); + break; + } + } + } + + if (errors & DISPC_IRQ_VID2_FIFO_UNDERFLOW) { + DSSERR("VID2_FIFO_UNDERFLOW, disabling VID2\n"); + for (i = 0; i < omap_dss_get_num_overlays(); ++i) { + struct omap_overlay *ovl; + ovl = omap_dss_get_overlay(i); + + if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC)) + continue; + + if (ovl->id == 2) { + dispc_enable_plane(ovl->id, 0); + dispc_go(ovl->manager->id); + mdelay(50); + break; + } + } + } + + if (errors & DISPC_IRQ_SYNC_LOST) { + struct omap_overlay_manager *manager = NULL; + bool enable = false; + + DSSERR("SYNC_LOST, disabling LCD\n"); + + for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) { + struct omap_overlay_manager *mgr; + mgr = omap_dss_get_overlay_manager(i); + + if (mgr->id == OMAP_DSS_CHANNEL_LCD) { + manager = mgr; + enable = mgr->device->state == + OMAP_DSS_DISPLAY_ACTIVE; + mgr->device->disable(mgr->device); + break; + } + } + + if (manager) { + for (i = 0; i < omap_dss_get_num_overlays(); ++i) { + struct omap_overlay *ovl; + ovl = omap_dss_get_overlay(i); + + if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC)) + continue; + + if (ovl->id != 0 && ovl->manager == manager) + dispc_enable_plane(ovl->id, 0); + } + + dispc_go(manager->id); + mdelay(50); + if (enable) + manager->device->enable(manager->device); + } + } + + if (errors & DISPC_IRQ_SYNC_LOST_DIGIT) { + struct omap_overlay_manager *manager = NULL; + bool enable = false; + + DSSERR("SYNC_LOST_DIGIT, disabling TV\n"); + + for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) { + struct omap_overlay_manager *mgr; + mgr = omap_dss_get_overlay_manager(i); + + if (mgr->id == OMAP_DSS_CHANNEL_DIGIT) { + manager = mgr; + enable = mgr->device->state == + OMAP_DSS_DISPLAY_ACTIVE; + mgr->device->disable(mgr->device); + break; + } + } + + if (manager) { + for (i = 0; i < omap_dss_get_num_overlays(); ++i) { + struct omap_overlay *ovl; + ovl = omap_dss_get_overlay(i); + + if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC)) + continue; + + if (ovl->id != 0 && ovl->manager == manager) + dispc_enable_plane(ovl->id, 0); + } + + dispc_go(manager->id); + mdelay(50); + if (enable) + manager->device->enable(manager->device); + } + } + + if (errors & DISPC_IRQ_OCP_ERR) { + DSSERR("OCP_ERR\n"); + for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) { + struct omap_overlay_manager *mgr; + mgr = omap_dss_get_overlay_manager(i); + + if (mgr->caps & OMAP_DSS_OVL_CAP_DISPC) + mgr->device->disable(mgr->device); + } + } + + spin_lock_irqsave(&dispc.irq_lock, flags); + dispc.irq_error_mask |= errors; + _omap_dispc_set_irqs(); + spin_unlock_irqrestore(&dispc.irq_lock, flags); +} + +int omap_dispc_wait_for_irq_timeout(u32 irqmask, unsigned long timeout) +{ + void dispc_irq_wait_handler(void *data, u32 mask) + { + complete((struct completion *)data); + } + + int r; + DECLARE_COMPLETION_ONSTACK(completion); + + r = omap_dispc_register_isr(dispc_irq_wait_handler, &completion, + irqmask); + + if (r) + return r; + + timeout = wait_for_completion_timeout(&completion, timeout); + + omap_dispc_unregister_isr(dispc_irq_wait_handler, &completion, irqmask); + + if (timeout == 0) + return -ETIMEDOUT; + + if (timeout == -ERESTARTSYS) + return -ERESTARTSYS; + + return 0; +} + +int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask, + unsigned long timeout) +{ + void dispc_irq_wait_handler(void *data, u32 mask) + { + complete((struct completion *)data); + } + + int r; + DECLARE_COMPLETION_ONSTACK(completion); + + r = omap_dispc_register_isr(dispc_irq_wait_handler, &completion, + irqmask); + + if (r) + return r; + + timeout = wait_for_completion_interruptible_timeout(&completion, + timeout); + + omap_dispc_unregister_isr(dispc_irq_wait_handler, &completion, irqmask); + + if (timeout == 0) + return -ETIMEDOUT; + + if (timeout == -ERESTARTSYS) + return -ERESTARTSYS; + + return 0; +} + +#ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC +void dispc_fake_vsync_irq(void) +{ + u32 irqstatus = DISPC_IRQ_VSYNC; + int i; + + for (i = 0; i < DISPC_MAX_NR_ISRS; i++) { + struct omap_dispc_isr_data *isr_data; + isr_data = &dispc.registered_isr[i]; + + if (!isr_data->isr) + continue; + + if (isr_data->mask & irqstatus) + isr_data->isr(isr_data->arg, irqstatus); + } +} +#endif + +static void _omap_dispc_initialize_irq(void) +{ + unsigned long flags; + + spin_lock_irqsave(&dispc.irq_lock, flags); + + memset(dispc.registered_isr, 0, sizeof(dispc.registered_isr)); + + dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR; + + /* there's SYNC_LOST_DIGIT waiting after enabling the DSS, + * so clear it */ + dispc_write_reg(DISPC_IRQSTATUS, dispc_read_reg(DISPC_IRQSTATUS)); + + _omap_dispc_set_irqs(); + + spin_unlock_irqrestore(&dispc.irq_lock, flags); +} + +void dispc_enable_sidle(void) +{ + REG_FLD_MOD(DISPC_SYSCONFIG, 2, 4, 3); /* SIDLEMODE: smart idle */ +} + +void dispc_disable_sidle(void) +{ + REG_FLD_MOD(DISPC_SYSCONFIG, 1, 4, 3); /* SIDLEMODE: no idle */ +} + +static void _omap_dispc_initial_config(void) +{ + u32 l; + + l = dispc_read_reg(DISPC_SYSCONFIG); + l = FLD_MOD(l, 2, 13, 12); /* MIDLEMODE: smart standby */ + l = FLD_MOD(l, 2, 4, 3); /* SIDLEMODE: smart idle */ + l = FLD_MOD(l, 1, 2, 2); /* ENWAKEUP */ + l = FLD_MOD(l, 1, 0, 0); /* AUTOIDLE */ + dispc_write_reg(DISPC_SYSCONFIG, l); + + /* FUNCGATED */ + REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9); + + /* L3 firewall setting: enable access to OCM RAM */ + if (cpu_is_omap24xx()) + __raw_writel(0x402000b0, IO_ADDRESS(0x680050a0)); + + _dispc_setup_color_conv_coef(); + + dispc_set_loadmode(OMAP_DSS_LOAD_FRAME_ONLY); + + dispc_read_plane_fifo_sizes(); +} + +int dispc_init(void) +{ + u32 rev; + + spin_lock_init(&dispc.irq_lock); + + INIT_WORK(&dispc.error_work, dispc_error_worker); + + dispc.base = ioremap(DISPC_BASE, DISPC_SZ_REGS); + if (!dispc.base) { + DSSERR("can't ioremap DISPC\n"); + return -ENOMEM; + } + + if (cpu_is_omap34xx()) { + dispc.dpll4_m4_ck = clk_get(NULL, "dpll4_m4_ck"); + if (IS_ERR(dispc.dpll4_m4_ck)) { + DSSERR("Failed to get dpll4_m4_ck\n"); + return -ENODEV; + } + } + + enable_clocks(1); + + _omap_dispc_initial_config(); + + _omap_dispc_initialize_irq(); + + dispc_save_context(); + + rev = dispc_read_reg(DISPC_REVISION); + printk(KERN_INFO "OMAP DISPC rev %d.%d\n", + FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); + + enable_clocks(0); + + return 0; +} + +void dispc_exit(void) +{ + if (cpu_is_omap34xx()) + clk_put(dispc.dpll4_m4_ck); + iounmap(dispc.base); +} + +int dispc_enable_plane(enum omap_plane plane, bool enable) +{ + DSSDBG("dispc_enable_plane %d, %d\n", plane, enable); + + enable_clocks(1); + _dispc_enable_plane(plane, enable); + enable_clocks(0); + + return 0; +} + +int dispc_setup_plane(enum omap_plane plane, + u32 paddr, u16 screen_width, + u16 pos_x, u16 pos_y, + u16 width, u16 height, + u16 out_width, u16 out_height, + enum omap_color_mode color_mode, + bool ilace, + enum omap_dss_rotation_type rotation_type, + u8 rotation, bool mirror, u8 global_alpha) +{ + int r = 0; + + DSSDBG("dispc_setup_plane %d, pa %x, sw %d, %d,%d, %dx%d -> " + "%dx%d, ilace %d, cmode %x, rot %d, mir %d\n", + plane, paddr, screen_width, pos_x, pos_y, + width, height, + out_width, out_height, + ilace, color_mode, + rotation, mirror); + + enable_clocks(1); + + r = _dispc_setup_plane(plane, + paddr, screen_width, + pos_x, pos_y, + width, height, + out_width, out_height, + color_mode, ilace, + rotation_type, + rotation, mirror, + global_alpha); + + enable_clocks(0); + + return r; +} diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c new file mode 100644 index 000000000000..424bced963af --- /dev/null +++ b/drivers/video/omap2/dss/display.c @@ -0,0 +1,659 @@ +/* + * linux/drivers/video/omap2/dss/display.c + * + * Copyright (C) 2009 Nokia Corporation + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> + * + * Some code and ideas taken from drivers/video/omap/ driver + * by Imre Deak. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#define DSS_SUBSYS_NAME "DISPLAY" + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/jiffies.h> +#include <linux/list.h> +#include <linux/platform_device.h> + +#include <mach/display.h> +#include "dss.h" + +static LIST_HEAD(display_list); + +static ssize_t display_enabled_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct omap_dss_device *dssdev = to_dss_device(dev); + bool enabled = dssdev->state != OMAP_DSS_DISPLAY_DISABLED; + + return snprintf(buf, PAGE_SIZE, "%d\n", enabled); +} + +static ssize_t display_enabled_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + struct omap_dss_device *dssdev = to_dss_device(dev); + bool enabled, r; + + enabled = simple_strtoul(buf, NULL, 10); + + if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) { + if (enabled) { + r = dssdev->enable(dssdev); + if (r) + return r; + } else { + dssdev->disable(dssdev); + } + } + + return size; +} + +static ssize_t display_upd_mode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct omap_dss_device *dssdev = to_dss_device(dev); + enum omap_dss_update_mode mode = OMAP_DSS_UPDATE_AUTO; + if (dssdev->get_update_mode) + mode = dssdev->get_update_mode(dssdev); + return snprintf(buf, PAGE_SIZE, "%d\n", mode); +} + +static ssize_t display_upd_mode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + struct omap_dss_device *dssdev = to_dss_device(dev); + int val, r; + enum omap_dss_update_mode mode; + + val = simple_strtoul(buf, NULL, 10); + + switch (val) { + case OMAP_DSS_UPDATE_DISABLED: + case OMAP_DSS_UPDATE_AUTO: + case OMAP_DSS_UPDATE_MANUAL: + mode = (enum omap_dss_update_mode)val; + break; + default: + return -EINVAL; + } + + r = dssdev->set_update_mode(dssdev, mode); + if (r) + return r; + + return size; +} + +static ssize_t display_tear_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct omap_dss_device *dssdev = to_dss_device(dev); + return snprintf(buf, PAGE_SIZE, "%d\n", + dssdev->get_te ? dssdev->get_te(dssdev) : 0); +} + +static ssize_t display_tear_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct omap_dss_device *dssdev = to_dss_device(dev); + unsigned long te; + int r; + + if (!dssdev->enable_te || !dssdev->get_te) + return -ENOENT; + + te = simple_strtoul(buf, NULL, 0); + + r = dssdev->enable_te(dssdev, te); + if (r) + return r; + + return size; +} + +static ssize_t display_timings_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct omap_dss_device *dssdev = to_dss_device(dev); + struct omap_video_timings t; + + if (!dssdev->get_timings) + return -ENOENT; + + dssdev->get_timings(dssdev, &t); + + return snprintf(buf, PAGE_SIZE, "%u,%u/%u/%u/%u,%u/%u/%u/%u\n", + t.pixel_clock, + t.x_res, t.hfp, t.hbp, t.hsw, + t.y_res, t.vfp, t.vbp, t.vsw); +} + +static ssize_t display_timings_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct omap_dss_device *dssdev = to_dss_device(dev); + struct omap_video_timings t; + int r, found; + + if (!dssdev->set_timings || !dssdev->check_timings) + return -ENOENT; + + found = 0; +#ifdef CONFIG_OMAP2_DSS_VENC + if (strncmp("pal", buf, 3) == 0) { + t = omap_dss_pal_timings; + found = 1; + } else if (strncmp("ntsc", buf, 4) == 0) { + t = omap_dss_ntsc_timings; + found = 1; + } +#endif + if (!found && sscanf(buf, "%u,%hu/%hu/%hu/%hu,%hu/%hu/%hu/%hu", + &t.pixel_clock, + &t.x_res, &t.hfp, &t.hbp, &t.hsw, + &t.y_res, &t.vfp, &t.vbp, &t.vsw) != 9) + return -EINVAL; + + r = dssdev->check_timings(dssdev, &t); + if (r) + return r; + + dssdev->set_timings(dssdev, &t); + + return size; +} + +static ssize_t display_rotate_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct omap_dss_device *dssdev = to_dss_device(dev); + int rotate; + if (!dssdev->get_rotate) + return -ENOENT; + rotate = dssdev->get_rotate(dssdev); + return snprintf(buf, PAGE_SIZE, "%u\n", rotate); +} + +static ssize_t display_rotate_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct omap_dss_device *dssdev = to_dss_device(dev); + unsigned long rot; + int r; + + if (!dssdev->set_rotate || !dssdev->get_rotate) + return -ENOENT; + + rot = simple_strtoul(buf, NULL, 0); + + r = dssdev->set_rotate(dssdev, rot); + if (r) + return r; + + return size; +} + +static ssize_t display_mirror_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct omap_dss_device *dssdev = to_dss_device(dev); + int mirror; + if (!dssdev->get_mirror) + return -ENOENT; + mirror = dssdev->get_mirror(dssdev); + return snprintf(buf, PAGE_SIZE, "%u\n", mirror); +} + +static ssize_t display_mirror_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct omap_dss_device *dssdev = to_dss_device(dev); + unsigned long mirror; + int r; + + if (!dssdev->set_mirror || !dssdev->get_mirror) + return -ENOENT; + + mirror = simple_strtoul(buf, NULL, 0); + + r = dssdev->set_mirror(dssdev, mirror); + if (r) + return r; + + return size; +} + +static ssize_t display_wss_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct omap_dss_device *dssdev = to_dss_device(dev); + unsigned int wss; + + if (!dssdev->get_wss) + return -ENOENT; + + wss = dssdev->get_wss(dssdev); + + return snprintf(buf, PAGE_SIZE, "0x%05x\n", wss); +} + +static ssize_t display_wss_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct omap_dss_device *dssdev = to_dss_device(dev); + unsigned long wss; + int r; + + if (!dssdev->get_wss || !dssdev->set_wss) + return -ENOENT; + + if (strict_strtoul(buf, 0, &wss)) + return -EINVAL; + + if (wss > 0xfffff) + return -EINVAL; + + r = dssdev->set_wss(dssdev, wss); + if (r) + return r; + + return size; +} + +static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR, + display_enabled_show, display_enabled_store); +static DEVICE_ATTR(update_mode, S_IRUGO|S_IWUSR, + display_upd_mode_show, display_upd_mode_store); +static DEVICE_ATTR(tear_elim, S_IRUGO|S_IWUSR, + display_tear_show, display_tear_store); +static DEVICE_ATTR(timings, S_IRUGO|S_IWUSR, + display_timings_show, display_timings_store); +static DEVICE_ATTR(rotate, S_IRUGO|S_IWUSR, + display_rotate_show, display_rotate_store); +static DEVICE_ATTR(mirror, S_IRUGO|S_IWUSR, + display_mirror_show, display_mirror_store); +static DEVICE_ATTR(wss, S_IRUGO|S_IWUSR, + display_wss_show, display_wss_store); + +static struct device_attribute *display_sysfs_attrs[] = { + &dev_attr_enabled, + &dev_attr_update_mode, + &dev_attr_tear_elim, + &dev_attr_timings, + &dev_attr_rotate, + &dev_attr_mirror, + &dev_attr_wss, + NULL +}; + +static void default_get_resolution(struct omap_dss_device *dssdev, + u16 *xres, u16 *yres) +{ + *xres = dssdev->panel.timings.x_res; + *yres = dssdev->panel.timings.y_res; +} + +void default_get_overlay_fifo_thresholds(enum omap_plane plane, + u32 fifo_size, enum omap_burst_size *burst_size, + u32 *fifo_low, u32 *fifo_high) +{ + unsigned low, high, size; + unsigned burst_size_bytes; + + *burst_size = OMAP_DSS_BURST_16x32; + burst_size_bytes = 16 * 32 / 8; + + *fifo_high = fifo_size - 1; + *fifo_low = fifo_size - burst_size_bytes; +} + +static int default_wait_vsync(struct omap_dss_device *dssdev) +{ + unsigned long timeout = msecs_to_jiffies(500); + u32 irq; + + if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) + irq = DISPC_IRQ_EVSYNC_ODD; + else + irq = DISPC_IRQ_VSYNC; + + return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout); +} + +static int default_get_recommended_bpp(struct omap_dss_device *dssdev) +{ + if (dssdev->panel.recommended_bpp) + return dssdev->panel.recommended_bpp; + + switch (dssdev->type) { + case OMAP_DISPLAY_TYPE_DPI: + if (dssdev->phy.dpi.data_lines == 24) + return 24; + else + return 16; + + case OMAP_DISPLAY_TYPE_DBI: + case OMAP_DISPLAY_TYPE_DSI: + if (dssdev->ctrl.pixel_size == 24) + return 24; + else + return 16; + case OMAP_DISPLAY_TYPE_VENC: + case OMAP_DISPLAY_TYPE_SDI: + return 24; + return 24; + default: + BUG(); + } +} + +/* Checks if replication logic should be used. Only use for active matrix, + * when overlay is in RGB12U or RGB16 mode, and LCD interface is + * 18bpp or 24bpp */ +bool dss_use_replication(struct omap_dss_device *dssdev, + enum omap_color_mode mode) +{ + int bpp; + + if (mode != OMAP_DSS_COLOR_RGB12U && mode != OMAP_DSS_COLOR_RGB16) + return false; + + if (dssdev->type == OMAP_DISPLAY_TYPE_DPI && + (dssdev->panel.config & OMAP_DSS_LCD_TFT) == 0) + return false; + + switch (dssdev->type) { + case OMAP_DISPLAY_TYPE_DPI: + bpp = dssdev->phy.dpi.data_lines; + break; + case OMAP_DISPLAY_TYPE_VENC: + case OMAP_DISPLAY_TYPE_SDI: + bpp = 24; + break; + case OMAP_DISPLAY_TYPE_DBI: + case OMAP_DISPLAY_TYPE_DSI: + bpp = dssdev->ctrl.pixel_size; + break; + default: + BUG(); + } + + return bpp > 16; +} + +void dss_init_device(struct platform_device *pdev, + struct omap_dss_device *dssdev) +{ + struct device_attribute *attr; + int i; + int r; + + switch (dssdev->type) { + case OMAP_DISPLAY_TYPE_DPI: +#ifdef CONFIG_OMAP2_DSS_RFBI + case OMAP_DISPLAY_TYPE_DBI: +#endif +#ifdef CONFIG_OMAP2_DSS_SDI + case OMAP_DISPLAY_TYPE_SDI: +#endif +#ifdef CONFIG_OMAP2_DSS_DSI + case OMAP_DISPLAY_TYPE_DSI: +#endif +#ifdef CONFIG_OMAP2_DSS_VENC + case OMAP_DISPLAY_TYPE_VENC: +#endif + break; + default: + DSSERR("Support for display '%s' not compiled in.\n", + dssdev->name); + return; + } + + dssdev->get_resolution = default_get_resolution; + dssdev->get_recommended_bpp = default_get_recommended_bpp; + dssdev->wait_vsync = default_wait_vsync; + + switch (dssdev->type) { + case OMAP_DISPLAY_TYPE_DPI: + r = dpi_init_display(dssdev); + break; +#ifdef CONFIG_OMAP2_DSS_RFBI + case OMAP_DISPLAY_TYPE_DBI: + r = rfbi_init_display(dssdev); + break; +#endif +#ifdef CONFIG_OMAP2_DSS_VENC + case OMAP_DISPLAY_TYPE_VENC: + r = venc_init_display(dssdev); + break; +#endif +#ifdef CONFIG_OMAP2_DSS_SDI + case OMAP_DISPLAY_TYPE_SDI: + r = sdi_init_display(dssdev); + break; +#endif +#ifdef CONFIG_OMAP2_DSS_DSI + case OMAP_DISPLAY_TYPE_DSI: + r = dsi_init_display(dssdev); + break; +#endif + default: + BUG(); + } + + if (r) { + DSSERR("failed to init display %s\n", dssdev->name); + return; + } + + /* create device sysfs files */ + i = 0; + while ((attr = display_sysfs_attrs[i++]) != NULL) { + r = device_create_file(&dssdev->dev, attr); + if (r) + DSSERR("failed to create sysfs file\n"); + } + + /* create display? sysfs links */ + r = sysfs_create_link(&pdev->dev.kobj, &dssdev->dev.kobj, + dev_name(&dssdev->dev)); + if (r) + DSSERR("failed to create sysfs display link\n"); +} + +void dss_uninit_device(struct platform_device *pdev, + struct omap_dss_device *dssdev) +{ + struct device_attribute *attr; + int i = 0; + + sysfs_remove_link(&pdev->dev.kobj, dev_name(&dssdev->dev)); + + while ((attr = display_sysfs_attrs[i++]) != NULL) + device_remove_file(&dssdev->dev, attr); + + if (dssdev->manager) + dssdev->manager->unset_device(dssdev->manager); +} + +static int dss_suspend_device(struct device *dev, void *data) +{ + int r; + struct omap_dss_device *dssdev = to_dss_device(dev); + + if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) { + dssdev->activate_after_resume = false; + return 0; + } + + if (!dssdev->suspend) { + DSSERR("display '%s' doesn't implement suspend\n", + dssdev->name); + return -ENOSYS; + } + + r = dssdev->suspend(dssdev); + if (r) + return r; + + dssdev->activate_after_resume = true; + + return 0; +} + +int dss_suspend_all_devices(void) +{ + int r; + struct bus_type *bus = dss_get_bus(); + + r = bus_for_each_dev(bus, NULL, NULL, dss_suspend_device); + if (r) { + /* resume all displays that were suspended */ + dss_resume_all_devices(); + return r; + } + + return 0; +} + +static int dss_resume_device(struct device *dev, void *data) +{ + int r; + struct omap_dss_device *dssdev = to_dss_device(dev); + + if (dssdev->activate_after_resume && dssdev->resume) { + r = dssdev->resume(dssdev); + if (r) + return r; + } + + dssdev->activate_after_resume = false; + + return 0; +} + +int dss_resume_all_devices(void) +{ + struct bus_type *bus = dss_get_bus(); + + return bus_for_each_dev(bus, NULL, NULL, dss_resume_device); +} + + +void omap_dss_get_device(struct omap_dss_device *dssdev) +{ + get_device(&dssdev->dev); +} +EXPORT_SYMBOL(omap_dss_get_device); + +void omap_dss_put_device(struct omap_dss_device *dssdev) +{ + put_device(&dssdev->dev); +} +EXPORT_SYMBOL(omap_dss_put_device); + +/* ref count of the found device is incremented. ref count + * of from-device is decremented. */ +struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from) +{ + struct device *dev; + struct device *dev_start = NULL; + struct omap_dss_device *dssdev = NULL; + + int match(struct device *dev, void *data) + { + /* skip panels connected to controllers */ + if (to_dss_device(dev)->panel.ctrl) + return 0; + + return 1; + } + + if (from) + dev_start = &from->dev; + dev = bus_find_device(dss_get_bus(), dev_start, NULL, match); + if (dev) + dssdev = to_dss_device(dev); + if (from) + put_device(&from->dev); + + return dssdev; +} +EXPORT_SYMBOL(omap_dss_get_next_device); + +struct omap_dss_device *omap_dss_find_device(void *data, + int (*match)(struct omap_dss_device *dssdev, void *data)) +{ + struct omap_dss_device *dssdev = NULL; + + while ((dssdev = omap_dss_get_next_device(dssdev)) != NULL) { + if (match(dssdev, data)) + return dssdev; + } + + return NULL; +} +EXPORT_SYMBOL(omap_dss_find_device); + +int omap_dss_start_device(struct omap_dss_device *dssdev) +{ + int r; + + if (!dssdev->driver) { + DSSDBG("no driver\n"); + r = -ENODEV; + goto err0; + } + + if (dssdev->ctrl.panel && !dssdev->ctrl.panel->driver) { + DSSDBG("no panel driver\n"); + r = -ENODEV; + goto err0; + } + + if (!try_module_get(dssdev->dev.driver->owner)) { + r = -ENODEV; + goto err0; + } + + if (dssdev->ctrl.panel) { + if (!try_module_get(dssdev->ctrl.panel->dev.driver->owner)) { + r = -ENODEV; + goto err1; + } + } + + return 0; +err1: + module_put(dssdev->dev.driver->owner); +err0: + return r; +} +EXPORT_SYMBOL(omap_dss_start_device); + +void omap_dss_stop_device(struct omap_dss_device *dssdev) +{ + if (dssdev->ctrl.panel) + module_put(dssdev->ctrl.panel->dev.driver->owner); + + module_put(dssdev->dev.driver->owner); +} +EXPORT_SYMBOL(omap_dss_stop_device); + diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c new file mode 100644 index 000000000000..27933db56497 --- /dev/null +++ b/drivers/video/omap2/dss/dpi.c @@ -0,0 +1,394 @@ +/* + * linux/drivers/video/omap2/dss/dpi.c + * + * Copyright (C) 2009 Nokia Corporation + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> + * + * Some code and ideas taken from drivers/video/omap/ driver + * by Imre Deak. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#define DSS_SUBSYS_NAME "DPI" + +#include <linux/kernel.h> +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/errno.h> + +#include <mach/board.h> +#include <mach/display.h> +#include <mach/cpu.h> + +#include "dss.h" + +static struct { + int update_enabled; +} dpi; + +#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL +static int dpi_set_dsi_clk(bool is_tft, unsigned long pck_req, + unsigned long *fck, int *lck_div, int *pck_div) +{ + struct dsi_clock_info cinfo; + int r; + + r = dsi_pll_calc_pck(is_tft, pck_req, &cinfo); + if (r) + return r; + + r = dsi_pll_program(&cinfo); + if (r) + return r; + + dss_select_clk_source(0, 1); + + dispc_set_lcd_divisor(cinfo.lck_div, cinfo.pck_div); + + *fck = cinfo.dsi1_pll_fclk; + *lck_div = cinfo.lck_div; + *pck_div = cinfo.pck_div; + + return 0; +} +#else +static int dpi_set_dispc_clk(bool is_tft, unsigned long pck_req, + unsigned long *fck, int *lck_div, int *pck_div) +{ + struct dispc_clock_info cinfo; + int r = 0; + + return 0; + r = dispc_calc_clock_div(is_tft, pck_req, &cinfo); + if (r) + return r; + + r = dispc_set_clock_div(&cinfo); + if (r) + return r; + + *fck = cinfo.fck; + *lck_div = cinfo.lck_div; + *pck_div = cinfo.pck_div; + + return 0; +} +#endif + +static int dpi_set_mode(struct omap_dss_device *dssdev) +{ + struct omap_video_timings *t = &dssdev->panel.timings; + int lck_div, pck_div; + unsigned long fck; + unsigned long pck; + bool is_tft; + int r = 0; + + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + + dispc_set_pol_freq(dssdev->panel.config, dssdev->panel.acbi, + dssdev->panel.acb); + + is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0; + +#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL + r = dpi_set_dsi_clk(is_tft, t->pixel_clock * 1000, + &fck, &lck_div, &pck_div); +#else + r = dpi_set_dispc_clk(is_tft, t->pixel_clock * 1000, + &fck, &lck_div, &pck_div); +#endif + if (r) + goto err0; + +#ifndef CONFIG_ARCH_OMAP4 + pck = fck / lck_div / pck_div / 1000; +#else + pck = 0; +#endif + + if (pck != t->pixel_clock) { + DSSWARN("Could not find exact pixel clock. " + "Requested %d kHz, got %lu kHz\n", + t->pixel_clock, pck); + + t->pixel_clock = pck; + } + + dispc_set_lcd_timings(t); + +err0: + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + return r; +} + +static int dpi_basic_init(struct omap_dss_device *dssdev) +{ + bool is_tft; + + is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0; + + dispc_set_parallel_interface_mode(OMAP_DSS_PARALLELMODE_BYPASS); + + dispc_set_lcd_display_type(is_tft ? OMAP_DSS_LCD_DISPLAY_TFT : + OMAP_DSS_LCD_DISPLAY_STN); + dispc_set_tft_data_lines(dssdev->phy.dpi.data_lines); + + return 0; +} + +static int dpi_display_enable(struct omap_dss_device *dssdev) +{ + int r; + + r = omap_dss_start_device(dssdev); + if (r) { + DSSERR("failed to start device\n"); + goto err0; + } + + if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { + DSSERR("display already enabled\n"); + r = -EINVAL; + goto err1; + } + + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + + r = dpi_basic_init(dssdev); + if (r) + goto err2; + +#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL + dss_clk_enable(DSS_CLK_FCK2); + r = dsi_pll_init(0, 1); + if (r) + goto err3; +#endif + r = dpi_set_mode(dssdev); + if (r) + goto err4; + + mdelay(2); + + dispc_enable_lcd_out(1); + + r = dssdev->driver->enable(dssdev); + if (r) + goto err5; + + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + + return 0; + +err5: + dispc_enable_lcd_out(0); +err4: +#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL + dsi_pll_uninit(); +err3: + dss_clk_disable(DSS_CLK_FCK2); +#endif +err2: + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); +err1: + omap_dss_stop_device(dssdev); +err0: + return r; +} + +static int dpi_display_resume(struct omap_dss_device *dssdev); + +static void dpi_display_disable(struct omap_dss_device *dssdev) +{ + if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED) + return; + + if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) + dpi_display_resume(dssdev); + + dssdev->driver->disable(dssdev); + + dispc_enable_lcd_out(0); + +#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL + dss_select_clk_source(0, 0); + dsi_pll_uninit(); + dss_clk_disable(DSS_CLK_FCK2); +#endif + + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + + dssdev->state = OMAP_DSS_DISPLAY_DISABLED; + + omap_dss_stop_device(dssdev); +} + +static int dpi_display_suspend(struct omap_dss_device *dssdev) +{ + if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) + return -EINVAL; + + DSSDBG("dpi_display_suspend\n"); + + if (dssdev->driver->suspend) + dssdev->driver->suspend(dssdev); + + dispc_enable_lcd_out(0); + + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + + dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; + + return 0; +} + +static int dpi_display_resume(struct omap_dss_device *dssdev) +{ + if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) + return -EINVAL; + + DSSDBG("dpi_display_resume\n"); + + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + + dispc_enable_lcd_out(1); + + if (dssdev->driver->resume) + dssdev->driver->resume(dssdev); + + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + + return 0; +} + +static void dpi_set_timings(struct omap_dss_device *dssdev, + struct omap_video_timings *timings) +{ + DSSDBG("dpi_set_timings\n"); + dssdev->panel.timings = *timings; + if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { + dpi_set_mode(dssdev); + dispc_go(OMAP_DSS_CHANNEL_LCD); + } +} + +static int dpi_check_timings(struct omap_dss_device *dssdev, + struct omap_video_timings *timings) +{ + bool is_tft; + int r = 0; + int lck_div, pck_div; + unsigned long fck; + unsigned long pck; + + if (!dispc_lcd_timings_ok(timings)) + return -EINVAL; + + if (timings->pixel_clock == 0) + return -EINVAL; + + is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0; + +#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL + { + struct dsi_clock_info cinfo; + r = dsi_pll_calc_pck(is_tft, timings->pixel_clock * 1000, + &cinfo); + + if (r) + return r; + + fck = cinfo.dsi1_pll_fclk; + lck_div = cinfo.lck_div; + pck_div = cinfo.pck_div; + } +#else + { + struct dispc_clock_info cinfo; + r = dispc_calc_clock_div(is_tft, timings->pixel_clock * 1000, + &cinfo); + + if (r) + return r; + + fck = cinfo.fck; + lck_div = cinfo.lck_div; + pck_div = cinfo.pck_div; + } +#endif + + pck = fck / lck_div / pck_div / 1000; + + timings->pixel_clock = pck; + + return 0; +} + +static void dpi_get_timings(struct omap_dss_device *dssdev, + struct omap_video_timings *timings) +{ + *timings = dssdev->panel.timings; +} + +static int dpi_display_set_update_mode(struct omap_dss_device *dssdev, + enum omap_dss_update_mode mode) +{ + if (mode == OMAP_DSS_UPDATE_MANUAL) + return -EINVAL; + + if (mode == OMAP_DSS_UPDATE_DISABLED) { + dispc_enable_lcd_out(0); + dpi.update_enabled = 0; + } else { + dispc_enable_lcd_out(1); + dpi.update_enabled = 1; + } + + return 0; +} + +static enum omap_dss_update_mode dpi_display_get_update_mode( + struct omap_dss_device *dssdev) +{ + return dpi.update_enabled ? OMAP_DSS_UPDATE_AUTO : + OMAP_DSS_UPDATE_DISABLED; +} + +int dpi_init_display(struct omap_dss_device *dssdev) +{ + DSSDBG("init_display\n"); + + dssdev->enable = dpi_display_enable; + dssdev->disable = dpi_display_disable; + dssdev->suspend = dpi_display_suspend; + dssdev->resume = dpi_display_resume; + dssdev->set_timings = dpi_set_timings; + dssdev->check_timings = dpi_check_timings; + dssdev->get_timings = dpi_get_timings; + dssdev->set_update_mode = dpi_display_set_update_mode; + dssdev->get_update_mode = dpi_display_get_update_mode; + + return 0; +} + +int dpi_init(void) +{ + return 0; +} + +void dpi_exit(void) +{ +} + diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c new file mode 100644 index 000000000000..33110394ca2a --- /dev/null +++ b/drivers/video/omap2/dss/dsi.c @@ -0,0 +1,3468 @@ +/* + * linux/drivers/video/omap2/dss/dsi.c + * + * Copyright (C) 2009 Nokia Corporation + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.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, see <http://www.gnu.org/licenses/>. + */ + +#define DSS_SUBSYS_NAME "DSI" + +#include <linux/kernel.h> +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/interrupt.h> +#include <linux/delay.h> +#include <linux/mutex.h> +#include <linux/seq_file.h> +#include <linux/platform_device.h> +#include <linux/regulator/consumer.h> +#include <linux/kthread.h> +#include <linux/wait.h> + +#include <mach/board.h> +#include <mach/display.h> +#include <mach/clock.h> + +#include "dss.h" + +/*#define VERBOSE_IRQ*/ + +#define DSI_BASE 0x4804FC00 + +struct dsi_reg { u16 idx; }; + +#define DSI_REG(idx) ((const struct dsi_reg) { idx }) + +#define DSI_SZ_REGS SZ_1K +/* DSI Protocol Engine */ + +#define DSI_REVISION DSI_REG(0x0000) +#define DSI_SYSCONFIG DSI_REG(0x0010) +#define DSI_SYSSTATUS DSI_REG(0x0014) +#define DSI_IRQSTATUS DSI_REG(0x0018) +#define DSI_IRQENABLE DSI_REG(0x001C) +#define DSI_CTRL DSI_REG(0x0040) +#define DSI_COMPLEXIO_CFG1 DSI_REG(0x0048) +#define DSI_COMPLEXIO_IRQ_STATUS DSI_REG(0x004C) +#define DSI_COMPLEXIO_IRQ_ENABLE DSI_REG(0x0050) +#define DSI_CLK_CTRL DSI_REG(0x0054) +#define DSI_TIMING1 DSI_REG(0x0058) +#define DSI_TIMING2 DSI_REG(0x005C) +#define DSI_VM_TIMING1 DSI_REG(0x0060) +#define DSI_VM_TIMING2 DSI_REG(0x0064) +#define DSI_VM_TIMING3 DSI_REG(0x0068) +#define DSI_CLK_TIMING DSI_REG(0x006C) +#define DSI_TX_FIFO_VC_SIZE DSI_REG(0x0070) +#define DSI_RX_FIFO_VC_SIZE DSI_REG(0x0074) +#define DSI_COMPLEXIO_CFG2 DSI_REG(0x0078) +#define DSI_RX_FIFO_VC_FULLNESS DSI_REG(0x007C) +#define DSI_VM_TIMING4 DSI_REG(0x0080) +#define DSI_TX_FIFO_VC_EMPTINESS DSI_REG(0x0084) +#define DSI_VM_TIMING5 DSI_REG(0x0088) +#define DSI_VM_TIMING6 DSI_REG(0x008C) +#define DSI_VM_TIMING7 DSI_REG(0x0090) +#define DSI_STOPCLK_TIMING DSI_REG(0x0094) +#define DSI_VC_CTRL(n) DSI_REG(0x0100 + (n * 0x20)) +#define DSI_VC_TE(n) DSI_REG(0x0104 + (n * 0x20)) +#define DSI_VC_LONG_PACKET_HEADER(n) DSI_REG(0x0108 + (n * 0x20)) +#define DSI_VC_LONG_PACKET_PAYLOAD(n) DSI_REG(0x010C + (n * 0x20)) +#define DSI_VC_SHORT_PACKET_HEADER(n) DSI_REG(0x0110 + (n * 0x20)) +#define DSI_VC_IRQSTATUS(n) DSI_REG(0x0118 + (n * 0x20)) +#define DSI_VC_IRQENABLE(n) DSI_REG(0x011C + (n * 0x20)) + +/* DSIPHY_SCP */ + +#define DSI_DSIPHY_CFG0 DSI_REG(0x200 + 0x0000) +#define DSI_DSIPHY_CFG1 DSI_REG(0x200 + 0x0004) +#define DSI_DSIPHY_CFG2 DSI_REG(0x200 + 0x0008) +#define DSI_DSIPHY_CFG5 DSI_REG(0x200 + 0x0014) + +/* DSI_PLL_CTRL_SCP */ + +#define DSI_PLL_CONTROL DSI_REG(0x300 + 0x0000) +#define DSI_PLL_STATUS DSI_REG(0x300 + 0x0004) +#define DSI_PLL_GO DSI_REG(0x300 + 0x0008) +#define DSI_PLL_CONFIGURATION1 DSI_REG(0x300 + 0x000C) +#define DSI_PLL_CONFIGURATION2 DSI_REG(0x300 + 0x0010) + +#define REG_GET(idx, start, end) \ + FLD_GET(dsi_read_reg(idx), start, end) + +#define REG_FLD_MOD(idx, val, start, end) \ + dsi_write_reg(idx, FLD_MOD(dsi_read_reg(idx), val, start, end)) + +/* Global interrupts */ +#define DSI_IRQ_VC0 (1 << 0) +#define DSI_IRQ_VC1 (1 << 1) +#define DSI_IRQ_VC2 (1 << 2) +#define DSI_IRQ_VC3 (1 << 3) +#define DSI_IRQ_WAKEUP (1 << 4) +#define DSI_IRQ_RESYNC (1 << 5) +#define DSI_IRQ_PLL_LOCK (1 << 7) +#define DSI_IRQ_PLL_UNLOCK (1 << 8) +#define DSI_IRQ_PLL_RECALL (1 << 9) +#define DSI_IRQ_COMPLEXIO_ERR (1 << 10) +#define DSI_IRQ_HS_TX_TIMEOUT (1 << 14) +#define DSI_IRQ_LP_RX_TIMEOUT (1 << 15) +#define DSI_IRQ_TE_TRIGGER (1 << 16) +#define DSI_IRQ_ACK_TRIGGER (1 << 17) +#define DSI_IRQ_SYNC_LOST (1 << 18) +#define DSI_IRQ_LDO_POWER_GOOD (1 << 19) +#define DSI_IRQ_TA_TIMEOUT (1 << 20) +#define DSI_IRQ_ERROR_MASK \ + (DSI_IRQ_HS_TX_TIMEOUT | DSI_IRQ_LP_RX_TIMEOUT | DSI_IRQ_SYNC_LOST | \ + DSI_IRQ_TA_TIMEOUT) +#define DSI_IRQ_CHANNEL_MASK 0xf + +/* Virtual channel interrupts */ +#define DSI_VC_IRQ_CS (1 << 0) +#define DSI_VC_IRQ_ECC_CORR (1 << 1) +#define DSI_VC_IRQ_PACKET_SENT (1 << 2) +#define DSI_VC_IRQ_FIFO_TX_OVF (1 << 3) +#define DSI_VC_IRQ_FIFO_RX_OVF (1 << 4) +#define DSI_VC_IRQ_BTA (1 << 5) +#define DSI_VC_IRQ_ECC_NO_CORR (1 << 6) +#define DSI_VC_IRQ_FIFO_TX_UDF (1 << 7) +#define DSI_VC_IRQ_PP_BUSY_CHANGE (1 << 8) +#define DSI_VC_IRQ_ERROR_MASK \ + (DSI_VC_IRQ_CS | DSI_VC_IRQ_ECC_CORR | DSI_VC_IRQ_FIFO_TX_OVF | \ + DSI_VC_IRQ_FIFO_RX_OVF | DSI_VC_IRQ_ECC_NO_CORR | \ + DSI_VC_IRQ_FIFO_TX_UDF) + +/* ComplexIO interrupts */ +#define DSI_CIO_IRQ_ERRSYNCESC1 (1 << 0) +#define DSI_CIO_IRQ_ERRSYNCESC2 (1 << 1) +#define DSI_CIO_IRQ_ERRSYNCESC3 (1 << 2) +#define DSI_CIO_IRQ_ERRESC1 (1 << 5) +#define DSI_CIO_IRQ_ERRESC2 (1 << 6) +#define DSI_CIO_IRQ_ERRESC3 (1 << 7) +#define DSI_CIO_IRQ_ERRCONTROL1 (1 << 10) +#define DSI_CIO_IRQ_ERRCONTROL2 (1 << 11) +#define DSI_CIO_IRQ_ERRCONTROL3 (1 << 12) +#define DSI_CIO_IRQ_STATEULPS1 (1 << 15) +#define DSI_CIO_IRQ_STATEULPS2 (1 << 16) +#define DSI_CIO_IRQ_STATEULPS3 (1 << 17) +#define DSI_CIO_IRQ_ERRCONTENTIONLP0_1 (1 << 20) +#define DSI_CIO_IRQ_ERRCONTENTIONLP1_1 (1 << 21) +#define DSI_CIO_IRQ_ERRCONTENTIONLP0_2 (1 << 22) +#define DSI_CIO_IRQ_ERRCONTENTIONLP1_2 (1 << 23) +#define DSI_CIO_IRQ_ERRCONTENTIONLP0_3 (1 << 24) +#define DSI_CIO_IRQ_ERRCONTENTIONLP1_3 (1 << 25) +#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL0 (1 << 30) +#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL1 (1 << 31) + +#define DSI_DT_DCS_SHORT_WRITE_0 0x05 +#define DSI_DT_DCS_SHORT_WRITE_1 0x15 +#define DSI_DT_DCS_READ 0x06 +#define DSI_DT_SET_MAX_RET_PKG_SIZE 0x37 +#define DSI_DT_NULL_PACKET 0x09 +#define DSI_DT_DCS_LONG_WRITE 0x39 + +#define DSI_DT_RX_ACK_WITH_ERR 0x02 +#define DSI_DT_RX_DCS_LONG_READ 0x1c +#define DSI_DT_RX_SHORT_READ_1 0x21 +#define DSI_DT_RX_SHORT_READ_2 0x22 + +#define FINT_MAX 2100000 +#define FINT_MIN 750000 +#define REGN_MAX (1 << 7) +#define REGM_MAX ((1 << 11) - 1) +#define REGM3_MAX (1 << 4) +#define REGM4_MAX (1 << 4) + +enum fifo_size { + DSI_FIFO_SIZE_0 = 0, + DSI_FIFO_SIZE_32 = 1, + DSI_FIFO_SIZE_64 = 2, + DSI_FIFO_SIZE_96 = 3, + DSI_FIFO_SIZE_128 = 4, +}; + +struct dsi_update_region { + bool dirty; + u16 x, y, w, h; + struct omap_dss_device *device; +}; + +static struct +{ + void __iomem *base; + + unsigned long dsi1_pll_fclk; /* Hz */ + unsigned long dsi2_pll_fclk; /* Hz */ + unsigned long dsiphy; /* Hz */ + unsigned long ddr_clk; /* Hz */ + + struct regulator *vdds_dsi_reg; + + struct { + struct omap_dss_device *dssdev; + enum fifo_size fifo_size; + int dest_per; /* destination peripheral 0-3 */ + } vc[4]; + + struct mutex lock; + struct mutex bus_lock; + + unsigned pll_locked; + + struct completion bta_completion; + + struct task_struct *thread; + wait_queue_head_t waitqueue; + + spinlock_t update_lock; + bool framedone_received; + struct dsi_update_region update_region; + struct dsi_update_region active_update_region; + struct completion update_completion; + + enum omap_dss_update_mode user_update_mode; + enum omap_dss_update_mode update_mode; + bool te_enabled; + bool use_ext_te; + + unsigned long cache_req_pck; + unsigned long cache_clk_freq; + struct dsi_clock_info cache_cinfo; + + u32 errors; + spinlock_t errors_lock; +#ifdef DEBUG + ktime_t perf_setup_time; + ktime_t perf_start_time; + ktime_t perf_start_time_auto; + int perf_measure_frames; +#endif + int debug_read; + int debug_write; +} dsi; + +#ifdef DEBUG +static unsigned int dsi_perf; +module_param_named(dsi_perf, dsi_perf, bool, 0644); +#endif + +static inline void dsi_write_reg(const struct dsi_reg idx, u32 val) +{ + __raw_writel(val, dsi.base + idx.idx); +} + +static inline u32 dsi_read_reg(const struct dsi_reg idx) +{ + return __raw_readl(dsi.base + idx.idx); +} + + +void dsi_save_context(void) +{ +} + +void dsi_restore_context(void) +{ +} + +void dsi_bus_lock(void) +{ + mutex_lock(&dsi.bus_lock); +} +EXPORT_SYMBOL(dsi_bus_lock); + +void dsi_bus_unlock(void) +{ + mutex_unlock(&dsi.bus_lock); +} +EXPORT_SYMBOL(dsi_bus_unlock); + +static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum, + int value) +{ + int t = 100000; + + while (REG_GET(idx, bitnum, bitnum) != value) { + if (--t == 0) + return !value; + } + + return value; +} + +#ifdef DEBUG +static void dsi_perf_mark_setup(void) +{ + dsi.perf_setup_time = ktime_get(); +} + +static void dsi_perf_mark_start(void) +{ + dsi.perf_start_time = ktime_get(); +} + +static void dsi_perf_mark_start_auto(void) +{ + dsi.perf_measure_frames = 0; + dsi.perf_start_time_auto = ktime_get(); +} + +static void dsi_perf_show(const char *name) +{ + ktime_t t, setup_time, trans_time; + u32 total_bytes; + u32 setup_us, trans_us, total_us; + + if (!dsi_perf) + return; + + if (dsi.update_mode == OMAP_DSS_UPDATE_DISABLED) + return; + + t = ktime_get(); + + setup_time = ktime_sub(dsi.perf_start_time, dsi.perf_setup_time); + setup_us = (u32)ktime_to_us(setup_time); + if (setup_us == 0) + setup_us = 1; + + trans_time = ktime_sub(t, dsi.perf_start_time); + trans_us = (u32)ktime_to_us(trans_time); + if (trans_us == 0) + trans_us = 1; + + total_us = setup_us + trans_us; + + total_bytes = dsi.active_update_region.w * + dsi.active_update_region.h * + dsi.active_update_region.device->ctrl.pixel_size / 8; + + if (dsi.update_mode == OMAP_DSS_UPDATE_AUTO) { + static u32 s_total_trans_us, s_total_setup_us; + static u32 s_min_trans_us = 0xffffffff, s_min_setup_us; + static u32 s_max_trans_us, s_max_setup_us; + const int numframes = 100; + ktime_t total_time_auto; + u32 total_time_auto_us; + + dsi.perf_measure_frames++; + + if (setup_us < s_min_setup_us) + s_min_setup_us = setup_us; + + if (setup_us > s_max_setup_us) + s_max_setup_us = setup_us; + + s_total_setup_us += setup_us; + + if (trans_us < s_min_trans_us) + s_min_trans_us = trans_us; + + if (trans_us > s_max_trans_us) + s_max_trans_us = trans_us; + + s_total_trans_us += trans_us; + + if (dsi.perf_measure_frames < numframes) + return; + + total_time_auto = ktime_sub(t, dsi.perf_start_time_auto); + total_time_auto_us = (u32)ktime_to_us(total_time_auto); + + printk(KERN_INFO "DSI(%s): %u fps, setup %u/%u/%u, trans " + "%u/%u/%u\n", name, + 1000 * 1000 * numframes / total_time_auto_us, + s_min_setup_us, + s_max_setup_us, + s_total_setup_us / numframes, + s_min_trans_us, + s_max_trans_us, + s_total_trans_us / numframes); + + s_total_setup_us = 0; + s_min_setup_us = 0xffffffff; + s_max_setup_us = 0; + s_total_trans_us = 0; + s_min_trans_us = 0xffffffff; + s_max_trans_us = 0; + dsi_perf_mark_start_auto(); + } else { + printk(KERN_INFO "DSI(%s): %u us + %u us = %u us (%uHz), " + "%u bytes %u kbytes/sec\n", + name, + setup_us, + trans_us, + total_us, + 1000*1000 / total_us, + total_bytes, + total_bytes * 1000 / total_us); + } +} +#else +#define dsi_perf_mark_setup() +#define dsi_perf_mark_start() +#define dsi_perf_mark_start_auto() +#define dsi_perf_show(x) +#endif + +static void print_irq_status(u32 status) +{ +#ifndef VERBOSE_IRQ + if ((status & ~DSI_IRQ_CHANNEL_MASK) == 0) + return; +#endif + printk(KERN_DEBUG "DSI IRQ: 0x%x: ", status); + +#define PIS(x) \ + if (status & DSI_IRQ_##x) \ + printk(#x " "); +#ifdef VERBOSE_IRQ + PIS(VC0); + PIS(VC1); + PIS(VC2); + PIS(VC3); +#endif + PIS(WAKEUP); + PIS(RESYNC); + PIS(PLL_LOCK); + PIS(PLL_UNLOCK); + PIS(PLL_RECALL); + PIS(COMPLEXIO_ERR); + PIS(HS_TX_TIMEOUT); + PIS(LP_RX_TIMEOUT); + PIS(TE_TRIGGER); + PIS(ACK_TRIGGER); + PIS(SYNC_LOST); + PIS(LDO_POWER_GOOD); + PIS(TA_TIMEOUT); +#undef PIS + + printk("\n"); +} + +static void print_irq_status_vc(int channel, u32 status) +{ +#ifndef VERBOSE_IRQ + if ((status & ~DSI_VC_IRQ_PACKET_SENT) == 0) + return; +#endif + printk(KERN_DEBUG "DSI VC(%d) IRQ 0x%x: ", channel, status); + +#define PIS(x) \ + if (status & DSI_VC_IRQ_##x) \ + printk(#x " "); + PIS(CS); + PIS(ECC_CORR); +#ifdef VERBOSE_IRQ + PIS(PACKET_SENT); +#endif + PIS(FIFO_TX_OVF); + PIS(FIFO_RX_OVF); + PIS(BTA); + PIS(ECC_NO_CORR); + PIS(FIFO_TX_UDF); + PIS(PP_BUSY_CHANGE); +#undef PIS + printk("\n"); +} + +static void print_irq_status_cio(u32 status) +{ + printk(KERN_DEBUG "DSI CIO IRQ 0x%x: ", status); + +#define PIS(x) \ + if (status & DSI_CIO_IRQ_##x) \ + printk(#x " "); + PIS(ERRSYNCESC1); + PIS(ERRSYNCESC2); + PIS(ERRSYNCESC3); + PIS(ERRESC1); + PIS(ERRESC2); + PIS(ERRESC3); + PIS(ERRCONTROL1); + PIS(ERRCONTROL2); + PIS(ERRCONTROL3); + PIS(STATEULPS1); + PIS(STATEULPS2); + PIS(STATEULPS3); + PIS(ERRCONTENTIONLP0_1); + PIS(ERRCONTENTIONLP1_1); + PIS(ERRCONTENTIONLP0_2); + PIS(ERRCONTENTIONLP1_2); + PIS(ERRCONTENTIONLP0_3); + PIS(ERRCONTENTIONLP1_3); + PIS(ULPSACTIVENOT_ALL0); + PIS(ULPSACTIVENOT_ALL1); +#undef PIS + + printk("\n"); +} + +static int debug_irq; + +/* called from dss */ +void dsi_irq_handler(void) +{ + u32 irqstatus, vcstatus, ciostatus; + int i; + + irqstatus = dsi_read_reg(DSI_IRQSTATUS); + + if (irqstatus & DSI_IRQ_ERROR_MASK) { + DSSERR("DSI error, irqstatus %x\n", irqstatus); + print_irq_status(irqstatus); + spin_lock(&dsi.errors_lock); + dsi.errors |= irqstatus & DSI_IRQ_ERROR_MASK; + spin_unlock(&dsi.errors_lock); + } else if (debug_irq) { + print_irq_status(irqstatus); + } + + for (i = 0; i < 4; ++i) { + if ((irqstatus & (1<<i)) == 0) + continue; + + vcstatus = dsi_read_reg(DSI_VC_IRQSTATUS(i)); + + if (vcstatus & DSI_VC_IRQ_BTA) + complete(&dsi.bta_completion); + + if (vcstatus & DSI_VC_IRQ_ERROR_MASK) { + DSSERR("DSI VC(%d) error, vc irqstatus %x\n", + i, vcstatus); + print_irq_status_vc(i, vcstatus); + } else if (debug_irq) { + print_irq_status_vc(i, vcstatus); + } + + dsi_write_reg(DSI_VC_IRQSTATUS(i), vcstatus); + } + + if (irqstatus & DSI_IRQ_COMPLEXIO_ERR) { + ciostatus = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); + + dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, ciostatus); + + DSSERR("DSI CIO error, cio irqstatus %x\n", ciostatus); + print_irq_status_cio(ciostatus); + } + + dsi_write_reg(DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK); +} + + +static void _dsi_initialize_irq(void) +{ + u32 l; + int i; + + /* disable all interrupts */ + dsi_write_reg(DSI_IRQENABLE, 0); + for (i = 0; i < 4; ++i) + dsi_write_reg(DSI_VC_IRQENABLE(i), 0); + dsi_write_reg(DSI_COMPLEXIO_IRQ_ENABLE, 0); + + /* clear interrupt status */ + l = dsi_read_reg(DSI_IRQSTATUS); + dsi_write_reg(DSI_IRQSTATUS, l & ~DSI_IRQ_CHANNEL_MASK); + + for (i = 0; i < 4; ++i) { + l = dsi_read_reg(DSI_VC_IRQSTATUS(i)); + dsi_write_reg(DSI_VC_IRQSTATUS(i), l); + } + + l = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); + dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, l); + + /* enable error irqs */ + l = DSI_IRQ_ERROR_MASK; + dsi_write_reg(DSI_IRQENABLE, l); + + l = DSI_VC_IRQ_ERROR_MASK; + for (i = 0; i < 4; ++i) + dsi_write_reg(DSI_VC_IRQENABLE(i), l); + + /* XXX zonda responds incorrectly, causing control error: + Exit from LP-ESC mode to LP11 uses wrong transition states on the + data lines LP0 and LN0. */ + dsi_write_reg(DSI_COMPLEXIO_IRQ_ENABLE, + -1 & (~DSI_CIO_IRQ_ERRCONTROL2)); +} + +static u32 dsi_get_errors(void) +{ + unsigned long flags; + u32 e; + spin_lock_irqsave(&dsi.errors_lock, flags); + e = dsi.errors; + dsi.errors = 0; + spin_unlock_irqrestore(&dsi.errors_lock, flags); + return e; +} + +static void dsi_vc_enable_bta_irq(int channel) +{ + u32 l; + + l = dsi_read_reg(DSI_VC_IRQENABLE(channel)); + l |= DSI_VC_IRQ_BTA; + dsi_write_reg(DSI_VC_IRQENABLE(channel), l); +} + +static void dsi_vc_disable_bta_irq(int channel) +{ + u32 l; + + l = dsi_read_reg(DSI_VC_IRQENABLE(channel)); + l &= ~DSI_VC_IRQ_BTA; + dsi_write_reg(DSI_VC_IRQENABLE(channel), l); +} + +/* DSI func clock. this could also be DSI2_PLL_FCLK */ +static inline void enable_clocks(bool enable) +{ + if (enable) + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + else + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); +} + +/* source clock for DSI PLL. this could also be PCLKFREE */ +static inline void dsi_enable_pll_clock(bool enable) +{ + if (enable) + dss_clk_enable(DSS_CLK_FCK2); + else + dss_clk_disable(DSS_CLK_FCK2); + + if (enable && dsi.pll_locked) { + if (wait_for_bit_change(DSI_PLL_STATUS, 1, 1) != 1) + DSSERR("cannot lock PLL when enabling clocks\n"); + } +} + +#ifdef DEBUG +static void _dsi_print_reset_status(void) +{ + u32 l; + + if (!dss_debug) + return; + + /* A dummy read using the SCP interface to any DSIPHY register is + * required after DSIPHY reset to complete the reset of the DSI complex + * I/O. */ + l = dsi_read_reg(DSI_DSIPHY_CFG5); + + printk(KERN_DEBUG "DSI resets: "); + + l = dsi_read_reg(DSI_PLL_STATUS); + printk("PLL (%d) ", FLD_GET(l, 0, 0)); + + l = dsi_read_reg(DSI_COMPLEXIO_CFG1); + printk("CIO (%d) ", FLD_GET(l, 29, 29)); + + l = dsi_read_reg(DSI_DSIPHY_CFG5); + printk("PHY (%x, %d, %d, %d)\n", + FLD_GET(l, 28, 26), + FLD_GET(l, 29, 29), + FLD_GET(l, 30, 30), + FLD_GET(l, 31, 31)); +} +#else +#define _dsi_print_reset_status() +#endif + +static inline int dsi_if_enable(bool enable) +{ + DSSDBG("dsi_if_enable(%d)\n", enable); + + enable = enable ? 1 : 0; + REG_FLD_MOD(DSI_CTRL, enable, 0, 0); /* IF_EN */ + + if (wait_for_bit_change(DSI_CTRL, 0, enable) != enable) { + DSSERR("Failed to set dsi_if_enable to %d\n", enable); + return -EIO; + } + + return 0; +} + +static unsigned long dsi_fclk_rate(void) +{ + unsigned long r; + + if (dss_get_dsi_clk_source() == 0) { + /* DSI FCLK source is DSS1_ALWON_FCK, which is dss1_fck */ + r = dss_clk_get_rate(DSS_CLK_FCK1); + } else { + /* DSI FCLK source is DSI2_PLL_FCLK */ + r = dsi.dsi2_pll_fclk; + } + + return r; +} + +static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev) +{ + unsigned n; + unsigned long dsi_fclk; + unsigned long lp_clk, lp_clk_req; + + dsi_fclk = dsi_fclk_rate(); + + lp_clk_req = dssdev->phy.dsi.lp_clk_hz; + + for (n = 1; n < (1 << 13) - 1; ++n) { + lp_clk = dsi_fclk / 2 / n; + if (lp_clk <= lp_clk_req) + break; + } + + if (n == (1 << 13) - 1) { + DSSERR("Failed to find LP_CLK_DIVISOR\n"); + return -EINVAL; + } + + DSSDBG("LP_CLK_DIV %u, LP_CLK %lu (req %lu)\n", n, lp_clk, lp_clk_req); + + REG_FLD_MOD(DSI_CLK_CTRL, n, 12, 0); /* LP_CLK_DIVISOR */ + if (dsi_fclk > 30*1000*1000) + REG_FLD_MOD(DSI_CLK_CTRL, 1, 21, 21); /* LP_RX_SYNCHRO_ENABLE */ + + return 0; +} + + +enum dsi_pll_power_state { + DSI_PLL_POWER_OFF = 0x0, + DSI_PLL_POWER_ON_HSCLK = 0x1, + DSI_PLL_POWER_ON_ALL = 0x2, + DSI_PLL_POWER_ON_DIV = 0x3, +}; + +static int dsi_pll_power(enum dsi_pll_power_state state) +{ + int t = 0; + + REG_FLD_MOD(DSI_CLK_CTRL, state, 31, 30); /* PLL_PWR_CMD */ + + /* PLL_PWR_STATUS */ + while (FLD_GET(dsi_read_reg(DSI_CLK_CTRL), 29, 28) != state) { + udelay(1); + if (t++ > 1000) { + DSSERR("Failed to set DSI PLL power mode to %d\n", + state); + return -ENODEV; + } + } + + return 0; +} + +int dsi_pll_calc_pck(bool is_tft, unsigned long req_pck, + struct dsi_clock_info *cinfo) +{ + struct dsi_clock_info cur, best; + int min_fck_per_pck; + int match = 0; + unsigned long dss_clk_fck2; + + dss_clk_fck2 = dss_clk_get_rate(DSS_CLK_FCK2); + + if (req_pck == dsi.cache_req_pck && + dsi.cache_cinfo.clkin == dss_clk_fck2) { + DSSDBG("DSI clock info found from cache\n"); + *cinfo = dsi.cache_cinfo; + return 0; + } + + min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK; + + if (min_fck_per_pck && + req_pck * min_fck_per_pck > DISPC_MAX_FCK) { + DSSERR("Requested pixel clock not possible with the current " + "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning " + "the constraint off.\n"); + min_fck_per_pck = 0; + } + + DSSDBG("dsi_pll_calc\n"); + +retry: + memset(&best, 0, sizeof(best)); + + memset(&cur, 0, sizeof(cur)); + cur.clkin = dss_clk_fck2; + cur.use_dss2_fck = 1; + cur.highfreq = 0; + + /* no highfreq: 0.75MHz < Fint = clkin / regn < 2.1MHz */ + /* highfreq: 0.75MHz < Fint = clkin / (2*regn) < 2.1MHz */ + /* To reduce PLL lock time, keep Fint high (around 2 MHz) */ + for (cur.regn = 1; cur.regn < REGN_MAX; ++cur.regn) { + if (cur.highfreq == 0) + cur.fint = cur.clkin / cur.regn; + else + cur.fint = cur.clkin / (2 * cur.regn); + + if (cur.fint > FINT_MAX || cur.fint < FINT_MIN) + continue; + + /* DSIPHY(MHz) = (2 * regm / regn) * (clkin / (highfreq + 1)) */ + for (cur.regm = 1; cur.regm < REGM_MAX; ++cur.regm) { + unsigned long a, b; + + a = 2 * cur.regm * (cur.clkin/1000); + b = cur.regn * (cur.highfreq + 1); + cur.dsiphy = a / b * 1000; + + if (cur.dsiphy > 1800 * 1000 * 1000) + break; + + /* DSI1_PLL_FCLK(MHz) = DSIPHY(MHz) / regm3 < 173MHz */ + for (cur.regm3 = 1; cur.regm3 < REGM3_MAX; + ++cur.regm3) { + cur.dsi1_pll_fclk = cur.dsiphy / cur.regm3; + + /* this will narrow down the search a bit, + * but still give pixclocks below what was + * requested */ + if (cur.dsi1_pll_fclk < req_pck) + break; + + if (cur.dsi1_pll_fclk > DISPC_MAX_FCK) + continue; + + if (min_fck_per_pck && + cur.dsi1_pll_fclk < + req_pck * min_fck_per_pck) + continue; + + match = 1; + + find_lck_pck_divs(is_tft, req_pck, + cur.dsi1_pll_fclk, + &cur.lck_div, + &cur.pck_div); + + cur.lck = cur.dsi1_pll_fclk / cur.lck_div; + cur.pck = cur.lck / cur.pck_div; + + if (abs(cur.pck - req_pck) < + abs(best.pck - req_pck)) { + best = cur; + + if (cur.pck == req_pck) + goto found; + } + } + } + } +found: + if (!match) { + if (min_fck_per_pck) { + DSSERR("Could not find suitable clock settings.\n" + "Turning FCK/PCK constraint off and" + "trying again.\n"); + min_fck_per_pck = 0; + goto retry; + } + + DSSERR("Could not find suitable clock settings.\n"); + + return -EINVAL; + } + + /* DSI2_PLL_FCLK (regm4) is not used. Set it to something sane. */ + best.regm4 = best.dsiphy / 48000000; + if (best.regm4 > REGM4_MAX) + best.regm4 = REGM4_MAX; + else if (best.regm4 == 0) + best.regm4 = 1; + best.dsi2_pll_fclk = best.dsiphy / best.regm4; + + if (cinfo) + *cinfo = best; + + dsi.cache_req_pck = req_pck; + dsi.cache_clk_freq = 0; + dsi.cache_cinfo = best; + + return 0; +} + +static int dsi_pll_calc_ddrfreq(unsigned long clk_freq, + struct dsi_clock_info *cinfo) +{ + struct dsi_clock_info cur, best; + const bool use_dss2_fck = 1; + unsigned long datafreq; + unsigned long dss_clk_fck2; + + DSSDBG("dsi_pll_calc_ddrfreq\n"); + + dss_clk_fck2 = dss_clk_get_rate(DSS_CLK_FCK2); + + if (clk_freq == dsi.cache_clk_freq && + dsi.cache_cinfo.clkin == dss_clk_fck2) { + DSSDBG("DSI clock info found from cache\n"); + *cinfo = dsi.cache_cinfo; + return 0; + } + + datafreq = clk_freq * 4; + + memset(&best, 0, sizeof(best)); + + memset(&cur, 0, sizeof(cur)); + cur.use_dss2_fck = use_dss2_fck; + if (use_dss2_fck) { + cur.clkin = dss_clk_fck2; + cur.highfreq = 0; + } else { + cur.clkin = dispc_pclk_rate(); + if (cur.clkin < 32000000) + cur.highfreq = 0; + else + cur.highfreq = 1; + } + + /* no highfreq: 0.75MHz < Fint = clkin / regn < 2.1MHz */ + /* highfreq: 0.75MHz < Fint = clkin / (2*regn) < 2.1MHz */ + /* To reduce PLL lock time, keep Fint high (around 2 MHz) */ + for (cur.regn = 1; cur.regn < REGN_MAX; ++cur.regn) { + if (cur.highfreq == 0) + cur.fint = cur.clkin / cur.regn; + else + cur.fint = cur.clkin / (2 * cur.regn); + + if (cur.fint > FINT_MAX || cur.fint < FINT_MIN) + continue; + + /* DSIPHY(MHz) = (2 * regm / regn) * (clkin / (highfreq + 1)) */ + for (cur.regm = 1; cur.regm < REGM_MAX; ++cur.regm) { + unsigned long a, b; + + a = 2 * cur.regm * (cur.clkin/1000); + b = cur.regn * (cur.highfreq + 1); + cur.dsiphy = a / b * 1000; + + if (cur.dsiphy > 1800 * 1000 * 1000) + break; + + if (abs(cur.dsiphy - datafreq) < + abs(best.dsiphy - datafreq)) { + best = cur; + /* DSSDBG("best %ld\n", best.dsiphy); */ + } + + if (cur.dsiphy == datafreq) + goto found; + } + } +found: + /* DSI1_PLL_FCLK (regm3) is not used. Set it to something sane. */ + best.regm3 = best.dsiphy / 48000000; + if (best.regm3 > REGM3_MAX) + best.regm3 = REGM3_MAX; + else if (best.regm3 == 0) + best.regm3 = 1; + best.dsi1_pll_fclk = best.dsiphy / best.regm3; + + /* DSI2_PLL_FCLK (regm4) is not used. Set it to something sane. */ + best.regm4 = best.dsiphy / 48000000; + if (best.regm4 > REGM4_MAX) + best.regm4 = REGM4_MAX; + else if (best.regm4 == 0) + best.regm4 = 1; + best.dsi2_pll_fclk = best.dsiphy / best.regm4; + + if (cinfo) + *cinfo = best; + + dsi.cache_clk_freq = clk_freq; + dsi.cache_req_pck = 0; + dsi.cache_cinfo = best; + + return 0; +} + +int dsi_pll_program(struct dsi_clock_info *cinfo) +{ + int r = 0; + u32 l; + + DSSDBG("dsi_pll_program\n"); + + dsi.dsiphy = cinfo->dsiphy; + dsi.ddr_clk = dsi.dsiphy / 4; + dsi.dsi1_pll_fclk = cinfo->dsi1_pll_fclk; + dsi.dsi2_pll_fclk = cinfo->dsi2_pll_fclk; + + DSSDBG("DSI Fint %ld\n", cinfo->fint); + + DSSDBG("clkin (%s) rate %ld, highfreq %d\n", + cinfo->use_dss2_fck ? "dss2_fck" : "pclkfree", + cinfo->clkin, + cinfo->highfreq); + + /* DSIPHY == CLKIN4DDR */ + DSSDBG("DSIPHY = 2 * %d / %d * %lu / %d = %lu\n", + cinfo->regm, + cinfo->regn, + cinfo->clkin, + cinfo->highfreq + 1, + cinfo->dsiphy); + + DSSDBG("Data rate on 1 DSI lane %ld Mbps\n", + dsi.dsiphy / 1000 / 1000 / 2); + + DSSDBG("Clock lane freq %ld Hz\n", dsi.ddr_clk); + + DSSDBG("regm3 = %d, dsi1_pll_fclk = %lu\n", + cinfo->regm3, cinfo->dsi1_pll_fclk); + DSSDBG("regm4 = %d, dsi2_pll_fclk = %lu\n", + cinfo->regm4, cinfo->dsi2_pll_fclk); + + REG_FLD_MOD(DSI_PLL_CONTROL, 0, 0, 0); /* DSI_PLL_AUTOMODE = manual */ + + l = dsi_read_reg(DSI_PLL_CONFIGURATION1); + l = FLD_MOD(l, 1, 0, 0); /* DSI_PLL_STOPMODE */ + l = FLD_MOD(l, cinfo->regn - 1, 7, 1); /* DSI_PLL_REGN */ + l = FLD_MOD(l, cinfo->regm, 18, 8); /* DSI_PLL_REGM */ + l = FLD_MOD(l, cinfo->regm3 - 1, 22, 19); /* DSI_CLOCK_DIV */ + l = FLD_MOD(l, cinfo->regm4 - 1, 26, 23); /* DSIPROTO_CLOCK_DIV */ + dsi_write_reg(DSI_PLL_CONFIGURATION1, l); + + l = dsi_read_reg(DSI_PLL_CONFIGURATION2); + l = FLD_MOD(l, 7, 4, 1); /* DSI_PLL_FREQSEL */ + /* DSI_PLL_CLKSEL */ + l = FLD_MOD(l, cinfo->use_dss2_fck ? 0 : 1, 11, 11); + l = FLD_MOD(l, cinfo->highfreq, 12, 12); /* DSI_PLL_HIGHFREQ */ + l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */ + l = FLD_MOD(l, 0, 14, 14); /* DSIPHY_CLKINEN */ + l = FLD_MOD(l, 1, 20, 20); /* DSI_HSDIVBYPASS */ + dsi_write_reg(DSI_PLL_CONFIGURATION2, l); + + REG_FLD_MOD(DSI_PLL_GO, 1, 0, 0); /* DSI_PLL_GO */ + + if (wait_for_bit_change(DSI_PLL_GO, 0, 0) != 0) { + DSSERR("dsi pll go bit not going down.\n"); + r = -EIO; + goto err; + } + + if (wait_for_bit_change(DSI_PLL_STATUS, 1, 1) != 1) { + DSSERR("cannot lock PLL\n"); + r = -EIO; + goto err; + } + + dsi.pll_locked = 1; + + l = dsi_read_reg(DSI_PLL_CONFIGURATION2); + l = FLD_MOD(l, 0, 0, 0); /* DSI_PLL_IDLE */ + l = FLD_MOD(l, 0, 5, 5); /* DSI_PLL_PLLLPMODE */ + l = FLD_MOD(l, 0, 6, 6); /* DSI_PLL_LOWCURRSTBY */ + l = FLD_MOD(l, 0, 7, 7); /* DSI_PLL_TIGHTPHASELOCK */ + l = FLD_MOD(l, 0, 8, 8); /* DSI_PLL_DRIFTGUARDEN */ + l = FLD_MOD(l, 0, 10, 9); /* DSI_PLL_LOCKSEL */ + l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */ + l = FLD_MOD(l, 1, 14, 14); /* DSIPHY_CLKINEN */ + l = FLD_MOD(l, 0, 15, 15); /* DSI_BYPASSEN */ + l = FLD_MOD(l, 1, 16, 16); /* DSS_CLOCK_EN */ + l = FLD_MOD(l, 0, 17, 17); /* DSS_CLOCK_PWDN */ + l = FLD_MOD(l, 1, 18, 18); /* DSI_PROTO_CLOCK_EN */ + l = FLD_MOD(l, 0, 19, 19); /* DSI_PROTO_CLOCK_PWDN */ + l = FLD_MOD(l, 0, 20, 20); /* DSI_HSDIVBYPASS */ + dsi_write_reg(DSI_PLL_CONFIGURATION2, l); + + DSSDBG("PLL config done\n"); +err: + return r; +} + +int dsi_pll_init(bool enable_hsclk, bool enable_hsdiv) +{ + int r = 0; + enum dsi_pll_power_state pwstate; + struct dispc_clock_info cinfo; + + DSSDBG("PLL init\n"); + + enable_clocks(1); + dsi_enable_pll_clock(1); + + /* XXX this should be calculated depending on the screen size, + * required framerate and DSI speed. + * For now 48MHz is enough for 864x480@60 with 360Mbps/lane + * with two lanes */ + r = dispc_calc_clock_div(1, 48 * 1000 * 1000, &cinfo); + if (r) + goto err0; + + r = dispc_set_clock_div(&cinfo); + if (r) { + DSSERR("Failed to set basic clocks\n"); + goto err0; + } + + r = regulator_enable(dsi.vdds_dsi_reg); + if (r) + goto err0; + + /* XXX PLL does not come out of reset without this... */ + dispc_pck_free_enable(1); + + if (wait_for_bit_change(DSI_PLL_STATUS, 0, 1) != 1) { + DSSERR("PLL not coming out of reset.\n"); + r = -ENODEV; + goto err1; + } + + /* XXX ... but if left on, we get problems when planes do not + * fill the whole display. No idea about this */ + dispc_pck_free_enable(0); + + if (enable_hsclk && enable_hsdiv) + pwstate = DSI_PLL_POWER_ON_ALL; + else if (enable_hsclk) + pwstate = DSI_PLL_POWER_ON_HSCLK; + else if (enable_hsdiv) + pwstate = DSI_PLL_POWER_ON_DIV; + else + pwstate = DSI_PLL_POWER_OFF; + + r = dsi_pll_power(pwstate); + + if (r) + goto err1; + + DSSDBG("PLL init done\n"); + + return 0; +err1: + regulator_disable(dsi.vdds_dsi_reg); +err0: + enable_clocks(0); + dsi_enable_pll_clock(0); + return r; +} + +void dsi_pll_uninit(void) +{ + enable_clocks(0); + dsi_enable_pll_clock(0); + + dsi.pll_locked = 0; + dsi_pll_power(DSI_PLL_POWER_OFF); + regulator_disable(dsi.vdds_dsi_reg); + DSSDBG("PLL uninit done\n"); +} + +unsigned long dsi_get_dsi1_pll_rate(void) +{ + return dsi.dsi1_pll_fclk; +} + +unsigned long dsi_get_dsi2_pll_rate(void) +{ + return dsi.dsi2_pll_fclk; +} + +void dsi_dump_clocks(struct seq_file *s) +{ + int clksel; + + enable_clocks(1); + + clksel = REG_GET(DSI_PLL_CONFIGURATION2, 11, 11); + + seq_printf(s, "- dsi -\n"); + + seq_printf(s, "dsi fclk source = %s\n", + dss_get_dsi_clk_source() == 0 ? + "dss1_alwon_fclk" : "dsi2_pll_fclk"); + + seq_printf(s, "dsi pll source = %s\n", + clksel == 0 ? + "dss2_alwon_fclk" : "pclkfree"); + + seq_printf(s, "DSIPHY\t\t%lu\nDDR_CLK\t\t%lu\n", + dsi.dsiphy, dsi.ddr_clk); + + seq_printf(s, "dsi1_pll_fck\t%lu (%s)\n" + "dsi2_pll_fck\t%lu (%s)\n", + dsi.dsi1_pll_fclk, + dss_get_dispc_clk_source() == 0 ? "off" : "on", + dsi.dsi2_pll_fclk, + dss_get_dsi_clk_source() == 0 ? "off" : "on"); + + enable_clocks(0); +} + +void dsi_dump_regs(struct seq_file *s) +{ +#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(r)) + + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + + DUMPREG(DSI_REVISION); + DUMPREG(DSI_SYSCONFIG); + DUMPREG(DSI_SYSSTATUS); + DUMPREG(DSI_IRQSTATUS); + DUMPREG(DSI_IRQENABLE); + DUMPREG(DSI_CTRL); + DUMPREG(DSI_COMPLEXIO_CFG1); + DUMPREG(DSI_COMPLEXIO_IRQ_STATUS); + DUMPREG(DSI_COMPLEXIO_IRQ_ENABLE); + DUMPREG(DSI_CLK_CTRL); + DUMPREG(DSI_TIMING1); + DUMPREG(DSI_TIMING2); + DUMPREG(DSI_VM_TIMING1); + DUMPREG(DSI_VM_TIMING2); + DUMPREG(DSI_VM_TIMING3); + DUMPREG(DSI_CLK_TIMING); + DUMPREG(DSI_TX_FIFO_VC_SIZE); + DUMPREG(DSI_RX_FIFO_VC_SIZE); + DUMPREG(DSI_COMPLEXIO_CFG2); + DUMPREG(DSI_RX_FIFO_VC_FULLNESS); + DUMPREG(DSI_VM_TIMING4); + DUMPREG(DSI_TX_FIFO_VC_EMPTINESS); + DUMPREG(DSI_VM_TIMING5); + DUMPREG(DSI_VM_TIMING6); + DUMPREG(DSI_VM_TIMING7); + DUMPREG(DSI_STOPCLK_TIMING); + + DUMPREG(DSI_VC_CTRL(0)); + DUMPREG(DSI_VC_TE(0)); + DUMPREG(DSI_VC_LONG_PACKET_HEADER(0)); + DUMPREG(DSI_VC_LONG_PACKET_PAYLOAD(0)); + DUMPREG(DSI_VC_SHORT_PACKET_HEADER(0)); + DUMPREG(DSI_VC_IRQSTATUS(0)); + DUMPREG(DSI_VC_IRQENABLE(0)); + + DUMPREG(DSI_VC_CTRL(1)); + DUMPREG(DSI_VC_TE(1)); + DUMPREG(DSI_VC_LONG_PACKET_HEADER(1)); + DUMPREG(DSI_VC_LONG_PACKET_PAYLOAD(1)); + DUMPREG(DSI_VC_SHORT_PACKET_HEADER(1)); + DUMPREG(DSI_VC_IRQSTATUS(1)); + DUMPREG(DSI_VC_IRQENABLE(1)); + + DUMPREG(DSI_VC_CTRL(2)); + DUMPREG(DSI_VC_TE(2)); + DUMPREG(DSI_VC_LONG_PACKET_HEADER(2)); + DUMPREG(DSI_VC_LONG_PACKET_PAYLOAD(2)); + DUMPREG(DSI_VC_SHORT_PACKET_HEADER(2)); + DUMPREG(DSI_VC_IRQSTATUS(2)); + DUMPREG(DSI_VC_IRQENABLE(2)); + + DUMPREG(DSI_VC_CTRL(3)); + DUMPREG(DSI_VC_TE(3)); + DUMPREG(DSI_VC_LONG_PACKET_HEADER(3)); + DUMPREG(DSI_VC_LONG_PACKET_PAYLOAD(3)); + DUMPREG(DSI_VC_SHORT_PACKET_HEADER(3)); + DUMPREG(DSI_VC_IRQSTATUS(3)); + DUMPREG(DSI_VC_IRQENABLE(3)); + + DUMPREG(DSI_DSIPHY_CFG0); + DUMPREG(DSI_DSIPHY_CFG1); + DUMPREG(DSI_DSIPHY_CFG2); + DUMPREG(DSI_DSIPHY_CFG5); + + DUMPREG(DSI_PLL_CONTROL); + DUMPREG(DSI_PLL_STATUS); + DUMPREG(DSI_PLL_GO); + DUMPREG(DSI_PLL_CONFIGURATION1); + DUMPREG(DSI_PLL_CONFIGURATION2); + + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); +#undef DUMPREG +} + +enum dsi_complexio_power_state { + DSI_COMPLEXIO_POWER_OFF = 0x0, + DSI_COMPLEXIO_POWER_ON = 0x1, + DSI_COMPLEXIO_POWER_ULPS = 0x2, +}; + +static int dsi_complexio_power(enum dsi_complexio_power_state state) +{ + int t = 0; + + /* PWR_CMD */ + REG_FLD_MOD(DSI_COMPLEXIO_CFG1, state, 28, 27); + + /* PWR_STATUS */ + while (FLD_GET(dsi_read_reg(DSI_COMPLEXIO_CFG1), 26, 25) != state) { + udelay(1); + if (t++ > 1000) { + DSSERR("failed to set complexio power state to " + "%d\n", state); + return -ENODEV; + } + } + + return 0; +} + +static void dsi_complexio_config(struct omap_dss_device *dssdev) +{ + u32 r; + + int clk_lane = dssdev->phy.dsi.clk_lane; + int data1_lane = dssdev->phy.dsi.data1_lane; + int data2_lane = dssdev->phy.dsi.data2_lane; + int clk_pol = dssdev->phy.dsi.clk_pol; + int data1_pol = dssdev->phy.dsi.data1_pol; + int data2_pol = dssdev->phy.dsi.data2_pol; + + r = dsi_read_reg(DSI_COMPLEXIO_CFG1); + r = FLD_MOD(r, clk_lane, 2, 0); + r = FLD_MOD(r, clk_pol, 3, 3); + r = FLD_MOD(r, data1_lane, 6, 4); + r = FLD_MOD(r, data1_pol, 7, 7); + r = FLD_MOD(r, data2_lane, 10, 8); + r = FLD_MOD(r, data2_pol, 11, 11); + dsi_write_reg(DSI_COMPLEXIO_CFG1, r); + + /* The configuration of the DSI complex I/O (number of data lanes, + position, differential order) should not be changed while + DSS.DSI_CLK_CRTRL[20] LP_CLK_ENABLE bit is set to 1. In order for + the hardware to take into account a new configuration of the complex + I/O (done in DSS.DSI_COMPLEXIO_CFG1 register), it is recommended to + follow this sequence: First set the DSS.DSI_CTRL[0] IF_EN bit to 1, + then reset the DSS.DSI_CTRL[0] IF_EN to 0, then set + DSS.DSI_CLK_CTRL[20] LP_CLK_ENABLE to 1 and finally set again the + DSS.DSI_CTRL[0] IF_EN bit to 1. If the sequence is not followed, the + DSI complex I/O configuration is unknown. */ + + /* + REG_FLD_MOD(DSI_CTRL, 1, 0, 0); + REG_FLD_MOD(DSI_CTRL, 0, 0, 0); + REG_FLD_MOD(DSI_CLK_CTRL, 1, 20, 20); + REG_FLD_MOD(DSI_CTRL, 1, 0, 0); + */ +} + +static inline unsigned ns2ddr(unsigned ns) +{ + /* convert time in ns to ddr ticks, rounding up */ + return (ns * (dsi.ddr_clk/1000/1000) + 999) / 1000; +} + +static inline unsigned ddr2ns(unsigned ddr) +{ + return ddr * 1000 * 1000 / (dsi.ddr_clk / 1000); +} + +static void dsi_complexio_timings(void) +{ + u32 r; + u32 ths_prepare, ths_prepare_ths_zero, ths_trail, ths_exit; + u32 tlpx_half, tclk_trail, tclk_zero; + u32 tclk_prepare; + + /* calculate timings */ + + /* 1 * DDR_CLK = 2 * UI */ + + /* min 40ns + 4*UI max 85ns + 6*UI */ + ths_prepare = ns2ddr(70) + 2; + + /* min 145ns + 10*UI */ + ths_prepare_ths_zero = ns2ddr(175) + 2; + + /* min max(8*UI, 60ns+4*UI) */ + ths_trail = ns2ddr(60) + 5; + + /* min 100ns */ + ths_exit = ns2ddr(145); + + /* tlpx min 50n */ + tlpx_half = ns2ddr(25); + + /* min 60ns */ + tclk_trail = ns2ddr(60) + 2; + + /* min 38ns, max 95ns */ + tclk_prepare = ns2ddr(65); + + /* min tclk-prepare + tclk-zero = 300ns */ + tclk_zero = ns2ddr(260); + + DSSDBG("ths_prepare %u (%uns), ths_prepare_ths_zero %u (%uns)\n", + ths_prepare, ddr2ns(ths_prepare), + ths_prepare_ths_zero, ddr2ns(ths_prepare_ths_zero)); + DSSDBG("ths_trail %u (%uns), ths_exit %u (%uns)\n", + ths_trail, ddr2ns(ths_trail), + ths_exit, ddr2ns(ths_exit)); + + DSSDBG("tlpx_half %u (%uns), tclk_trail %u (%uns), " + "tclk_zero %u (%uns)\n", + tlpx_half, ddr2ns(tlpx_half), + tclk_trail, ddr2ns(tclk_trail), + tclk_zero, ddr2ns(tclk_zero)); + DSSDBG("tclk_prepare %u (%uns)\n", + tclk_prepare, ddr2ns(tclk_prepare)); + + /* program timings */ + + r = dsi_read_reg(DSI_DSIPHY_CFG0); + r = FLD_MOD(r, ths_prepare, 31, 24); + r = FLD_MOD(r, ths_prepare_ths_zero, 23, 16); + r = FLD_MOD(r, ths_trail, 15, 8); + r = FLD_MOD(r, ths_exit, 7, 0); + dsi_write_reg(DSI_DSIPHY_CFG0, r); + + r = dsi_read_reg(DSI_DSIPHY_CFG1); + r = FLD_MOD(r, tlpx_half, 22, 16); + r = FLD_MOD(r, tclk_trail, 15, 8); + r = FLD_MOD(r, tclk_zero, 7, 0); + dsi_write_reg(DSI_DSIPHY_CFG1, r); + + r = dsi_read_reg(DSI_DSIPHY_CFG2); + r = FLD_MOD(r, tclk_prepare, 7, 0); + dsi_write_reg(DSI_DSIPHY_CFG2, r); +} + + +static int dsi_complexio_init(struct omap_dss_device *dssdev) +{ + int r = 0; + + DSSDBG("dsi_complexio_init\n"); + + /* CIO_CLK_ICG, enable L3 clk to CIO */ + REG_FLD_MOD(DSI_CLK_CTRL, 1, 14, 14); + + /* A dummy read using the SCP interface to any DSIPHY register is + * required after DSIPHY reset to complete the reset of the DSI complex + * I/O. */ + dsi_read_reg(DSI_DSIPHY_CFG5); + + if (wait_for_bit_change(DSI_DSIPHY_CFG5, 30, 1) != 1) { + DSSERR("ComplexIO PHY not coming out of reset.\n"); + r = -ENODEV; + goto err; + } + + dsi_complexio_config(dssdev); + + r = dsi_complexio_power(DSI_COMPLEXIO_POWER_ON); + + if (r) + goto err; + + if (wait_for_bit_change(DSI_COMPLEXIO_CFG1, 29, 1) != 1) { + DSSERR("ComplexIO not coming out of reset.\n"); + r = -ENODEV; + goto err; + } + + if (wait_for_bit_change(DSI_COMPLEXIO_CFG1, 21, 1) != 1) { + DSSERR("ComplexIO LDO power down.\n"); + r = -ENODEV; + goto err; + } + + dsi_complexio_timings(); + + /* + The configuration of the DSI complex I/O (number of data lanes, + position, differential order) should not be changed while + DSS.DSI_CLK_CRTRL[20] LP_CLK_ENABLE bit is set to 1. For the + hardware to recognize a new configuration of the complex I/O (done + in DSS.DSI_COMPLEXIO_CFG1 register), it is recommended to follow + this sequence: First set the DSS.DSI_CTRL[0] IF_EN bit to 1, next + reset the DSS.DSI_CTRL[0] IF_EN to 0, then set DSS.DSI_CLK_CTRL[20] + LP_CLK_ENABLE to 1, and finally, set again the DSS.DSI_CTRL[0] IF_EN + bit to 1. If the sequence is not followed, the DSi complex I/O + configuration is undetermined. + */ + dsi_if_enable(1); + dsi_if_enable(0); + REG_FLD_MOD(DSI_CLK_CTRL, 1, 20, 20); /* LP_CLK_ENABLE */ + dsi_if_enable(1); + dsi_if_enable(0); + + DSSDBG("CIO init done\n"); +err: + return r; +} + +static void dsi_complexio_uninit(void) +{ + dsi_complexio_power(DSI_COMPLEXIO_POWER_OFF); +} + +static int _dsi_wait_reset(void) +{ + int i = 0; + + while (REG_GET(DSI_SYSSTATUS, 0, 0) == 0) { + if (i++ > 5) { + DSSERR("soft reset failed\n"); + return -ENODEV; + } + udelay(1); + } + + return 0; +} + +static int _dsi_reset(void) +{ + /* Soft reset */ + REG_FLD_MOD(DSI_SYSCONFIG, 1, 1, 1); + return _dsi_wait_reset(); +} + + +static void dsi_config_tx_fifo(enum fifo_size size1, enum fifo_size size2, + enum fifo_size size3, enum fifo_size size4) +{ + u32 r = 0; + int add = 0; + int i; + + dsi.vc[0].fifo_size = size1; + dsi.vc[1].fifo_size = size2; + dsi.vc[2].fifo_size = size3; + dsi.vc[3].fifo_size = size4; + + for (i = 0; i < 4; i++) { + u8 v; + int size = dsi.vc[i].fifo_size; + + if (add + size > 4) { + DSSERR("Illegal FIFO configuration\n"); + BUG(); + } + + v = FLD_VAL(add, 2, 0) | FLD_VAL(size, 7, 4); + r |= v << (8 * i); + /*DSSDBG("TX FIFO vc %d: size %d, add %d\n", i, size, add); */ + add += size; + } + + dsi_write_reg(DSI_TX_FIFO_VC_SIZE, r); +} + +static void dsi_config_rx_fifo(enum fifo_size size1, enum fifo_size size2, + enum fifo_size size3, enum fifo_size size4) +{ + u32 r = 0; + int add = 0; + int i; + + dsi.vc[0].fifo_size = size1; + dsi.vc[1].fifo_size = size2; + dsi.vc[2].fifo_size = size3; + dsi.vc[3].fifo_size = size4; + + for (i = 0; i < 4; i++) { + u8 v; + int size = dsi.vc[i].fifo_size; + + if (add + size > 4) { + DSSERR("Illegal FIFO configuration\n"); + BUG(); + } + + v = FLD_VAL(add, 2, 0) | FLD_VAL(size, 7, 4); + r |= v << (8 * i); + /*DSSDBG("RX FIFO vc %d: size %d, add %d\n", i, size, add); */ + add += size; + } + + dsi_write_reg(DSI_RX_FIFO_VC_SIZE, r); +} + +static int dsi_force_tx_stop_mode_io(void) +{ + u32 r; + + r = dsi_read_reg(DSI_TIMING1); + r = FLD_MOD(r, 1, 15, 15); /* FORCE_TX_STOP_MODE_IO */ + dsi_write_reg(DSI_TIMING1, r); + + if (wait_for_bit_change(DSI_TIMING1, 15, 0) != 0) { + DSSERR("TX_STOP bit not going down\n"); + return -EIO; + } + + return 0; +} + +static void dsi_vc_print_status(int channel) +{ + u32 r; + + r = dsi_read_reg(DSI_VC_CTRL(channel)); + DSSDBG("vc %d: TX_FIFO_NOT_EMPTY %d, BTA_EN %d, VC_BUSY %d, " + "TX_FIFO_FULL %d, RX_FIFO_NOT_EMPTY %d, ", + channel, + FLD_GET(r, 5, 5), + FLD_GET(r, 6, 6), + FLD_GET(r, 15, 15), + FLD_GET(r, 16, 16), + FLD_GET(r, 20, 20)); + + r = dsi_read_reg(DSI_TX_FIFO_VC_EMPTINESS); + DSSDBG("EMPTINESS %d\n", (r >> (8 * channel)) & 0xff); +} + +static void dsi_vc_config(int channel) +{ + u32 r; + + DSSDBG("dsi_vc_config %d\n", channel); + + r = dsi_read_reg(DSI_VC_CTRL(channel)); + + r = FLD_MOD(r, 0, 1, 1); /* SOURCE, 0 = L4 */ + r = FLD_MOD(r, 0, 2, 2); /* BTA_SHORT_EN */ + r = FLD_MOD(r, 0, 3, 3); /* BTA_LONG_EN */ + r = FLD_MOD(r, 0, 4, 4); /* MODE, 0 = command */ + r = FLD_MOD(r, 1, 7, 7); /* CS_TX_EN */ + r = FLD_MOD(r, 1, 8, 8); /* ECC_TX_EN */ + r = FLD_MOD(r, 0, 9, 9); /* MODE_SPEED, high speed on/off */ + + r = FLD_MOD(r, 4, 29, 27); /* DMA_RX_REQ_NB = no dma */ + r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */ + + dsi_write_reg(DSI_VC_CTRL(channel), r); +} + +static void dsi_vc_config_vp(int channel) +{ + u32 r; + + DSSDBG("dsi_vc_config_vp\n"); + + r = dsi_read_reg(DSI_VC_CTRL(channel)); + + r = FLD_MOD(r, 1, 1, 1); /* SOURCE, 1 = video port */ + r = FLD_MOD(r, 0, 2, 2); /* BTA_SHORT_EN */ + r = FLD_MOD(r, 0, 3, 3); /* BTA_LONG_EN */ + r = FLD_MOD(r, 0, 4, 4); /* MODE, 0 = command */ + r = FLD_MOD(r, 1, 7, 7); /* CS_TX_EN */ + r = FLD_MOD(r, 1, 8, 8); /* ECC_TX_EN */ + r = FLD_MOD(r, 1, 9, 9); /* MODE_SPEED, high speed on/off */ + + r = FLD_MOD(r, 4, 29, 27); /* DMA_RX_REQ_NB = no dma */ + r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */ + + dsi_write_reg(DSI_VC_CTRL(channel), r); +} + + +static int dsi_vc_enable(int channel, bool enable) +{ + DSSDBG("dsi_vc_enable channel %d, enable %d\n", channel, enable); + + enable = enable ? 1 : 0; + + REG_FLD_MOD(DSI_VC_CTRL(channel), enable, 0, 0); + + if (wait_for_bit_change(DSI_VC_CTRL(channel), 0, enable) != enable) { + DSSERR("Failed to set dsi_vc_enable to %d\n", enable); + return -EIO; + } + + return 0; +} + +static void dsi_vc_enable_hs(int channel, bool enable) +{ + DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable); + + dsi_vc_enable(channel, 0); + dsi_if_enable(0); + + REG_FLD_MOD(DSI_VC_CTRL(channel), enable, 9, 9); + + dsi_vc_enable(channel, 1); + dsi_if_enable(1); + + dsi_force_tx_stop_mode_io(); +} + +static void dsi_vc_flush_long_data(int channel) +{ + while (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { + u32 val; + val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel)); + DSSDBG("\t\tb1 %#02x b2 %#02x b3 %#02x b4 %#02x\n", + (val >> 0) & 0xff, + (val >> 8) & 0xff, + (val >> 16) & 0xff, + (val >> 24) & 0xff); + } +} + +static void dsi_show_rx_ack_with_err(u16 err) +{ + DSSERR("\tACK with ERROR (%#x):\n", err); + if (err & (1 << 0)) + DSSERR("\t\tSoT Error\n"); + if (err & (1 << 1)) + DSSERR("\t\tSoT Sync Error\n"); + if (err & (1 << 2)) + DSSERR("\t\tEoT Sync Error\n"); + if (err & (1 << 3)) + DSSERR("\t\tEscape Mode Entry Command Error\n"); + if (err & (1 << 4)) + DSSERR("\t\tLP Transmit Sync Error\n"); + if (err & (1 << 5)) + DSSERR("\t\tHS Receive Timeout Error\n"); + if (err & (1 << 6)) + DSSERR("\t\tFalse Control Error\n"); + if (err & (1 << 7)) + DSSERR("\t\t(reserved7)\n"); + if (err & (1 << 8)) + DSSERR("\t\tECC Error, single-bit (corrected)\n"); + if (err & (1 << 9)) + DSSERR("\t\tECC Error, multi-bit (not corrected)\n"); + if (err & (1 << 10)) + DSSERR("\t\tChecksum Error\n"); + if (err & (1 << 11)) + DSSERR("\t\tData type not recognized\n"); + if (err & (1 << 12)) + DSSERR("\t\tInvalid VC ID\n"); + if (err & (1 << 13)) + DSSERR("\t\tInvalid Transmission Length\n"); + if (err & (1 << 14)) + DSSERR("\t\t(reserved14)\n"); + if (err & (1 << 15)) + DSSERR("\t\tDSI Protocol Violation\n"); +} + +static u16 dsi_vc_flush_receive_data(int channel) +{ + /* RX_FIFO_NOT_EMPTY */ + while (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { + u32 val; + u8 dt; + val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel)); + DSSDBG("\trawval %#08x\n", val); + dt = FLD_GET(val, 5, 0); + if (dt == DSI_DT_RX_ACK_WITH_ERR) { + u16 err = FLD_GET(val, 23, 8); + dsi_show_rx_ack_with_err(err); + } else if (dt == DSI_DT_RX_SHORT_READ_1) { + DSSDBG("\tDCS short response, 1 byte: %#x\n", + FLD_GET(val, 23, 8)); + } else if (dt == DSI_DT_RX_SHORT_READ_2) { + DSSDBG("\tDCS short response, 2 byte: %#x\n", + FLD_GET(val, 23, 8)); + } else if (dt == DSI_DT_RX_DCS_LONG_READ) { + DSSDBG("\tDCS long response, len %d\n", + FLD_GET(val, 23, 8)); + dsi_vc_flush_long_data(channel); + } else { + DSSERR("\tunknown datatype 0x%02x\n", dt); + } + } + return 0; +} + +static int dsi_vc_send_bta(int channel) +{ + unsigned long tmo; + + /*DSSDBG("dsi_vc_send_bta_sync %d\n", channel); */ + + if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { /* RX_FIFO_NOT_EMPTY */ + DSSERR("rx fifo not empty when sending BTA, dumping data:\n"); + dsi_vc_flush_receive_data(channel); + } + + REG_FLD_MOD(DSI_VC_CTRL(channel), 1, 6, 6); /* BTA_EN */ + + tmo = jiffies + msecs_to_jiffies(10); + while (REG_GET(DSI_VC_CTRL(channel), 6, 6) == 1) { + if (time_after(jiffies, tmo)) { + DSSERR("Failed to send BTA\n"); + return -EIO; + } + } + + return 0; +} + +static int dsi_vc_send_bta_sync(int channel) +{ + int r = 0; + u32 err; + + INIT_COMPLETION(dsi.bta_completion); + + dsi_vc_enable_bta_irq(channel); + + r = dsi_vc_send_bta(channel); + if (r) + goto err; + + if (wait_for_completion_timeout(&dsi.bta_completion, + msecs_to_jiffies(500)) == 0) { + DSSERR("Failed to receive BTA\n"); + r = -EIO; + goto err; + } + + err = dsi_get_errors(); + if (err) { + DSSERR("Error while sending BTA: %x\n", err); + r = -EIO; + goto err; + } +err: + dsi_vc_disable_bta_irq(channel); + + return r; +} + +static inline void dsi_vc_write_long_header(int channel, u8 data_type, + u16 len, u8 ecc) +{ + u32 val; + u8 data_id; + + WARN_ON(!mutex_is_locked(&dsi.bus_lock)); + + /*data_id = data_type | channel << 6; */ + data_id = data_type | dsi.vc[channel].dest_per << 6; + + val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) | + FLD_VAL(ecc, 31, 24); + + dsi_write_reg(DSI_VC_LONG_PACKET_HEADER(channel), val); +} + +static inline void dsi_vc_write_long_payload(int channel, + u8 b1, u8 b2, u8 b3, u8 b4) +{ + u32 val; + + val = b4 << 24 | b3 << 16 | b2 << 8 | b1 << 0; + +/* DSSDBG("\twriting %02x, %02x, %02x, %02x (%#010x)\n", + b1, b2, b3, b4, val); */ + + dsi_write_reg(DSI_VC_LONG_PACKET_PAYLOAD(channel), val); +} + +static int dsi_vc_send_long(int channel, u8 data_type, u8 *data, u16 len, + u8 ecc) +{ + /*u32 val; */ + int i; + u8 *p; + int r = 0; + u8 b1, b2, b3, b4; + + if (dsi.debug_write) + DSSDBG("dsi_vc_send_long, %d bytes\n", len); + + /* len + header */ + if (dsi.vc[channel].fifo_size * 32 * 4 < len + 4) { + DSSERR("unable to send long packet: packet too long.\n"); + return -EINVAL; + } + + dsi_vc_write_long_header(channel, data_type, len, ecc); + + /*dsi_vc_print_status(0); */ + + p = data; + for (i = 0; i < len >> 2; i++) { + if (dsi.debug_write) + DSSDBG("\tsending full packet %d\n", i); + /*dsi_vc_print_status(0); */ + + b1 = *p++; + b2 = *p++; + b3 = *p++; + b4 = *p++; + + dsi_vc_write_long_payload(channel, b1, b2, b3, b4); + } + + i = len % 4; + if (i) { + b1 = 0; b2 = 0; b3 = 0; + + if (dsi.debug_write) + DSSDBG("\tsending remainder bytes %d\n", i); + + switch (i) { + case 3: + b1 = *p++; + b2 = *p++; + b3 = *p++; + break; + case 2: + b1 = *p++; + b2 = *p++; + break; + case 1: + b1 = *p++; + break; + } + + dsi_vc_write_long_payload(channel, b1, b2, b3, 0); + } + + return r; +} + +static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc) +{ + u32 r; + u8 data_id; + + WARN_ON(!mutex_is_locked(&dsi.bus_lock)); + + if (dsi.debug_write) + DSSDBG("dsi_vc_send_short(ch%d, dt %#x, b1 %#x, b2 %#x)\n", + channel, + data_type, data & 0xff, (data >> 8) & 0xff); + + if (FLD_GET(dsi_read_reg(DSI_VC_CTRL(channel)), 16, 16)) { + DSSERR("ERROR FIFO FULL, aborting transfer\n"); + return -EINVAL; + } + + data_id = data_type | channel << 6; + + r = (data_id << 0) | (data << 8) | (ecc << 24); + + dsi_write_reg(DSI_VC_SHORT_PACKET_HEADER(channel), r); + + return 0; +} + +int dsi_vc_send_null(int channel) +{ + u8 nullpkg[] = {0, 0, 0, 0}; + return dsi_vc_send_long(0, DSI_DT_NULL_PACKET, nullpkg, 4, 0); +} +EXPORT_SYMBOL(dsi_vc_send_null); + +int dsi_vc_dcs_write_nosync(int channel, u8 *data, int len) +{ + int r; + + BUG_ON(len == 0); + + if (len == 1) { + r = dsi_vc_send_short(channel, DSI_DT_DCS_SHORT_WRITE_0, + data[0], 0); + } else if (len == 2) { + r = dsi_vc_send_short(channel, DSI_DT_DCS_SHORT_WRITE_1, + data[0] | (data[1] << 8), 0); + } else { + /* 0x39 = DCS Long Write */ + r = dsi_vc_send_long(channel, DSI_DT_DCS_LONG_WRITE, + data, len, 0); + } + + return r; +} +EXPORT_SYMBOL(dsi_vc_dcs_write_nosync); + +int dsi_vc_dcs_write(int channel, u8 *data, int len) +{ + int r; + + r = dsi_vc_dcs_write_nosync(channel, data, len); + if (r) + return r; + + /* Some devices need time to process the msg in low power mode. + This also makes the write synchronous, and checks that + the peripheral is still alive */ + r = dsi_vc_send_bta_sync(channel); + + return r; +} +EXPORT_SYMBOL(dsi_vc_dcs_write); + +int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen) +{ + u32 val; + u8 dt; + int r; + + if (dsi.debug_read) + DSSDBG("dsi_vc_dcs_read\n"); + + r = dsi_vc_send_short(channel, DSI_DT_DCS_READ, dcs_cmd, 0); + if (r) + return r; + + r = dsi_vc_send_bta_sync(channel); + if (r) + return r; + + /* RX_FIFO_NOT_EMPTY */ + if (REG_GET(DSI_VC_CTRL(channel), 20, 20) == 0) { + DSSERR("RX fifo empty when trying to read.\n"); + return -EIO; + } + + val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel)); + if (dsi.debug_read) + DSSDBG("\theader: %08x\n", val); + dt = FLD_GET(val, 5, 0); + if (dt == DSI_DT_RX_ACK_WITH_ERR) { + u16 err = FLD_GET(val, 23, 8); + dsi_show_rx_ack_with_err(err); + return -1; + + } else if (dt == DSI_DT_RX_SHORT_READ_1) { + u8 data = FLD_GET(val, 15, 8); + if (dsi.debug_read) + DSSDBG("\tDCS short response, 1 byte: %02x\n", data); + + if (buflen < 1) + return -1; + + buf[0] = data; + + return 1; + } else if (dt == DSI_DT_RX_SHORT_READ_2) { + u16 data = FLD_GET(val, 23, 8); + if (dsi.debug_read) + DSSDBG("\tDCS short response, 2 byte: %04x\n", data); + + if (buflen < 2) + return -1; + + buf[0] = data & 0xff; + buf[1] = (data >> 8) & 0xff; + + return 2; + } else if (dt == DSI_DT_RX_DCS_LONG_READ) { + int w; + int len = FLD_GET(val, 23, 8); + if (dsi.debug_read) + DSSDBG("\tDCS long response, len %d\n", len); + + if (len > buflen) + return -1; + + /* two byte checksum ends the packet, not included in len */ + for (w = 0; w < len + 2;) { + int b; + val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel)); + if (dsi.debug_read) + DSSDBG("\t\t%02x %02x %02x %02x\n", + (val >> 0) & 0xff, + (val >> 8) & 0xff, + (val >> 16) & 0xff, + (val >> 24) & 0xff); + + for (b = 0; b < 4; ++b) { + if (w < len) + buf[w] = (val >> (b * 8)) & 0xff; + /* we discard the 2 byte checksum */ + ++w; + } + } + + return len; + + } else { + DSSERR("\tunknown datatype 0x%02x\n", dt); + return -1; + } +} +EXPORT_SYMBOL(dsi_vc_dcs_read); + + +int dsi_vc_set_max_rx_packet_size(int channel, u16 len) +{ + return dsi_vc_send_short(channel, DSI_DT_SET_MAX_RET_PKG_SIZE, + len, 0); +} +EXPORT_SYMBOL(dsi_vc_set_max_rx_packet_size); + + +static int dsi_set_lp_rx_timeout(int ns, int x4, int x16) +{ + u32 r; + unsigned long fck; + int ticks; + + /* ticks in DSI_FCK */ + + fck = dsi_fclk_rate(); + ticks = (fck / 1000 / 1000) * ns / 1000; + + if (ticks > 0x1fff) { + DSSERR("LP_TX_TO too high\n"); + return -EINVAL; + } + + r = dsi_read_reg(DSI_TIMING2); + r = FLD_MOD(r, 1, 15, 15); /* LP_RX_TO */ + r = FLD_MOD(r, x16, 14, 14); /* LP_RX_TO_X16 */ + r = FLD_MOD(r, x4, 13, 13); /* LP_RX_TO_X4 */ + r = FLD_MOD(r, ticks, 12, 0); /* LP_RX_COUNTER */ + dsi_write_reg(DSI_TIMING2, r); + + DSSDBG("LP_RX_TO %ld ns (%#x ticks)\n", + (ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1) * 1000) / + (fck / 1000 / 1000), + ticks); + + return 0; +} + +static int dsi_set_ta_timeout(int ns, int x8, int x16) +{ + u32 r; + unsigned long fck; + int ticks; + + /* ticks in DSI_FCK */ + + fck = dsi_fclk_rate(); + ticks = (fck / 1000 / 1000) * ns / 1000; + + if (ticks > 0x1fff) { + DSSERR("TA_TO too high\n"); + return -EINVAL; + } + + r = dsi_read_reg(DSI_TIMING1); + r = FLD_MOD(r, 1, 31, 31); /* TA_TO */ + r = FLD_MOD(r, x16, 30, 30); /* TA_TO_X16 */ + r = FLD_MOD(r, x8, 29, 29); /* TA_TO_X8 */ + r = FLD_MOD(r, ticks, 28, 16); /* TA_TO_COUNTER */ + dsi_write_reg(DSI_TIMING1, r); + + DSSDBG("TA_TO %ld ns (%#x ticks)\n", + (ticks * (x16 ? 16 : 1) * (x8 ? 8 : 1) * 1000) / + (fck / 1000 / 1000), + ticks); + + return 0; +} + +static int dsi_set_stop_state_counter(int ns, int x4, int x16) +{ + u32 r; + unsigned long fck; + int ticks; + + /* ticks in DSI_FCK */ + + fck = dsi_fclk_rate(); + ticks = (fck / 1000 / 1000) * ns / 1000; + + if (ticks > 0x1fff) { + DSSERR("STOP_STATE_COUNTER_IO too high\n"); + return -EINVAL; + } + + r = dsi_read_reg(DSI_TIMING1); + r = FLD_MOD(r, 1, 15, 15); /* FORCE_TX_STOP_MODE_IO */ + r = FLD_MOD(r, x16, 14, 14); /* STOP_STATE_X16_IO */ + r = FLD_MOD(r, x4, 13, 13); /* STOP_STATE_X4_IO */ + r = FLD_MOD(r, ticks, 12, 0); /* STOP_STATE_COUNTER_IO */ + dsi_write_reg(DSI_TIMING1, r); + + DSSDBG("STOP_STATE_COUNTER %ld ns (%#x ticks)\n", + (ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1) * 1000) / + (fck / 1000 / 1000), + ticks); + + return 0; +} + +static int dsi_set_hs_tx_timeout(int ns, int x4, int x16) +{ + u32 r; + unsigned long fck; + int ticks; + + /* ticks in TxByteClkHS */ + + fck = dsi.ddr_clk / 4; + ticks = (fck / 1000 / 1000) * ns / 1000; + + if (ticks > 0x1fff) { + DSSERR("HS_TX_TO too high\n"); + return -EINVAL; + } + + r = dsi_read_reg(DSI_TIMING2); + r = FLD_MOD(r, 1, 31, 31); /* HS_TX_TO */ + r = FLD_MOD(r, x16, 30, 30); /* HS_TX_TO_X16 */ + r = FLD_MOD(r, x4, 29, 29); /* HS_TX_TO_X8 (4 really) */ + r = FLD_MOD(r, ticks, 28, 16); /* HS_TX_TO_COUNTER */ + dsi_write_reg(DSI_TIMING2, r); + + DSSDBG("HS_TX_TO %ld ns (%#x ticks)\n", + (ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1) * 1000) / + (fck / 1000 / 1000), + ticks); + + return 0; +} +static int dsi_proto_config(struct omap_dss_device *dssdev) +{ + u32 r; + int buswidth = 0; + int div; + + dsi_config_tx_fifo(DSI_FIFO_SIZE_128, + DSI_FIFO_SIZE_0, + DSI_FIFO_SIZE_0, + DSI_FIFO_SIZE_0); + + dsi_config_rx_fifo(DSI_FIFO_SIZE_128, + DSI_FIFO_SIZE_0, + DSI_FIFO_SIZE_0, + DSI_FIFO_SIZE_0); + + /* XXX what values for the timeouts? */ + dsi_set_stop_state_counter(1000, 0, 0); + + dsi_set_ta_timeout(50000, 1, 1); + + /* 3000ns * 16 */ + dsi_set_lp_rx_timeout(3000, 0, 1); + + /* 10000ns * 4 */ + dsi_set_hs_tx_timeout(10000, 1, 0); + + switch (dssdev->ctrl.pixel_size) { + case 16: + buswidth = 0; + break; + case 18: + buswidth = 1; + break; + case 24: + buswidth = 2; + break; + default: + BUG(); + } + + r = dsi_read_reg(DSI_CTRL); + r = FLD_MOD(r, 1, 1, 1); /* CS_RX_EN */ + r = FLD_MOD(r, 1, 2, 2); /* ECC_RX_EN */ + r = FLD_MOD(r, 1, 3, 3); /* TX_FIFO_ARBITRATION */ + + div = dispc_lclk_rate() / dispc_pclk_rate(); + r = FLD_MOD(r, div == 2 ? 0 : 1, 4, 4); /* VP_CLK_RATIO */ + r = FLD_MOD(r, buswidth, 7, 6); /* VP_DATA_BUS_WIDTH */ + r = FLD_MOD(r, 0, 8, 8); /* VP_CLK_POL */ + r = FLD_MOD(r, 2, 13, 12); /* LINE_BUFFER, 2 lines */ + r = FLD_MOD(r, 1, 14, 14); /* TRIGGER_RESET_MODE */ + r = FLD_MOD(r, 1, 19, 19); /* EOT_ENABLE */ + r = FLD_MOD(r, 1, 24, 24); /* DCS_CMD_ENABLE */ + r = FLD_MOD(r, 0, 25, 25); /* DCS_CMD_CODE, 1=start, 0=continue */ + + dsi_write_reg(DSI_CTRL, r); + + /* we configure vc0 for L4 communication, and + * vc1 for dispc */ + dsi_vc_config(0); + dsi_vc_config_vp(1); + + /* set all vc targets to peripheral 0 */ + dsi.vc[0].dest_per = 0; + dsi.vc[1].dest_per = 0; + dsi.vc[2].dest_per = 0; + dsi.vc[3].dest_per = 0; + + return 0; +} + +static void dsi_proto_timings(struct omap_dss_device *dssdev) +{ + unsigned tlpx, tclk_zero, tclk_prepare, tclk_trail; + unsigned tclk_pre, tclk_post; + unsigned ths_prepare, ths_prepare_ths_zero, ths_zero; + unsigned ths_trail, ths_exit; + unsigned ddr_clk_pre, ddr_clk_post; + unsigned enter_hs_mode_lat, exit_hs_mode_lat; + unsigned ths_eot; + u32 r; + + r = dsi_read_reg(DSI_DSIPHY_CFG0); + ths_prepare = FLD_GET(r, 31, 24); + ths_prepare_ths_zero = FLD_GET(r, 23, 16); + ths_zero = ths_prepare_ths_zero - ths_prepare; + ths_trail = FLD_GET(r, 15, 8); + ths_exit = FLD_GET(r, 7, 0); + + r = dsi_read_reg(DSI_DSIPHY_CFG1); + tlpx = FLD_GET(r, 22, 16) * 2; + tclk_trail = FLD_GET(r, 15, 8); + tclk_zero = FLD_GET(r, 7, 0); + + r = dsi_read_reg(DSI_DSIPHY_CFG2); + tclk_prepare = FLD_GET(r, 7, 0); + + /* min 8*UI */ + tclk_pre = 20; + /* min 60ns + 52*UI */ + tclk_post = ns2ddr(60) + 26; + + /* ths_eot is 2 for 2 datalanes and 4 for 1 datalane */ + if (dssdev->phy.dsi.data1_lane != 0 && + dssdev->phy.dsi.data2_lane != 0) + ths_eot = 2; + else + ths_eot = 4; + + ddr_clk_pre = DIV_ROUND_UP(tclk_pre + tlpx + tclk_zero + tclk_prepare, + 4); + ddr_clk_post = DIV_ROUND_UP(tclk_post + tclk_trail, 4) + ths_eot; + + BUG_ON(ddr_clk_pre == 0 || ddr_clk_pre > 255); + BUG_ON(ddr_clk_post == 0 || ddr_clk_post > 255); + + r = dsi_read_reg(DSI_CLK_TIMING); + r = FLD_MOD(r, ddr_clk_pre, 15, 8); + r = FLD_MOD(r, ddr_clk_post, 7, 0); + dsi_write_reg(DSI_CLK_TIMING, r); + + DSSDBG("ddr_clk_pre %u, ddr_clk_post %u\n", + ddr_clk_pre, + ddr_clk_post); + + enter_hs_mode_lat = 1 + DIV_ROUND_UP(tlpx, 4) + + DIV_ROUND_UP(ths_prepare, 4) + + DIV_ROUND_UP(ths_zero + 3, 4); + + exit_hs_mode_lat = DIV_ROUND_UP(ths_trail + ths_exit, 4) + 1 + ths_eot; + + r = FLD_VAL(enter_hs_mode_lat, 31, 16) | + FLD_VAL(exit_hs_mode_lat, 15, 0); + dsi_write_reg(DSI_VM_TIMING7, r); + + DSSDBG("enter_hs_mode_lat %u, exit_hs_mode_lat %u\n", + enter_hs_mode_lat, exit_hs_mode_lat); +} + + +#define DSI_DECL_VARS \ + int __dsi_cb = 0; u32 __dsi_cv = 0; + +#define DSI_FLUSH(ch) \ + if (__dsi_cb > 0) { \ + /*DSSDBG("sending long packet %#010x\n", __dsi_cv);*/ \ + dsi_write_reg(DSI_VC_LONG_PACKET_PAYLOAD(ch), __dsi_cv); \ + __dsi_cb = __dsi_cv = 0; \ + } + +#define DSI_PUSH(ch, data) \ + do { \ + __dsi_cv |= (data) << (__dsi_cb * 8); \ + /*DSSDBG("cv = %#010x, cb = %d\n", __dsi_cv, __dsi_cb);*/ \ + if (++__dsi_cb > 3) \ + DSI_FLUSH(ch); \ + } while (0) + +static int dsi_update_screen_l4(struct omap_dss_device *dssdev, + int x, int y, int w, int h) +{ + /* Note: supports only 24bit colors in 32bit container */ + int first = 1; + int fifo_stalls = 0; + int max_dsi_packet_size; + int max_data_per_packet; + int max_pixels_per_packet; + int pixels_left; + int bytespp = dssdev->ctrl.pixel_size / 8; + int scr_width; + u32 __iomem *data; + int start_offset; + int horiz_inc; + int current_x; + struct omap_overlay *ovl; + + debug_irq = 0; + + DSSDBG("dsi_update_screen_l4 (%d,%d %dx%d)\n", + x, y, w, h); + + ovl = dssdev->manager->overlays[0]; + + if (ovl->info.color_mode != OMAP_DSS_COLOR_RGB24U) + return -EINVAL; + + if (dssdev->ctrl.pixel_size != 24) + return -EINVAL; + + scr_width = ovl->info.screen_width; + data = ovl->info.vaddr; + + start_offset = scr_width * y + x; + horiz_inc = scr_width - w; + current_x = x; + + /* We need header(4) + DCSCMD(1) + pixels(numpix*bytespp) bytes + * in fifo */ + + /* When using CPU, max long packet size is TX buffer size */ + max_dsi_packet_size = dsi.vc[0].fifo_size * 32 * 4; + + /* we seem to get better perf if we divide the tx fifo to half, + and while the other half is being sent, we fill the other half + max_dsi_packet_size /= 2; */ + + max_data_per_packet = max_dsi_packet_size - 4 - 1; + + max_pixels_per_packet = max_data_per_packet / bytespp; + + DSSDBG("max_pixels_per_packet %d\n", max_pixels_per_packet); + + pixels_left = w * h; + + DSSDBG("total pixels %d\n", pixels_left); + + data += start_offset; + + while (pixels_left > 0) { + /* 0x2c = write_memory_start */ + /* 0x3c = write_memory_continue */ + u8 dcs_cmd = first ? 0x2c : 0x3c; + int pixels; + DSI_DECL_VARS; + first = 0; + +#if 1 + /* using fifo not empty */ + /* TX_FIFO_NOT_EMPTY */ + while (FLD_GET(dsi_read_reg(DSI_VC_CTRL(0)), 5, 5)) { + udelay(1); + fifo_stalls++; + if (fifo_stalls > 0xfffff) { + DSSERR("fifo stalls overflow, pixels left %d\n", + pixels_left); + dsi_if_enable(0); + return -EIO; + } + } +#elif 1 + /* using fifo emptiness */ + while ((REG_GET(DSI_TX_FIFO_VC_EMPTINESS, 7, 0)+1)*4 < + max_dsi_packet_size) { + fifo_stalls++; + if (fifo_stalls > 0xfffff) { + DSSERR("fifo stalls overflow, pixels left %d\n", + pixels_left); + dsi_if_enable(0); + return -EIO; + } + } +#else + while ((REG_GET(DSI_TX_FIFO_VC_EMPTINESS, 7, 0)+1)*4 == 0) { + fifo_stalls++; + if (fifo_stalls > 0xfffff) { + DSSERR("fifo stalls overflow, pixels left %d\n", + pixels_left); + dsi_if_enable(0); + return -EIO; + } + } +#endif + pixels = min(max_pixels_per_packet, pixels_left); + + pixels_left -= pixels; + + dsi_vc_write_long_header(0, DSI_DT_DCS_LONG_WRITE, + 1 + pixels * bytespp, 0); + + DSI_PUSH(0, dcs_cmd); + + while (pixels-- > 0) { + u32 pix = __raw_readl(data++); + + DSI_PUSH(0, (pix >> 16) & 0xff); + DSI_PUSH(0, (pix >> 8) & 0xff); + DSI_PUSH(0, (pix >> 0) & 0xff); + + current_x++; + if (current_x == x+w) { + current_x = x; + data += horiz_inc; + } + } + + DSI_FLUSH(0); + } + + return 0; +} + +static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, + u16 x, u16 y, u16 w, u16 h) +{ + int bytespp = dssdev->ctrl.pixel_size / 8; + int len; + int total_len; + int packet_payload; + int packet_len; + u32 l; + bool use_te_trigger; + + use_te_trigger = dsi.te_enabled && !dsi.use_ext_te; + + if (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL) + DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n", + x, y, w, h); + + len = w * h * bytespp; + + /* XXX: one packet could be longer, I think? Line buffer is + * 1024 x 24bits, but we have to put DCS cmd there also. + * 1023 * 3 should work, but causes strange color effects. */ + packet_payload = min(w, (u16)1020) * bytespp; + + packet_len = packet_payload + 1; /* 1 byte for DCS cmd */ + total_len = (len / packet_payload) * packet_len; + + if (len % packet_payload) + total_len += (len % packet_payload) + 1; + + if (0) + dsi_vc_print_status(1); + + l = FLD_VAL(total_len, 23, 0); /* TE_SIZE */ + dsi_write_reg(DSI_VC_TE(1), l); + + dsi_vc_write_long_header(1, DSI_DT_DCS_LONG_WRITE, packet_len, 0); + + if (use_te_trigger) + l = FLD_MOD(l, 1, 30, 30); /* TE_EN */ + else + l = FLD_MOD(l, 1, 31, 31); /* TE_START */ + dsi_write_reg(DSI_VC_TE(1), l); + + dispc_disable_sidle(); + + dss_start_update(dssdev); + + if (use_te_trigger) + dsi_vc_send_bta(1); +} + +static void dsi_framedone_irq_callback(void *data, u32 mask) +{ + dispc_enable_sidle(); + + dsi.framedone_received = true; + wake_up(&dsi.waitqueue); +} + +static void dsi_set_update_region(struct omap_dss_device *dssdev, + u16 x, u16 y, u16 w, u16 h) +{ + spin_lock(&dsi.update_lock); + if (dsi.update_region.dirty) { + dsi.update_region.x = min(x, dsi.update_region.x); + dsi.update_region.y = min(y, dsi.update_region.y); + dsi.update_region.w = max(w, dsi.update_region.w); + dsi.update_region.h = max(h, dsi.update_region.h); + } else { + dsi.update_region.x = x; + dsi.update_region.y = y; + dsi.update_region.w = w; + dsi.update_region.h = h; + } + + dsi.update_region.device = dssdev; + dsi.update_region.dirty = true; + + spin_unlock(&dsi.update_lock); + +} + +static void dsi_start_auto_update(struct omap_dss_device *dssdev) +{ + u16 w, h; + + DSSDBG("starting auto update\n"); + + /* In automatic mode the overlay settings are applied like on DPI/SDI. + * The overlay settings may not have been applied, if we were in manual + * mode earlier, so do it here */ + dssdev->manager->apply(dssdev->manager); + + dssdev->get_resolution(dssdev, &w, &h); + + dsi_set_update_region(dssdev, 0, 0, w, h); + + dsi_perf_mark_start_auto(); + + wake_up(&dsi.waitqueue); +} + +static int dsi_set_te(struct omap_dss_device *dssdev, bool enable) +{ + dssdev->driver->enable_te(dssdev, enable); + + if (!dsi.use_ext_te) { + if (enable) { + /* disable LP_RX_TO, so that we can receive TE. Time + * to wait for TE is longer than the timer allows */ + REG_FLD_MOD(DSI_TIMING2, 0, 15, 15); /* LP_RX_TO */ + } else { + REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */ + } + } + + return 0; +} + +static void dsi_handle_framedone(void) +{ + u32 l; + unsigned long tmo; + int i = 0; + + l = REG_GET(DSI_VC_TE(1), 23, 0); /* TE_SIZE */ + + /* We get FRAMEDONE when DISPC has finished sending pixels and turns + * itself off. However, DSI still has the pixels in its buffers, and is + * sending the data. Thus we have to wait until we can do a new + * transfer or turn the clocks off. There shouldn't be much stuff in + * DSI buffers, if any, so we'll just busyloop */ + if (l > 0) { + tmo = jiffies + msecs_to_jiffies(50); + while (REG_GET(DSI_VC_TE(1), 23, 0) > 0) { /* TE_SIZE */ + i++; + if (time_after(jiffies, tmo)) { + DSSERR("timeout waiting TE_SIZE to zero: %u\n", + REG_GET(DSI_VC_TE(1), 23, 0)); + break; + } + schedule(); + } + } + + if (REG_GET(DSI_VC_TE(1), 30, 30)) + DSSERR("TE_EN not zero\n"); + + if (REG_GET(DSI_VC_TE(1), 31, 31)) + DSSERR("TE_START not zero\n"); + + if (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL) + DSSDBG("FRAMEDONE\n"); + +#if 0 + if (l) + DSSWARN("FRAMEDONE irq too early, %d bytes, %d loops\n", l, i); +#else + if (l > 1024*3) + DSSWARN("FRAMEDONE irq too early, %d bytes, %d loops\n", l, i); +#endif + +#ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC + dispc_fake_vsync_irq(); +#endif + +static int dsi_update_thread(void *data) + { + unsigned long timeout; + struct omap_dss_device *device; + u16 x, y, w, h; + + while (1) { + bool sched; + + wait_event_interruptible(dsi.waitqueue, + dsi.update_mode == OMAP_DSS_UPDATE_AUTO || + (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL && + dsi.update_region.dirty == true) || + kthread_should_stop()); + + if (kthread_should_stop()) + break; + + dsi_bus_lock(); + + if (dsi.update_mode == OMAP_DSS_UPDATE_DISABLED || + kthread_should_stop()) { + dsi_bus_unlock(); + break; + } + + dsi_perf_mark_setup(); + + if (dsi.update_region.dirty) { + spin_lock(&dsi.update_lock); + dsi.active_update_region = dsi.update_region; + dsi.update_region.dirty = false; + spin_unlock(&dsi.update_lock); + } + + device = dsi.active_update_region.device; + x = dsi.active_update_region.x; + y = dsi.active_update_region.y; + w = dsi.active_update_region.w; + h = dsi.active_update_region.h; + + if (device->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { + + if (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL) { + dispc_setup_partial_planes(device, + &x, &y, &w, &h); +#if 1 + /* XXX there seems to be a bug in this driver + * or OMAP hardware. Some updates with certain + * widths and x coordinates fail. These widths + * are always odd, so "fix" it here for now */ + if (w & 1) { + u16 dw, dh; + device->get_resolution(device, + &dw, &dh); + if (x + w == dw) + x &= ~1; + ++w; + dispc_setup_partial_planes(device, + &x, &y, &w, &h); + } +#endif + } + + dispc_set_lcd_size(w, h); + } + + /* XXX We don't need to send the update area coords to the + * panel every time. But for some reason TE doesn't work if we + * don't send at least a BTA here... */ +#if 0 + if (dsi.active_update_region.dirty) { + dsi.active_update_region.dirty = false; + device->driver->setup_update(device, x, y, w, h); + } +#else + device->driver->setup_update(device, x, y, w, h); +#endif + + if (dsi.te_enabled && dsi.use_ext_te && device->wait_for_te) + device->wait_for_te(device); + + dsi_perf_mark_start(); + + if (device->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { + dsi_update_screen_dispc(device, x, y, w, h); + + /* wait for framedone */ + timeout = msecs_to_jiffies(500); + timeout = wait_event_timeout(dsi.waitqueue, + dsi.framedone_received == true, + timeout); + + dsi.framedone_received = false; + + if (timeout == 0) { + DSSERR("framedone timeout\n"); + DSSERR("failed update %d,%d %dx%d\n", + x, y, w, h); + + dispc_enable_sidle(); + dispc_enable_lcd_out(0); + } else { + dsi_handle_framedone(); + dsi_perf_show("DISPC"); + } + } else { + dsi_update_screen_l4(device, x, y, w, h); + dsi_perf_show("L4"); + } + + sched = atomic_read(&dsi.bus_lock.count) < 0; + + complete_all(&dsi.update_completion); + + dsi_bus_unlock(); + + /* XXX We need to give others chance to get the bus lock. Is + * there a better way for this? */ + if (dsi.update_mode == OMAP_DSS_UPDATE_AUTO && sched) + schedule_timeout_interruptible(1); + } + + DSSDBG("update thread exiting\n"); + + return 0; + } + + +/* Display funcs */ + +static int dsi_display_init_dispc(struct omap_dss_device *dssdev) +{ + int r; + + r = omap_dispc_register_isr(dsi_framedone_irq_callback, NULL, + DISPC_IRQ_FRAMEDONE); + if (r) { + DSSERR("can't get FRAMEDONE irq\n"); + return r; + } + + dispc_set_lcd_display_type(OMAP_DSS_LCD_DISPLAY_TFT); + + dispc_set_parallel_interface_mode(OMAP_DSS_PARALLELMODE_DSI); + dispc_enable_fifohandcheck(1); + + dispc_set_tft_data_lines(dssdev->ctrl.pixel_size); + + { + struct omap_video_timings timings = { + .hsw = 1, + .hfp = 1, + .hbp = 1, + .vsw = 1, + .vfp = 0, + .vbp = 0, + }; + + dispc_set_lcd_timings(&timings); + } + + return 0; +} + +static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev) +{ + omap_dispc_unregister_isr(dsi_framedone_irq_callback, NULL, + DISPC_IRQ_FRAMEDONE); +} + +static int dsi_display_init_dsi(struct omap_dss_device *dssdev) +{ + struct dsi_clock_info cinfo; + int r; + + _dsi_print_reset_status(); + + r = dsi_pll_init(1, 0); + if (r) + goto err0; + + r = dsi_pll_calc_ddrfreq(dssdev->phy.dsi.ddr_clk_hz, &cinfo); + if (r) + goto err1; + + r = dsi_pll_program(&cinfo); + if (r) + goto err1; + + DSSDBG("PLL OK\n"); + + r = dsi_complexio_init(dssdev); + if (r) + goto err1; + + _dsi_print_reset_status(); + + dsi_proto_timings(dssdev); + dsi_set_lp_clk_divisor(dssdev); + + if (1) + _dsi_print_reset_status(); + + r = dsi_proto_config(dssdev); + if (r) + goto err2; + + /* enable interface */ + dsi_vc_enable(0, 1); + dsi_vc_enable(1, 1); + dsi_if_enable(1); + dsi_force_tx_stop_mode_io(); + + if (dssdev->driver->enable) { + r = dssdev->driver->enable(dssdev); + if (r) + goto err3; + } + + /* enable high-speed after initial config */ + dsi_vc_enable_hs(0, 1); + + return 0; +err3: + dsi_if_enable(0); +err2: + dsi_complexio_uninit(); +err1: + dsi_pll_uninit(); +err0: + return r; +} + +static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev) +{ + if (dssdev->driver->disable) + dssdev->driver->disable(dssdev); + + dsi_complexio_uninit(); + dsi_pll_uninit(); +} + +static int dsi_core_init(void) +{ + /* Autoidle */ + REG_FLD_MOD(DSI_SYSCONFIG, 1, 0, 0); + + /* ENWAKEUP */ + REG_FLD_MOD(DSI_SYSCONFIG, 1, 2, 2); + + /* SIDLEMODE smart-idle */ + REG_FLD_MOD(DSI_SYSCONFIG, 2, 4, 3); + + _dsi_initialize_irq(); + + return 0; +} + +static int dsi_display_enable(struct omap_dss_device *dssdev) +{ + int r = 0; + + DSSDBG("dsi_display_enable\n"); + + mutex_lock(&dsi.lock); + dsi_bus_lock(); + + r = omap_dss_start_device(dssdev); + if (r) { + DSSERR("failed to start device\n"); + goto err0; + } + + if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { + DSSERR("dssdev already enabled\n"); + r = -EINVAL; + goto err1; + } + + enable_clocks(1); + dsi_enable_pll_clock(1); + + r = _dsi_reset(); + if (r) + goto err2; + + dsi_core_init(); + + r = dsi_display_init_dispc(dssdev); + if (r) + goto err2; + + r = dsi_display_init_dsi(dssdev); + if (r) + goto err3; + + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + + dsi.use_ext_te = dssdev->phy.dsi.ext_te; + dsi_set_te(dssdev, dsi.te_enabled); + + dsi.update_mode = dsi.user_update_mode; + if (dsi.update_mode == OMAP_DSS_UPDATE_AUTO) + dsi_start_auto_update(dssdev); + + dsi_bus_unlock(); + mutex_unlock(&dsi.lock); + + return 0; + +err3: + dsi_display_uninit_dispc(dssdev); +err2: + enable_clocks(0); + dsi_enable_pll_clock(0); +err1: + omap_dss_stop_device(dssdev); +err0: + dsi_bus_unlock(); + mutex_unlock(&dsi.lock); + DSSDBG("dsi_display_enable FAILED\n"); + return r; +} + +static void dsi_display_disable(struct omap_dss_device *dssdev) +{ + DSSDBG("dsi_display_disable\n"); + + mutex_lock(&dsi.lock); + dsi_bus_lock(); + + if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED || + dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) + goto end; + + dsi.update_mode = OMAP_DSS_UPDATE_DISABLED; + dssdev->state = OMAP_DSS_DISPLAY_DISABLED; + + dsi_display_uninit_dispc(dssdev); + + dsi_display_uninit_dsi(dssdev); + + enable_clocks(0); + dsi_enable_pll_clock(0); + + omap_dss_stop_device(dssdev); +end: + dsi_bus_unlock(); + mutex_unlock(&dsi.lock); +} + +static int dsi_display_suspend(struct omap_dss_device *dssdev) +{ + DSSDBG("dsi_display_suspend\n"); + + mutex_lock(&dsi.lock); + dsi_bus_lock(); + + if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED || + dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) + goto end; + + dsi.update_mode = OMAP_DSS_UPDATE_DISABLED; + dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; + + dsi_display_uninit_dispc(dssdev); + + dsi_display_uninit_dsi(dssdev); + + enable_clocks(0); + dsi_enable_pll_clock(0); +end: + dsi_bus_unlock(); + mutex_unlock(&dsi.lock); + + return 0; +} + +static int dsi_display_resume(struct omap_dss_device *dssdev) +{ + int r; + + DSSDBG("dsi_display_resume\n"); + + mutex_lock(&dsi.lock); + dsi_bus_lock(); + + if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) { + DSSERR("dssdev not suspended\n"); + r = -EINVAL; + goto err0; + } + + enable_clocks(1); + dsi_enable_pll_clock(1); + + r = _dsi_reset(); + if (r) + goto err1; + + dsi_core_init(); + + r = dsi_display_init_dispc(dssdev); + if (r) + goto err1; + + r = dsi_display_init_dsi(dssdev); + if (r) + goto err2; + + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + + dsi_set_te(dssdev, dsi.te_enabled); + + dsi.update_mode = dsi.user_update_mode; + if (dsi.update_mode == OMAP_DSS_UPDATE_AUTO) + dsi_start_auto_update(dssdev); + + dsi_bus_unlock(); + mutex_unlock(&dsi.lock); + + return 0; + +err2: + dsi_display_uninit_dispc(dssdev); +err1: + enable_clocks(0); + dsi_enable_pll_clock(0); +err0: + dsi_bus_unlock(); + mutex_unlock(&dsi.lock); + DSSDBG("dsi_display_resume FAILED\n"); + return r; +} + +static int dsi_display_update(struct omap_dss_device *dssdev, + u16 x, u16 y, u16 w, u16 h) +{ + int r = 0; + u16 dw, dh; + + DSSDBG("dsi_display_update(%d,%d %dx%d)\n", x, y, w, h); + + mutex_lock(&dsi.lock); + + if (dsi.update_mode != OMAP_DSS_UPDATE_MANUAL) + goto end; + + if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) + goto end; + + dssdev->get_resolution(dssdev, &dw, &dh); + + if (x > dw || y > dh) + goto end; + + if (x + w > dw) + w = dw - x; + + if (y + h > dh) + h = dh - y; + + if (w == 0 || h == 0) + goto end; + + dsi_set_update_region(dssdev, x, y, w, h); + + wake_up(&dsi.waitqueue); + +end: + mutex_unlock(&dsi.lock); + + return r; +} + +static int dsi_display_sync(struct omap_dss_device *dssdev) +{ + bool wait; + + DSSDBG("dsi_display_sync()\n"); + + mutex_lock(&dsi.lock); + dsi_bus_lock(); + + if (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL && + dsi.update_region.dirty) { + INIT_COMPLETION(dsi.update_completion); + wait = true; + } else { + wait = false; + } + + dsi_bus_unlock(); + mutex_unlock(&dsi.lock); + + if (wait) + wait_for_completion_interruptible(&dsi.update_completion); + + DSSDBG("dsi_display_sync() done\n"); + return 0; +} + +static int dsi_display_set_update_mode(struct omap_dss_device *dssdev, + enum omap_dss_update_mode mode) +{ + DSSDBGF("%d", mode); + + mutex_lock(&dsi.lock); + dsi_bus_lock(); + + if (dsi.update_mode != mode) { + dsi.user_update_mode = mode; + dsi.update_mode = mode; + + if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE && + mode == OMAP_DSS_UPDATE_AUTO) + dsi_start_auto_update(dssdev); + } + + dsi_bus_unlock(); + mutex_unlock(&dsi.lock); + + return 0; +} + +static enum omap_dss_update_mode dsi_display_get_update_mode( + struct omap_dss_device *dssdev) +{ + return dsi.update_mode; +} + + +static int dsi_display_enable_te(struct omap_dss_device *dssdev, bool enable) +{ + DSSDBGF("%d", enable); + + if (!dssdev->driver->enable_te) + return -ENOENT; + + dsi_bus_lock(); + + dsi.te_enabled = enable; + + if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) + goto end; + + dsi_set_te(dssdev, enable); +end: + dsi_bus_unlock(); + + return 0; +} + +static int dsi_display_get_te(struct omap_dss_device *dssdev) +{ + return dsi.te_enabled; +} + +static int dsi_display_set_rotate(struct omap_dss_device *dssdev, u8 rotate) +{ + + DSSDBGF("%d", rotate); + + if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate) + return -EINVAL; + + dsi_bus_lock(); + dssdev->driver->set_rotate(dssdev, rotate); + if (dsi.update_mode == OMAP_DSS_UPDATE_AUTO) { + u16 w, h; + /* the display dimensions may have changed, so set a new + * update region */ + dssdev->get_resolution(dssdev, &w, &h); + dsi_set_update_region(dssdev, 0, 0, w, h); + } + dsi_bus_unlock(); + + return 0; +} + +static u8 dsi_display_get_rotate(struct omap_dss_device *dssdev) +{ + if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate) + return 0; + + return dssdev->driver->get_rotate(dssdev); +} + +static int dsi_display_set_mirror(struct omap_dss_device *dssdev, bool mirror) +{ + DSSDBGF("%d", mirror); + + if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror) + return -EINVAL; + + dsi_bus_lock(); + dssdev->driver->set_mirror(dssdev, mirror); + dsi_bus_unlock(); + + return 0; +} + +static bool dsi_display_get_mirror(struct omap_dss_device *dssdev) +{ + if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror) + return 0; + + return dssdev->driver->get_mirror(dssdev); +} + +static int dsi_display_run_test(struct omap_dss_device *dssdev, int test_num) +{ + int r; + + if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) + return -EIO; + + DSSDBGF("%d", test_num); + + dsi_bus_lock(); + + /* run test first in low speed mode */ + dsi_vc_enable_hs(0, 0); + + if (dssdev->driver->run_test) { + r = dssdev->driver->run_test(dssdev, test_num); + if (r) + goto end; + } + + /* then in high speed */ + dsi_vc_enable_hs(0, 1); + + if (dssdev->driver->run_test) { + r = dssdev->driver->run_test(dssdev, test_num); + if (r) + goto end; + } + +end: + dsi_vc_enable_hs(0, 1); + + dsi_bus_unlock(); + + return r; +} + +static int dsi_display_memory_read(struct omap_dss_device *dssdev, + void *buf, size_t size, + u16 x, u16 y, u16 w, u16 h) +{ + int r; + + DSSDBGF(""); + + if (!dssdev->driver->memory_read) + return -EINVAL; + + if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) + return -EIO; + + dsi_bus_lock(); + + r = dssdev->driver->memory_read(dssdev, buf, size, + x, y, w, h); + + dsi_bus_unlock(); + + return r; +} + +void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, + u32 fifo_size, enum omap_burst_size *burst_size, + u32 *fifo_low, u32 *fifo_high) +{ + unsigned burst_size_bytes; + + *burst_size = OMAP_DSS_BURST_16x32; + burst_size_bytes = 16 * 32 / 8; + + *fifo_high = fifo_size - burst_size_bytes; + *fifo_low = 0; +} + +int dsi_init_display(struct omap_dss_device *dssdev) +{ + DSSDBG("DSI init\n"); + + dssdev->enable = dsi_display_enable; + dssdev->disable = dsi_display_disable; + dssdev->suspend = dsi_display_suspend; + dssdev->resume = dsi_display_resume; + dssdev->update = dsi_display_update; + dssdev->sync = dsi_display_sync; + dssdev->set_update_mode = dsi_display_set_update_mode; + dssdev->get_update_mode = dsi_display_get_update_mode; + dssdev->enable_te = dsi_display_enable_te; + dssdev->get_te = dsi_display_get_te; + + dssdev->get_rotate = dsi_display_get_rotate; + dssdev->set_rotate = dsi_display_set_rotate; + + dssdev->get_mirror = dsi_display_get_mirror; + dssdev->set_mirror = dsi_display_set_mirror; + + dssdev->run_test = dsi_display_run_test; + dssdev->memory_read = dsi_display_memory_read; + + dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; + + dsi.vc[0].dssdev = dssdev; + dsi.vc[1].dssdev = dssdev; + + return 0; +} + +int dsi_init(struct platform_device *pdev) +{ + u32 rev; + + spin_lock_init(&dsi.errors_lock); + dsi.errors = 0; + + /* XXX fail properly */ + + init_completion(&dsi.bta_completion); + init_completion(&dsi.update_completion); + + dsi.thread = kthread_create(dsi_update_thread, NULL, "dsi"); + if (IS_ERR(dsi.thread)) { + DSSERR("cannot create kthread\n"); + return PTR_ERR(dsi.thread); + } + init_waitqueue_head(&dsi.waitqueue); + spin_lock_init(&dsi.update_lock); + + mutex_init(&dsi.lock); + mutex_init(&dsi.bus_lock); + + dsi.update_mode = OMAP_DSS_UPDATE_DISABLED; + dsi.user_update_mode = OMAP_DSS_UPDATE_DISABLED; + + dsi.base = ioremap(DSI_BASE, DSI_SZ_REGS); + if (!dsi.base) { + DSSERR("can't ioremap DSI\n"); + return -ENOMEM; + } + + dsi.vdds_dsi_reg = regulator_get(&pdev->dev, "vdds_dsi"); + if (IS_ERR(dsi.vdds_dsi_reg)) { + iounmap(dsi.base); + DSSERR("can't get VDDS_DSI regulator\n"); + return PTR_ERR(dsi.vdds_dsi_reg); + } + + enable_clocks(1); + + rev = dsi_read_reg(DSI_REVISION); + printk(KERN_INFO "OMAP DSI rev %d.%d\n", + FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); + + enable_clocks(0); + + wake_up_process(dsi.thread); + + return 0; +} + +void dsi_exit(void) +{ + kthread_stop(dsi.thread); + + regulator_put(dsi.vdds_dsi_reg); + + iounmap(dsi.base); + + DSSDBG("omap_dsi_exit\n"); +} + diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c new file mode 100644 index 000000000000..db709bb254dc --- /dev/null +++ b/drivers/video/omap2/dss/dss.c @@ -0,0 +1,362 @@ +/* + * linux/drivers/video/omap2/dss/dss.c + * + * Copyright (C) 2009 Nokia Corporation + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> + * + * Some code and ideas taken from drivers/video/omap/ driver + * by Imre Deak. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#define DSS_SUBSYS_NAME "DSS" + +#include <linux/kernel.h> +#include <linux/io.h> +#include <linux/err.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/seq_file.h> + +#include <mach/display.h> +#include "dss.h" + +#ifndef CONFIG_ARCH_OMAP4 +/* DSS */ +#define DSS_BASE 0x48050000 +/* DISPLAY CONTROLLER */ +#define DISPC_BASE 0x48050400 +#else +/* DSS */ +#define DSS_BASE 0x48042000 +/* DISPLAY CONTROLLER */ +#define DISPC_BASE 0x48043000 +#endif + +#define DSS_SZ_REGS SZ_512 + +struct dss_reg { + u16 idx; +}; + +#define DSS_REG(idx) ((const struct dss_reg) { idx }) + +#define DSS_REVISION DSS_REG(0x0000) +#define DSS_SYSCONFIG DSS_REG(0x0010) +#define DSS_SYSSTATUS DSS_REG(0x0014) +#define DSS_IRQSTATUS DSS_REG(0x0018) +#define DSS_CONTROL DSS_REG(0x0040) +#define DSS_SDI_CONTROL DSS_REG(0x0044) +#define DSS_PLL_CONTROL DSS_REG(0x0048) +#define DSS_SDI_STATUS DSS_REG(0x005C) + +#define REG_GET(idx, start, end) \ + FLD_GET(dss_read_reg(idx), start, end) + +#define REG_FLD_MOD(idx, val, start, end) \ + dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end)) + +static struct { + void __iomem *base; + + u32 ctx[DSS_SZ_REGS / sizeof(u32)]; +} dss; + +static int _omap_dss_wait_reset(void); + +static inline void dss_write_reg(const struct dss_reg idx, u32 val) +{ + __raw_writel(val, dss.base + idx.idx); +} + +static inline u32 dss_read_reg(const struct dss_reg idx) +{ + return __raw_readl(dss.base + idx.idx); +} + +#define SR(reg) \ + dss.ctx[(DSS_##reg).idx / sizeof(u32)] = dss_read_reg(DSS_##reg) +#define RR(reg) \ + dss_write_reg(DSS_##reg, dss.ctx[(DSS_##reg).idx / sizeof(u32)]) + +void dss_save_context(void) +{ + if (cpu_is_omap24xx()) + return; + + SR(SYSCONFIG); + SR(CONTROL); + +#ifdef CONFIG_OMAP2_DSS_SDI + SR(SDI_CONTROL); + SR(PLL_CONTROL); +#endif +} + +void dss_restore_context(void) +{ + if (_omap_dss_wait_reset()) + DSSERR("DSS not coming out of reset after sleep\n"); + + RR(SYSCONFIG); + RR(CONTROL); + +#ifdef CONFIG_OMAP2_DSS_SDI + RR(SDI_CONTROL); + RR(PLL_CONTROL); +#endif +} + +#undef SR +#undef RR + +void dss_sdi_init(u8 datapairs) +{ + u32 l; + + BUG_ON(datapairs > 3 || datapairs < 1); + + l = dss_read_reg(DSS_SDI_CONTROL); + l = FLD_MOD(l, 0xf, 19, 15); /* SDI_PDIV */ + l = FLD_MOD(l, datapairs-1, 3, 2); /* SDI_PRSEL */ + l = FLD_MOD(l, 2, 1, 0); /* SDI_BWSEL */ + dss_write_reg(DSS_SDI_CONTROL, l); + + l = dss_read_reg(DSS_PLL_CONTROL); + l = FLD_MOD(l, 0x7, 25, 22); /* SDI_PLL_FREQSEL */ + l = FLD_MOD(l, 0xb, 16, 11); /* SDI_PLL_REGN */ + l = FLD_MOD(l, 0xb4, 10, 1); /* SDI_PLL_REGM */ + dss_write_reg(DSS_PLL_CONTROL, l); +} + +void dss_sdi_enable(void) +{ + dispc_pck_free_enable(1); + + /* Reset SDI PLL */ + REG_FLD_MOD(DSS_PLL_CONTROL, 1, 18, 18); /* SDI_PLL_SYSRESET */ + udelay(1); /* wait 2x PCLK */ + + /* Lock SDI PLL */ + REG_FLD_MOD(DSS_PLL_CONTROL, 1, 28, 28); /* SDI_PLL_GOBIT */ + + /* Waiting for PLL lock request to complete */ + while (dss_read_reg(DSS_SDI_STATUS) & (1 << 6)) + ; + + /* Clearing PLL_GO bit */ + REG_FLD_MOD(DSS_PLL_CONTROL, 0, 28, 28); + + /* Waiting for PLL to lock */ + while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 5))) + ; + + dispc_lcd_enable_signal(1); + + /* Waiting for SDI reset to complete */ + while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 2))) + ; +} + +void dss_sdi_disable(void) +{ + dispc_lcd_enable_signal(0); + + dispc_pck_free_enable(0); + + /* Reset SDI PLL */ + REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */ +} + +void dss_dump_regs(struct seq_file *s) +{ +#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r)) + + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + + DUMPREG(DSS_REVISION); + DUMPREG(DSS_SYSCONFIG); + DUMPREG(DSS_SYSSTATUS); + DUMPREG(DSS_IRQSTATUS); + DUMPREG(DSS_CONTROL); + DUMPREG(DSS_SDI_CONTROL); + DUMPREG(DSS_PLL_CONTROL); + DUMPREG(DSS_SDI_STATUS); + + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); +#undef DUMPREG +} + +void dss_select_clk_source(bool dsi, bool dispc) +{ + u32 r; + r = dss_read_reg(DSS_CONTROL); + r = FLD_MOD(r, dsi, 1, 1); /* DSI_CLK_SWITCH */ + r = FLD_MOD(r, dispc, 0, 0); /* DISPC_CLK_SWITCH */ + dss_write_reg(DSS_CONTROL, r); +} + +int dss_get_dsi_clk_source(void) +{ + return FLD_GET(dss_read_reg(DSS_CONTROL), 1, 1); +} + +int dss_get_dispc_clk_source(void) +{ + return FLD_GET(dss_read_reg(DSS_CONTROL), 0, 0); +} + +static irqreturn_t dss_irq_handler_omap2(int irq, void *arg) +{ + dispc_irq_handler(); + + return IRQ_HANDLED; +} + +static irqreturn_t dss_irq_handler_omap3(int irq, void *arg) +{ + u32 irqstatus; + + irqstatus = dss_read_reg(DSS_IRQSTATUS); + + if (irqstatus & (1<<0)) /* DISPC_IRQ */ + dispc_irq_handler(); +#ifdef CONFIG_OMAP2_DSS_DSI + if (irqstatus & (1<<1)) /* DSI_IRQ */ + dsi_irq_handler(); +#endif + + return IRQ_HANDLED; +} + +static int _omap_dss_wait_reset(void) +{ + unsigned timeout = 1000; + + while (REG_GET(DSS_SYSSTATUS, 0, 0) == 0) { + udelay(1); + if (!--timeout) { + DSSERR("soft reset failed\n"); + return -ENODEV; + } + } + + return 0; +} + +static int _omap_dss_reset(void) +{ + /* Soft reset */ + REG_FLD_MOD(DSS_SYSCONFIG, 1, 1, 1); + return _omap_dss_wait_reset(); +} + +void dss_set_venc_output(enum omap_dss_venc_type type) +{ + int l = 0; + + if (type == OMAP_DSS_VENC_TYPE_COMPOSITE) + l = 0; + else if (type == OMAP_DSS_VENC_TYPE_SVIDEO) + l = 1; + else + BUG(); + + /* venc out selection. 0 = comp, 1 = svideo */ + REG_FLD_MOD(DSS_CONTROL, l, 6, 6); +} + +void dss_set_dac_pwrdn_bgz(bool enable) +{ + REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */ +} + +int dss_init(bool skip_init) +{ + int r; + u32 rev; + + dss.base = ioremap(DSS_BASE, DSS_SZ_REGS); + if (!dss.base) { + DSSERR("can't ioremap DSS\n"); + r = -ENOMEM; + goto fail0; + } + + if (!skip_init) { + /* disable LCD and DIGIT output. This seems to fix the synclost + * problem that we get, if the bootloader starts the DSS and + * the kernel resets it */ + omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440); + + /* We need to wait here a bit, otherwise we sometimes start to + * get synclost errors, and after that only power cycle will + * restore DSS functionality. I have no idea why this happens. + * And we have to wait _before_ resetting the DSS, but after + * enabling clocks. + */ + msleep(50); + + _omap_dss_reset(); + } + + /* autoidle */ + REG_FLD_MOD(DSS_SYSCONFIG, 1, 0, 0); + + /* Select DPLL */ + REG_FLD_MOD(DSS_CONTROL, 0, 0, 0); + +#ifdef CONFIG_OMAP2_DSS_VENC + REG_FLD_MOD(DSS_CONTROL, 1, 4, 4); /* venc dac demen */ + REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */ + REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */ +#endif + +#ifndef CONFIG_ARCH_OMAP4 + r = request_irq(INT_24XX_DSS_IRQ, + cpu_is_omap24xx() + ? dss_irq_handler_omap2 + : dss_irq_handler_omap3, + 0, "OMAP DSS", NULL); +#else + r = request_irq(INT_44XX_DSS_IRQ, + dss_irq_handler_omap3, + 0, "OMAP DSS", (void *)1); +#endif + if (r < 0) { + DSSERR("omap2 dss: request_irq failed\n"); + goto fail1; + } + + dss_save_context(); + + rev = dss_read_reg(DSS_REVISION); + printk(KERN_INFO "OMAP DSS rev %d.%d\n", + FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); + + return 0; + +fail1: + iounmap(dss.base); +fail0: + return r; +} + +void dss_exit(void) +{ + free_irq(INT_24XX_DSS_IRQ, NULL); + + iounmap(dss.base); +} + diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h new file mode 100644 index 000000000000..506a4b6842a1 --- /dev/null +++ b/drivers/video/omap2/dss/dss.h @@ -0,0 +1,359 @@ +/* + * linux/drivers/video/omap2/dss/dss.h + * + * Copyright (C) 2009 Nokia Corporation + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> + * + * Some code and ideas taken from drivers/video/omap/ driver + * by Imre Deak. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __OMAP2_DSS_H +#define __OMAP2_DSS_H + +#ifdef CONFIG_OMAP2_DSS_DEBUG_SUPPORT +#define DEBUG +#endif + +#ifdef DEBUG +extern unsigned int dss_debug; +#ifdef DSS_SUBSYS_NAME +#define DSSDBG(format, ...) \ + if (dss_debug) \ + printk(KERN_DEBUG "omapdss " DSS_SUBSYS_NAME ": " format, \ + ## __VA_ARGS__) +#else +#define DSSDBG(format, ...) \ + if (dss_debug) \ + printk(KERN_DEBUG "omapdss: " format, ## __VA_ARGS__) +#endif + +#ifdef DSS_SUBSYS_NAME +#define DSSDBGF(format, ...) \ + if (dss_debug) \ + printk(KERN_DEBUG "omapdss " DSS_SUBSYS_NAME \ + ": %s(" format ")\n", \ + __func__, \ + ## __VA_ARGS__) +#else +#define DSSDBGF(format, ...) \ + if (dss_debug) \ + printk(KERN_DEBUG "omapdss: " \ + ": %s(" format ")\n", \ + __func__, \ + ## __VA_ARGS__) +#endif + +#else /* DEBUG */ +#define DSSDBG(format, ...) +#define DSSDBGF(format, ...) +#endif + + +#ifdef DSS_SUBSYS_NAME +#define DSSERR(format, ...) \ + printk(KERN_ERR "omapdss " DSS_SUBSYS_NAME " error: " format, \ + ## __VA_ARGS__) +#else +#define DSSERR(format, ...) \ + printk(KERN_ERR "omapdss error: " format, ## __VA_ARGS__) +#endif + +#ifdef DSS_SUBSYS_NAME +#define DSSINFO(format, ...) \ + printk(KERN_INFO "omapdss " DSS_SUBSYS_NAME ": " format, \ + ## __VA_ARGS__) +#else +#define DSSINFO(format, ...) \ + printk(KERN_INFO "omapdss: " format, ## __VA_ARGS__) +#endif + +#ifdef DSS_SUBSYS_NAME +#define DSSWARN(format, ...) \ + printk(KERN_WARNING "omapdss " DSS_SUBSYS_NAME ": " format, \ + ## __VA_ARGS__) +#else +#define DSSWARN(format, ...) \ + printk(KERN_WARNING "omapdss: " format, ## __VA_ARGS__) +#endif + +/* OMAP TRM gives bitfields as start:end, where start is the higher bit + number. For example 7:0 */ +#define FLD_MASK(start, end) (((1 << (start - end + 1)) - 1) << (end)) +#define FLD_VAL(val, start, end) (((val) << end) & FLD_MASK(start, end)) +#define FLD_GET(val, start, end) (((val) & FLD_MASK(start, end)) >> (end)) +#define FLD_MOD(orig, val, start, end) \ + (((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end)) + +#define DISPC_MAX_FCK 173000000 + +enum omap_burst_size { + OMAP_DSS_BURST_4x32 = 0, + OMAP_DSS_BURST_8x32 = 1, + OMAP_DSS_BURST_16x32 = 2, +}; + +enum omap_parallel_interface_mode { + OMAP_DSS_PARALLELMODE_BYPASS, /* MIPI DPI */ + OMAP_DSS_PARALLELMODE_RFBI, /* MIPI DBI */ + OMAP_DSS_PARALLELMODE_DSI, +}; + +enum dss_clock { + DSS_CLK_ICK = 1 << 0, + DSS_CLK_FCK1 = 1 << 1, + DSS_CLK_FCK2 = 1 << 2, + DSS_CLK_54M = 1 << 3, + DSS_CLK_96M = 1 << 4, +}; + +struct dispc_clock_info { + /* rates that we get with dividers below */ + unsigned long fck; + unsigned long lck; + unsigned long pck; + + /* dividers */ + u16 fck_div; + u16 lck_div; + u16 pck_div; +}; + +struct dsi_clock_info { + /* rates that we get with dividers below */ + unsigned long fint; + unsigned long dsiphy; + unsigned long clkin; + unsigned long dsi1_pll_fclk; + unsigned long dsi2_pll_fclk; + unsigned long lck; + unsigned long pck; + + /* dividers */ + u16 regn; + u16 regm; + u16 regm3; + u16 regm4; + + u16 lck_div; + u16 pck_div; + + u8 highfreq; + bool use_dss2_fck; +}; + +struct seq_file; +struct platform_device; + +/* core */ +void dss_clk_enable(enum dss_clock clks); +void dss_clk_disable(enum dss_clock clks); +unsigned long dss_clk_get_rate(enum dss_clock clk); +int dss_need_ctx_restore(void); +void dss_dump_clocks(struct seq_file *s); +struct bus_type *dss_get_bus(void); + +/* display */ +int dss_suspend_all_devices(void); +int dss_resume_all_devices(void); + +void dss_init_device(struct platform_device *pdev, + struct omap_dss_device *dssdev); +void dss_uninit_device(struct platform_device *pdev, + struct omap_dss_device *dssdev); +bool dss_use_replication(struct omap_dss_device *dssdev, + enum omap_color_mode mode); +int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl); +void dss_setup_partial_planes(struct omap_dss_device *dssdev, + u16 *x, u16 *y, u16 *w, u16 *h); +void dss_start_update(struct omap_dss_device *dssdev); +void default_get_overlay_fifo_thresholds(enum omap_plane plane, + u32 fifo_size, enum omap_burst_size *burst_size, + u32 *fifo_low, u32 *fifo_high); + +/* manager */ +int dss_init_overlay_managers(struct platform_device *pdev); +void dss_uninit_overlay_managers(struct platform_device *pdev); +int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl); +void dss_setup_partial_planes(struct omap_dss_device *dssdev, + u16 *x, u16 *y, u16 *w, u16 *h); +void dss_start_update(struct omap_dss_device *dssdev); + +/* overlay */ +void dss_init_overlays(struct platform_device *pdev); +void dss_uninit_overlays(struct platform_device *pdev); +int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev); +void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr); +#ifdef L4_EXAMPLE +void dss_overlay_setup_l4_manager(struct omap_overlay_manager *mgr); +#endif +void dss_recheck_connections(struct omap_dss_device *dssdev, bool force); + +/* DSS */ +int dss_init(bool skip_init); +void dss_exit(void); + +void dss_save_context(void); +void dss_restore_context(void); + +void dss_dump_regs(struct seq_file *s); + +void dss_sdi_init(u8 datapairs); +void dss_sdi_enable(void); +void dss_sdi_disable(void); + +void dss_select_clk_source(bool dsi, bool dispc); +int dss_get_dsi_clk_source(void); +int dss_get_dispc_clk_source(void); +void dss_set_venc_output(enum omap_dss_venc_type type); +void dss_set_dac_pwrdn_bgz(bool enable); + +/* SDI */ +int sdi_init(bool skip_init); +void sdi_exit(void); +int sdi_init_display(struct omap_dss_device *display); + +/* DSI */ +int dsi_init(struct platform_device *pdev); +void dsi_exit(void); + +void dsi_dump_clocks(struct seq_file *s); +void dsi_dump_regs(struct seq_file *s); + +void dsi_save_context(void); +void dsi_restore_context(void); + +int dsi_init_display(struct omap_dss_device *display); +void dsi_irq_handler(void); +unsigned long dsi_get_dsi1_pll_rate(void); +unsigned long dsi_get_dsi2_pll_rate(void); +int dsi_pll_calc_pck(bool is_tft, unsigned long req_pck, + struct dsi_clock_info *cinfo); +int dsi_pll_program(struct dsi_clock_info *cinfo); +int dsi_pll_init(bool enable_hsclk, bool enable_hsdiv); +void dsi_pll_uninit(void); +void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, + u32 fifo_size, enum omap_burst_size *burst_size, + u32 *fifo_low, u32 *fifo_high); + +/* DPI */ +int dpi_init(void); +void dpi_exit(void); +int dpi_init_display(struct omap_dss_device *dssdev); + +/* DISPC */ +int dispc_init(void); +void dispc_exit(void); +void dispc_dump_clocks(struct seq_file *s); +void dispc_dump_regs(struct seq_file *s); +void dispc_irq_handler(void); +void dispc_fake_vsync_irq(void); + +void dispc_save_context(void); +void dispc_restore_context(void); + +void dispc_enable_sidle(void); +void dispc_disable_sidle(void); + +void dispc_lcd_enable_signal_polarity(bool act_high); +void dispc_lcd_enable_signal(bool enable); +void dispc_pck_free_enable(bool enable); +void dispc_enable_fifohandcheck(bool enable); + +void dispc_set_lcd_size(u16 width, u16 height); +void dispc_set_digit_size(u16 width, u16 height); +u32 dispc_get_plane_fifo_size(enum omap_plane plane); +void dispc_setup_plane_fifo(enum omap_plane plane, u32 low, u32 high); +void dispc_enable_fifomerge(bool enable); +void dispc_set_burst_size(enum omap_plane plane, + enum omap_burst_size burst_size); + +void dispc_set_plane_ba0(enum omap_plane plane, u32 paddr); +void dispc_set_plane_ba1(enum omap_plane plane, u32 paddr); +void dispc_set_plane_pos(enum omap_plane plane, u16 x, u16 y); +void dispc_set_plane_size(enum omap_plane plane, u16 width, u16 height); +void dispc_set_channel_out(enum omap_plane plane, + enum omap_channel channel_out); + +int dispc_setup_plane(enum omap_plane plane, + u32 paddr, u16 screen_width, + u16 pos_x, u16 pos_y, + u16 width, u16 height, + u16 out_width, u16 out_height, + enum omap_color_mode color_mode, + bool ilace, + enum omap_dss_rotation_type rotation_type, + u8 rotation, bool mirror, + u8 global_alpha); + +bool dispc_go_busy(enum omap_channel channel); +void dispc_go(enum omap_channel channel); +void dispc_enable_lcd_out(bool enable); +void dispc_enable_digit_out(bool enable); +int dispc_enable_plane(enum omap_plane plane, bool enable); +void dispc_enable_replication(enum omap_plane plane, bool enable); + +void dispc_set_parallel_interface_mode(enum omap_parallel_interface_mode mode); +void dispc_set_tft_data_lines(u8 data_lines); +void dispc_set_lcd_display_type(enum omap_lcd_display_type type); +void dispc_set_loadmode(enum omap_dss_load_mode mode); + +void dispc_set_default_color(enum omap_channel channel, u32 color); +u32 dispc_get_default_color(enum omap_channel channel); +void dispc_set_trans_key(enum omap_channel ch, + enum omap_dss_trans_key_type type, + u32 trans_key); +void dispc_get_trans_key(enum omap_channel ch, + enum omap_dss_trans_key_type *type, + u32 *trans_key); +void dispc_enable_trans_key(enum omap_channel ch, bool enable); +void dispc_enable_alpha_blending(enum omap_channel ch, bool enable); +bool dispc_trans_key_enabled(enum omap_channel ch); +bool dispc_alpha_blending_enabled(enum omap_channel ch); + +bool dispc_lcd_timings_ok(struct omap_video_timings *timings); +void dispc_set_lcd_timings(struct omap_video_timings *timings); +unsigned long dispc_fclk_rate(void); +unsigned long dispc_lclk_rate(void); +unsigned long dispc_pclk_rate(void); +void dispc_set_pol_freq(enum omap_panel_config config, u8 acbi, u8 acb); +void find_lck_pck_divs(bool is_tft, unsigned long req_pck, unsigned long fck, + u16 *lck_div, u16 *pck_div); +int dispc_calc_clock_div(bool is_tft, unsigned long req_pck, + struct dispc_clock_info *cinfo); +int dispc_set_clock_div(struct dispc_clock_info *cinfo); +int dispc_get_clock_div(struct dispc_clock_info *cinfo); +void dispc_set_lcd_divisor(u16 lck_div, u16 pck_div); + +/* VENC */ +int venc_init(struct platform_device *pdev); +void venc_exit(void); +void venc_dump_regs(struct seq_file *s); +int venc_init_display(struct omap_dss_device *display); + +/* RFBI */ +int rfbi_init(void); +void rfbi_exit(void); +void rfbi_dump_regs(struct seq_file *s); + +int rfbi_configure(int rfbi_module, int bpp, int lines); +void rfbi_enable_rfbi(bool enable); +void rfbi_transfer_area(u16 width, u16 height, + void (callback)(void *data), void *data); +void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t); +unsigned long rfbi_get_max_tx_rate(void); +int rfbi_init_display(struct omap_dss_device *display); + +#endif diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c new file mode 100644 index 000000000000..ceba2916bf6e --- /dev/null +++ b/drivers/video/omap2/dss/manager.c @@ -0,0 +1,1479 @@ +/* + * linux/drivers/video/omap2/dss/manager.c + * + * Copyright (C) 2009 Nokia Corporation + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> + * + * Some code and ideas taken from drivers/video/omap/ driver + * by Imre Deak. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#define DSS_SUBSYS_NAME "MANAGER" + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/spinlock.h> +#include <linux/jiffies.h> + +#include <mach/display.h> +#include <mach/cpu.h> + +#include "dss.h" + +static int num_managers; +static struct list_head manager_list; + +static ssize_t manager_name_show(struct omap_overlay_manager *mgr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%s\n", mgr->name); +} + +static ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%s\n", + mgr->device ? mgr->device->name : "<none>"); +} + +static ssize_t manager_display_store(struct omap_overlay_manager *mgr, + const char *buf, size_t size) +{ + int r = 0; + size_t len = size; + struct omap_dss_device *dssdev = NULL; + + int match(struct omap_dss_device *dssdev, void *data) + { + const char *str = data; + return sysfs_streq(dssdev->name, str); + } + + if (buf[size-1] == '\n') + --len; + + if (len > 0) + dssdev = omap_dss_find_device((void *)buf, match); + + if (len > 0 && dssdev == NULL) + return -EINVAL; + + if (dssdev) + DSSDBG("display %s found\n", dssdev->name); + + if (mgr->device) { + r = mgr->unset_device(mgr); + if (r) { + DSSERR("failed to unset display\n"); + goto put_device; + } + } + + if (dssdev) { + r = mgr->set_device(mgr, dssdev); + if (r) { + DSSERR("failed to set manager\n"); + goto put_device; + } + + r = mgr->apply(mgr); + if (r) { + DSSERR("failed to apply dispc config\n"); + goto put_device; + } + } + +put_device: + if (dssdev) + omap_dss_put_device(dssdev); + + return r ? r : size; +} + +static ssize_t manager_default_color_show(struct omap_overlay_manager *mgr, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", mgr->info.default_color); +} + +static ssize_t manager_default_color_store(struct omap_overlay_manager *mgr, + const char *buf, size_t size) +{ + struct omap_overlay_manager_info info; + u32 color; + int r; + + if (sscanf(buf, "%d", &color) != 1) + return -EINVAL; + + mgr->get_manager_info(mgr, &info); + + info.default_color = color; + + r = mgr->set_manager_info(mgr, &info); + if (r) + return r; + + r = mgr->apply(mgr); + if (r) + return r; + + return size; +} + +static const char *trans_key_type_str[] = { + "gfx-destination", + "video-source", +}; + +static ssize_t manager_trans_key_type_show(struct omap_overlay_manager *mgr, + char *buf) +{ + enum omap_dss_trans_key_type key_type; + + key_type = mgr->info.trans_key_type; + BUG_ON(key_type >= ARRAY_SIZE(trans_key_type_str)); + + return snprintf(buf, PAGE_SIZE, "%s\n", trans_key_type_str[key_type]); +} + +static ssize_t manager_trans_key_type_store(struct omap_overlay_manager *mgr, + const char *buf, size_t size) +{ + enum omap_dss_trans_key_type key_type; + struct omap_overlay_manager_info info; + int r; + + for (key_type = OMAP_DSS_COLOR_KEY_GFX_DST; + key_type < ARRAY_SIZE(trans_key_type_str); key_type++) { + if (sysfs_streq(buf, trans_key_type_str[key_type])) + break; + } + + if (key_type == ARRAY_SIZE(trans_key_type_str)) + return -EINVAL; + + mgr->get_manager_info(mgr, &info); + + info.trans_key_type = key_type; + + r = mgr->set_manager_info(mgr, &info); + if (r) + return r; + + r = mgr->apply(mgr); + if (r) + return r; + + return size; +} + +static ssize_t manager_trans_key_value_show(struct omap_overlay_manager *mgr, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", mgr->info.trans_key); +} + +static ssize_t manager_trans_key_value_store(struct omap_overlay_manager *mgr, + const char *buf, size_t size) +{ + struct omap_overlay_manager_info info; + u32 key_value; + int r; + + if (sscanf(buf, "%d", &key_value) != 1) + return -EINVAL; + + mgr->get_manager_info(mgr, &info); + + info.trans_key = key_value; + + r = mgr->set_manager_info(mgr, &info); + if (r) + return r; + + r = mgr->apply(mgr); + if (r) + return r; + + return size; +} + +static ssize_t manager_trans_key_enabled_show(struct omap_overlay_manager *mgr, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", mgr->info.trans_enabled); +} + +static ssize_t manager_trans_key_enabled_store(struct omap_overlay_manager *mgr, + const char *buf, size_t size) +{ + struct omap_overlay_manager_info info; + int enable; + int r; + + if (sscanf(buf, "%d", &enable) != 1) + return -EINVAL; + + mgr->get_manager_info(mgr, &info); + + info.trans_enabled = enable ? true : false; + + r = mgr->set_manager_info(mgr, &info); + if (r) + return r; + + r = mgr->apply(mgr); + if (r) + return r; + + return size; +} + +static ssize_t manager_alpha_blending_enabled_show( + struct omap_overlay_manager *mgr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", mgr->info.alpha_enabled); +} + +static ssize_t manager_alpha_blending_enabled_store( + struct omap_overlay_manager *mgr, + const char *buf, size_t size) +{ + struct omap_overlay_manager_info info; + int enable; + int r; + + if (sscanf(buf, "%d", &enable) != 1) + return -EINVAL; + + mgr->get_manager_info(mgr, &info); + + info.alpha_enabled = enable ? true : false; + + r = mgr->set_manager_info(mgr, &info); + if (r) + return r; + + r = mgr->apply(mgr); + if (r) + return r; + + return size; +} + +struct manager_attribute { + struct attribute attr; + ssize_t (*show)(struct omap_overlay_manager *, char *); + ssize_t (*store)(struct omap_overlay_manager *, const char *, size_t); +}; + +#define MANAGER_ATTR(_name, _mode, _show, _store) \ + struct manager_attribute manager_attr_##_name = \ + __ATTR(_name, _mode, _show, _store) + +static MANAGER_ATTR(name, S_IRUGO, manager_name_show, NULL); +static MANAGER_ATTR(display, S_IRUGO|S_IWUSR, + manager_display_show, manager_display_store); +static MANAGER_ATTR(default_color, S_IRUGO|S_IWUSR, + manager_default_color_show, manager_default_color_store); +static MANAGER_ATTR(trans_key_type, S_IRUGO|S_IWUSR, + manager_trans_key_type_show, manager_trans_key_type_store); +static MANAGER_ATTR(trans_key_value, S_IRUGO|S_IWUSR, + manager_trans_key_value_show, manager_trans_key_value_store); +static MANAGER_ATTR(trans_key_enabled, S_IRUGO|S_IWUSR, + manager_trans_key_enabled_show, + manager_trans_key_enabled_store); +static MANAGER_ATTR(alpha_blending_enabled, S_IRUGO|S_IWUSR, + manager_alpha_blending_enabled_show, + manager_alpha_blending_enabled_store); + + +static struct attribute *manager_sysfs_attrs[] = { + &manager_attr_name.attr, + &manager_attr_display.attr, + &manager_attr_default_color.attr, + &manager_attr_trans_key_type.attr, + &manager_attr_trans_key_value.attr, + &manager_attr_trans_key_enabled.attr, + &manager_attr_alpha_blending_enabled.attr, + NULL +}; + +static ssize_t manager_attr_show(struct kobject *kobj, struct attribute *attr, + char *buf) +{ + struct omap_overlay_manager *manager; + struct manager_attribute *manager_attr; + + manager = container_of(kobj, struct omap_overlay_manager, kobj); + manager_attr = container_of(attr, struct manager_attribute, attr); + + if (!manager_attr->show) + return -ENOENT; + + return manager_attr->show(manager, buf); +} + +static ssize_t manager_attr_store(struct kobject *kobj, struct attribute *attr, + const char *buf, size_t size) +{ + struct omap_overlay_manager *manager; + struct manager_attribute *manager_attr; + + manager = container_of(kobj, struct omap_overlay_manager, kobj); + manager_attr = container_of(attr, struct manager_attribute, attr); + + if (!manager_attr->store) + return -ENOENT; + + return manager_attr->store(manager, buf, size); +} + +static struct sysfs_ops manager_sysfs_ops = { + .show = manager_attr_show, + .store = manager_attr_store, +}; + +static struct kobj_type manager_ktype = { + .sysfs_ops = &manager_sysfs_ops, + .default_attrs = manager_sysfs_attrs, +}; + +/* + * We have 4 levels of cache for the dispc settings. First two are in SW and + * the latter two in HW. + * + * +--------------------+ + * |overlay/manager_info| + * +--------------------+ + * v + * apply() + * v + * +--------------------+ + * | dss_cache | + * +--------------------+ + * v + * configure() + * v + * +--------------------+ + * | shadow registers | + * +--------------------+ + * v + * VFP or lcd/digit_enable + * v + * +--------------------+ + * | registers | + * +--------------------+ + */ + +struct overlay_cache_data { + /* If true, cache changed, but not written to shadow registers. Set + * in apply(), cleared when registers written. */ + bool dirty; + /* If true, shadow registers contain changed values not yet in real + * registers. Set when writing to shadow registers, cleared at + * VSYNC/EVSYNC */ + bool shadow_dirty; + + bool enabled; + + u32 paddr; + void __iomem *vaddr; + u16 screen_width; + u16 width; + u16 height; + enum omap_color_mode color_mode; + u8 rotation; + enum omap_dss_rotation_type rotation_type; + bool mirror; + + u16 pos_x; + u16 pos_y; + u16 out_width; /* if 0, out_width == width */ + u16 out_height; /* if 0, out_height == height */ + u8 global_alpha; + + enum omap_channel channel; + bool replication; + bool ilace; + + enum omap_burst_size burst_size; + u32 fifo_low; + u32 fifo_high; + + bool manual_update; +}; + +struct manager_cache_data { + /* If true, cache changed, but not written to shadow registers. Set + * in apply(), cleared when registers written. */ + bool dirty; + /* If true, shadow registers contain changed values not yet in real + * registers. Set when writing to shadow registers, cleared at + * VSYNC/EVSYNC */ + bool shadow_dirty; + + u32 default_color; + + enum omap_dss_trans_key_type trans_key_type; + u32 trans_key; + bool trans_enabled; + + bool alpha_enabled; + + bool manual_upd_display; + bool manual_update; + bool do_manual_update; + + /* manual update region */ + u16 x, y, w, h; +}; + +static struct { + spinlock_t lock; + struct overlay_cache_data overlay_cache[3]; + struct manager_cache_data manager_cache[2]; + + bool irq_enabled; +} dss_cache; + +static int omap_dss_set_device(struct omap_overlay_manager *mgr, + struct omap_dss_device *dssdev) +{ + int i; + int r; + + if (dssdev->manager) { + DSSERR("display '%s' already has a manager '%s'\n", + dssdev->name, dssdev->manager->name); + return -EINVAL; + } + + if ((mgr->supported_displays & dssdev->type) == 0) { + DSSERR("display '%s' does not support manager '%s'\n", + dssdev->name, mgr->name); + return -EINVAL; + } + + for (i = 0; i < mgr->num_overlays; i++) { + struct omap_overlay *ovl = mgr->overlays[i]; + + if (ovl->manager != mgr || !ovl->info.enabled) + continue; + + r = dss_check_overlay(ovl, dssdev); + if (r) + return r; + } + + dssdev->manager = mgr; + mgr->device = dssdev; + mgr->device_changed = true; + + return 0; +} + +static int omap_dss_unset_device(struct omap_overlay_manager *mgr) +{ + if (!mgr->device) { + DSSERR("failed to unset display, display not set.\n"); + return -EINVAL; + } + + mgr->device->manager = NULL; + mgr->device = NULL; + mgr->device_changed = true; + + return 0; +} + +static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) +{ + unsigned long timeout = msecs_to_jiffies(500); + struct manager_cache_data *mc; + enum omap_channel channel; + u32 irq; + int r; + int i; + + if (!mgr->device) + return 0; + + if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) { + irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; + channel = OMAP_DSS_CHANNEL_DIGIT; + } else { + if (mgr->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { + enum omap_dss_update_mode mode; + mode = mgr->device->get_update_mode(mgr->device); + if (mode != OMAP_DSS_UPDATE_AUTO) + return 0; + + irq = DISPC_IRQ_FRAMEDONE; + } else { + irq = DISPC_IRQ_VSYNC; + } + channel = OMAP_DSS_CHANNEL_LCD; + } + + mc = &dss_cache.manager_cache[mgr->id]; + i = 0; + while (1) { + unsigned long flags; + bool shadow_dirty, dirty; + + spin_lock_irqsave(&dss_cache.lock, flags); + dirty = mc->dirty; + shadow_dirty = mc->shadow_dirty; + spin_unlock_irqrestore(&dss_cache.lock, flags); + + if (!dirty && !shadow_dirty) { + r = 0; + break; + } + + /* 4 iterations is the worst case: + * 1 - initial iteration, dirty = true (between VFP and VSYNC) + * 2 - first VSYNC, dirty = true + * 3 - dirty = false, shadow_dirty = true + * 4 - shadow_dirty = false */ + if (i++ == 3) { + DSSERR("mgr(%d)->wait_for_go() not finishing\n", + mgr->id); + r = 0; + break; + } + + r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout); + if (r == -ERESTARTSYS) + break; + + if (r) { + DSSERR("mgr(%d)->wait_for_go() timeout\n", mgr->id); + break; + } + } + + return r; +} + +int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl) +{ + unsigned long timeout = msecs_to_jiffies(500); + enum omap_channel channel; + struct overlay_cache_data *oc; + struct omap_dss_device *dssdev; + u32 irq; + int r; + int i; + + if (!ovl->manager || !ovl->manager->device) + return 0; + + dssdev = ovl->manager->device; + + if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { + irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; + channel = OMAP_DSS_CHANNEL_DIGIT; + } else { + if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { + enum omap_dss_update_mode mode; + mode = dssdev->get_update_mode(dssdev); + if (mode != OMAP_DSS_UPDATE_AUTO) + return 0; + + irq = DISPC_IRQ_FRAMEDONE; + } else { + irq = DISPC_IRQ_VSYNC; + } + channel = OMAP_DSS_CHANNEL_LCD; + } + + oc = &dss_cache.overlay_cache[ovl->id]; + i = 0; + while (1) { + unsigned long flags; + bool shadow_dirty, dirty; + + spin_lock_irqsave(&dss_cache.lock, flags); + dirty = oc->dirty; + shadow_dirty = oc->shadow_dirty; + spin_unlock_irqrestore(&dss_cache.lock, flags); + + if (!dirty && !shadow_dirty) { + r = 0; + break; + } + + /* 4 iterations is the worst case: + * 1 - initial iteration, dirty = true (between VFP and VSYNC) + * 2 - first VSYNC, dirty = true + * 3 - dirty = false, shadow_dirty = true + * 4 - shadow_dirty = false */ + if (i++ == 3) { + DSSERR("ovl(%d)->wait_for_go() not finishing\n", + ovl->id); + r = 0; + break; + } + + r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout); + if (r == -ERESTARTSYS) + break; + + if (r) { + DSSERR("ovl(%d)->wait_for_go() timeout\n", ovl->id); + break; + } + } + + return r; +} + +static int overlay_enabled(struct omap_overlay *ovl) +{ + return ovl->info.enabled && ovl->manager && ovl->manager->device; +} + +/* Is rect1 a subset of rect2? */ +static bool rectangle_subset(int x1, int y1, int w1, int h1, + int x2, int y2, int w2, int h2) +{ + if (x1 < x2 || y1 < y2) + return false; + + if (x1 + w1 > x2 + w2) + return false; + + if (y1 + h1 > y2 + h2) + return false; + + return true; +} + +/* Do rect1 and rect2 overlap? */ +static bool rectangle_intersects(int x1, int y1, int w1, int h1, + int x2, int y2, int w2, int h2) +{ + if (x1 >= x2 + w2) + return false; + + if (x2 >= x1 + w1) + return false; + + if (y1 >= y2 + h2) + return false; + + if (y2 >= y1 + h1) + return false; + + return true; +} + +static bool dispc_is_overlay_scaled(struct overlay_cache_data *oc) +{ + if (oc->out_width != 0 && oc->width != oc->out_width) + return true; + + if (oc->out_height != 0 && oc->height != oc->out_height) + return true; + + return false; +} + +static int configure_overlay(enum omap_plane plane) +{ + struct overlay_cache_data *c; + struct manager_cache_data *mc; + u16 outw, outh; + u16 x, y, w, h; + u32 paddr; + int r; + + DSSDBGF("%d", plane); + + c = &dss_cache.overlay_cache[plane]; + + if (!c->enabled) { + dispc_enable_plane(plane, 0); + return 0; + } + + mc = &dss_cache.manager_cache[c->channel]; + + x = c->pos_x; + y = c->pos_y; + w = c->width; + h = c->height; + outw = c->out_width == 0 ? c->width : c->out_width; + outh = c->out_height == 0 ? c->height : c->out_height; + paddr = c->paddr; + + if (c->manual_update && mc->do_manual_update) { + unsigned bpp; + /* If the overlay is outside the update region, disable it */ + if (!rectangle_intersects(mc->x, mc->y, mc->w, mc->h, + x, y, outw, outh)) { + dispc_enable_plane(plane, 0); + return 0; + } + + switch (c->color_mode) { + case OMAP_DSS_COLOR_RGB16: + case OMAP_DSS_COLOR_ARGB16: + case OMAP_DSS_COLOR_YUV2: + case OMAP_DSS_COLOR_UYVY: + bpp = 16; + break; + + case OMAP_DSS_COLOR_RGB24P: + bpp = 24; + break; + + case OMAP_DSS_COLOR_RGB24U: + case OMAP_DSS_COLOR_ARGB32: + case OMAP_DSS_COLOR_RGBA32: + case OMAP_DSS_COLOR_RGBX32: + bpp = 32; + break; + + default: + BUG(); + } + + if (mc->x > c->pos_x) { + x = 0; + w -= (mc->x - c->pos_x); + paddr += (mc->x - c->pos_x) * bpp / 8; + } else { + x = c->pos_x - mc->x; + } + + if (mc->y > c->pos_y) { + y = 0; + h -= (mc->y - c->pos_y); + paddr += (mc->y - c->pos_y) * c->screen_width * bpp / 8; + } else { + y = c->pos_y - mc->y; + } + + if (mc->w < (x+w)) + w -= (x+w) - (mc->w); + + if (mc->h < (y+h)) + h -= (y+h) - (mc->h); + + if (!dispc_is_overlay_scaled(c)) { + outw = w; + outh = h; + } + } + + r = dispc_setup_plane(plane, + paddr, + c->screen_width, + x, y, + w, h, + outw, outh, + c->color_mode, + c->ilace, + c->rotation_type, + c->rotation, + c->mirror, + c->global_alpha); + + if (r) { + /* this shouldn't happen */ + DSSERR("dispc_setup_plane failed for ovl %d\n", plane); + dispc_enable_plane(plane, 0); + return r; + } + + dispc_enable_replication(plane, c->replication); + + dispc_set_burst_size(plane, c->burst_size); + dispc_setup_plane_fifo(plane, c->fifo_low, c->fifo_high); + + dispc_enable_plane(plane, 1); + + return 0; +} + +static void configure_manager(enum omap_channel channel) +{ + struct manager_cache_data *c; + + DSSDBGF("%d", channel); + + c = &dss_cache.manager_cache[channel]; + + dispc_set_trans_key(channel, c->trans_key_type, c->trans_key); + dispc_enable_trans_key(channel, c->trans_enabled); + dispc_enable_alpha_blending(channel, c->alpha_enabled); +} + +/* configure_dispc() tries to write values from cache to shadow registers. + * It writes only to those managers/overlays that are not busy. + * returns 0 if everything could be written to shadow registers. + * returns 1 if not everything could be written to shadow registers. */ +static int configure_dispc(void) +{ + struct overlay_cache_data *oc; + struct manager_cache_data *mc; + const int num_ovls = ARRAY_SIZE(dss_cache.overlay_cache); + const int num_mgrs = ARRAY_SIZE(dss_cache.manager_cache); + int i; + int r; + + bool mgr_busy[2]; + bool mgr_go[2]; + bool busy; + + r = 0; + busy = false; + mgr_busy[0] = dispc_go_busy(0); + mgr_busy[1] = dispc_go_busy(1); + mgr_go[0] = false; + mgr_go[1] = false; + + /* Commit overlay settings */ + for (i = 0; i < num_ovls; ++i) { + oc = &dss_cache.overlay_cache[i]; + mc = &dss_cache.manager_cache[oc->channel]; + + if (!oc->dirty) + continue; + + if (oc->manual_update && !mc->do_manual_update) + continue; + + if (mgr_busy[oc->channel]) { + busy = true; + continue; + } + + r = configure_overlay(i); + if (r) + DSSERR("configure_overlay %d failed\n", i); + oc->dirty = false; + oc->shadow_dirty = true; + mgr_go[oc->channel] = true; + } + + /* Commit manager settings */ + for (i = 0; i < num_mgrs; ++i) { + mc = &dss_cache.manager_cache[i]; + + if (!mc->dirty) + continue; + + if (mc->manual_update && !mc->do_manual_update) + continue; + + if (mgr_busy[i]) { + busy = true; + continue; + } + + configure_manager(i); + mc->dirty = false; + mc->shadow_dirty = true; + mgr_go[i] = true; + } + + /* set GO */ + for (i = 0; i < num_mgrs; ++i) { + mc = &dss_cache.manager_cache[i]; + + if (!mgr_go[i]) + continue; + /* We don't need GO with manual update display. LCD iface will + * always be turned off after frame, and new settings will be + * taken in to use at next update */ + if (!mc->manual_upd_display) + dispc_go(i); + } + + if (busy) + r = 1; + else + r = 0; + + return r; +} + +/* Configure dispc for partial update. Return possibly modified update + * area */ +void dss_setup_partial_planes(struct omap_dss_device *dssdev, + u16 *xi, u16 *yi, u16 *wi, u16 *hi) +{ + struct overlay_cache_data *oc; + struct manager_cache_data *mc; + const int num_ovls = ARRAY_SIZE(dss_cache.overlay_cache); + struct omap_overlay_manager *mgr; + int i; + u16 x, y, w, h; + unsigned long flags; + + x = *xi; + y = *yi; + w = *wi; + h = *hi; + + DSSDBG("dispc_setup_partial_planes %d,%d %dx%d\n", + *xi, *yi, *wi, *hi); + + mgr = dssdev->manager; + + if (!mgr) { + DSSDBG("no manager\n"); + return; + } + + spin_lock_irqsave(&dss_cache.lock, flags); + + /* We need to show the whole overlay if it is scaled. So look for + * those, and make the update area larger if found. + * Also mark the overlay cache dirty */ + for (i = 0; i < num_ovls; ++i) { + unsigned x1, y1, x2, y2; + unsigned outw, outh; + + oc = &dss_cache.overlay_cache[i]; + + if (oc->channel != mgr->id) + continue; + + oc->dirty = true; + + if (!oc->enabled) + continue; + + if (!dispc_is_overlay_scaled(oc)) + continue; + + outw = oc->out_width == 0 ? oc->width : oc->out_width; + outh = oc->out_height == 0 ? oc->height : oc->out_height; + + /* is the overlay outside the update region? */ + if (!rectangle_intersects(x, y, w, h, + oc->pos_x, oc->pos_y, + outw, outh)) + continue; + + /* if the overlay totally inside the update region? */ + if (rectangle_subset(oc->pos_x, oc->pos_y, outw, outh, + x, y, w, h)) + continue; + + if (x > oc->pos_x) + x1 = oc->pos_x; + else + x1 = x; + + if (y > oc->pos_y) + y1 = oc->pos_y; + else + y1 = y; + + if ((x + w) < (oc->pos_x + outw)) + x2 = oc->pos_x + outw; + else + x2 = x + w; + + if ((y + h) < (oc->pos_y + outh)) + y2 = oc->pos_y + outh; + else + y2 = y + h; + + x = x1; + y = y1; + w = x2 - x1; + h = y2 - y1; + + DSSDBG("changing upd area due to ovl(%d) scaling %d,%d %dx%d\n", + i, x, y, w, h); + } + + mc = &dss_cache.manager_cache[mgr->id]; + mc->do_manual_update = true; + mc->x = x; + mc->y = y; + mc->w = w; + mc->h = h; + + configure_dispc(); + + mc->do_manual_update = false; + + spin_unlock_irqrestore(&dss_cache.lock, flags); + + *xi = x; + *yi = y; + *wi = w; + *hi = h; +} + +void dss_start_update(struct omap_dss_device *dssdev) +{ + struct manager_cache_data *mc; + struct overlay_cache_data *oc; + const int num_ovls = ARRAY_SIZE(dss_cache.overlay_cache); + const int num_mgrs = ARRAY_SIZE(dss_cache.manager_cache); + struct omap_overlay_manager *mgr; + int i; + + mgr = dssdev->manager; + + for (i = 0; i < num_ovls; ++i) { + oc = &dss_cache.overlay_cache[i]; + if (oc->channel != mgr->id) + continue; + + oc->shadow_dirty = false; + } + + for (i = 0; i < num_mgrs; ++i) { + mc = &dss_cache.manager_cache[i]; + if (mgr->id != i) + continue; + + mc->shadow_dirty = false; + } + + dispc_enable_lcd_out(1); +} + +static void dss_apply_irq_handler(void *data, u32 mask) +{ + struct manager_cache_data *mc; + struct overlay_cache_data *oc; + const int num_ovls = ARRAY_SIZE(dss_cache.overlay_cache); + const int num_mgrs = ARRAY_SIZE(dss_cache.manager_cache); + int i, r; + bool mgr_busy[2]; + + mgr_busy[0] = dispc_go_busy(0); + mgr_busy[1] = dispc_go_busy(1); + + spin_lock(&dss_cache.lock); + + for (i = 0; i < num_ovls; ++i) { + oc = &dss_cache.overlay_cache[i]; + if (!mgr_busy[oc->channel]) + oc->shadow_dirty = false; + } + + for (i = 0; i < num_mgrs; ++i) { + mc = &dss_cache.manager_cache[i]; + if (!mgr_busy[i]) + mc->shadow_dirty = false; + } + + r = configure_dispc(); + if (r == 1) + goto end; + + /* re-read busy flags */ + mgr_busy[0] = dispc_go_busy(0); + mgr_busy[1] = dispc_go_busy(1); + + /* keep running as long as there are busy managers, so that + * we can collect overlay-applied information */ + for (i = 0; i < num_mgrs; ++i) + if (mgr_busy[i]) + goto end; + + omap_dispc_unregister_isr(dss_apply_irq_handler, NULL, + DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD | + DISPC_IRQ_EVSYNC_EVEN); + dss_cache.irq_enabled = false; + +end: + spin_unlock(&dss_cache.lock); +} + +static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) +{ + struct overlay_cache_data *oc; + struct manager_cache_data *mc; + int i; + struct omap_overlay *ovl; + int num_planes_enabled = 0; + bool use_fifomerge; + unsigned long flags; + int r; + + DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name); + + spin_lock_irqsave(&dss_cache.lock, flags); + + /* Configure overlays */ + for (i = 0; i < omap_dss_get_num_overlays(); ++i) { + struct omap_dss_device *dssdev; + + ovl = omap_dss_get_overlay(i); + + if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC)) + continue; + oc = &dss_cache.overlay_cache[ovl->id]; + + if (!overlay_enabled(ovl)) { + if (oc->enabled) { + oc->enabled = false; + oc->dirty = true; + } + continue; + } + + if (!ovl->info_dirty) { + if (oc->enabled) + ++num_planes_enabled; + continue; + } + + dssdev = ovl->manager->device; + + if (dss_check_overlay(ovl, dssdev)) { + if (oc->enabled) { + oc->enabled = false; + oc->dirty = true; + } + continue; + } + + ovl->info_dirty = false; + oc->dirty = true; + + oc->paddr = ovl->info.paddr; + oc->vaddr = ovl->info.vaddr; + oc->screen_width = ovl->info.screen_width; + oc->width = ovl->info.width; + oc->height = ovl->info.height; + oc->color_mode = ovl->info.color_mode; + oc->rotation = ovl->info.rotation; + oc->rotation_type = ovl->info.rotation_type; + oc->mirror = ovl->info.mirror; + oc->pos_x = ovl->info.pos_x; + oc->pos_y = ovl->info.pos_y; + oc->out_width = ovl->info.out_width; + oc->out_height = ovl->info.out_height; + oc->global_alpha = ovl->info.global_alpha; + + oc->replication = + dss_use_replication(dssdev, ovl->info.color_mode); + + oc->ilace = dssdev->type == OMAP_DISPLAY_TYPE_VENC; + + oc->channel = ovl->manager->id; + + oc->enabled = true; + + oc->manual_update = + dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE && + dssdev->get_update_mode(dssdev) != OMAP_DSS_UPDATE_AUTO; + + ++num_planes_enabled; + + } + /* Configure managers */ + list_for_each_entry(mgr, &manager_list, list) { + struct omap_dss_device *dssdev; + + if (!(mgr->caps & OMAP_DSS_OVL_MGR_CAP_DISPC)) + continue; + mc = &dss_cache.manager_cache[mgr->id]; + + if (mgr->device_changed) { + mgr->device_changed = false; + mgr->info_dirty = true; + } + + if (!mgr->info_dirty) + continue; + + if (!mgr->device) + continue; + + dssdev = mgr->device; + + mgr->info_dirty = false; + mc->dirty = true; + + mc->default_color = mgr->info.default_color; + mc->trans_key_type = mgr->info.trans_key_type; + mc->trans_key = mgr->info.trans_key; + mc->trans_enabled = mgr->info.trans_enabled; + mc->alpha_enabled = mgr->info.alpha_enabled; + + mc->manual_upd_display = + dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; + + mc->manual_update = + dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE && + dssdev->get_update_mode(dssdev) != OMAP_DSS_UPDATE_AUTO; + } + + /* XXX TODO: Try to get fifomerge working. The problem is that it + * affects both managers, not individually but at the same time. This + * means the change has to be well synchronized. I guess the proper way + * is to have a two step process for fifo merge: + * fifomerge enable: + * 1. disable other planes, leaving one plane enabled + * 2. wait until the planes are disabled on HW + * 3. config merged fifo thresholds, enable fifomerge + * fifomerge disable: + * 1. config unmerged fifo thresholds, disable fifomerge + * 2. wait until fifo changes are in HW + * 3. enable planes + */ + use_fifomerge = false; + + /* Configure overlay fifos */ + for (i = 0; i < omap_dss_get_num_overlays(); ++i) { + struct omap_dss_device *dssdev; + u32 size; + + ovl = omap_dss_get_overlay(i); + + if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC)) + continue; + + oc = &dss_cache.overlay_cache[ovl->id]; + + if (!oc->enabled) + continue; + + dssdev = ovl->manager->device; + + size = dispc_get_plane_fifo_size(ovl->id); + if (use_fifomerge) + size *= 3; + + switch (dssdev->type) { + case OMAP_DISPLAY_TYPE_DPI: + case OMAP_DISPLAY_TYPE_DBI: + case OMAP_DISPLAY_TYPE_SDI: + case OMAP_DISPLAY_TYPE_VENC: + default_get_overlay_fifo_thresholds(ovl->id, size, + &oc->burst_size, &oc->fifo_low, + &oc->fifo_high); + break; +#ifdef CONFIG_OMAP2_DSS_DSI + case OMAP_DISPLAY_TYPE_DSI: + dsi_get_overlay_fifo_thresholds(ovl->id, size, + &oc->burst_size, &oc->fifo_low, + &oc->fifo_high); + break; +#endif + default: + BUG(); + } + } + + r = 0; + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + if (!dss_cache.irq_enabled) { + r = omap_dispc_register_isr(dss_apply_irq_handler, NULL, + DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD | + DISPC_IRQ_EVSYNC_EVEN); + dss_cache.irq_enabled = true; + } + configure_dispc(); + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + + spin_unlock_irqrestore(&dss_cache.lock, flags); + + return r; +} + +static int dss_check_manager(struct omap_overlay_manager *mgr) +{ + /* OMAP does not support destination color keying and alpha blending + * simultaneously. */ + + if (mgr->info.alpha_enabled && mgr->info.trans_enabled && + mgr->info.trans_key_type == OMAP_DSS_COLOR_KEY_GFX_DST) + return -EINVAL; + + mgr->info_dirty = true; + + return 0; +} + +static int omap_dss_mgr_set_info(struct omap_overlay_manager *mgr, + struct omap_overlay_manager_info *info) +{ + int r; + struct omap_overlay_manager_info old_info; + + old_info = mgr->info; + mgr->info = *info; + + r = dss_check_manager(mgr); + if (r) { + mgr->info = old_info; + return r; + } + + return 0; +} + +static void omap_dss_mgr_get_info(struct omap_overlay_manager *mgr, + struct omap_overlay_manager_info *info) +{ + *info = mgr->info; +} + +static void omap_dss_add_overlay_manager(struct omap_overlay_manager *manager) +{ + ++num_managers; + list_add_tail(&manager->list, &manager_list); +} + +int dss_init_overlay_managers(struct platform_device *pdev) +{ + int i, r; + + spin_lock_init(&dss_cache.lock); + INIT_LIST_HEAD(&manager_list); + + num_managers = 0; + + for (i = 0; i < 2; ++i) { + struct omap_overlay_manager *mgr; + mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); + + BUG_ON(mgr == NULL); + + switch (i) { + case 0: + mgr->name = "lcd"; + mgr->id = OMAP_DSS_CHANNEL_LCD; + mgr->supported_displays = + OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI | + OMAP_DISPLAY_TYPE_SDI | OMAP_DISPLAY_TYPE_DSI; + break; + case 1: + mgr->name = "tv"; + mgr->id = OMAP_DSS_CHANNEL_DIGIT; + mgr->supported_displays = OMAP_DISPLAY_TYPE_VENC; + break; + } + + mgr->set_device = &omap_dss_set_device; + mgr->unset_device = &omap_dss_unset_device; + mgr->apply = &omap_dss_mgr_apply; + mgr->set_manager_info = &omap_dss_mgr_set_info; + mgr->get_manager_info = &omap_dss_mgr_get_info; + mgr->wait_for_go = &dss_mgr_wait_for_go; + + mgr->caps = OMAP_DSS_OVL_MGR_CAP_DISPC; + + dss_overlay_setup_dispc_manager(mgr); + + omap_dss_add_overlay_manager(mgr); + + r = kobject_init_and_add(&mgr->kobj, &manager_ktype, + &pdev->dev.kobj, "manager%d", i); + + if (r) { + DSSERR("failed to create sysfs file\n"); + continue; + } + } + +#ifdef L4_EXAMPLE + { + int omap_dss_mgr_apply_l4(struct omap_overlay_manager *mgr) + { + DSSDBG("omap_dss_mgr_apply_l4(%s)\n", mgr->name); + + return 0; + } + + struct omap_overlay_manager *mgr; + mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); + + BUG_ON(mgr == NULL); + + mgr->name = "l4"; + mgr->supported_displays = + OMAP_DISPLAY_TYPE_DBI | OMAP_DISPLAY_TYPE_DSI; + + mgr->set_device = &omap_dss_set_device; + mgr->unset_device = &omap_dss_unset_device; + mgr->apply = &omap_dss_mgr_apply_l4; + mgr->set_manager_info = &omap_dss_mgr_set_info; + mgr->get_manager_info = &omap_dss_mgr_get_info; + + dss_overlay_setup_l4_manager(mgr); + + omap_dss_add_overlay_manager(mgr); + + r = kobject_init_and_add(&mgr->kobj, &manager_ktype, + &pdev->dev.kobj, "managerl4"); + + if (r) + DSSERR("failed to create sysfs file\n"); + } +#endif + + return 0; +} + +void dss_uninit_overlay_managers(struct platform_device *pdev) +{ + struct omap_overlay_manager *mgr; + + while (!list_empty(&manager_list)) { + mgr = list_first_entry(&manager_list, + struct omap_overlay_manager, list); + list_del(&mgr->list); + kobject_del(&mgr->kobj); + kobject_put(&mgr->kobj); + kfree(mgr); + } + + num_managers = 0; +} + +int omap_dss_get_num_overlay_managers(void) +{ + return num_managers; +} +EXPORT_SYMBOL(omap_dss_get_num_overlay_managers); + +struct omap_overlay_manager *omap_dss_get_overlay_manager(int num) +{ + int i = 0; + struct omap_overlay_manager *mgr; + + list_for_each_entry(mgr, &manager_list, list) { + if (i++ == num) + return mgr; + } + + return NULL; +} +EXPORT_SYMBOL(omap_dss_get_overlay_manager); + +#ifdef L4_EXAMPLE +static int ovl_mgr_apply_l4(struct omap_overlay_manager *mgr) +{ + DSSDBG("omap_dss_mgr_apply_l4(%s)\n", mgr->name); + return 0; +} +#endif diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c new file mode 100644 index 000000000000..a905f2b9f298 --- /dev/null +++ b/drivers/video/omap2/dss/overlay.c @@ -0,0 +1,660 @@ +/* + * linux/drivers/video/omap2/dss/overlay.c + * + * Copyright (C) 2009 Nokia Corporation + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> + * + * Some code and ideas taken from drivers/video/omap/ driver + * by Imre Deak. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#define DSS_SUBSYS_NAME "OVERLAY" + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/err.h> +#include <linux/sysfs.h> +#include <linux/kobject.h> +#include <linux/platform_device.h> + +#include <mach/display.h> + +#include "dss.h" + +static int num_overlays; +static struct list_head overlay_list; + +static ssize_t overlay_name_show(struct omap_overlay *ovl, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%s\n", ovl->name); +} + +static ssize_t overlay_manager_show(struct omap_overlay *ovl, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%s\n", + ovl->manager ? ovl->manager->name : "<none>"); +} + +static ssize_t overlay_manager_store(struct omap_overlay *ovl, const char *buf, + size_t size) +{ + int i, r; + struct omap_overlay_manager *mgr = NULL; + struct omap_overlay_manager *old_mgr; + int len = size; + + if (buf[size-1] == '\n') + --len; + + if (len > 0) { + for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) { + mgr = omap_dss_get_overlay_manager(i); + + if (strncmp(buf, mgr->name, len) == 0) + break; + + mgr = NULL; + } + } + + if (len > 0 && mgr == NULL) + return -EINVAL; + + if (mgr) + DSSDBG("manager %s found\n", mgr->name); + + if (mgr == ovl->manager) + return size; + + old_mgr = ovl->manager; + + /* detach old manager */ + if (old_mgr) { + r = ovl->unset_manager(ovl); + if (r) { + DSSERR("detach failed\n"); + return r; + } + + r = old_mgr->apply(old_mgr); + if (r) + return r; + } + + if (mgr) { + r = ovl->set_manager(ovl, mgr); + if (r) { + DSSERR("Failed to attach overlay\n"); + return r; + } + + r = mgr->apply(mgr); + if (r) + return r; + } + return size; +} + +static ssize_t overlay_input_size_show(struct omap_overlay *ovl, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d,%d\n", + ovl->info.width, ovl->info.height); +} + +static ssize_t overlay_screen_width_show(struct omap_overlay *ovl, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", ovl->info.screen_width); +} + +static ssize_t overlay_position_show(struct omap_overlay *ovl, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d,%d\n", + ovl->info.pos_x, ovl->info.pos_y); +} + +static ssize_t overlay_position_store(struct omap_overlay *ovl, + const char *buf, size_t size) +{ + int r; + char *last; + struct omap_overlay_info info; + + ovl->get_overlay_info(ovl, &info); + + info.pos_x = simple_strtoul(buf, &last, 10); + ++last; + if (last - buf >= size) + return -EINVAL; + + info.pos_y = simple_strtoul(last, &last, 10); + + r = ovl->set_overlay_info(ovl, &info); + if (r) + return r; + + if (ovl->manager) { + r = ovl->manager->apply(ovl->manager); + if (r) + return r; + } + + return size; +} + +static ssize_t overlay_output_size_show(struct omap_overlay *ovl, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d,%d\n", + ovl->info.out_width, ovl->info.out_height); +} + +static ssize_t overlay_output_size_store(struct omap_overlay *ovl, + const char *buf, size_t size) +{ + int r; + char *last; + struct omap_overlay_info info; + + ovl->get_overlay_info(ovl, &info); + + info.out_width = simple_strtoul(buf, &last, 10); + ++last; + if (last - buf >= size) + return -EINVAL; + + info.out_height = simple_strtoul(last, &last, 10); + + r = ovl->set_overlay_info(ovl, &info); + if (r) + return r; + + if (ovl->manager) { + r = ovl->manager->apply(ovl->manager); + if (r) + return r; + } + + return size; +} + +static ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", ovl->info.enabled); +} + +static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf, + size_t size) +{ + int r; + struct omap_overlay_info info; + + ovl->get_overlay_info(ovl, &info); + + info.enabled = simple_strtoul(buf, NULL, 10); + + r = ovl->set_overlay_info(ovl, &info); + if (r) + return r; + + if (ovl->manager) { + r = ovl->manager->apply(ovl->manager); + if (r) + return r; + } + + return size; +} + +static ssize_t overlay_global_alpha_show(struct omap_overlay *ovl, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", + ovl->info.global_alpha); +} + +static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl, + const char *buf, size_t size) +{ + int r; + struct omap_overlay_info info; + + ovl->get_overlay_info(ovl, &info); + + /* Video1 plane does not support global alpha + * to always make it 255 completely opaque + */ + if (ovl->id == OMAP_DSS_VIDEO1) + info.global_alpha = 255; + else + info.global_alpha = simple_strtoul(buf, NULL, 10); + + r = ovl->set_overlay_info(ovl, &info); + if (r) + return r; + + if (ovl->manager) { + r = ovl->manager->apply(ovl->manager); + if (r) + return r; + } + + return size; +} + +struct overlay_attribute { + struct attribute attr; + ssize_t (*show)(struct omap_overlay *, char *); + ssize_t (*store)(struct omap_overlay *, const char *, size_t); +}; + +#define OVERLAY_ATTR(_name, _mode, _show, _store) \ + struct overlay_attribute overlay_attr_##_name = \ + __ATTR(_name, _mode, _show, _store) + +static OVERLAY_ATTR(name, S_IRUGO, overlay_name_show, NULL); +static OVERLAY_ATTR(manager, S_IRUGO|S_IWUSR, + overlay_manager_show, overlay_manager_store); +static OVERLAY_ATTR(input_size, S_IRUGO, overlay_input_size_show, NULL); +static OVERLAY_ATTR(screen_width, S_IRUGO, overlay_screen_width_show, NULL); +static OVERLAY_ATTR(position, S_IRUGO|S_IWUSR, + overlay_position_show, overlay_position_store); +static OVERLAY_ATTR(output_size, S_IRUGO|S_IWUSR, + overlay_output_size_show, overlay_output_size_store); +static OVERLAY_ATTR(enabled, S_IRUGO|S_IWUSR, + overlay_enabled_show, overlay_enabled_store); +static OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR, + overlay_global_alpha_show, overlay_global_alpha_store); + +static struct attribute *overlay_sysfs_attrs[] = { + &overlay_attr_name.attr, + &overlay_attr_manager.attr, + &overlay_attr_input_size.attr, + &overlay_attr_screen_width.attr, + &overlay_attr_position.attr, + &overlay_attr_output_size.attr, + &overlay_attr_enabled.attr, + &overlay_attr_global_alpha.attr, + NULL +}; + +static ssize_t overlay_attr_show(struct kobject *kobj, struct attribute *attr, + char *buf) +{ + struct omap_overlay *overlay; + struct overlay_attribute *overlay_attr; + + overlay = container_of(kobj, struct omap_overlay, kobj); + overlay_attr = container_of(attr, struct overlay_attribute, attr); + + if (!overlay_attr->show) + return -ENOENT; + + return overlay_attr->show(overlay, buf); +} + +static ssize_t overlay_attr_store(struct kobject *kobj, struct attribute *attr, + const char *buf, size_t size) +{ + struct omap_overlay *overlay; + struct overlay_attribute *overlay_attr; + + overlay = container_of(kobj, struct omap_overlay, kobj); + overlay_attr = container_of(attr, struct overlay_attribute, attr); + + if (!overlay_attr->store) + return -ENOENT; + + return overlay_attr->store(overlay, buf, size); +} + +static struct sysfs_ops overlay_sysfs_ops = { + .show = overlay_attr_show, + .store = overlay_attr_store, +}; + +static struct kobj_type overlay_ktype = { + .sysfs_ops = &overlay_sysfs_ops, + .default_attrs = overlay_sysfs_attrs, +}; + +/* Check if overlay parameters are compatible with display */ +int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev) +{ + struct omap_overlay_info *info; + u16 outw, outh; + u16 dw, dh; + + if (!dssdev) + return 0; + + if (!ovl->info.enabled) + return 0; + + info = &ovl->info; + + if (info->paddr == 0) { + DSSDBG("check_overlay failed: paddr 0\n"); + return -EINVAL; + } + + dssdev->get_resolution(dssdev, &dw, &dh); + + DSSDBG("check_overlay %d: (%d,%d %dx%d -> %dx%d) disp (%dx%d)\n", + ovl->id, + info->pos_x, info->pos_y, + info->width, info->height, + info->out_width, info->out_height, + dw, dh); + + if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) { + outw = info->width; + outh = info->height; + } else { + if (info->out_width == 0) + outw = info->width; + else + outw = info->out_width; + + if (info->out_height == 0) + outh = info->height; + else + outh = info->out_height; + } + + if (dw < info->pos_x + outw) { + DSSDBG("check_overlay failed 1: %d < %d + %d\n", + dw, info->pos_x, outw); + return -EINVAL; + } + + if (dh < info->pos_y + outh) { + DSSDBG("check_overlay failed 2: %d < %d + %d\n", + dh, info->pos_y, outh); + return -EINVAL; + } + + if ((ovl->supported_modes & info->color_mode) == 0) { + DSSERR("overlay doesn't support mode %d\n", info->color_mode); + return -EINVAL; + } + + return 0; +} + +static int dss_ovl_set_overlay_info(struct omap_overlay *ovl, + struct omap_overlay_info *info) +{ + int r; + struct omap_overlay_info old_info; + + old_info = ovl->info; + ovl->info = *info; + + if (ovl->manager) { + r = dss_check_overlay(ovl, ovl->manager->device); + if (r) { + ovl->info = old_info; + return r; + } + } + + ovl->info_dirty = true; + + return 0; +} + +static void dss_ovl_get_overlay_info(struct omap_overlay *ovl, + struct omap_overlay_info *info) +{ + *info = ovl->info; +} + +static int dss_ovl_wait_for_go(struct omap_overlay *ovl) +{ + return dss_mgr_wait_for_go_ovl(ovl); +} + +static int omap_dss_set_manager(struct omap_overlay *ovl, + struct omap_overlay_manager *mgr) +{ + int r; + + if (!mgr) + return -EINVAL; + + if (ovl->manager) { + DSSERR("overlay '%s' already has a manager '%s'\n", + ovl->name, ovl->manager->name); + return -EINVAL; + } + + r = ovl->wait_for_go(ovl); + if (r) + return r; + + if (ovl->info.enabled) { + DSSERR("overlay has to be disabled to change the manager\n"); + return -EINVAL; + } + + ovl->manager = mgr; + + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + dispc_set_channel_out(ovl->id, mgr->id); + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + + return 0; +} + +static int omap_dss_unset_manager(struct omap_overlay *ovl) +{ + if (!ovl->manager) { + DSSERR("failed to detach overlay: manager not set\n"); + return -EINVAL; + } + + ovl->manager = NULL; + /* XXX disable overlay? */ + + return 0; +} + +int omap_dss_get_num_overlays(void) +{ + return num_overlays; +} +EXPORT_SYMBOL(omap_dss_get_num_overlays); + +struct omap_overlay *omap_dss_get_overlay(int num) +{ + int i = 0; + struct omap_overlay *ovl; + + list_for_each_entry(ovl, &overlay_list, list) { + if (i++ == num) + return ovl; + } + + return NULL; +} +EXPORT_SYMBOL(omap_dss_get_overlay); + +static void omap_dss_add_overlay(struct omap_overlay *overlay) +{ + ++num_overlays; + list_add_tail(&overlay->list, &overlay_list); +} + +static struct omap_overlay *dispc_overlays[3]; + +void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr) +{ + mgr->num_overlays = 3; + mgr->overlays = dispc_overlays; +} + +#ifdef L4_EXAMPLE +static struct omap_overlay *l4_overlays[1]; +void dss_overlay_setup_l4_manager(struct omap_overlay_manager *mgr) +{ + mgr->num_overlays = 1; + mgr->overlays = l4_overlays; +} +#endif + +void dss_init_overlays(struct platform_device *pdev) +{ + int i, r; + + INIT_LIST_HEAD(&overlay_list); + + num_overlays = 0; + + for (i = 0; i < 3; ++i) { + struct omap_overlay *ovl; + ovl = kzalloc(sizeof(*ovl), GFP_KERNEL); + + BUG_ON(ovl == NULL); + + switch (i) { + case 0: + ovl->name = "gfx"; + ovl->id = OMAP_DSS_GFX; + ovl->supported_modes = OMAP_DSS_COLOR_GFX_OMAP3; + ovl->caps = OMAP_DSS_OVL_CAP_DISPC; + ovl->info.global_alpha = 255; + break; + case 1: + ovl->name = "vid1"; + ovl->id = OMAP_DSS_VIDEO1; + ovl->supported_modes = OMAP_DSS_COLOR_VID_OMAP3; + ovl->caps = OMAP_DSS_OVL_CAP_SCALE | + OMAP_DSS_OVL_CAP_DISPC; + ovl->info.global_alpha = 255; + break; + case 2: + ovl->name = "vid2"; + ovl->id = OMAP_DSS_VIDEO2; + ovl->supported_modes = OMAP_DSS_COLOR_VID_OMAP3; + ovl->caps = OMAP_DSS_OVL_CAP_SCALE | + OMAP_DSS_OVL_CAP_DISPC; + ovl->info.global_alpha = 255; + break; + } + + ovl->set_manager = &omap_dss_set_manager; + ovl->unset_manager = &omap_dss_unset_manager; + ovl->set_overlay_info = &dss_ovl_set_overlay_info; + ovl->get_overlay_info = &dss_ovl_get_overlay_info; + ovl->wait_for_go = &dss_ovl_wait_for_go; + + omap_dss_add_overlay(ovl); + + r = kobject_init_and_add(&ovl->kobj, &overlay_ktype, + &pdev->dev.kobj, "overlay%d", i); + + if (r) { + DSSERR("failed to create sysfs file\n"); + continue; + } + + dispc_overlays[i] = ovl; + } + +#ifdef L4_EXAMPLE + { + struct omap_overlay *ovl; + ovl = kzalloc(sizeof(*ovl), GFP_KERNEL); + + BUG_ON(ovl == NULL); + + ovl->name = "l4"; + ovl->supported_modes = OMAP_DSS_COLOR_RGB24U; + + ovl->set_manager = &omap_dss_set_manager; + ovl->unset_manager = &omap_dss_unset_manager; + ovl->set_overlay_info = &dss_ovl_set_overlay_info; + ovl->get_overlay_info = &dss_ovl_get_overlay_info; + + omap_dss_add_overlay(ovl); + + r = kobject_init_and_add(&ovl->kobj, &overlay_ktype, + &pdev->dev.kobj, "overlayl4"); + + if (r) + DSSERR("failed to create sysfs file\n"); + + l4_overlays[0] = ovl; + } +#endif +} + +/* connect overlays to the new device, if not already connected. if force + * selected, connect always. */ +void dss_recheck_connections(struct omap_dss_device *dssdev, bool force) +{ + int i; + struct omap_overlay_manager *lcd_mgr; + struct omap_overlay_manager *tv_mgr; + struct omap_overlay_manager *mgr = NULL; + + lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD); + tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_TV); + + if (dssdev->type != OMAP_DISPLAY_TYPE_VENC) { + if (!lcd_mgr->device || force) { + if (lcd_mgr->device) + lcd_mgr->unset_device(lcd_mgr); + lcd_mgr->set_device(lcd_mgr, dssdev); + mgr = lcd_mgr; + } + } + + if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { + if (!tv_mgr->device || force) { + if (tv_mgr->device) + tv_mgr->unset_device(tv_mgr); + tv_mgr->set_device(tv_mgr, dssdev); + mgr = tv_mgr; + } + } + + if (mgr) { + for (i = 0; i < 3; i++) { + struct omap_overlay *ovl; + ovl = omap_dss_get_overlay(i); + if (!ovl->manager || force) { + if (ovl->manager) + omap_dss_unset_manager(ovl); + omap_dss_set_manager(ovl, mgr); + } + } + } +} + +void dss_uninit_overlays(struct platform_device *pdev) +{ + struct omap_overlay *ovl; + + while (!list_empty(&overlay_list)) { + ovl = list_first_entry(&overlay_list, + struct omap_overlay, list); + list_del(&ovl->list); + kobject_del(&ovl->kobj); + kobject_put(&ovl->kobj); + kfree(ovl); + } + + num_overlays = 0; +} + diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c new file mode 100644 index 000000000000..9dd2349dda1d --- /dev/null +++ b/drivers/video/omap2/dss/rfbi.c @@ -0,0 +1,1310 @@ +/* + * linux/drivers/video/omap2/dss/rfbi.c + * + * Copyright (C) 2009 Nokia Corporation + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> + * + * Some code and ideas taken from drivers/video/omap/ driver + * by Imre Deak. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#define DSS_SUBSYS_NAME "RFBI" + +#include <linux/kernel.h> +#include <linux/dma-mapping.h> +#include <linux/vmalloc.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/delay.h> +#include <linux/kfifo.h> +#include <linux/ktime.h> +#include <linux/hrtimer.h> +#include <linux/seq_file.h> + +#include <mach/board.h> +#include <mach/display.h> +#include "dss.h" + +/*#define MEASURE_PERF*/ + +#define RFBI_BASE 0x48050800 + +struct rfbi_reg { u16 idx; }; + +#define RFBI_REG(idx) ((const struct rfbi_reg) { idx }) + +#define RFBI_REVISION RFBI_REG(0x0000) +#define RFBI_SYSCONFIG RFBI_REG(0x0010) +#define RFBI_SYSSTATUS RFBI_REG(0x0014) +#define RFBI_CONTROL RFBI_REG(0x0040) +#define RFBI_PIXEL_CNT RFBI_REG(0x0044) +#define RFBI_LINE_NUMBER RFBI_REG(0x0048) +#define RFBI_CMD RFBI_REG(0x004c) +#define RFBI_PARAM RFBI_REG(0x0050) +#define RFBI_DATA RFBI_REG(0x0054) +#define RFBI_READ RFBI_REG(0x0058) +#define RFBI_STATUS RFBI_REG(0x005c) + +#define RFBI_CONFIG(n) RFBI_REG(0x0060 + (n)*0x18) +#define RFBI_ONOFF_TIME(n) RFBI_REG(0x0064 + (n)*0x18) +#define RFBI_CYCLE_TIME(n) RFBI_REG(0x0068 + (n)*0x18) +#define RFBI_DATA_CYCLE1(n) RFBI_REG(0x006c + (n)*0x18) +#define RFBI_DATA_CYCLE2(n) RFBI_REG(0x0070 + (n)*0x18) +#define RFBI_DATA_CYCLE3(n) RFBI_REG(0x0074 + (n)*0x18) + +#define RFBI_VSYNC_WIDTH RFBI_REG(0x0090) +#define RFBI_HSYNC_WIDTH RFBI_REG(0x0094) + +#define RFBI_CMD_FIFO_LEN_BYTES (16 * sizeof(struct update_param)) + +#define REG_FLD_MOD(idx, val, start, end) \ + rfbi_write_reg(idx, FLD_MOD(rfbi_read_reg(idx), val, start, end)) + +/* To work around an RFBI transfer rate limitation */ +#define OMAP_RFBI_RATE_LIMIT 1 + +enum omap_rfbi_cycleformat { + OMAP_DSS_RFBI_CYCLEFORMAT_1_1 = 0, + OMAP_DSS_RFBI_CYCLEFORMAT_2_1 = 1, + OMAP_DSS_RFBI_CYCLEFORMAT_3_1 = 2, + OMAP_DSS_RFBI_CYCLEFORMAT_3_2 = 3, +}; + +enum omap_rfbi_datatype { + OMAP_DSS_RFBI_DATATYPE_12 = 0, + OMAP_DSS_RFBI_DATATYPE_16 = 1, + OMAP_DSS_RFBI_DATATYPE_18 = 2, + OMAP_DSS_RFBI_DATATYPE_24 = 3, +}; + +enum omap_rfbi_parallelmode { + OMAP_DSS_RFBI_PARALLELMODE_8 = 0, + OMAP_DSS_RFBI_PARALLELMODE_9 = 1, + OMAP_DSS_RFBI_PARALLELMODE_12 = 2, + OMAP_DSS_RFBI_PARALLELMODE_16 = 3, +}; + +enum update_cmd { + RFBI_CMD_UPDATE = 0, + RFBI_CMD_SYNC = 1, +}; + +static int rfbi_convert_timings(struct rfbi_timings *t); +static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div); +static void process_cmd_fifo(void); + +static struct { + void __iomem *base; + + unsigned long l4_khz; + + enum omap_rfbi_datatype datatype; + enum omap_rfbi_parallelmode parallelmode; + + enum omap_rfbi_te_mode te_mode; + int te_enabled; + + void (*framedone_callback)(void *data); + void *framedone_callback_data; + + struct omap_dss_device *dssdev[2]; + + struct kfifo *cmd_fifo; + spinlock_t cmd_lock; + struct completion cmd_done; + atomic_t cmd_fifo_full; + atomic_t cmd_pending; +#ifdef MEASURE_PERF + unsigned perf_bytes; + ktime_t perf_setup_time; + ktime_t perf_start_time; +#endif +} rfbi; + +struct update_region { + u16 x; + u16 y; + u16 w; + u16 h; +}; + +struct update_param { + u8 rfbi_module; + u8 cmd; + + union { + struct update_region r; + struct completion *sync; + } par; +}; + +static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val) +{ + __raw_writel(val, rfbi.base + idx.idx); +} + +static inline u32 rfbi_read_reg(const struct rfbi_reg idx) +{ + return __raw_readl(rfbi.base + idx.idx); +} + +static void rfbi_enable_clocks(bool enable) +{ + if (enable) + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + else + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); +} + +void omap_rfbi_write_command(const void *buf, u32 len) +{ + rfbi_enable_clocks(1); + switch (rfbi.parallelmode) { + case OMAP_DSS_RFBI_PARALLELMODE_8: + { + const u8 *b = buf; + for (; len; len--) + rfbi_write_reg(RFBI_CMD, *b++); + break; + } + + case OMAP_DSS_RFBI_PARALLELMODE_16: + { + const u16 *w = buf; + BUG_ON(len & 1); + for (; len; len -= 2) + rfbi_write_reg(RFBI_CMD, *w++); + break; + } + + case OMAP_DSS_RFBI_PARALLELMODE_9: + case OMAP_DSS_RFBI_PARALLELMODE_12: + default: + BUG(); + } + rfbi_enable_clocks(0); +} +EXPORT_SYMBOL(omap_rfbi_write_command); + +void omap_rfbi_read_data(void *buf, u32 len) +{ + rfbi_enable_clocks(1); + switch (rfbi.parallelmode) { + case OMAP_DSS_RFBI_PARALLELMODE_8: + { + u8 *b = buf; + for (; len; len--) { + rfbi_write_reg(RFBI_READ, 0); + *b++ = rfbi_read_reg(RFBI_READ); + } + break; + } + + case OMAP_DSS_RFBI_PARALLELMODE_16: + { + u16 *w = buf; + BUG_ON(len & ~1); + for (; len; len -= 2) { + rfbi_write_reg(RFBI_READ, 0); + *w++ = rfbi_read_reg(RFBI_READ); + } + break; + } + + case OMAP_DSS_RFBI_PARALLELMODE_9: + case OMAP_DSS_RFBI_PARALLELMODE_12: + default: + BUG(); + } + rfbi_enable_clocks(0); +} +EXPORT_SYMBOL(omap_rfbi_read_data); + +void omap_rfbi_write_data(const void *buf, u32 len) +{ + rfbi_enable_clocks(1); + switch (rfbi.parallelmode) { + case OMAP_DSS_RFBI_PARALLELMODE_8: + { + const u8 *b = buf; + for (; len; len--) + rfbi_write_reg(RFBI_PARAM, *b++); + break; + } + + case OMAP_DSS_RFBI_PARALLELMODE_16: + { + const u16 *w = buf; + BUG_ON(len & 1); + for (; len; len -= 2) + rfbi_write_reg(RFBI_PARAM, *w++); + break; + } + + case OMAP_DSS_RFBI_PARALLELMODE_9: + case OMAP_DSS_RFBI_PARALLELMODE_12: + default: + BUG(); + + } + rfbi_enable_clocks(0); +} +EXPORT_SYMBOL(omap_rfbi_write_data); + +void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width, + u16 x, u16 y, + u16 w, u16 h) +{ + int start_offset = scr_width * y + x; + int horiz_offset = scr_width - w; + int i; + + rfbi_enable_clocks(1); + + if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_16 && + rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_8) { + const u16 __iomem *pd = buf; + pd += start_offset; + + for (; h; --h) { + for (i = 0; i < w; ++i) { + const u8 __iomem *b = (const u8 __iomem *)pd; + rfbi_write_reg(RFBI_PARAM, __raw_readb(b+1)); + rfbi_write_reg(RFBI_PARAM, __raw_readb(b+0)); + ++pd; + } + pd += horiz_offset; + } + } else if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_24 && + rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_8) { + const u32 __iomem *pd = buf; + pd += start_offset; + + for (; h; --h) { + for (i = 0; i < w; ++i) { + const u8 __iomem *b = (const u8 __iomem *)pd; + rfbi_write_reg(RFBI_PARAM, __raw_readb(b+2)); + rfbi_write_reg(RFBI_PARAM, __raw_readb(b+1)); + rfbi_write_reg(RFBI_PARAM, __raw_readb(b+0)); + ++pd; + } + pd += horiz_offset; + } + } else if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_16 && + rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_16) { + const u16 __iomem *pd = buf; + pd += start_offset; + + for (; h; --h) { + for (i = 0; i < w; ++i) { + rfbi_write_reg(RFBI_PARAM, __raw_readw(pd)); + ++pd; + } + pd += horiz_offset; + } + } else { + BUG(); + } + + rfbi_enable_clocks(0); +} +EXPORT_SYMBOL(omap_rfbi_write_pixels); + +#ifdef MEASURE_PERF +static void perf_mark_setup(void) +{ + rfbi.perf_setup_time = ktime_get(); +} + +static void perf_mark_start(void) +{ + rfbi.perf_start_time = ktime_get(); +} + +static void perf_show(const char *name) +{ + ktime_t t, setup_time, trans_time; + u32 total_bytes; + u32 setup_us, trans_us, total_us; + + t = ktime_get(); + + setup_time = ktime_sub(rfbi.perf_start_time, rfbi.perf_setup_time); + setup_us = (u32)ktime_to_us(setup_time); + if (setup_us == 0) + setup_us = 1; + + trans_time = ktime_sub(t, rfbi.perf_start_time); + trans_us = (u32)ktime_to_us(trans_time); + if (trans_us == 0) + trans_us = 1; + + total_us = setup_us + trans_us; + + total_bytes = rfbi.perf_bytes; + + DSSINFO("%s update %u us + %u us = %u us (%uHz), %u bytes, " + "%u kbytes/sec\n", + name, + setup_us, + trans_us, + total_us, + 1000*1000 / total_us, + total_bytes, + total_bytes * 1000 / total_us); +} +#else +#define perf_mark_setup() +#define perf_mark_start() +#define perf_show(x) +#endif + +void rfbi_transfer_area(u16 width, u16 height, + void (callback)(void *data), void *data) +{ + u32 l; + + /*BUG_ON(callback == 0);*/ + BUG_ON(rfbi.framedone_callback != NULL); + + DSSDBG("rfbi_transfer_area %dx%d\n", width, height); + + dispc_set_lcd_size(width, height); + + dispc_enable_lcd_out(1); + + rfbi.framedone_callback = callback; + rfbi.framedone_callback_data = data; + + rfbi_enable_clocks(1); + + rfbi_write_reg(RFBI_PIXEL_CNT, width * height); + + l = rfbi_read_reg(RFBI_CONTROL); + l = FLD_MOD(l, 1, 0, 0); /* enable */ + if (!rfbi.te_enabled) + l = FLD_MOD(l, 1, 4, 4); /* ITE */ + + perf_mark_start(); + + rfbi_write_reg(RFBI_CONTROL, l); +} + +static void framedone_callback(void *data, u32 mask) +{ + void (*callback)(void *data); + + DSSDBG("FRAMEDONE\n"); + + perf_show("DISPC"); + + REG_FLD_MOD(RFBI_CONTROL, 0, 0, 0); + + rfbi_enable_clocks(0); + + callback = rfbi.framedone_callback; + rfbi.framedone_callback = NULL; + + /*callback(rfbi.framedone_callback_data);*/ + + atomic_set(&rfbi.cmd_pending, 0); + + process_cmd_fifo(); +} + +#if 1 /* VERBOSE */ +static void rfbi_print_timings(void) +{ + u32 l; + u32 time; + + l = rfbi_read_reg(RFBI_CONFIG(0)); + time = 1000000000 / rfbi.l4_khz; + if (l & (1 << 4)) + time *= 2; + + DSSDBG("Tick time %u ps\n", time); + l = rfbi_read_reg(RFBI_ONOFF_TIME(0)); + DSSDBG("CSONTIME %d, CSOFFTIME %d, WEONTIME %d, WEOFFTIME %d, " + "REONTIME %d, REOFFTIME %d\n", + l & 0x0f, (l >> 4) & 0x3f, (l >> 10) & 0x0f, (l >> 14) & 0x3f, + (l >> 20) & 0x0f, (l >> 24) & 0x3f); + + l = rfbi_read_reg(RFBI_CYCLE_TIME(0)); + DSSDBG("WECYCLETIME %d, RECYCLETIME %d, CSPULSEWIDTH %d, " + "ACCESSTIME %d\n", + (l & 0x3f), (l >> 6) & 0x3f, (l >> 12) & 0x3f, + (l >> 22) & 0x3f); +} +#else +static void rfbi_print_timings(void) {} +#endif + + + + +static u32 extif_clk_period; + +static inline unsigned long round_to_extif_ticks(unsigned long ps, int div) +{ + int bus_tick = extif_clk_period * div; + return (ps + bus_tick - 1) / bus_tick * bus_tick; +} + +static int calc_reg_timing(struct rfbi_timings *t, int div) +{ + t->clk_div = div; + + t->cs_on_time = round_to_extif_ticks(t->cs_on_time, div); + + t->we_on_time = round_to_extif_ticks(t->we_on_time, div); + t->we_off_time = round_to_extif_ticks(t->we_off_time, div); + t->we_cycle_time = round_to_extif_ticks(t->we_cycle_time, div); + + t->re_on_time = round_to_extif_ticks(t->re_on_time, div); + t->re_off_time = round_to_extif_ticks(t->re_off_time, div); + t->re_cycle_time = round_to_extif_ticks(t->re_cycle_time, div); + + t->access_time = round_to_extif_ticks(t->access_time, div); + t->cs_off_time = round_to_extif_ticks(t->cs_off_time, div); + t->cs_pulse_width = round_to_extif_ticks(t->cs_pulse_width, div); + + DSSDBG("[reg]cson %d csoff %d reon %d reoff %d\n", + t->cs_on_time, t->cs_off_time, t->re_on_time, t->re_off_time); + DSSDBG("[reg]weon %d weoff %d recyc %d wecyc %d\n", + t->we_on_time, t->we_off_time, t->re_cycle_time, + t->we_cycle_time); + DSSDBG("[reg]rdaccess %d cspulse %d\n", + t->access_time, t->cs_pulse_width); + + return rfbi_convert_timings(t); +} + +static int calc_extif_timings(struct rfbi_timings *t) +{ + u32 max_clk_div; + int div; + + rfbi_get_clk_info(&extif_clk_period, &max_clk_div); + for (div = 1; div <= max_clk_div; div++) { + if (calc_reg_timing(t, div) == 0) + break; + } + + if (div <= max_clk_div) + return 0; + + DSSERR("can't setup timings\n"); + return -1; +} + + +void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t) +{ + int r; + + if (!t->converted) { + r = calc_extif_timings(t); + if (r < 0) + DSSERR("Failed to calc timings\n"); + } + + BUG_ON(!t->converted); + + rfbi_enable_clocks(1); + rfbi_write_reg(RFBI_ONOFF_TIME(rfbi_module), t->tim[0]); + rfbi_write_reg(RFBI_CYCLE_TIME(rfbi_module), t->tim[1]); + + /* TIMEGRANULARITY */ + REG_FLD_MOD(RFBI_CONFIG(rfbi_module), + (t->tim[2] ? 1 : 0), 4, 4); + + rfbi_print_timings(); + rfbi_enable_clocks(0); +} + +static int ps_to_rfbi_ticks(int time, int div) +{ + unsigned long tick_ps; + int ret; + + /* Calculate in picosecs to yield more exact results */ + tick_ps = 1000000000 / (rfbi.l4_khz) * div; + + ret = (time + tick_ps - 1) / tick_ps; + + return ret; +} + +#ifdef OMAP_RFBI_RATE_LIMIT +unsigned long rfbi_get_max_tx_rate(void) +{ + unsigned long l4_rate, dss1_rate; + int min_l4_ticks = 0; + int i; + + /* According to TI this can't be calculated so make the + * adjustments for a couple of known frequencies and warn for + * others. + */ + static const struct { + unsigned long l4_clk; /* HZ */ + unsigned long dss1_clk; /* HZ */ + unsigned long min_l4_ticks; + } ftab[] = { + { 55, 132, 7, }, /* 7.86 MPix/s */ + { 110, 110, 12, }, /* 9.16 MPix/s */ + { 110, 132, 10, }, /* 11 Mpix/s */ + { 120, 120, 10, }, /* 12 Mpix/s */ + { 133, 133, 10, }, /* 13.3 Mpix/s */ + }; + + l4_rate = rfbi.l4_khz / 1000; + dss1_rate = dss_clk_get_rate(DSS_CLK_FCK1) / 1000000; + + for (i = 0; i < ARRAY_SIZE(ftab); i++) { + /* Use a window instead of an exact match, to account + * for different DPLL multiplier / divider pairs. + */ + if (abs(ftab[i].l4_clk - l4_rate) < 3 && + abs(ftab[i].dss1_clk - dss1_rate) < 3) { + min_l4_ticks = ftab[i].min_l4_ticks; + break; + } + } + if (i == ARRAY_SIZE(ftab)) { + /* Can't be sure, return anyway the maximum not + * rate-limited. This might cause a problem only for the + * tearing synchronisation. + */ + DSSERR("can't determine maximum RFBI transfer rate\n"); + return rfbi.l4_khz * 1000; + } + return rfbi.l4_khz * 1000 / min_l4_ticks; +} +#else +int rfbi_get_max_tx_rate(void) +{ + return rfbi.l4_khz * 1000; +} +#endif + +static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div) +{ + *clk_period = 1000000000 / rfbi.l4_khz; + *max_clk_div = 2; +} + +static int rfbi_convert_timings(struct rfbi_timings *t) +{ + u32 l; + int reon, reoff, weon, weoff, cson, csoff, cs_pulse; + int actim, recyc, wecyc; + int div = t->clk_div; + + if (div <= 0 || div > 2) + return -1; + + /* Make sure that after conversion it still holds that: + * weoff > weon, reoff > reon, recyc >= reoff, wecyc >= weoff, + * csoff > cson, csoff >= max(weoff, reoff), actim > reon + */ + weon = ps_to_rfbi_ticks(t->we_on_time, div); + weoff = ps_to_rfbi_ticks(t->we_off_time, div); + if (weoff <= weon) + weoff = weon + 1; + if (weon > 0x0f) + return -1; + if (weoff > 0x3f) + return -1; + + reon = ps_to_rfbi_ticks(t->re_on_time, div); + reoff = ps_to_rfbi_ticks(t->re_off_time, div); + if (reoff <= reon) + reoff = reon + 1; + if (reon > 0x0f) + return -1; + if (reoff > 0x3f) + return -1; + + cson = ps_to_rfbi_ticks(t->cs_on_time, div); + csoff = ps_to_rfbi_ticks(t->cs_off_time, div); + if (csoff <= cson) + csoff = cson + 1; + if (csoff < max(weoff, reoff)) + csoff = max(weoff, reoff); + if (cson > 0x0f) + return -1; + if (csoff > 0x3f) + return -1; + + l = cson; + l |= csoff << 4; + l |= weon << 10; + l |= weoff << 14; + l |= reon << 20; + l |= reoff << 24; + + t->tim[0] = l; + + actim = ps_to_rfbi_ticks(t->access_time, div); + if (actim <= reon) + actim = reon + 1; + if (actim > 0x3f) + return -1; + + wecyc = ps_to_rfbi_ticks(t->we_cycle_time, div); + if (wecyc < weoff) + wecyc = weoff; + if (wecyc > 0x3f) + return -1; + + recyc = ps_to_rfbi_ticks(t->re_cycle_time, div); + if (recyc < reoff) + recyc = reoff; + if (recyc > 0x3f) + return -1; + + cs_pulse = ps_to_rfbi_ticks(t->cs_pulse_width, div); + if (cs_pulse > 0x3f) + return -1; + + l = wecyc; + l |= recyc << 6; + l |= cs_pulse << 12; + l |= actim << 22; + + t->tim[1] = l; + + t->tim[2] = div - 1; + + t->converted = 1; + + return 0; +} + +/* xxx FIX module selection missing */ +int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode, + unsigned hs_pulse_time, unsigned vs_pulse_time, + int hs_pol_inv, int vs_pol_inv, int extif_div) +{ + int hs, vs; + int min; + u32 l; + + hs = ps_to_rfbi_ticks(hs_pulse_time, 1); + vs = ps_to_rfbi_ticks(vs_pulse_time, 1); + if (hs < 2) + return -EDOM; + if (mode == OMAP_DSS_RFBI_TE_MODE_2) + min = 2; + else /* OMAP_DSS_RFBI_TE_MODE_1 */ + min = 4; + if (vs < min) + return -EDOM; + if (vs == hs) + return -EINVAL; + rfbi.te_mode = mode; + DSSDBG("setup_te: mode %d hs %d vs %d hs_inv %d vs_inv %d\n", + mode, hs, vs, hs_pol_inv, vs_pol_inv); + + rfbi_enable_clocks(1); + rfbi_write_reg(RFBI_HSYNC_WIDTH, hs); + rfbi_write_reg(RFBI_VSYNC_WIDTH, vs); + + l = rfbi_read_reg(RFBI_CONFIG(0)); + if (hs_pol_inv) + l &= ~(1 << 21); + else + l |= 1 << 21; + if (vs_pol_inv) + l &= ~(1 << 20); + else + l |= 1 << 20; + rfbi_enable_clocks(0); + + return 0; +} +EXPORT_SYMBOL(omap_rfbi_setup_te); + +/* xxx FIX module selection missing */ +int omap_rfbi_enable_te(bool enable, unsigned line) +{ + u32 l; + + DSSDBG("te %d line %d mode %d\n", enable, line, rfbi.te_mode); + if (line > (1 << 11) - 1) + return -EINVAL; + + rfbi_enable_clocks(1); + l = rfbi_read_reg(RFBI_CONFIG(0)); + l &= ~(0x3 << 2); + if (enable) { + rfbi.te_enabled = 1; + l |= rfbi.te_mode << 2; + } else + rfbi.te_enabled = 0; + rfbi_write_reg(RFBI_CONFIG(0), l); + rfbi_write_reg(RFBI_LINE_NUMBER, line); + rfbi_enable_clocks(0); + + return 0; +} +EXPORT_SYMBOL(omap_rfbi_enable_te); + +#if 0 +static void rfbi_enable_config(int enable1, int enable2) +{ + u32 l; + int cs = 0; + + if (enable1) + cs |= 1<<0; + if (enable2) + cs |= 1<<1; + + rfbi_enable_clocks(1); + + l = rfbi_read_reg(RFBI_CONTROL); + + l = FLD_MOD(l, cs, 3, 2); + l = FLD_MOD(l, 0, 1, 1); + + rfbi_write_reg(RFBI_CONTROL, l); + + + l = rfbi_read_reg(RFBI_CONFIG(0)); + l = FLD_MOD(l, 0, 3, 2); /* TRIGGERMODE: ITE */ + /*l |= FLD_VAL(2, 8, 7); */ /* L4FORMAT, 2pix/L4 */ + /*l |= FLD_VAL(0, 8, 7); */ /* L4FORMAT, 1pix/L4 */ + + l = FLD_MOD(l, 0, 16, 16); /* A0POLARITY */ + l = FLD_MOD(l, 1, 20, 20); /* TE_VSYNC_POLARITY */ + l = FLD_MOD(l, 1, 21, 21); /* HSYNCPOLARITY */ + + l = FLD_MOD(l, OMAP_DSS_RFBI_PARALLELMODE_8, 1, 0); + rfbi_write_reg(RFBI_CONFIG(0), l); + + rfbi_enable_clocks(0); +} +#endif + +int rfbi_configure(int rfbi_module, int bpp, int lines) +{ + u32 l; + int cycle1 = 0, cycle2 = 0, cycle3 = 0; + enum omap_rfbi_cycleformat cycleformat; + enum omap_rfbi_datatype datatype; + enum omap_rfbi_parallelmode parallelmode; + + switch (bpp) { + case 12: + datatype = OMAP_DSS_RFBI_DATATYPE_12; + break; + case 16: + datatype = OMAP_DSS_RFBI_DATATYPE_16; + break; + case 18: + datatype = OMAP_DSS_RFBI_DATATYPE_18; + break; + case 24: + datatype = OMAP_DSS_RFBI_DATATYPE_24; + break; + default: + BUG(); + return 1; + } + rfbi.datatype = datatype; + + switch (lines) { + case 8: + parallelmode = OMAP_DSS_RFBI_PARALLELMODE_8; + break; + case 9: + parallelmode = OMAP_DSS_RFBI_PARALLELMODE_9; + break; + case 12: + parallelmode = OMAP_DSS_RFBI_PARALLELMODE_12; + break; + case 16: + parallelmode = OMAP_DSS_RFBI_PARALLELMODE_16; + break; + default: + BUG(); + return 1; + } + rfbi.parallelmode = parallelmode; + + if ((bpp % lines) == 0) { + switch (bpp / lines) { + case 1: + cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_1_1; + break; + case 2: + cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_2_1; + break; + case 3: + cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_3_1; + break; + default: + BUG(); + return 1; + } + } else if ((2 * bpp % lines) == 0) { + if ((2 * bpp / lines) == 3) + cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_3_2; + else { + BUG(); + return 1; + } + } else { + BUG(); + return 1; + } + + switch (cycleformat) { + case OMAP_DSS_RFBI_CYCLEFORMAT_1_1: + cycle1 = lines; + break; + + case OMAP_DSS_RFBI_CYCLEFORMAT_2_1: + cycle1 = lines; + cycle2 = lines; + break; + + case OMAP_DSS_RFBI_CYCLEFORMAT_3_1: + cycle1 = lines; + cycle2 = lines; + cycle3 = lines; + break; + + case OMAP_DSS_RFBI_CYCLEFORMAT_3_2: + cycle1 = lines; + cycle2 = (lines / 2) | ((lines / 2) << 16); + cycle3 = (lines << 16); + break; + } + + rfbi_enable_clocks(1); + + REG_FLD_MOD(RFBI_CONTROL, 0, 3, 2); /* clear CS */ + + l = 0; + l |= FLD_VAL(parallelmode, 1, 0); + l |= FLD_VAL(0, 3, 2); /* TRIGGERMODE: ITE */ + l |= FLD_VAL(0, 4, 4); /* TIMEGRANULARITY */ + l |= FLD_VAL(datatype, 6, 5); + /* l |= FLD_VAL(2, 8, 7); */ /* L4FORMAT, 2pix/L4 */ + l |= FLD_VAL(0, 8, 7); /* L4FORMAT, 1pix/L4 */ + l |= FLD_VAL(cycleformat, 10, 9); + l |= FLD_VAL(0, 12, 11); /* UNUSEDBITS */ + l |= FLD_VAL(0, 16, 16); /* A0POLARITY */ + l |= FLD_VAL(0, 17, 17); /* REPOLARITY */ + l |= FLD_VAL(0, 18, 18); /* WEPOLARITY */ + l |= FLD_VAL(0, 19, 19); /* CSPOLARITY */ + l |= FLD_VAL(1, 20, 20); /* TE_VSYNC_POLARITY */ + l |= FLD_VAL(1, 21, 21); /* HSYNCPOLARITY */ + rfbi_write_reg(RFBI_CONFIG(rfbi_module), l); + + rfbi_write_reg(RFBI_DATA_CYCLE1(rfbi_module), cycle1); + rfbi_write_reg(RFBI_DATA_CYCLE2(rfbi_module), cycle2); + rfbi_write_reg(RFBI_DATA_CYCLE3(rfbi_module), cycle3); + + + l = rfbi_read_reg(RFBI_CONTROL); + l = FLD_MOD(l, rfbi_module+1, 3, 2); /* Select CSx */ + l = FLD_MOD(l, 0, 1, 1); /* clear bypass */ + rfbi_write_reg(RFBI_CONTROL, l); + + + DSSDBG("RFBI config: bpp %d, lines %d, cycles: 0x%x 0x%x 0x%x\n", + bpp, lines, cycle1, cycle2, cycle3); + + rfbi_enable_clocks(0); + + return 0; +} +EXPORT_SYMBOL(rfbi_configure); + +static int rfbi_find_display(struct omap_dss_device *dssdev) +{ + if (dssdev == rfbi.dssdev[0]) + return 0; + + if (dssdev == rfbi.dssdev[1]) + return 1; + + BUG(); + return -1; +} + + +static void signal_fifo_waiters(void) +{ + if (atomic_read(&rfbi.cmd_fifo_full) > 0) { + /* DSSDBG("SIGNALING: Fifo not full for waiter!\n"); */ + complete(&rfbi.cmd_done); + atomic_dec(&rfbi.cmd_fifo_full); + } +} + +/* returns 1 for async op, and 0 for sync op */ +static int do_update(struct omap_dss_device *dssdev, struct update_region *upd) +{ + u16 x = upd->x; + u16 y = upd->y; + u16 w = upd->w; + u16 h = upd->h; + + perf_mark_setup(); + + if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { + /*dssdev->driver->enable_te(dssdev, 1); */ + dss_setup_partial_planes(dssdev, &x, &y, &w, &h); + } + +#ifdef MEASURE_PERF + rfbi.perf_bytes = w * h * 2; /* XXX always 16bit */ +#endif + + dssdev->driver->setup_update(dssdev, x, y, w, h); + + if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { + rfbi_transfer_area(w, h, NULL, NULL); + return 1; + } else { + struct omap_overlay *ovl; + void __iomem *addr; + int scr_width; + + ovl = dssdev->manager->overlays[0]; + scr_width = ovl->info.screen_width; + addr = ovl->info.vaddr; + + omap_rfbi_write_pixels(addr, scr_width, x, y, w, h); + + perf_show("L4"); + + return 0; + } +} + +static void process_cmd_fifo(void) +{ + int len; + struct update_param p; + struct omap_dss_device *dssdev; + unsigned long flags; + + if (atomic_inc_return(&rfbi.cmd_pending) != 1) + return; + + while (true) { + spin_lock_irqsave(rfbi.cmd_fifo->lock, flags); + + len = __kfifo_get(rfbi.cmd_fifo, (unsigned char *)&p, + sizeof(struct update_param)); + if (len == 0) { + DSSDBG("nothing more in fifo\n"); + atomic_set(&rfbi.cmd_pending, 0); + spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags); + break; + } + + /* DSSDBG("fifo full %d\n", rfbi.cmd_fifo_full.counter);*/ + + spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags); + + BUG_ON(len != sizeof(struct update_param)); + BUG_ON(p.rfbi_module > 1); + + dssdev = rfbi.dssdev[p.rfbi_module]; + + if (p.cmd == RFBI_CMD_UPDATE) { + if (do_update(dssdev, &p.par.r)) + break; /* async op */ + } else if (p.cmd == RFBI_CMD_SYNC) { + DSSDBG("Signaling SYNC done!\n"); + complete(p.par.sync); + } else + BUG(); + } + + signal_fifo_waiters(); +} + +static void rfbi_push_cmd(struct update_param *p) +{ + int ret; + + while (1) { + unsigned long flags; + int available; + + spin_lock_irqsave(rfbi.cmd_fifo->lock, flags); + available = RFBI_CMD_FIFO_LEN_BYTES - + __kfifo_len(rfbi.cmd_fifo); + +/* DSSDBG("%d bytes left in fifo\n", available); */ + if (available < sizeof(struct update_param)) { + DSSDBG("Going to wait because FIFO FULL..\n"); + spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags); + atomic_inc(&rfbi.cmd_fifo_full); + wait_for_completion(&rfbi.cmd_done); + /*DSSDBG("Woke up because fifo not full anymore\n");*/ + continue; + } + + ret = __kfifo_put(rfbi.cmd_fifo, (unsigned char *)p, + sizeof(struct update_param)); +/* DSSDBG("pushed %d bytes\n", ret);*/ + + spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags); + + BUG_ON(ret != sizeof(struct update_param)); + + break; + } +} + +static void rfbi_push_update(int rfbi_module, int x, int y, int w, int h) +{ + struct update_param p; + + p.rfbi_module = rfbi_module; + p.cmd = RFBI_CMD_UPDATE; + + p.par.r.x = x; + p.par.r.y = y; + p.par.r.w = w; + p.par.r.h = h; + + DSSDBG("RFBI pushed %d,%d %dx%d\n", x, y, w, h); + + rfbi_push_cmd(&p); + + process_cmd_fifo(); +} + +static void rfbi_push_sync(int rfbi_module, struct completion *sync_comp) +{ + struct update_param p; + + p.rfbi_module = rfbi_module; + p.cmd = RFBI_CMD_SYNC; + p.par.sync = sync_comp; + + rfbi_push_cmd(&p); + + DSSDBG("RFBI sync pushed to cmd fifo\n"); + + process_cmd_fifo(); +} + +void rfbi_dump_regs(struct seq_file *s) +{ +#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r)) + + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + + DUMPREG(RFBI_REVISION); + DUMPREG(RFBI_SYSCONFIG); + DUMPREG(RFBI_SYSSTATUS); + DUMPREG(RFBI_CONTROL); + DUMPREG(RFBI_PIXEL_CNT); + DUMPREG(RFBI_LINE_NUMBER); + DUMPREG(RFBI_CMD); + DUMPREG(RFBI_PARAM); + DUMPREG(RFBI_DATA); + DUMPREG(RFBI_READ); + DUMPREG(RFBI_STATUS); + + DUMPREG(RFBI_CONFIG(0)); + DUMPREG(RFBI_ONOFF_TIME(0)); + DUMPREG(RFBI_CYCLE_TIME(0)); + DUMPREG(RFBI_DATA_CYCLE1(0)); + DUMPREG(RFBI_DATA_CYCLE2(0)); + DUMPREG(RFBI_DATA_CYCLE3(0)); + + DUMPREG(RFBI_CONFIG(1)); + DUMPREG(RFBI_ONOFF_TIME(1)); + DUMPREG(RFBI_CYCLE_TIME(1)); + DUMPREG(RFBI_DATA_CYCLE1(1)); + DUMPREG(RFBI_DATA_CYCLE2(1)); + DUMPREG(RFBI_DATA_CYCLE3(1)); + + DUMPREG(RFBI_VSYNC_WIDTH); + DUMPREG(RFBI_HSYNC_WIDTH); + + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); +#undef DUMPREG +} + +int rfbi_init(void) +{ + u32 rev; + u32 l; + + spin_lock_init(&rfbi.cmd_lock); + rfbi.cmd_fifo = kfifo_alloc(RFBI_CMD_FIFO_LEN_BYTES, GFP_KERNEL, + &rfbi.cmd_lock); + if (IS_ERR(rfbi.cmd_fifo)) + return -ENOMEM; + + init_completion(&rfbi.cmd_done); + atomic_set(&rfbi.cmd_fifo_full, 0); + atomic_set(&rfbi.cmd_pending, 0); + + rfbi.base = ioremap(RFBI_BASE, SZ_256); + if (!rfbi.base) { + DSSERR("can't ioremap RFBI\n"); + return -ENOMEM; + } + + rfbi_enable_clocks(1); + + msleep(10); + + rfbi.l4_khz = dss_clk_get_rate(DSS_CLK_ICK) / 1000; + + /* Enable autoidle and smart-idle */ + l = rfbi_read_reg(RFBI_SYSCONFIG); + l |= (1 << 0) | (2 << 3); + rfbi_write_reg(RFBI_SYSCONFIG, l); + + rev = rfbi_read_reg(RFBI_REVISION); + printk(KERN_INFO "OMAP RFBI rev %d.%d\n", + FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); + + rfbi_enable_clocks(0); + + return 0; +} + +void rfbi_exit(void) +{ + DSSDBG("rfbi_exit\n"); + + kfifo_free(rfbi.cmd_fifo); + + iounmap(rfbi.base); +} + +/* struct omap_display support */ +static int rfbi_display_update(struct omap_dss_device *dssdev, + u16 x, u16 y, u16 w, u16 h) +{ + int rfbi_module; + + if (w == 0 || h == 0) + return 0; + + rfbi_module = rfbi_find_display(dssdev); + + rfbi_push_update(rfbi_module, x, y, w, h); + + return 0; +} + +static int rfbi_display_sync(struct omap_dss_device *dssdev) +{ + struct completion sync_comp; + int rfbi_module; + + rfbi_module = rfbi_find_display(dssdev); + + init_completion(&sync_comp); + rfbi_push_sync(rfbi_module, &sync_comp); + DSSDBG("Waiting for SYNC to happen...\n"); + wait_for_completion(&sync_comp); + DSSDBG("Released from SYNC\n"); + return 0; +} + +static int rfbi_display_enable_te(struct omap_dss_device *dssdev, bool enable) +{ + dssdev->driver->enable_te(dssdev, enable); + return 0; +} + +static int rfbi_display_enable(struct omap_dss_device *dssdev) +{ + int r; + + r = omap_dss_start_device(dssdev); + if (r) { + DSSERR("failed to start device\n"); + goto err0; + } + + r = omap_dispc_register_isr(framedone_callback, NULL, + DISPC_IRQ_FRAMEDONE); + if (r) { + DSSERR("can't get FRAMEDONE irq\n"); + goto err1; + } + + dispc_set_lcd_display_type(OMAP_DSS_LCD_DISPLAY_TFT); + + dispc_set_parallel_interface_mode(OMAP_DSS_PARALLELMODE_RFBI); + + dispc_set_tft_data_lines(dssdev->ctrl.pixel_size); + + rfbi_configure(dssdev->phy.rfbi.channel, + dssdev->ctrl.pixel_size, + dssdev->phy.rfbi.data_lines); + + rfbi_set_timings(dssdev->phy.rfbi.channel, + &dssdev->ctrl.rfbi_timings); + + + if (dssdev->driver->enable) { + r = dssdev->driver->enable(dssdev); + if (r) + goto err2; + } + + return 0; +err2: + omap_dispc_unregister_isr(framedone_callback, NULL, + DISPC_IRQ_FRAMEDONE); +err1: + omap_dss_stop_device(dssdev); +err0: + return r; +} + +static void rfbi_display_disable(struct omap_dss_device *dssdev) +{ + dssdev->driver->disable(dssdev); + omap_dispc_unregister_isr(framedone_callback, NULL, + DISPC_IRQ_FRAMEDONE); + omap_dss_stop_device(dssdev); +} + +int rfbi_init_display(struct omap_dss_device *dssdev) +{ + dssdev->enable = rfbi_display_enable; + dssdev->disable = rfbi_display_disable; + dssdev->update = rfbi_display_update; + dssdev->sync = rfbi_display_sync; + dssdev->enable_te = rfbi_display_enable_te; + + rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev; + + dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; + + return 0; +} diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c new file mode 100644 index 000000000000..7fa54ab88543 --- /dev/null +++ b/drivers/video/omap2/dss/sdi.c @@ -0,0 +1,370 @@ +/* + * linux/drivers/video/omap2/dss/sdi.c + * + * Copyright (C) 2009 Nokia Corporation + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.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, see <http://www.gnu.org/licenses/>. + */ + +#define DSS_SUBSYS_NAME "SDI" + +#include <linux/kernel.h> +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/io.h> + +#include <mach/board.h> +#include <mach/display.h> +#include "dss.h" + +#define CONTROL_PADCONF_BASE 0x48002000 + +#define OMAP_SDI_PAD_DIS(pe, pu) ((7 << 0) | /* MODE 7 = safe */ \ + (((pe) ? 1 : 0) << 3) | /* PULL_ENA */ \ + (((pu) ? 1 : 0) << 4) | /* PULL_UP */ \ + (1 << 8)) /* INPUT_EN */ + +#define OMAP_SDI_PAD_EN (1 << 0) /* MODE 1 = SDI_xx */ + +#define OMAP_SDI_PAD_MASK OMAP_SDI_PAD_DIS(1, 1) + +static struct { + bool skip_init; + bool update_enabled; +} sdi; + +/* CONTROL_PADCONF_DSS_DATAXX */ +static const u16 sdi_pads[] = +{ + 0x0f0, /* 10[ 7..0]:SDI_DAT1N */ + 0x0f2, /* 10[15..0]:SDI_DAT1P */ + 0x0f4, /* 12[ 7..0]:SDI_DAT2N */ + 0x0f6, /* 12[15..0]:SDI_DAT2P */ + 0x0f8, /* 14[ 7..0]:SDI_DAT3N */ + 0x0fa, /* 14[15..0]:SDI_DAT3P */ + 0x108, /* 22[ 7..0]:SDI_CLKN */ + 0x10a, /* 22[15..0]:SDI_CLKP */ +}; + +/* + * Check if bootloader / platform code has configured the SDI pads properly. + * This means it either configured all required pads for SDI mode, or that it + * left all the required pads unconfigured. + */ +static int sdi_pad_init(struct omap_dss_device *dssdev) +{ + unsigned req_map; + bool configured = false; + bool unconfigured = false; + int data_pairs; + int i; + + data_pairs = dssdev->phy.sdi.datapairs; + req_map = (1 << (data_pairs * 2)) - 1; /* data lanes */ + req_map |= 3 << 6; /* clk lane */ + for (i = 0; i < ARRAY_SIZE(sdi_pads); i++) { + u32 reg; + u32 val; + + if (!((1 << i) & req_map)) + /* Ignore unneded pads. */ + continue; + reg = CONTROL_PADCONF_BASE + sdi_pads[i]; + val = omap_readw(reg); + switch (val & 0x07) { /* pad mode */ + case 1: + if (unconfigured) + break; + /* Is the pull configuration ok for SDI mode? */ + if ((val & OMAP_SDI_PAD_MASK) != OMAP_SDI_PAD_EN) + break; + configured = true; + break; + case 0: + case 7: + if (configured) + break; + unconfigured = true; + break; + default: + break; + } + } + if (i != ARRAY_SIZE(sdi_pads)) { + DSSERR("SDI: invalid pad configuration\n"); + return -1; + } + + return 0; +} + +static void sdi_pad_config(struct omap_dss_device *dssdev, bool enable) +{ + int data_pairs; + bool pad_off_pe, pad_off_pu; + unsigned req_map; + int i; + + data_pairs = dssdev->phy.sdi.datapairs; + pad_off_pe = dssdev->phy.sdi.pad_off_pe; + pad_off_pu = dssdev->phy.sdi.pad_off_pu; + req_map = (1 << (data_pairs * 2)) - 1; /* data lanes */ + req_map |= 3 << 6; /* clk lane */ + for (i = 0; i < ARRAY_SIZE(sdi_pads); i++) { + u32 reg; + u16 val; + + if (!((1 << i) & req_map)) + continue; + if (enable) + val = OMAP_SDI_PAD_EN; + else + val = OMAP_SDI_PAD_DIS(pad_off_pe, pad_off_pu); + reg = CONTROL_PADCONF_BASE + sdi_pads[i]; + omap_writew(val, reg); + } +} + +static void sdi_basic_init(void) +{ + dispc_set_parallel_interface_mode(OMAP_DSS_PARALLELMODE_BYPASS); + + dispc_set_lcd_display_type(OMAP_DSS_LCD_DISPLAY_TFT); + dispc_set_tft_data_lines(24); + dispc_lcd_enable_signal_polarity(1); +} + +static int sdi_display_enable(struct omap_dss_device *dssdev) +{ + struct omap_video_timings *t = &dssdev->panel.timings; + struct dispc_clock_info cinfo; + u16 lck_div, pck_div; + unsigned long fck; + unsigned long pck; + int r; + + r = omap_dss_start_device(dssdev); + if (r) { + DSSERR("failed to start device\n"); + goto err0; + } + + if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { + DSSERR("dssdev already enabled\n"); + r = -EINVAL; + goto err1; + } + + sdi_pad_config(dssdev, 1); + + /* In case of skip_init sdi_init has already enabled the clocks */ + if (!sdi.skip_init) + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + + sdi_basic_init(); + + /* 15.5.9.1.2 */ + dssdev->panel.config |= OMAP_DSS_LCD_RF | OMAP_DSS_LCD_ONOFF; + + dispc_set_pol_freq(dssdev->panel.config, dssdev->panel.acbi, + dssdev->panel.acb); + + if (!sdi.skip_init) + r = dispc_calc_clock_div(1, t->pixel_clock * 1000, + &cinfo); + else + r = dispc_get_clock_div(&cinfo); + + if (r) + goto err2; + + fck = cinfo.fck; + lck_div = cinfo.lck_div; + pck_div = cinfo.pck_div; + + pck = fck / lck_div / pck_div / 1000; + + if (pck != t->pixel_clock) { + DSSWARN("Could not find exact pixel clock. Requested %d kHz, " + "got %lu kHz\n", + t->pixel_clock, pck); + + t->pixel_clock = pck; + } + + + dispc_set_lcd_timings(t); + + r = dispc_set_clock_div(&cinfo); + if (r) + goto err2; + + if (!sdi.skip_init) { + dss_sdi_init(dssdev->phy.sdi.datapairs); + dss_sdi_enable(); + mdelay(2); + } + + dispc_enable_lcd_out(1); + + if (dssdev->driver->enable) { + r = dssdev->driver->enable(dssdev); + if (r) + goto err3; + } + + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + + sdi.skip_init = 0; + + return 0; +err3: + dispc_enable_lcd_out(0); +err2: + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); +err1: + omap_dss_stop_device(dssdev); +err0: + return r; +} + +static int sdi_display_resume(struct omap_dss_device *dssdev); + +static void sdi_display_disable(struct omap_dss_device *dssdev) +{ + if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED) + return; + + if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) + sdi_display_resume(dssdev); + + if (dssdev->driver->disable) + dssdev->driver->disable(dssdev); + + dispc_enable_lcd_out(0); + + dss_sdi_disable(); + + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + sdi_pad_config(dssdev, 0); + + dssdev->state = OMAP_DSS_DISPLAY_DISABLED; + + omap_dss_stop_device(dssdev); +} + +static int sdi_display_suspend(struct omap_dss_device *dssdev) +{ + if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) + return -EINVAL; + + if (dssdev->driver->suspend) + dssdev->driver->suspend(dssdev); + + dispc_enable_lcd_out(0); + + dss_sdi_disable(); + + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + sdi_pad_config(dssdev, 0); + + dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; + + return 0; +} + +static int sdi_display_resume(struct omap_dss_device *dssdev) +{ + if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) + return -EINVAL; + + sdi_pad_config(dssdev, 1); + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + + dss_sdi_enable(); + mdelay(2); + + dispc_enable_lcd_out(1); + + if (dssdev->driver->resume) + dssdev->driver->resume(dssdev); + + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + + return 0; +} + +static int sdi_display_set_update_mode(struct omap_dss_device *dssdev, + enum omap_dss_update_mode mode) +{ + if (mode == OMAP_DSS_UPDATE_MANUAL) + return -EINVAL; + + if (mode == OMAP_DSS_UPDATE_DISABLED) { + dispc_enable_lcd_out(0); + sdi.update_enabled = 0; + } else { + dispc_enable_lcd_out(1); + sdi.update_enabled = 1; + } + + return 0; +} + +static enum omap_dss_update_mode sdi_display_get_update_mode( + struct omap_dss_device *dssdev) +{ + return sdi.update_enabled ? OMAP_DSS_UPDATE_AUTO : + OMAP_DSS_UPDATE_DISABLED; +} + +static void sdi_get_timings(struct omap_dss_device *dssdev, + struct omap_video_timings *timings) +{ + *timings = dssdev->panel.timings; +} + +int sdi_init_display(struct omap_dss_device *dssdev) +{ + DSSDBG("SDI init\n"); + + dssdev->enable = sdi_display_enable; + dssdev->disable = sdi_display_disable; + dssdev->suspend = sdi_display_suspend; + dssdev->resume = sdi_display_resume; + dssdev->set_update_mode = sdi_display_set_update_mode; + dssdev->get_update_mode = sdi_display_get_update_mode; + dssdev->get_timings = sdi_get_timings; + + return sdi_pad_init(dssdev); +} + +int sdi_init(bool skip_init) +{ + /* we store this for first display enable, then clear it */ + sdi.skip_init = skip_init; + + /* + * Enable clocks already here, otherwise there would be a toggle + * of them until sdi_display_enable is called. + */ + if (skip_init) + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + return 0; +} + +void sdi_exit(void) +{ +} diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c new file mode 100644 index 000000000000..d8a83b2410e6 --- /dev/null +++ b/drivers/video/omap2/dss/venc.c @@ -0,0 +1,782 @@ +/* + * linux/drivers/video/omap2/dss/venc.c + * + * Copyright (C) 2009 Nokia Corporation + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> + * + * VENC settings from TI's DSS driver + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#define DSS_SUBSYS_NAME "VENC" + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/mutex.h> +#include <linux/completion.h> +#include <linux/delay.h> +#include <linux/string.h> +#include <linux/seq_file.h> +#include <linux/platform_device.h> +#include <linux/regulator/consumer.h> + +#include <mach/display.h> +#include <mach/cpu.h> + +#include "dss.h" + +#define VENC_BASE 0x48050C00 + +/* Venc registers */ +#define VENC_REV_ID 0x00 +#define VENC_STATUS 0x04 +#define VENC_F_CONTROL 0x08 +#define VENC_VIDOUT_CTRL 0x10 +#define VENC_SYNC_CTRL 0x14 +#define VENC_LLEN 0x1C +#define VENC_FLENS 0x20 +#define VENC_HFLTR_CTRL 0x24 +#define VENC_CC_CARR_WSS_CARR 0x28 +#define VENC_C_PHASE 0x2C +#define VENC_GAIN_U 0x30 +#define VENC_GAIN_V 0x34 +#define VENC_GAIN_Y 0x38 +#define VENC_BLACK_LEVEL 0x3C +#define VENC_BLANK_LEVEL 0x40 +#define VENC_X_COLOR 0x44 +#define VENC_M_CONTROL 0x48 +#define VENC_BSTAMP_WSS_DATA 0x4C +#define VENC_S_CARR 0x50 +#define VENC_LINE21 0x54 +#define VENC_LN_SEL 0x58 +#define VENC_L21__WC_CTL 0x5C +#define VENC_HTRIGGER_VTRIGGER 0x60 +#define VENC_SAVID__EAVID 0x64 +#define VENC_FLEN__FAL 0x68 +#define VENC_LAL__PHASE_RESET 0x6C +#define VENC_HS_INT_START_STOP_X 0x70 +#define VENC_HS_EXT_START_STOP_X 0x74 +#define VENC_VS_INT_START_X 0x78 +#define VENC_VS_INT_STOP_X__VS_INT_START_Y 0x7C +#define VENC_VS_INT_STOP_Y__VS_EXT_START_X 0x80 +#define VENC_VS_EXT_STOP_X__VS_EXT_START_Y 0x84 +#define VENC_VS_EXT_STOP_Y 0x88 +#define VENC_AVID_START_STOP_X 0x90 +#define VENC_AVID_START_STOP_Y 0x94 +#define VENC_FID_INT_START_X__FID_INT_START_Y 0xA0 +#define VENC_FID_INT_OFFSET_Y__FID_EXT_START_X 0xA4 +#define VENC_FID_EXT_START_Y__FID_EXT_OFFSET_Y 0xA8 +#define VENC_TVDETGP_INT_START_STOP_X 0xB0 +#define VENC_TVDETGP_INT_START_STOP_Y 0xB4 +#define VENC_GEN_CTRL 0xB8 +#define VENC_OUTPUT_CONTROL 0xC4 +#define VENC_OUTPUT_TEST 0xC8 +#define VENC_DAC_B__DAC_C 0xC8 + +struct venc_config { + u32 f_control; + u32 vidout_ctrl; + u32 sync_ctrl; + u32 llen; + u32 flens; + u32 hfltr_ctrl; + u32 cc_carr_wss_carr; + u32 c_phase; + u32 gain_u; + u32 gain_v; + u32 gain_y; + u32 black_level; + u32 blank_level; + u32 x_color; + u32 m_control; + u32 bstamp_wss_data; + u32 s_carr; + u32 line21; + u32 ln_sel; + u32 l21__wc_ctl; + u32 htrigger_vtrigger; + u32 savid__eavid; + u32 flen__fal; + u32 lal__phase_reset; + u32 hs_int_start_stop_x; + u32 hs_ext_start_stop_x; + u32 vs_int_start_x; + u32 vs_int_stop_x__vs_int_start_y; + u32 vs_int_stop_y__vs_ext_start_x; + u32 vs_ext_stop_x__vs_ext_start_y; + u32 vs_ext_stop_y; + u32 avid_start_stop_x; + u32 avid_start_stop_y; + u32 fid_int_start_x__fid_int_start_y; + u32 fid_int_offset_y__fid_ext_start_x; + u32 fid_ext_start_y__fid_ext_offset_y; + u32 tvdetgp_int_start_stop_x; + u32 tvdetgp_int_start_stop_y; + u32 gen_ctrl; +}; + +/* from TRM */ +static const struct venc_config venc_config_pal_trm = { + .f_control = 0, + .vidout_ctrl = 1, + .sync_ctrl = 0x40, + .llen = 0x35F, /* 863 */ + .flens = 0x270, /* 624 */ + .hfltr_ctrl = 0, + .cc_carr_wss_carr = 0x2F7225ED, + .c_phase = 0, + .gain_u = 0x111, + .gain_v = 0x181, + .gain_y = 0x140, + .black_level = 0x3B, + .blank_level = 0x3B, + .x_color = 0x7, + .m_control = 0x2, + .bstamp_wss_data = 0x3F, + .s_carr = 0x2A098ACB, + .line21 = 0, + .ln_sel = 0x01290015, + .l21__wc_ctl = 0x0000F603, + .htrigger_vtrigger = 0, + + .savid__eavid = 0x06A70108, + .flen__fal = 0x00180270, + .lal__phase_reset = 0x00040135, + .hs_int_start_stop_x = 0x00880358, + .hs_ext_start_stop_x = 0x000F035F, + .vs_int_start_x = 0x01A70000, + .vs_int_stop_x__vs_int_start_y = 0x000001A7, + .vs_int_stop_y__vs_ext_start_x = 0x01AF0000, + .vs_ext_stop_x__vs_ext_start_y = 0x000101AF, + .vs_ext_stop_y = 0x00000025, + .avid_start_stop_x = 0x03530083, + .avid_start_stop_y = 0x026C002E, + .fid_int_start_x__fid_int_start_y = 0x0001008A, + .fid_int_offset_y__fid_ext_start_x = 0x002E0138, + .fid_ext_start_y__fid_ext_offset_y = 0x01380001, + + .tvdetgp_int_start_stop_x = 0x00140001, + .tvdetgp_int_start_stop_y = 0x00010001, + .gen_ctrl = 0x00FF0000, +}; + +/* from TRM */ +static const struct venc_config venc_config_ntsc_trm = { + .f_control = 0, + .vidout_ctrl = 1, + .sync_ctrl = 0x8040, + .llen = 0x359, + .flens = 0x20C, + .hfltr_ctrl = 0, + .cc_carr_wss_carr = 0x043F2631, + .c_phase = 0, + .gain_u = 0x102, + .gain_v = 0x16C, + .gain_y = 0x12F, + .black_level = 0x43, + .blank_level = 0x38, + .x_color = 0x7, + .m_control = 0x1, + .bstamp_wss_data = 0x38, + .s_carr = 0x21F07C1F, + .line21 = 0, + .ln_sel = 0x01310011, + .l21__wc_ctl = 0x0000F003, + .htrigger_vtrigger = 0, + + .savid__eavid = 0x069300F4, + .flen__fal = 0x0016020C, + .lal__phase_reset = 0x00060107, + .hs_int_start_stop_x = 0x008E0350, + .hs_ext_start_stop_x = 0x000F0359, + .vs_int_start_x = 0x01A00000, + .vs_int_stop_x__vs_int_start_y = 0x020701A0, + .vs_int_stop_y__vs_ext_start_x = 0x01AC0024, + .vs_ext_stop_x__vs_ext_start_y = 0x020D01AC, + .vs_ext_stop_y = 0x00000006, + .avid_start_stop_x = 0x03480078, + .avid_start_stop_y = 0x02060024, + .fid_int_start_x__fid_int_start_y = 0x0001008A, + .fid_int_offset_y__fid_ext_start_x = 0x01AC0106, + .fid_ext_start_y__fid_ext_offset_y = 0x01060006, + + .tvdetgp_int_start_stop_x = 0x00140001, + .tvdetgp_int_start_stop_y = 0x00010001, + .gen_ctrl = 0x00F90000, +}; + +static const struct venc_config venc_config_pal_bdghi = { + .f_control = 0, + .vidout_ctrl = 0, + .sync_ctrl = 0, + .hfltr_ctrl = 0, + .x_color = 0, + .line21 = 0, + .ln_sel = 21, + .htrigger_vtrigger = 0, + .tvdetgp_int_start_stop_x = 0x00140001, + .tvdetgp_int_start_stop_y = 0x00010001, + .gen_ctrl = 0x00FB0000, + + .llen = 864-1, + .flens = 625-1, + .cc_carr_wss_carr = 0x2F7625ED, + .c_phase = 0xDF, + .gain_u = 0x111, + .gain_v = 0x181, + .gain_y = 0x140, + .black_level = 0x3e, + .blank_level = 0x3e, + .m_control = 0<<2 | 1<<1, + .bstamp_wss_data = 0x42, + .s_carr = 0x2a098acb, + .l21__wc_ctl = 0<<13 | 0x16<<8 | 0<<0, + .savid__eavid = 0x06A70108, + .flen__fal = 23<<16 | 624<<0, + .lal__phase_reset = 2<<17 | 310<<0, + .hs_int_start_stop_x = 0x00920358, + .hs_ext_start_stop_x = 0x000F035F, + .vs_int_start_x = 0x1a7<<16, + .vs_int_stop_x__vs_int_start_y = 0x000601A7, + .vs_int_stop_y__vs_ext_start_x = 0x01AF0036, + .vs_ext_stop_x__vs_ext_start_y = 0x27101af, + .vs_ext_stop_y = 0x05, + .avid_start_stop_x = 0x03530082, + .avid_start_stop_y = 0x0270002E, + .fid_int_start_x__fid_int_start_y = 0x0005008A, + .fid_int_offset_y__fid_ext_start_x = 0x002E0138, + .fid_ext_start_y__fid_ext_offset_y = 0x01380005, +}; + +const struct omap_video_timings omap_dss_pal_timings = { + .x_res = 720, + .y_res = 574, + .pixel_clock = 13500, + .hsw = 64, + .hfp = 12, + .hbp = 68, + .vsw = 5, + .vfp = 5, + .vbp = 41, +}; +EXPORT_SYMBOL(omap_dss_pal_timings); + +const struct omap_video_timings omap_dss_ntsc_timings = { + .x_res = 720, + .y_res = 482, + .pixel_clock = 13500, + .hsw = 64, + .hfp = 16, + .hbp = 58, + .vsw = 6, + .vfp = 6, + .vbp = 31, +}; +EXPORT_SYMBOL(omap_dss_ntsc_timings); + +static struct { + void __iomem *base; + struct mutex venc_lock; + u32 wss_data; + struct regulator *vdda_dac_reg; +} venc; + +static inline void venc_write_reg(int idx, u32 val) +{ + __raw_writel(val, venc.base + idx); +} + +static inline u32 venc_read_reg(int idx) +{ + u32 l = __raw_readl(venc.base + idx); + return l; +} + +static void venc_write_config(const struct venc_config *config) +{ + DSSDBG("write venc conf\n"); + + venc_write_reg(VENC_LLEN, config->llen); + venc_write_reg(VENC_FLENS, config->flens); + venc_write_reg(VENC_CC_CARR_WSS_CARR, config->cc_carr_wss_carr); + venc_write_reg(VENC_C_PHASE, config->c_phase); + venc_write_reg(VENC_GAIN_U, config->gain_u); + venc_write_reg(VENC_GAIN_V, config->gain_v); + venc_write_reg(VENC_GAIN_Y, config->gain_y); + venc_write_reg(VENC_BLACK_LEVEL, config->black_level); + venc_write_reg(VENC_BLANK_LEVEL, config->blank_level); + venc_write_reg(VENC_M_CONTROL, config->m_control); + venc_write_reg(VENC_BSTAMP_WSS_DATA, config->bstamp_wss_data | + venc.wss_data); + venc_write_reg(VENC_S_CARR, config->s_carr); + venc_write_reg(VENC_L21__WC_CTL, config->l21__wc_ctl); + venc_write_reg(VENC_SAVID__EAVID, config->savid__eavid); + venc_write_reg(VENC_FLEN__FAL, config->flen__fal); + venc_write_reg(VENC_LAL__PHASE_RESET, config->lal__phase_reset); + venc_write_reg(VENC_HS_INT_START_STOP_X, config->hs_int_start_stop_x); + venc_write_reg(VENC_HS_EXT_START_STOP_X, config->hs_ext_start_stop_x); + venc_write_reg(VENC_VS_INT_START_X, config->vs_int_start_x); + venc_write_reg(VENC_VS_INT_STOP_X__VS_INT_START_Y, + config->vs_int_stop_x__vs_int_start_y); + venc_write_reg(VENC_VS_INT_STOP_Y__VS_EXT_START_X, + config->vs_int_stop_y__vs_ext_start_x); + venc_write_reg(VENC_VS_EXT_STOP_X__VS_EXT_START_Y, + config->vs_ext_stop_x__vs_ext_start_y); + venc_write_reg(VENC_VS_EXT_STOP_Y, config->vs_ext_stop_y); + venc_write_reg(VENC_AVID_START_STOP_X, config->avid_start_stop_x); + venc_write_reg(VENC_AVID_START_STOP_Y, config->avid_start_stop_y); + venc_write_reg(VENC_FID_INT_START_X__FID_INT_START_Y, + config->fid_int_start_x__fid_int_start_y); + venc_write_reg(VENC_FID_INT_OFFSET_Y__FID_EXT_START_X, + config->fid_int_offset_y__fid_ext_start_x); + venc_write_reg(VENC_FID_EXT_START_Y__FID_EXT_OFFSET_Y, + config->fid_ext_start_y__fid_ext_offset_y); + + venc_write_reg(VENC_DAC_B__DAC_C, venc_read_reg(VENC_DAC_B__DAC_C)); + venc_write_reg(VENC_VIDOUT_CTRL, config->vidout_ctrl); + venc_write_reg(VENC_HFLTR_CTRL, config->hfltr_ctrl); + venc_write_reg(VENC_X_COLOR, config->x_color); + venc_write_reg(VENC_LINE21, config->line21); + venc_write_reg(VENC_LN_SEL, config->ln_sel); + venc_write_reg(VENC_HTRIGGER_VTRIGGER, config->htrigger_vtrigger); + venc_write_reg(VENC_TVDETGP_INT_START_STOP_X, + config->tvdetgp_int_start_stop_x); + venc_write_reg(VENC_TVDETGP_INT_START_STOP_Y, + config->tvdetgp_int_start_stop_y); + venc_write_reg(VENC_GEN_CTRL, config->gen_ctrl); + venc_write_reg(VENC_F_CONTROL, config->f_control); + venc_write_reg(VENC_SYNC_CTRL, config->sync_ctrl); +} + +static void venc_reset(void) +{ + int t = 1000; + + venc_write_reg(VENC_F_CONTROL, 1<<8); + while (venc_read_reg(VENC_F_CONTROL) & (1<<8)) { + if (--t == 0) { + DSSERR("Failed to reset venc\n"); + return; + } + } + + /* the magical sleep that makes things work */ + msleep(20); +} + +static void venc_enable_clocks(int enable) +{ + if (enable) + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_54M | + DSS_CLK_96M); + else + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_54M | + DSS_CLK_96M); +} + +static const struct venc_config *venc_timings_to_config( + struct omap_video_timings *timings) +{ + if (memcmp(&omap_dss_pal_timings, timings, sizeof(*timings)) == 0) + return &venc_config_pal_trm; + + if (memcmp(&omap_dss_ntsc_timings, timings, sizeof(*timings)) == 0) + return &venc_config_ntsc_trm; + + BUG(); +} + + + + + +/* driver */ +static int venc_panel_probe(struct omap_dss_device *dssdev) +{ + dssdev->panel.timings = omap_dss_pal_timings; + + return 0; +} + +static void venc_panel_remove(struct omap_dss_device *dssdev) +{ +} + +static int venc_panel_enable(struct omap_dss_device *dssdev) +{ + int r = 0; + + /* wait couple of vsyncs until enabling the LCD */ + msleep(50); + + if (dssdev->platform_enable) + r = dssdev->platform_enable(dssdev); + + return r; +} + +static void venc_panel_disable(struct omap_dss_device *dssdev) +{ + if (dssdev->platform_disable) + dssdev->platform_disable(dssdev); + + /* wait at least 5 vsyncs after disabling the LCD */ + + msleep(100); +} + +static int venc_panel_suspend(struct omap_dss_device *dssdev) +{ + venc_panel_disable(dssdev); + return 0; +} + +static int venc_panel_resume(struct omap_dss_device *dssdev) +{ + return venc_panel_enable(dssdev); +} + +static struct omap_dss_driver venc_driver = { + .probe = venc_panel_probe, + .remove = venc_panel_remove, + + .enable = venc_panel_enable, + .disable = venc_panel_disable, + .suspend = venc_panel_suspend, + .resume = venc_panel_resume, + + .driver = { + .name = "venc", + .owner = THIS_MODULE, + }, +}; +/* driver end */ + + + +int venc_init(struct platform_device *pdev) +{ + u8 rev_id; + + mutex_init(&venc.venc_lock); + + venc.wss_data = 0; + + venc.base = ioremap(VENC_BASE, SZ_1K); + if (!venc.base) { + DSSERR("can't ioremap VENC\n"); + return -ENOMEM; + } + + venc.vdda_dac_reg = regulator_get(&pdev->dev, "vdda_dac"); + if (IS_ERR(venc.vdda_dac_reg)) { + iounmap(venc.base); + DSSERR("can't get VDDA_DAC regulator\n"); + return PTR_ERR(venc.vdda_dac_reg); + } + + venc_enable_clocks(1); + + rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff); + printk(KERN_INFO "OMAP VENC rev %d\n", rev_id); + + venc_enable_clocks(0); + + return omap_dss_register_driver(&venc_driver); +} + +void venc_exit(void) +{ + omap_dss_unregister_driver(&venc_driver); + + regulator_put(venc.vdda_dac_reg); + + iounmap(venc.base); +} + +static void venc_power_on(struct omap_dss_device *dssdev) +{ + venc_enable_clocks(1); + + venc_reset(); + venc_write_config(venc_timings_to_config(&dssdev->panel.timings)); + + dss_set_venc_output(dssdev->phy.venc.type); + dss_set_dac_pwrdn_bgz(1); + + if (dssdev->phy.venc.type == OMAP_DSS_VENC_TYPE_COMPOSITE) { + if (cpu_is_omap24xx()) + venc_write_reg(VENC_OUTPUT_CONTROL, 0x2); + else + venc_write_reg(VENC_OUTPUT_CONTROL, 0xa); + } else { /* S-Video */ + venc_write_reg(VENC_OUTPUT_CONTROL, 0xd); + } + + dispc_set_digit_size(dssdev->panel.timings.x_res, + dssdev->panel.timings.y_res/2); + + regulator_enable(venc.vdda_dac_reg); + + if (dssdev->platform_enable) + dssdev->platform_enable(dssdev); + + dispc_enable_digit_out(1); +} + +static void venc_power_off(struct omap_dss_device *dssdev) +{ + venc_write_reg(VENC_OUTPUT_CONTROL, 0); + dss_set_dac_pwrdn_bgz(0); + + dispc_enable_digit_out(0); + + if (dssdev->platform_disable) + dssdev->platform_disable(dssdev); + + regulator_disable(venc.vdda_dac_reg); + + venc_enable_clocks(0); +} + +static int venc_enable_display(struct omap_dss_device *dssdev) +{ + int r = 0; + + DSSDBG("venc_enable_display\n"); + + mutex_lock(&venc.venc_lock); + + if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { + r = -EINVAL; + goto err; + } + + venc_power_on(dssdev); + + venc.wss_data = 0; + + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; +err: + mutex_unlock(&venc.venc_lock); + + return r; +} + +static void venc_disable_display(struct omap_dss_device *dssdev) +{ + DSSDBG("venc_disable_display\n"); + + mutex_lock(&venc.venc_lock); + + if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED) + goto end; + + if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) { + /* suspended is the same as disabled with venc */ + dssdev->state = OMAP_DSS_DISPLAY_DISABLED; + goto end; + } + + venc_power_off(dssdev); + + dssdev->state = OMAP_DSS_DISPLAY_DISABLED; +end: + mutex_unlock(&venc.venc_lock); +} + +static int venc_display_suspend(struct omap_dss_device *dssdev) +{ + int r = 0; + + DSSDBG("venc_display_suspend\n"); + + mutex_lock(&venc.venc_lock); + + if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) { + r = -EINVAL; + goto err; + } + + venc_power_off(dssdev); + + dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; +err: + mutex_unlock(&venc.venc_lock); + + return r; +} + +static int venc_display_resume(struct omap_dss_device *dssdev) +{ + int r = 0; + + DSSDBG("venc_display_resume\n"); + + mutex_lock(&venc.venc_lock); + + if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) { + r = -EINVAL; + goto err; + } + + venc_power_on(dssdev); + + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; +err: + mutex_unlock(&venc.venc_lock); + + return r; +} + +static void venc_get_timings(struct omap_dss_device *dssdev, + struct omap_video_timings *timings) +{ + *timings = dssdev->panel.timings; +} + +static void venc_set_timings(struct omap_dss_device *dssdev, + struct omap_video_timings *timings) +{ + DSSDBG("venc_set_timings\n"); + + /* Reset WSS data when the TV standard changes. */ + if (memcmp(&dssdev->panel.timings, timings, sizeof(*timings))) + venc.wss_data = 0; + + dssdev->panel.timings = *timings; + if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { + /* turn the venc off and on to get new timings to use */ + venc_disable_display(dssdev); + venc_enable_display(dssdev); + } +} + +static int venc_check_timings(struct omap_dss_device *dssdev, + struct omap_video_timings *timings) +{ + DSSDBG("venc_check_timings\n"); + + if (memcmp(&omap_dss_pal_timings, timings, sizeof(*timings)) == 0) + return 0; + + if (memcmp(&omap_dss_ntsc_timings, timings, sizeof(*timings)) == 0) + return 0; + + return -EINVAL; +} + +static u32 venc_get_wss(struct omap_dss_device *dssdev) +{ + /* Invert due to VENC_L21_WC_CTL:INV=1 */ + return (venc.wss_data >> 8) ^ 0xfffff; +} + +static int venc_set_wss(struct omap_dss_device *dssdev, u32 wss) +{ + const struct venc_config *config; + + DSSDBG("venc_set_wss\n"); + + mutex_lock(&venc.venc_lock); + + config = venc_timings_to_config(&dssdev->panel.timings); + + /* Invert due to VENC_L21_WC_CTL:INV=1 */ + venc.wss_data = (wss ^ 0xfffff) << 8; + + venc_enable_clocks(1); + + venc_write_reg(VENC_BSTAMP_WSS_DATA, config->bstamp_wss_data | + venc.wss_data); + + venc_enable_clocks(0); + + mutex_unlock(&venc.venc_lock); + + return 0; +} + +int venc_init_display(struct omap_dss_device *dssdev) +{ + DSSDBG("init_display\n"); + + dssdev->enable = venc_enable_display; + dssdev->disable = venc_disable_display; + dssdev->suspend = venc_display_suspend; + dssdev->resume = venc_display_resume; + dssdev->get_timings = venc_get_timings; + dssdev->set_timings = venc_set_timings; + dssdev->check_timings = venc_check_timings; + dssdev->get_wss = venc_get_wss; + dssdev->set_wss = venc_set_wss; + + return 0; +} + +void venc_dump_regs(struct seq_file *s) +{ +#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r)) + + venc_enable_clocks(1); + + DUMPREG(VENC_F_CONTROL); + DUMPREG(VENC_VIDOUT_CTRL); + DUMPREG(VENC_SYNC_CTRL); + DUMPREG(VENC_LLEN); + DUMPREG(VENC_FLENS); + DUMPREG(VENC_HFLTR_CTRL); + DUMPREG(VENC_CC_CARR_WSS_CARR); + DUMPREG(VENC_C_PHASE); + DUMPREG(VENC_GAIN_U); + DUMPREG(VENC_GAIN_V); + DUMPREG(VENC_GAIN_Y); + DUMPREG(VENC_BLACK_LEVEL); + DUMPREG(VENC_BLANK_LEVEL); + DUMPREG(VENC_X_COLOR); + DUMPREG(VENC_M_CONTROL); + DUMPREG(VENC_BSTAMP_WSS_DATA); + DUMPREG(VENC_S_CARR); + DUMPREG(VENC_LINE21); + DUMPREG(VENC_LN_SEL); + DUMPREG(VENC_L21__WC_CTL); + DUMPREG(VENC_HTRIGGER_VTRIGGER); + DUMPREG(VENC_SAVID__EAVID); + DUMPREG(VENC_FLEN__FAL); + DUMPREG(VENC_LAL__PHASE_RESET); + DUMPREG(VENC_HS_INT_START_STOP_X); + DUMPREG(VENC_HS_EXT_START_STOP_X); + DUMPREG(VENC_VS_INT_START_X); + DUMPREG(VENC_VS_INT_STOP_X__VS_INT_START_Y); + DUMPREG(VENC_VS_INT_STOP_Y__VS_EXT_START_X); + DUMPREG(VENC_VS_EXT_STOP_X__VS_EXT_START_Y); + DUMPREG(VENC_VS_EXT_STOP_Y); + DUMPREG(VENC_AVID_START_STOP_X); + DUMPREG(VENC_AVID_START_STOP_Y); + DUMPREG(VENC_FID_INT_START_X__FID_INT_START_Y); + DUMPREG(VENC_FID_INT_OFFSET_Y__FID_EXT_START_X); + DUMPREG(VENC_FID_EXT_START_Y__FID_EXT_OFFSET_Y); + DUMPREG(VENC_TVDETGP_INT_START_STOP_X); + DUMPREG(VENC_TVDETGP_INT_START_STOP_Y); + DUMPREG(VENC_GEN_CTRL); + DUMPREG(VENC_OUTPUT_CONTROL); + DUMPREG(VENC_OUTPUT_TEST); + + venc_enable_clocks(0); + +#undef DUMPREG +} diff --git a/drivers/video/omap2/omapfb/Kconfig b/drivers/video/omap2/omapfb/Kconfig new file mode 100644 index 000000000000..77ca9c9d6390 --- /dev/null +++ b/drivers/video/omap2/omapfb/Kconfig @@ -0,0 +1,35 @@ +menuconfig FB_OMAP2 + tristate "OMAP2/3 frame buffer support (EXPERIMENTAL)" + depends on FB && OMAP2_DSS + default y + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + Frame buffer driver for OMAP2/3 based boards. + +config FB_OMAP2_DEBUG_SUPPORT + bool "Debug support for OMAP2/3 FB" + default y + depends on FB_OMAP2 + help + Support for debug output. You have to enable the actual printing + with debug module parameter. + +config FB_OMAP2_FORCE_AUTO_UPDATE + bool "Force main display to automatic update mode" + depends on FB_OMAP2 + help + Forces main display to automatic update mode (if possible), + and also enables tearsync (if possible). By default + displays that support manual update are started in manual + update mode. + +config FB_OMAP2_NUM_FBS + int "Number of framebuffers" + range 1 10 + default 3 + depends on FB_OMAP2 + help + Select the number of framebuffers created. OMAP2/3 has 3 overlays + so normally this would be 3. diff --git a/drivers/video/omap2/omapfb/Makefile b/drivers/video/omap2/omapfb/Makefile new file mode 100644 index 000000000000..51c2e00d9bf8 --- /dev/null +++ b/drivers/video/omap2/omapfb/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_FB_OMAP2) += omapfb.o +omapfb-y := omapfb-main.o omapfb-sysfs.o omapfb-ioctl.o diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c new file mode 100644 index 000000000000..257f7cbc0e00 --- /dev/null +++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c @@ -0,0 +1,709 @@ +/* + * linux/drivers/video/omap2/omapfb-ioctl.c + * + * Copyright (C) 2008 Nokia Corporation + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> + * + * Some code and ideas taken from drivers/video/omap/ driver + * by Imre Deak. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/fb.h> +#include <linux/device.h> +#include <linux/uaccess.h> +#include <linux/platform_device.h> +#include <linux/mm.h> +#include <linux/omapfb.h> +#include <linux/vmalloc.h> + +#include <mach/display.h> +#include <mach/vrfb.h> + +#include "omapfb.h" + +static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi) +{ + struct omapfb_info *ofbi = FB2OFB(fbi); + struct omapfb2_device *fbdev = ofbi->fbdev; + struct omap_dss_device *display = fb2display(fbi); + struct omap_overlay *ovl; + struct omap_overlay_info info; + int r = 0; + + DBG("omapfb_setup_plane\n"); + + if (ofbi->num_overlays != 1) { + r = -EINVAL; + goto out; + } + + /* XXX uses only the first overlay */ + ovl = ofbi->overlays[0]; + + if (pi->enabled && !ofbi->region.size) { + /* + * This plane's memory was freed, can't enable it + * until it's reallocated. + */ + r = -EINVAL; + goto out; + } + + ovl->get_overlay_info(ovl, &info); + + info.pos_x = pi->pos_x; + info.pos_y = pi->pos_y; + info.out_width = pi->out_width; + info.out_height = pi->out_height; + info.enabled = pi->enabled; + + r = ovl->set_overlay_info(ovl, &info); + if (r) + goto out; + + if (ovl->manager) { + r = ovl->manager->apply(ovl->manager); + if (r) + goto out; + } + + if (display) { + u16 w, h; + + if (display->sync) + display->sync(display); + + display->get_resolution(display, &w, &h); + + if (display->update) + display->update(display, 0, 0, w, h); + } + +out: + if (r) + dev_err(fbdev->dev, "setup_plane failed\n"); + return r; +} + +static int omapfb_query_plane(struct fb_info *fbi, struct omapfb_plane_info *pi) +{ + struct omapfb_info *ofbi = FB2OFB(fbi); + + if (ofbi->num_overlays != 1) { + memset(pi, 0, sizeof(*pi)); + } else { + struct omap_overlay_info *ovli; + struct omap_overlay *ovl; + + ovl = ofbi->overlays[0]; + ovli = &ovl->info; + + pi->pos_x = ovli->pos_x; + pi->pos_y = ovli->pos_y; + pi->enabled = ovli->enabled; + pi->channel_out = 0; /* xxx */ + pi->mirror = 0; + pi->out_width = ovli->out_width; + pi->out_height = ovli->out_height; + } + + return 0; +} + +static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi) +{ + struct omapfb_info *ofbi = FB2OFB(fbi); + struct omapfb2_device *fbdev = ofbi->fbdev; + struct omapfb2_mem_region *rg; + int r, i; + size_t size; + + if (mi->type > OMAPFB_MEMTYPE_MAX) + return -EINVAL; + + size = PAGE_ALIGN(mi->size); + + rg = &ofbi->region; + + for (i = 0; i < ofbi->num_overlays; i++) { + if (ofbi->overlays[i]->info.enabled) + return -EBUSY; + } + + if (rg->size != size || rg->type != mi->type) { + r = omapfb_realloc_fbmem(fbi, size, mi->type); + if (r) { + dev_err(fbdev->dev, "realloc fbmem failed\n"); + return r; + } + } + + return 0; +} + +static int omapfb_query_mem(struct fb_info *fbi, struct omapfb_mem_info *mi) +{ + struct omapfb_info *ofbi = FB2OFB(fbi); + struct omapfb2_mem_region *rg; + + rg = &ofbi->region; + memset(mi, 0, sizeof(*mi)); + + mi->size = rg->size; + mi->type = rg->type; + + return 0; +} + +static int omapfb_update_window(struct fb_info *fbi, + u32 x, u32 y, u32 w, u32 h) +{ + struct omap_dss_device *display = fb2display(fbi); + u16 dw, dh; + + if (!display) + return 0; + + if (w == 0 || h == 0) + return 0; + + display->get_resolution(display, &dw, &dh); + + if (x + w > dw || y + h > dh) + return -EINVAL; + + display->update(display, x, y, w, h); + + return 0; +} + +static int omapfb_set_update_mode(struct fb_info *fbi, + enum omapfb_update_mode mode) +{ + struct omap_dss_device *display = fb2display(fbi); + enum omap_dss_update_mode um; + int r; + + if (!display || !display->set_update_mode) + return -EINVAL; + + switch (mode) { + case OMAPFB_UPDATE_DISABLED: + um = OMAP_DSS_UPDATE_DISABLED; + break; + + case OMAPFB_AUTO_UPDATE: + um = OMAP_DSS_UPDATE_AUTO; + break; + + case OMAPFB_MANUAL_UPDATE: + um = OMAP_DSS_UPDATE_MANUAL; + break; + + default: + return -EINVAL; + } + + r = display->set_update_mode(display, um); + + return r; +} + +static int omapfb_get_update_mode(struct fb_info *fbi, + enum omapfb_update_mode *mode) +{ + struct omap_dss_device *display = fb2display(fbi); + enum omap_dss_update_mode m; + + if (!display || !display->get_update_mode) + return -EINVAL; + + m = display->get_update_mode(display); + + switch (m) { + case OMAP_DSS_UPDATE_DISABLED: + *mode = OMAPFB_UPDATE_DISABLED; + break; + case OMAP_DSS_UPDATE_AUTO: + *mode = OMAPFB_AUTO_UPDATE; + break; + case OMAP_DSS_UPDATE_MANUAL: + *mode = OMAPFB_MANUAL_UPDATE; + break; + default: + BUG(); + } + + return 0; +} + +/* XXX this color key handling is a hack... */ +static struct omapfb_color_key omapfb_color_keys[2]; + +static int _omapfb_set_color_key(struct omap_overlay_manager *mgr, + struct omapfb_color_key *ck) +{ + struct omap_overlay_manager_info info; + enum omap_dss_trans_key_type kt; + int r; + + mgr->get_manager_info(mgr, &info); + + if (ck->key_type == OMAPFB_COLOR_KEY_DISABLED) { + info.trans_enabled = false; + omapfb_color_keys[mgr->id] = *ck; + + r = mgr->set_manager_info(mgr, &info); + if (r) + return r; + + r = mgr->apply(mgr); + + return r; + } + + switch (ck->key_type) { + case OMAPFB_COLOR_KEY_GFX_DST: + kt = OMAP_DSS_COLOR_KEY_GFX_DST; + break; + case OMAPFB_COLOR_KEY_VID_SRC: + kt = OMAP_DSS_COLOR_KEY_VID_SRC; + break; + default: + return -EINVAL; + } + + info.default_color = ck->background; + info.trans_key = ck->trans_key; + info.trans_key_type = kt; + info.trans_enabled = true; + + omapfb_color_keys[mgr->id] = *ck; + + r = mgr->set_manager_info(mgr, &info); + if (r) + return r; + + r = mgr->apply(mgr); + + return r; +} + +static int omapfb_set_color_key(struct fb_info *fbi, + struct omapfb_color_key *ck) +{ + struct omapfb_info *ofbi = FB2OFB(fbi); + struct omapfb2_device *fbdev = ofbi->fbdev; + int r; + int i; + struct omap_overlay_manager *mgr = NULL; + + omapfb_lock(fbdev); + + for (i = 0; i < ofbi->num_overlays; i++) { + if (ofbi->overlays[i]->manager) { + mgr = ofbi->overlays[i]->manager; + break; + } + } + + if (!mgr) { + r = -EINVAL; + goto err; + } + + r = _omapfb_set_color_key(mgr, ck); +err: + omapfb_unlock(fbdev); + + return r; +} + +static int omapfb_get_color_key(struct fb_info *fbi, + struct omapfb_color_key *ck) +{ + struct omapfb_info *ofbi = FB2OFB(fbi); + struct omapfb2_device *fbdev = ofbi->fbdev; + struct omap_overlay_manager *mgr = NULL; + int r = 0; + int i; + + omapfb_lock(fbdev); + + for (i = 0; i < ofbi->num_overlays; i++) { + if (ofbi->overlays[i]->manager) { + mgr = ofbi->overlays[i]->manager; + break; + } + } + + if (!mgr) { + r = -EINVAL; + goto err; + } + + *ck = omapfb_color_keys[mgr->id]; +err: + omapfb_unlock(fbdev); + + return r; +} + +static int omapfb_memory_read(struct fb_info *fbi, + struct omapfb_memory_read *mr) +{ + struct omap_dss_device *display = fb2display(fbi); + void *buf; + int r; + + if (!display || !display->memory_read) + return -ENOENT; + + if (!access_ok(VERIFY_WRITE, mr->buffer, mr->buffer_size)) + return -EFAULT; + + if (mr->w * mr->h * 3 > mr->buffer_size) + return -EINVAL; + + buf = vmalloc(mr->buffer_size); + if (!buf) { + DBG("vmalloc failed\n"); + return -ENOMEM; + } + + r = display->memory_read(display, buf, mr->buffer_size, + mr->x, mr->y, mr->w, mr->h); + + if (r > 0) { + if (copy_to_user(mr->buffer, buf, mr->buffer_size)) + r = -EFAULT; + } + + vfree(buf); + + return r; +} + +static int omapfb_get_ovl_colormode(struct omapfb2_device *fbdev, + struct omapfb_ovl_colormode *mode) +{ + int ovl_idx = mode->overlay_idx; + int mode_idx = mode->mode_idx; + struct omap_overlay *ovl; + enum omap_color_mode supported_modes; + struct fb_var_screeninfo var; + int i; + + if (ovl_idx >= fbdev->num_overlays) + return -ENODEV; + ovl = fbdev->overlays[ovl_idx]; + supported_modes = ovl->supported_modes; + + mode_idx = mode->mode_idx; + + for (i = 0; i < sizeof(supported_modes) * 8; i++) { + if (!(supported_modes & (1 << i))) + continue; + /* + * It's possible that the FB doesn't support a mode + * that is supported by the overlay, so call the + * following here. + */ + if (dss_mode_to_fb_mode(1 << i, &var) < 0) + continue; + + mode_idx--; + if (mode_idx < 0) + break; + } + + if (i == sizeof(supported_modes) * 8) + return -ENOENT; + + mode->bits_per_pixel = var.bits_per_pixel; + mode->nonstd = var.nonstd; + mode->red = var.red; + mode->green = var.green; + mode->blue = var.blue; + mode->transp = var.transp; + + return 0; +} + +static int omapfb_wait_for_go(struct fb_info *fbi) +{ + struct omapfb_info *ofbi = FB2OFB(fbi); + int r = 0; + int i; + + for (i = 0; i < ofbi->num_overlays; ++i) { + struct omap_overlay *ovl = ofbi->overlays[i]; + r = ovl->wait_for_go(ovl); + if (r) + break; + } + + return r; +} + +int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) +{ + struct omapfb_info *ofbi = FB2OFB(fbi); + struct omapfb2_device *fbdev = ofbi->fbdev; + struct omap_dss_device *display = fb2display(fbi); + + union { + struct omapfb_update_window_old uwnd_o; + struct omapfb_update_window uwnd; + struct omapfb_plane_info plane_info; + struct omapfb_caps caps; + struct omapfb_mem_info mem_info; + struct omapfb_color_key color_key; + struct omapfb_ovl_colormode ovl_colormode; + enum omapfb_update_mode update_mode; + int test_num; + struct omapfb_memory_read memory_read; + } p; + + int r = 0; + + switch (cmd) { + case OMAPFB_SYNC_GFX: + DBG("ioctl SYNC_GFX\n"); + if (!display || !display->sync) { + /* DSS1 never returns an error here, so we neither */ + /*r = -EINVAL;*/ + break; + } + + r = display->sync(display); + break; + + case OMAPFB_UPDATE_WINDOW_OLD: + DBG("ioctl UPDATE_WINDOW_OLD\n"); + if (!display || !display->update) { + r = -EINVAL; + break; + } + + if (copy_from_user(&p.uwnd_o, + (void __user *)arg, + sizeof(p.uwnd_o))) { + r = -EFAULT; + break; + } + + r = omapfb_update_window(fbi, p.uwnd_o.x, p.uwnd_o.y, + p.uwnd_o.width, p.uwnd_o.height); + break; + + case OMAPFB_UPDATE_WINDOW: + DBG("ioctl UPDATE_WINDOW\n"); + if (!display || !display->update) { + r = -EINVAL; + break; + } + + if (copy_from_user(&p.uwnd, (void __user *)arg, + sizeof(p.uwnd))) { + r = -EFAULT; + break; + } + + r = omapfb_update_window(fbi, p.uwnd.x, p.uwnd.y, + p.uwnd.width, p.uwnd.height); + break; + + case OMAPFB_SETUP_PLANE: + DBG("ioctl SETUP_PLANE\n"); + if (copy_from_user(&p.plane_info, (void __user *)arg, + sizeof(p.plane_info))) + r = -EFAULT; + else + r = omapfb_setup_plane(fbi, &p.plane_info); + break; + + case OMAPFB_QUERY_PLANE: + DBG("ioctl QUERY_PLANE\n"); + r = omapfb_query_plane(fbi, &p.plane_info); + if (r < 0) + break; + if (copy_to_user((void __user *)arg, &p.plane_info, + sizeof(p.plane_info))) + r = -EFAULT; + break; + + case OMAPFB_SETUP_MEM: + DBG("ioctl SETUP_MEM\n"); + if (copy_from_user(&p.mem_info, (void __user *)arg, + sizeof(p.mem_info))) + r = -EFAULT; + else + r = omapfb_setup_mem(fbi, &p.mem_info); + break; + + case OMAPFB_QUERY_MEM: + DBG("ioctl QUERY_MEM\n"); + r = omapfb_query_mem(fbi, &p.mem_info); + if (r < 0) + break; + if (copy_to_user((void __user *)arg, &p.mem_info, + sizeof(p.mem_info))) + r = -EFAULT; + break; + + case OMAPFB_GET_CAPS: + DBG("ioctl GET_CAPS\n"); + if (!display) { + r = -EINVAL; + break; + } + + memset(&p.caps, 0, sizeof(p.caps)); + p.caps.ctrl = display->caps; + + if (copy_to_user((void __user *)arg, &p.caps, sizeof(p.caps))) + r = -EFAULT; + break; + + case OMAPFB_GET_OVERLAY_COLORMODE: + DBG("ioctl GET_OVERLAY_COLORMODE\n"); + if (copy_from_user(&p.ovl_colormode, (void __user *)arg, + sizeof(p.ovl_colormode))) { + r = -EFAULT; + break; + } + r = omapfb_get_ovl_colormode(fbdev, &p.ovl_colormode); + if (r < 0) + break; + if (copy_to_user((void __user *)arg, &p.ovl_colormode, + sizeof(p.ovl_colormode))) + r = -EFAULT; + break; + + case OMAPFB_SET_UPDATE_MODE: + DBG("ioctl SET_UPDATE_MODE\n"); + if (get_user(p.update_mode, (int __user *)arg)) + r = -EFAULT; + else + r = omapfb_set_update_mode(fbi, p.update_mode); + break; + + case OMAPFB_GET_UPDATE_MODE: + DBG("ioctl GET_UPDATE_MODE\n"); + r = omapfb_get_update_mode(fbi, &p.update_mode); + if (r) + break; + if (put_user(p.update_mode, + (enum omapfb_update_mode __user *)arg)) + r = -EFAULT; + break; + + case OMAPFB_SET_COLOR_KEY: + DBG("ioctl SET_COLOR_KEY\n"); + if (copy_from_user(&p.color_key, (void __user *)arg, + sizeof(p.color_key))) + r = -EFAULT; + else + r = omapfb_set_color_key(fbi, &p.color_key); + break; + + case OMAPFB_GET_COLOR_KEY: + DBG("ioctl GET_COLOR_KEY\n"); + r = omapfb_get_color_key(fbi, &p.color_key); + if (r) + break; + if (copy_to_user((void __user *)arg, &p.color_key, + sizeof(p.color_key))) + r = -EFAULT; + break; + + case OMAPFB_WAITFORVSYNC: + DBG("ioctl WAITFORVSYNC\n"); + if (!display) { + r = -EINVAL; + break; + } + + r = display->wait_vsync(display); + break; + + case OMAPFB_WAITFORGO: + DBG("ioctl WAITFORGO\n"); + if (!display) { + r = -EINVAL; + break; + } + + r = omapfb_wait_for_go(fbi); + break; + + /* LCD and CTRL tests do the same thing for backward + * compatibility */ + case OMAPFB_LCD_TEST: + DBG("ioctl LCD_TEST\n"); + if (get_user(p.test_num, (int __user *)arg)) { + r = -EFAULT; + break; + } + if (!display || !display->run_test) { + r = -EINVAL; + break; + } + + r = display->run_test(display, p.test_num); + + break; + + case OMAPFB_CTRL_TEST: + DBG("ioctl CTRL_TEST\n"); + if (get_user(p.test_num, (int __user *)arg)) { + r = -EFAULT; + break; + } + if (!display || !display->run_test) { + r = -EINVAL; + break; + } + + r = display->run_test(display, p.test_num); + + break; + + case OMAPFB_MEMORY_READ: + DBG("ioctl MEMORY_READ\n"); + + if (copy_from_user(&p.memory_read, (void __user *)arg, + sizeof(p.memory_read))) { + r = -EFAULT; + break; + } + + r = omapfb_memory_read(fbi, &p.memory_read); + + break; + + default: + dev_err(fbdev->dev, "Unknown ioctl 0x%x\n", cmd); + r = -EINVAL; + } + + if (r < 0) + DBG("ioctl failed: %d\n", r); + + return r; +} + + diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c new file mode 100644 index 000000000000..7806d20711c0 --- /dev/null +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -0,0 +1,2143 @@ +/* + * linux/drivers/video/omap2/omapfb-main.c + * + * Copyright (C) 2008 Nokia Corporation + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> + * + * Some code and ideas taken from drivers/video/omap/ driver + * by Imre Deak. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/module.h> +#include <linux/delay.h> +#include <linux/fb.h> +#include <linux/dma-mapping.h> +#include <linux/vmalloc.h> +#include <linux/device.h> +#include <linux/platform_device.h> +#include <linux/omapfb.h> + +#include <mach/display.h> +#include <mach/vram.h> +#include <mach/vrfb.h> + +#include "omapfb.h" + +#define MODULE_NAME "omapfb" + +static char *def_mode; +static char *def_vram; +static int def_vrfb; +static int def_rotate; +static int def_mirror; + +#ifdef DEBUG +unsigned int omapfb_debug; +module_param_named(debug, omapfb_debug, bool, 0644); +static unsigned int omapfb_test_pattern; +module_param_named(test, omapfb_test_pattern, bool, 0644); +#endif + +#ifdef DEBUG +static void draw_pixel(struct fb_info *fbi, int x, int y, unsigned color) +{ + struct fb_var_screeninfo *var = &fbi->var; + struct fb_fix_screeninfo *fix = &fbi->fix; + void __iomem *addr = fbi->screen_base; + const unsigned bytespp = var->bits_per_pixel >> 3; + const unsigned line_len = fix->line_length / bytespp; + + int r = (color >> 16) & 0xff; + int g = (color >> 8) & 0xff; + int b = (color >> 0) & 0xff; + + if (var->bits_per_pixel == 16) { + u16 __iomem *p = (u16 __iomem *)addr; + p += y * line_len + x; + + r = r * 32 / 256; + g = g * 64 / 256; + b = b * 32 / 256; + + __raw_writew((r << 11) | (g << 5) | (b << 0), p); + } else if (var->bits_per_pixel == 24) { + u8 __iomem *p = (u8 __iomem *)addr; + p += (y * line_len + x) * 3; + + __raw_writeb(b, p + 0); + __raw_writeb(g, p + 1); + __raw_writeb(r, p + 2); + } else if (var->bits_per_pixel == 32) { + u32 __iomem *p = (u32 __iomem *)addr; + p += y * line_len + x; + __raw_writel(color, p); + } +} + +static void fill_fb(struct fb_info *fbi) +{ + struct fb_var_screeninfo *var = &fbi->var; + const short w = var->xres_virtual; + const short h = var->yres_virtual; + void __iomem *addr = fbi->screen_base; + int y, x; + + if (!addr) + return; + + DBG("fill_fb %dx%d, line_len %d bytes\n", w, h, fbi->fix.line_length); + + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + if (x < 20 && y < 20) + draw_pixel(fbi, x, y, 0xffffff); + else if (x < 20 && (y > 20 && y < h - 20)) + draw_pixel(fbi, x, y, 0xff); + else if (y < 20 && (x > 20 && x < w - 20)) + draw_pixel(fbi, x, y, 0xff00); + else if (x > w - 20 && (y > 20 && y < h - 20)) + draw_pixel(fbi, x, y, 0xff0000); + else if (y > h - 20 && (x > 20 && x < w - 20)) + draw_pixel(fbi, x, y, 0xffff00); + else if (x == 20 || x == w - 20 || + y == 20 || y == h - 20) + draw_pixel(fbi, x, y, 0xffffff); + else if (x == y || w - x == h - y) + draw_pixel(fbi, x, y, 0xff00ff); + else if (w - x == y || x == h - y) + draw_pixel(fbi, x, y, 0x00ffff); + else if (x > 20 && y > 20 && x < w - 20 && y < h - 20) { + int t = x * 3 / w; + unsigned r = 0, g = 0, b = 0; + unsigned c; + if (var->bits_per_pixel == 16) { + if (t == 0) + b = (y % 32) * 256 / 32; + else if (t == 1) + g = (y % 64) * 256 / 64; + else if (t == 2) + r = (y % 32) * 256 / 32; + } else { + if (t == 0) + b = (y % 256); + else if (t == 1) + g = (y % 256); + else if (t == 2) + r = (y % 256); + } + c = (r << 16) | (g << 8) | (b << 0); + draw_pixel(fbi, x, y, c); + } else { + draw_pixel(fbi, x, y, 0); + } + } + } +} +#endif + +static unsigned omapfb_get_vrfb_offset(struct omapfb_info *ofbi, int rot) +{ + struct vrfb *vrfb = &ofbi->region.vrfb; + unsigned offset; + + switch (rot) { + case FB_ROTATE_UR: + offset = 0; + break; + case FB_ROTATE_CW: + offset = vrfb->yoffset; + break; + case FB_ROTATE_UD: + offset = vrfb->yoffset * OMAP_VRFB_LINE_LEN + vrfb->xoffset; + break; + case FB_ROTATE_CCW: + offset = vrfb->xoffset * OMAP_VRFB_LINE_LEN; + break; + default: + BUG(); + } + + offset *= vrfb->bytespp; + + return offset; +} + +static u32 omapfb_get_region_rot_paddr(struct omapfb_info *ofbi, int rot) +{ + if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { + return ofbi->region.vrfb.paddr[rot] + + omapfb_get_vrfb_offset(ofbi, rot); + } else { + return ofbi->region.paddr; + } +} + +u32 omapfb_get_region_paddr(struct omapfb_info *ofbi) +{ + if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) + return ofbi->region.vrfb.paddr[0]; + else + return ofbi->region.paddr; +} + +void __iomem *omapfb_get_region_vaddr(struct omapfb_info *ofbi) +{ + if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) + return ofbi->region.vrfb.vaddr[0]; + else + return ofbi->region.vaddr; +} + +static struct omapfb_colormode omapfb_colormodes[] = { + { + .dssmode = OMAP_DSS_COLOR_UYVY, + .bits_per_pixel = 16, + .nonstd = OMAPFB_COLOR_YUV422, + }, { + .dssmode = OMAP_DSS_COLOR_YUV2, + .bits_per_pixel = 16, + .nonstd = OMAPFB_COLOR_YUY422, + }, { + .dssmode = OMAP_DSS_COLOR_ARGB16, + .bits_per_pixel = 16, + .red = { .length = 4, .offset = 8, .msb_right = 0 }, + .green = { .length = 4, .offset = 4, .msb_right = 0 }, + .blue = { .length = 4, .offset = 0, .msb_right = 0 }, + .transp = { .length = 4, .offset = 12, .msb_right = 0 }, + }, { + .dssmode = OMAP_DSS_COLOR_RGB16, + .bits_per_pixel = 16, + .red = { .length = 5, .offset = 11, .msb_right = 0 }, + .green = { .length = 6, .offset = 5, .msb_right = 0 }, + .blue = { .length = 5, .offset = 0, .msb_right = 0 }, + .transp = { .length = 0, .offset = 0, .msb_right = 0 }, + }, { + .dssmode = OMAP_DSS_COLOR_RGB24P, + .bits_per_pixel = 24, + .red = { .length = 8, .offset = 16, .msb_right = 0 }, + .green = { .length = 8, .offset = 8, .msb_right = 0 }, + .blue = { .length = 8, .offset = 0, .msb_right = 0 }, + .transp = { .length = 0, .offset = 0, .msb_right = 0 }, + }, { + .dssmode = OMAP_DSS_COLOR_RGB24U, + .bits_per_pixel = 32, + .red = { .length = 8, .offset = 16, .msb_right = 0 }, + .green = { .length = 8, .offset = 8, .msb_right = 0 }, + .blue = { .length = 8, .offset = 0, .msb_right = 0 }, + .transp = { .length = 0, .offset = 0, .msb_right = 0 }, + }, { + .dssmode = OMAP_DSS_COLOR_ARGB32, + .bits_per_pixel = 32, + .red = { .length = 8, .offset = 16, .msb_right = 0 }, + .green = { .length = 8, .offset = 8, .msb_right = 0 }, + .blue = { .length = 8, .offset = 0, .msb_right = 0 }, + .transp = { .length = 8, .offset = 24, .msb_right = 0 }, + }, { + .dssmode = OMAP_DSS_COLOR_RGBA32, + .bits_per_pixel = 32, + .red = { .length = 8, .offset = 24, .msb_right = 0 }, + .green = { .length = 8, .offset = 16, .msb_right = 0 }, + .blue = { .length = 8, .offset = 8, .msb_right = 0 }, + .transp = { .length = 8, .offset = 0, .msb_right = 0 }, + }, { + .dssmode = OMAP_DSS_COLOR_RGBX32, + .bits_per_pixel = 32, + .red = { .length = 8, .offset = 24, .msb_right = 0 }, + .green = { .length = 8, .offset = 16, .msb_right = 0 }, + .blue = { .length = 8, .offset = 8, .msb_right = 0 }, + .transp = { .length = 0, .offset = 0, .msb_right = 0 }, + }, +}; + +static bool cmp_var_to_colormode(struct fb_var_screeninfo *var, + struct omapfb_colormode *color) +{ + bool cmp_component(struct fb_bitfield *f1, struct fb_bitfield *f2) + { + return f1->length == f2->length && + f1->offset == f2->offset && + f1->msb_right == f2->msb_right; + } + + if (var->bits_per_pixel == 0 || + var->red.length == 0 || + var->blue.length == 0 || + var->green.length == 0) + return 0; + + return var->bits_per_pixel == color->bits_per_pixel && + cmp_component(&var->red, &color->red) && + cmp_component(&var->green, &color->green) && + cmp_component(&var->blue, &color->blue) && + cmp_component(&var->transp, &color->transp); +} + +static void assign_colormode_to_var(struct fb_var_screeninfo *var, + struct omapfb_colormode *color) +{ + var->bits_per_pixel = color->bits_per_pixel; + var->nonstd = color->nonstd; + var->red = color->red; + var->green = color->green; + var->blue = color->blue; + var->transp = color->transp; +} + +static enum omap_color_mode fb_mode_to_dss_mode(struct fb_var_screeninfo *var) +{ + enum omap_color_mode dssmode; + int i; + + /* first match with nonstd field */ + if (var->nonstd) { + for (i = 0; i < ARRAY_SIZE(omapfb_colormodes); ++i) { + struct omapfb_colormode *mode = &omapfb_colormodes[i]; + if (var->nonstd == mode->nonstd) { + assign_colormode_to_var(var, mode); + return mode->dssmode; + } + } + + return -EINVAL; + } + + /* then try exact match of bpp and colors */ + for (i = 0; i < ARRAY_SIZE(omapfb_colormodes); ++i) { + struct omapfb_colormode *mode = &omapfb_colormodes[i]; + if (cmp_var_to_colormode(var, mode)) { + assign_colormode_to_var(var, mode); + return mode->dssmode; + } + } + + /* match with bpp if user has not filled color fields + * properly */ + switch (var->bits_per_pixel) { + case 1: + dssmode = OMAP_DSS_COLOR_CLUT1; + break; + case 2: + dssmode = OMAP_DSS_COLOR_CLUT2; + break; + case 4: + dssmode = OMAP_DSS_COLOR_CLUT4; + break; + case 8: + dssmode = OMAP_DSS_COLOR_CLUT8; + break; + case 12: + dssmode = OMAP_DSS_COLOR_RGB12U; + break; + case 16: + dssmode = OMAP_DSS_COLOR_RGB16; + break; + case 24: + dssmode = OMAP_DSS_COLOR_RGB24P; + break; + case 32: + dssmode = OMAP_DSS_COLOR_RGB24U; + break; + default: + return -EINVAL; + } + + for (i = 0; i < ARRAY_SIZE(omapfb_colormodes); ++i) { + struct omapfb_colormode *mode = &omapfb_colormodes[i]; + if (dssmode == mode->dssmode) { + assign_colormode_to_var(var, mode); + return mode->dssmode; + } + } + + return -EINVAL; +} + +int dss_mode_to_fb_mode(enum omap_color_mode dssmode, + struct fb_var_screeninfo *var) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(omapfb_colormodes); ++i) { + struct omapfb_colormode *mode = &omapfb_colormodes[i]; + if (dssmode == mode->dssmode) { + assign_colormode_to_var(var, mode); + return 0; + } + } + return -ENOENT; +} + +void set_fb_fix(struct fb_info *fbi) +{ + struct fb_fix_screeninfo *fix = &fbi->fix; + struct fb_var_screeninfo *var = &fbi->var; + struct omapfb_info *ofbi = FB2OFB(fbi); + struct omapfb2_mem_region *rg = &ofbi->region; + + DBG("set_fb_fix\n"); + + /* used by open/write in fbmem.c */ + fbi->screen_base = (char __iomem *)omapfb_get_region_vaddr(ofbi); + + DBG("changing rotation to %d\n", var->rotate); + + /* used by mmap in fbmem.c */ + if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { + switch (var->nonstd) { + case OMAPFB_COLOR_YUV422: + case OMAPFB_COLOR_YUY422: + fix->line_length = + (OMAP_VRFB_LINE_LEN * var->bits_per_pixel) >> 2; + break; + default: + fix->line_length = + (OMAP_VRFB_LINE_LEN * var->bits_per_pixel) >> 3; + break; + } + } else + fix->line_length = + (var->xres_virtual * var->bits_per_pixel) >> 3; + fix->smem_start = omapfb_get_region_paddr(ofbi); + fix->smem_len = rg->size; + + fix->type = FB_TYPE_PACKED_PIXELS; + + if (var->nonstd) + fix->visual = FB_VISUAL_PSEUDOCOLOR; + else { + switch (var->bits_per_pixel) { + case 32: + case 24: + case 16: + case 12: + fix->visual = FB_VISUAL_TRUECOLOR; + /* 12bpp is stored in 16 bits */ + break; + case 1: + case 2: + case 4: + case 8: + fix->visual = FB_VISUAL_PSEUDOCOLOR; + break; + } + } + + fix->accel = FB_ACCEL_NONE; + + fix->xpanstep = 1; + fix->ypanstep = 1; + + if (rg->size && ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { + enum omap_color_mode mode = 0; + mode = fb_mode_to_dss_mode(var); + + omap_vrfb_setup(&rg->vrfb, rg->paddr, + var->xres_virtual, + var->yres_virtual, + mode); + } +} + +/* check new var and possibly modify it to be ok */ +int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var) +{ + struct omapfb_info *ofbi = FB2OFB(fbi); + struct omap_dss_device *display = fb2display(fbi); + unsigned long max_frame_size; + unsigned long line_size; + int xres_min, yres_min; + int xres_max, yres_max; + enum omap_color_mode mode = 0; + int i; + int bytespp; + + DBG("check_fb_var %d\n", ofbi->id); + + if (ofbi->region.size == 0) + return 0; + + mode = fb_mode_to_dss_mode(var); + if (mode < 0) { + DBG("cannot convert var to omap dss mode\n"); + return -EINVAL; + } + + for (i = 0; i < ofbi->num_overlays; ++i) { + if ((ofbi->overlays[i]->supported_modes & mode) == 0) { + DBG("invalid mode\n"); + return -EINVAL; + } + } + + if (var->rotate < 0 || var->rotate > 3) + return -EINVAL; + + xres_min = OMAPFB_PLANE_XRES_MIN; + xres_max = 2048; + yres_min = OMAPFB_PLANE_YRES_MIN; + yres_max = 2048; + + bytespp = var->bits_per_pixel >> 3; + + /* XXX: some applications seem to set virtual res to 0. */ + if (var->xres_virtual == 0) + var->xres_virtual = var->xres; + + if (var->yres_virtual == 0) + var->yres_virtual = var->yres; + + if (var->xres_virtual < xres_min || var->yres_virtual < yres_min) + return -EINVAL; + + if (var->xres < xres_min) + var->xres = xres_min; + if (var->yres < yres_min) + var->yres = yres_min; + if (var->xres > xres_max) + var->xres = xres_max; + if (var->yres > yres_max) + var->yres = yres_max; + + if (var->xres > var->xres_virtual) + var->xres = var->xres_virtual; + if (var->yres > var->yres_virtual) + var->yres = var->yres_virtual; + + if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) + line_size = OMAP_VRFB_LINE_LEN * bytespp; + else + line_size = var->xres_virtual * bytespp; + + max_frame_size = ofbi->region.size; + + DBG("max frame size %lu, line size %lu\n", max_frame_size, line_size); + + if (line_size * var->yres_virtual > max_frame_size) { + DBG("can't fit FB into memory, reducing y\n"); + var->yres_virtual = max_frame_size / line_size; + + if (var->yres_virtual < yres_min) + var->yres_virtual = yres_min; + + if (var->yres > var->yres_virtual) + var->yres = var->yres_virtual; + } + + if (line_size * var->yres_virtual > max_frame_size) { + DBG("can't fit FB into memory, reducing x\n"); + if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) + return -EINVAL; + + var->xres_virtual = max_frame_size / var->yres_virtual / + bytespp; + + if (var->xres_virtual < xres_min) + var->xres_virtual = xres_min; + + if (var->xres > var->xres_virtual) + var->xres = var->xres_virtual; + + line_size = var->xres_virtual * bytespp; + } + + if (line_size * var->yres_virtual > max_frame_size) { + DBG("cannot fit FB to memory\n"); + return -EINVAL; + } + + if (var->xres + var->xoffset > var->xres_virtual) + var->xoffset = var->xres_virtual - var->xres; + if (var->yres + var->yoffset > var->yres_virtual) + var->yoffset = var->yres_virtual - var->yres; + + DBG("xres = %d, yres = %d, vxres = %d, vyres = %d\n", + var->xres, var->yres, + var->xres_virtual, var->yres_virtual); + + var->height = -1; + var->width = -1; + var->grayscale = 0; + + if (display && display->get_timings) { + struct omap_video_timings timings; + display->get_timings(display, &timings); + + /* pixclock in ps, the rest in pixclock */ + var->pixclock = timings.pixel_clock != 0 ? + KHZ2PICOS(timings.pixel_clock) : + 0; + var->left_margin = timings.hfp; + var->right_margin = timings.hbp; + var->upper_margin = timings.vfp; + var->lower_margin = timings.vbp; + var->hsync_len = timings.hsw; + var->vsync_len = timings.vsw; + } else { + var->pixclock = 0; + var->left_margin = 0; + var->right_margin = 0; + var->upper_margin = 0; + var->lower_margin = 0; + var->hsync_len = 0; + var->vsync_len = 0; + } + + /* TODO: get these from panel->config */ + var->vmode = FB_VMODE_NONINTERLACED; + var->sync = 0; + + return 0; +} + +/* + * --------------------------------------------------------------------------- + * fbdev framework callbacks + * --------------------------------------------------------------------------- + */ +static int omapfb_open(struct fb_info *fbi, int user) +{ + return 0; +} + +static int omapfb_release(struct fb_info *fbi, int user) +{ +#if 0 + struct omapfb_info *ofbi = FB2OFB(fbi); + struct omapfb2_device *fbdev = ofbi->fbdev; + struct omap_dss_device *display = fb2display(fbi); + + DBG("Closing fb with plane index %d\n", ofbi->id); + + omapfb_lock(fbdev); + + if (display && display->get_update_mode && display->update) { + /* XXX this update should be removed, I think. But it's + * good for debugging */ + if (display->get_update_mode(display) == + OMAP_DSS_UPDATE_MANUAL) { + u16 w, h; + + if (display->sync) + display->sync(display); + + display->get_resolution(display, &w, &h); + display->update(display, 0, 0, w, h); + } + } + + if (display && display->sync) + display->sync(display); + + omapfb_unlock(fbdev); +#endif + return 0; +} + +/* setup overlay according to the fb */ +static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl, + u16 posx, u16 posy, u16 outw, u16 outh) +{ + int r = 0; + struct omapfb_info *ofbi = FB2OFB(fbi); + struct fb_var_screeninfo *var = &fbi->var; + struct fb_fix_screeninfo *fix = &fbi->fix; + enum omap_color_mode mode = 0; + int offset; + u32 data_start_p; + void __iomem *data_start_v; + struct omap_overlay_info info; + int xres, yres; + int screen_width; + int mirror; + int rotation = var->rotate; + int i; + + for (i = 0; i < ofbi->num_overlays; i++) { + if (ovl != ofbi->overlays[i]) + continue; + + rotation = (rotation + ofbi->rotation[i]) % 4; + break; + } + + DBG("setup_overlay %d, posx %d, posy %d, outw %d, outh %d\n", ofbi->id, + posx, posy, outw, outh); + + if (rotation == FB_ROTATE_CW || rotation == FB_ROTATE_CCW) { + xres = var->yres; + yres = var->xres; + } else { + xres = var->xres; + yres = var->yres; + } + + offset = ((var->yoffset * var->xres_virtual + + var->xoffset) * var->bits_per_pixel) >> 3; + + if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { + data_start_p = omapfb_get_region_rot_paddr(ofbi, rotation); + data_start_v = NULL; + } else { + data_start_p = omapfb_get_region_paddr(ofbi); + data_start_v = omapfb_get_region_vaddr(ofbi); + } + + data_start_p += offset; + data_start_v += offset; + + mode = fb_mode_to_dss_mode(var); + + if (mode == -EINVAL) { + DBG("fb_mode_to_dss_mode failed"); + r = -EINVAL; + goto err; + } + + switch (var->nonstd) { + case OMAPFB_COLOR_YUV422: + case OMAPFB_COLOR_YUY422: + if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { + screen_width = fix->line_length + / (var->bits_per_pixel >> 2); + break; + } + default: + screen_width = fix->line_length / (var->bits_per_pixel >> 3); + break; + } + + ovl->get_overlay_info(ovl, &info); + + if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) + mirror = 0; + else + mirror = ofbi->mirror; + + info.paddr = data_start_p; + info.vaddr = data_start_v; + info.screen_width = screen_width; + info.width = xres; + info.height = yres; + info.color_mode = mode; + info.rotation_type = ofbi->rotation_type; + info.rotation = rotation; + info.mirror = mirror; + + info.pos_x = posx; + info.pos_y = posy; + info.out_width = outw; + info.out_height = outh; + + r = ovl->set_overlay_info(ovl, &info); + if (r) { + DBG("ovl->setup_overlay_info failed\n"); + goto err; + } + + return 0; + +err: + DBG("setup_overlay failed\n"); + return r; +} + +/* apply var to the overlay */ +int omapfb_apply_changes(struct fb_info *fbi, int init) +{ + int r = 0; + struct omapfb_info *ofbi = FB2OFB(fbi); + struct fb_var_screeninfo *var = &fbi->var; + struct omap_overlay *ovl; + u16 posx, posy; + u16 outw, outh; + int i; + +#ifdef DEBUG + if (omapfb_test_pattern) + fill_fb(fbi); +#endif + + for (i = 0; i < ofbi->num_overlays; i++) { + ovl = ofbi->overlays[i]; + + DBG("apply_changes, fb %d, ovl %d\n", ofbi->id, ovl->id); + + if (ofbi->region.size == 0) { + /* the fb is not available. disable the overlay */ + omapfb_overlay_enable(ovl, 0); + if (!init && ovl->manager) + ovl->manager->apply(ovl->manager); + continue; + } + + if (init || (ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) { + int rotation = (var->rotate + ofbi->rotation[i]) % 4; + if (rotation == FB_ROTATE_CW || + rotation == FB_ROTATE_CCW) { + outw = var->yres; + outh = var->xres; + } else { + outw = var->xres; + outh = var->yres; + } + } else { + outw = ovl->info.out_width; + outh = ovl->info.out_height; + } + + if (init) { + posx = 0; + posy = 0; + } else { + posx = ovl->info.pos_x; + posy = ovl->info.pos_y; + } + + r = omapfb_setup_overlay(fbi, ovl, posx, posy, outw, outh); + if (r) + goto err; + + if (!init && ovl->manager) + ovl->manager->apply(ovl->manager); + } + return 0; +err: + DBG("apply_changes failed\n"); + return r; +} + +/* checks var and eventually tweaks it to something supported, + * DO NOT MODIFY PAR */ +static int omapfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi) +{ + int r; + + DBG("check_var(%d)\n", FB2OFB(fbi)->id); + + r = check_fb_var(fbi, var); + + return r; +} + +/* set the video mode according to info->var */ +static int omapfb_set_par(struct fb_info *fbi) +{ + int r; + + DBG("set_par(%d)\n", FB2OFB(fbi)->id); + + set_fb_fix(fbi); + r = omapfb_apply_changes(fbi, 0); + + return r; +} + +static int omapfb_pan_display(struct fb_var_screeninfo *var, + struct fb_info *fbi) +{ + struct omapfb_info *ofbi = FB2OFB(fbi); + int r = 0; + + DBG("pan_display(%d)\n", ofbi->id); + + if (var->xoffset != fbi->var.xoffset || + var->yoffset != fbi->var.yoffset) { + struct fb_var_screeninfo new_var; + + new_var = fbi->var; + new_var.xoffset = var->xoffset; + new_var.yoffset = var->yoffset; + + r = check_fb_var(fbi, &new_var); + + if (r == 0) { + fbi->var = new_var; + set_fb_fix(fbi); + r = omapfb_apply_changes(fbi, 0); + } + } + + return r; +} + +static void mmap_user_open(struct vm_area_struct *vma) +{ + struct omapfb_info *ofbi = (struct omapfb_info *)vma->vm_private_data; + + atomic_inc(&ofbi->map_count); +} + +static void mmap_user_close(struct vm_area_struct *vma) +{ + struct omapfb_info *ofbi = (struct omapfb_info *)vma->vm_private_data; + + atomic_dec(&ofbi->map_count); +} + +static struct vm_operations_struct mmap_user_ops = { + .open = mmap_user_open, + .close = mmap_user_close, +}; + +static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma) +{ + struct omapfb_info *ofbi = FB2OFB(fbi); + struct fb_fix_screeninfo *fix = &fbi->fix; + unsigned long off; + unsigned long start; + u32 len; + + if (vma->vm_end - vma->vm_start == 0) + return 0; + if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) + return -EINVAL; + off = vma->vm_pgoff << PAGE_SHIFT; + + start = omapfb_get_region_paddr(ofbi); + len = fix->smem_len; + if (off >= len) + return -EINVAL; + if ((vma->vm_end - vma->vm_start + off) > len) + return -EINVAL; + + off += start; + + DBG("user mmap region start %lx, len %d, off %lx\n", start, len, off); + + vma->vm_pgoff = off >> PAGE_SHIFT; + vma->vm_flags |= VM_IO | VM_RESERVED; + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); + vma->vm_ops = &mmap_user_ops; + vma->vm_private_data = ofbi; + if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, vma->vm_page_prot)) + return -EAGAIN; + /* vm_ops.open won't be called for mmap itself. */ + atomic_inc(&ofbi->map_count); + return 0; +} + +/* Store a single color palette entry into a pseudo palette or the hardware + * palette if one is available. For now we support only 16bpp and thus store + * the entry only to the pseudo palette. + */ +static int _setcolreg(struct fb_info *fbi, u_int regno, u_int red, u_int green, + u_int blue, u_int transp, int update_hw_pal) +{ + /*struct omapfb_info *ofbi = FB2OFB(fbi);*/ + /*struct omapfb2_device *fbdev = ofbi->fbdev;*/ + struct fb_var_screeninfo *var = &fbi->var; + int r = 0; + + enum omapfb_color_format mode = OMAPFB_COLOR_RGB24U; /* XXX */ + + /*switch (plane->color_mode) {*/ + switch (mode) { + case OMAPFB_COLOR_YUV422: + case OMAPFB_COLOR_YUV420: + case OMAPFB_COLOR_YUY422: + r = -EINVAL; + break; + case OMAPFB_COLOR_CLUT_8BPP: + case OMAPFB_COLOR_CLUT_4BPP: + case OMAPFB_COLOR_CLUT_2BPP: + case OMAPFB_COLOR_CLUT_1BPP: + /* + if (fbdev->ctrl->setcolreg) + r = fbdev->ctrl->setcolreg(regno, red, green, blue, + transp, update_hw_pal); + */ + /* Fallthrough */ + r = -EINVAL; + break; + case OMAPFB_COLOR_RGB565: + case OMAPFB_COLOR_RGB444: + case OMAPFB_COLOR_RGB24P: + case OMAPFB_COLOR_RGB24U: + if (r != 0) + break; + + if (regno < 0) { + r = -EINVAL; + break; + } + + if (regno < 16) { + u16 pal; + pal = ((red >> (16 - var->red.length)) << + var->red.offset) | + ((green >> (16 - var->green.length)) << + var->green.offset) | + (blue >> (16 - var->blue.length)); + ((u32 *)(fbi->pseudo_palette))[regno] = pal; + } + break; + default: + BUG(); + } + return r; +} + +static int omapfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, + u_int transp, struct fb_info *info) +{ + DBG("setcolreg\n"); + + return _setcolreg(info, regno, red, green, blue, transp, 1); +} + +static int omapfb_setcmap(struct fb_cmap *cmap, struct fb_info *info) +{ + int count, index, r; + u16 *red, *green, *blue, *transp; + u16 trans = 0xffff; + + DBG("setcmap\n"); + + red = cmap->red; + green = cmap->green; + blue = cmap->blue; + transp = cmap->transp; + index = cmap->start; + + for (count = 0; count < cmap->len; count++) { + if (transp) + trans = *transp++; + r = _setcolreg(info, index++, *red++, *green++, *blue++, trans, + count == cmap->len - 1); + if (r != 0) + return r; + } + + return 0; +} + +static void omapfb_vrfb_suspend_all(struct omapfb2_device *fbdev) +{ + int i; + + for (i = 0; i < fbdev->num_fbs; i++) { + struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]); + + if (ofbi->region.vrfb.vaddr[0]) + omap_vrfb_suspend_ctx(&ofbi->region.vrfb); + } +} + +static void omapfb_vrfb_resume_all(struct omapfb2_device *fbdev) +{ + int i; + + for (i = 0; i < fbdev->num_fbs; i++) { + struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]); + + if (ofbi->region.vrfb.vaddr[0]) + omap_vrfb_resume_ctx(&ofbi->region.vrfb); + } +} + +static int omapfb_blank(int blank, struct fb_info *fbi) +{ + struct omapfb_info *ofbi = FB2OFB(fbi); + struct omapfb2_device *fbdev = ofbi->fbdev; + struct omap_dss_device *display = fb2display(fbi); + int do_update = 0; + int r = 0; + + omapfb_lock(fbdev); + + switch (blank) { + case FB_BLANK_UNBLANK: + if (display->state != OMAP_DSS_DISPLAY_SUSPENDED) + goto exit; + + omapfb_vrfb_resume_all(fbdev); + + if (display->resume) + r = display->resume(display); + + if (r == 0 && display->get_update_mode && + display->get_update_mode(display) == + OMAP_DSS_UPDATE_MANUAL) + do_update = 1; + + break; + + case FB_BLANK_NORMAL: + /* FB_BLANK_NORMAL could be implemented. + * Needs DSS additions. */ + case FB_BLANK_VSYNC_SUSPEND: + case FB_BLANK_HSYNC_SUSPEND: + case FB_BLANK_POWERDOWN: + if (display->state != OMAP_DSS_DISPLAY_ACTIVE) + goto exit; + + if (display->suspend) + r = display->suspend(display); + + omapfb_vrfb_suspend_all(fbdev); + + break; + + default: + r = -EINVAL; + } + +exit: + omapfb_unlock(fbdev); + + if (r == 0 && do_update && display->update) { + u16 w, h; + display->get_resolution(display, &w, &h); + + r = display->update(display, 0, 0, w, h); + } + + return r; +} + +#if 0 +/* XXX fb_read and fb_write are needed for VRFB */ +ssize_t omapfb_write(struct fb_info *info, const char __user *buf, + size_t count, loff_t *ppos) +{ + DBG("omapfb_write %d, %lu\n", count, (unsigned long)*ppos); + /* XXX needed for VRFB */ + return count; +} +#endif + +static struct fb_ops omapfb_ops = { + .owner = THIS_MODULE, + .fb_open = omapfb_open, + .fb_release = omapfb_release, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, + .fb_blank = omapfb_blank, + .fb_ioctl = omapfb_ioctl, + .fb_check_var = omapfb_check_var, + .fb_set_par = omapfb_set_par, + .fb_pan_display = omapfb_pan_display, + .fb_mmap = omapfb_mmap, + .fb_setcolreg = omapfb_setcolreg, + .fb_setcmap = omapfb_setcmap, + /*.fb_write = omapfb_write,*/ +}; + +static void omapfb_free_fbmem(struct fb_info *fbi) +{ + struct omapfb_info *ofbi = FB2OFB(fbi); + struct omapfb2_device *fbdev = ofbi->fbdev; + struct omapfb2_mem_region *rg; + + rg = &ofbi->region; + + if (rg->paddr) + if (omap_vram_free(rg->paddr, rg->size)) + dev_err(fbdev->dev, "VRAM FREE failed\n"); + + if (rg->vaddr) + iounmap(rg->vaddr); + + if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { + /* unmap the 0 angle rotation */ + if (rg->vrfb.vaddr[0]) { + iounmap(rg->vrfb.vaddr[0]); + omap_vrfb_release_ctx(&rg->vrfb); + } + } + + rg->vaddr = NULL; + rg->paddr = 0; + rg->alloc = 0; + rg->size = 0; +} + +static void clear_fb_info(struct fb_info *fbi) +{ + memset(&fbi->var, 0, sizeof(fbi->var)); + memset(&fbi->fix, 0, sizeof(fbi->fix)); + strlcpy(fbi->fix.id, MODULE_NAME, sizeof(fbi->fix.id)); +} + +static int omapfb_free_all_fbmem(struct omapfb2_device *fbdev) +{ + int i; + + DBG("free all fbmem\n"); + + for (i = 0; i < fbdev->num_fbs; i++) { + struct fb_info *fbi = fbdev->fbs[i]; + omapfb_free_fbmem(fbi); + clear_fb_info(fbi); + } + + return 0; +} + +static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size, + unsigned long paddr) +{ + struct omapfb_info *ofbi = FB2OFB(fbi); + struct omapfb2_device *fbdev = ofbi->fbdev; + struct omapfb2_mem_region *rg; + void __iomem *vaddr; + int r; + + rg = &ofbi->region; + memset(rg, 0, sizeof(*rg)); + + size = PAGE_ALIGN(size); + + if (!paddr) { + DBG("allocating %lu bytes for fb %d\n", size, ofbi->id); + r = omap_vram_alloc(OMAPFB_MEMTYPE_SDRAM, size, &paddr); + } else { + DBG("reserving %lu bytes at %lx for fb %d\n", size, paddr, + ofbi->id); + r = omap_vram_reserve(paddr, size); + } + + if (r) { + dev_err(fbdev->dev, "failed to allocate framebuffer\n"); + return -ENOMEM; + } + + if (ofbi->rotation_type != OMAP_DSS_ROT_VRFB) { + vaddr = ioremap_wc(paddr, size); + + if (!vaddr) { + dev_err(fbdev->dev, "failed to ioremap framebuffer\n"); + omap_vram_free(paddr, size); + return -ENOMEM; + } + + DBG("allocated VRAM paddr %lx, vaddr %p\n", paddr, vaddr); + } else { + void __iomem *va; + + r = omap_vrfb_request_ctx(&rg->vrfb); + if (r) { + dev_err(fbdev->dev, "vrfb create ctx failed\n"); + return r; + } + + /* only ioremap the 0 angle view */ + va = ioremap_wc(rg->vrfb.paddr[0], size); + + if (!va) { + printk(KERN_ERR "vrfb: ioremap failed\n"); + omap_vrfb_release_ctx(&rg->vrfb); + return -ENOMEM; + } + + DBG("ioremapped vrfb area 0 to %p\n", va); + + rg->vrfb.vaddr[0] = va; + + vaddr = NULL; + } + + rg->paddr = paddr; + rg->vaddr = vaddr; + rg->size = size; + rg->alloc = 1; + + return 0; +} + +/* allocate fbmem using display resolution as reference */ +static int omapfb_alloc_fbmem_display(struct fb_info *fbi, unsigned long size, + unsigned long paddr) +{ + struct omapfb_info *ofbi = FB2OFB(fbi); + struct omap_dss_device *display; + int bytespp; + + display = fb2display(fbi); + + if (!display) + return 0; + + switch (display->get_recommended_bpp(display)) { + case 16: + bytespp = 2; + break; + case 24: + bytespp = 4; + break; + default: + bytespp = 4; + break; + } + + if (!size) { + u16 w, h; + + display->get_resolution(display, &w, &h); + + if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { +#ifdef DEBUG + int oldw = w, oldh = h; +#endif + + omap_vrfb_adjust_size(&w, &h, bytespp); + + /* Because we change the resolution of the 0 degree + * view, we need to alloc max(w, h) for height */ + h = max(w, h); + w = OMAP_VRFB_LINE_LEN; + + DBG("adjusting fb mem size for VRFB, %dx%d -> %dx%d\n", + oldw, oldh, w, h); + } + + size = w * h * bytespp; + } + + if (!size) + return 0; + + return omapfb_alloc_fbmem(fbi, size, paddr); +} + +static enum omap_color_mode fb_format_to_dss_mode(enum omapfb_color_format fmt) +{ + enum omap_color_mode mode; + + switch (fmt) { + case OMAPFB_COLOR_RGB565: + mode = OMAP_DSS_COLOR_RGB16; + break; + case OMAPFB_COLOR_YUV422: + mode = OMAP_DSS_COLOR_YUV2; + break; + case OMAPFB_COLOR_CLUT_8BPP: + mode = OMAP_DSS_COLOR_CLUT8; + break; + case OMAPFB_COLOR_CLUT_4BPP: + mode = OMAP_DSS_COLOR_CLUT4; + break; + case OMAPFB_COLOR_CLUT_2BPP: + mode = OMAP_DSS_COLOR_CLUT2; + break; + case OMAPFB_COLOR_CLUT_1BPP: + mode = OMAP_DSS_COLOR_CLUT1; + break; + case OMAPFB_COLOR_RGB444: + mode = OMAP_DSS_COLOR_RGB12U; + break; + case OMAPFB_COLOR_YUY422: + mode = OMAP_DSS_COLOR_UYVY; + break; + case OMAPFB_COLOR_ARGB16: + mode = OMAP_DSS_COLOR_ARGB16; + break; + case OMAPFB_COLOR_RGB24U: + mode = OMAP_DSS_COLOR_RGB24U; + break; + case OMAPFB_COLOR_RGB24P: + mode = OMAP_DSS_COLOR_RGB24P; + break; + case OMAPFB_COLOR_ARGB32: + mode = OMAP_DSS_COLOR_ARGB32; + break; + case OMAPFB_COLOR_RGBA32: + mode = OMAP_DSS_COLOR_RGBA32; + break; + case OMAPFB_COLOR_RGBX32: + mode = OMAP_DSS_COLOR_RGBX32; + break; + default: + mode = -EINVAL; + } + + return mode; +} + +static int omapfb_parse_vram_param(const char *param, int max_entries, + unsigned long *sizes, unsigned long *paddrs) +{ + int fbnum; + unsigned long size; + unsigned long paddr = 0; + char *p, *start; + + start = (char *)param; + + while (1) { + p = start; + + fbnum = simple_strtoul(p, &p, 10); + + if (p == param) + return -EINVAL; + + if (*p != ':') + return -EINVAL; + + if (fbnum >= max_entries) + return -EINVAL; + + size = memparse(p + 1, &p); + + if (!size) + return -EINVAL; + + paddr = 0; + + if (*p == '@') { + paddr = simple_strtoul(p + 1, &p, 16); + + if (!paddr) + return -EINVAL; + + } + + paddrs[fbnum] = paddr; + sizes[fbnum] = size; + + if (*p == 0) + break; + + if (*p != ',') + return -EINVAL; + + ++p; + + start = p; + } + + return 0; +} + +static int omapfb_allocate_all_fbs(struct omapfb2_device *fbdev) +{ + int i, r; + unsigned long vram_sizes[10]; + unsigned long vram_paddrs[10]; + + memset(&vram_sizes, 0, sizeof(vram_sizes)); + memset(&vram_paddrs, 0, sizeof(vram_paddrs)); + + if (def_vram && omapfb_parse_vram_param(def_vram, 10, + vram_sizes, vram_paddrs)) { + dev_err(fbdev->dev, "failed to parse vram parameter\n"); + + memset(&vram_sizes, 0, sizeof(vram_sizes)); + memset(&vram_paddrs, 0, sizeof(vram_paddrs)); + } + + if (fbdev->dev->platform_data) { + struct omapfb_platform_data *opd; + opd = fbdev->dev->platform_data; + for (i = 0; i < opd->mem_desc.region_cnt; ++i) { + if (!vram_sizes[i]) { + unsigned long size; + unsigned long paddr; + + size = opd->mem_desc.region[i].size; + paddr = opd->mem_desc.region[i].paddr; + + vram_sizes[i] = size; + vram_paddrs[i] = paddr; + } + } + } + + for (i = 0; i < fbdev->num_fbs; i++) { + /* allocate memory automatically only for fb0, or if + * excplicitly defined with vram or plat data option */ + if (i == 0 || vram_sizes[i] != 0) { + r = omapfb_alloc_fbmem_display(fbdev->fbs[i], + vram_sizes[i], vram_paddrs[i]); + + if (r) + return r; + } + } + + for (i = 0; i < fbdev->num_fbs; i++) { + struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]); + struct omapfb2_mem_region *rg; + rg = &ofbi->region; + + DBG("region%d phys %08x virt %p size=%lu\n", + i, + rg->paddr, + rg->vaddr, + rg->size); + } + + return 0; +} + +int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type) +{ + struct omapfb_info *ofbi = FB2OFB(fbi); + struct omapfb2_device *fbdev = ofbi->fbdev; + struct omap_dss_device *display = fb2display(fbi); + struct omapfb2_mem_region *rg = &ofbi->region; + unsigned long old_size = rg->size; + unsigned long old_paddr = rg->paddr; + int old_type = rg->type; + int r; + + if (type > OMAPFB_MEMTYPE_MAX) + return -EINVAL; + + size = PAGE_ALIGN(size); + + if (old_size == size && old_type == type) + return 0; + + if (display && display->sync) + display->sync(display); + + omapfb_free_fbmem(fbi); + + if (size == 0) { + clear_fb_info(fbi); + return 0; + } + + r = omapfb_alloc_fbmem(fbi, size, 0); + + if (r) { + if (old_size) + omapfb_alloc_fbmem(fbi, old_size, old_paddr); + + if (rg->size == 0) + clear_fb_info(fbi); + + return r; + } + + if (old_size == size) + return 0; + + if (old_size == 0) { + DBG("initializing fb %d\n", ofbi->id); + r = omapfb_fb_init(fbdev, fbi); + if (r) { + DBG("omapfb_fb_init failed\n"); + goto err; + } + r = omapfb_apply_changes(fbi, 1); + if (r) { + DBG("omapfb_apply_changes failed\n"); + goto err; + } + } else { + struct fb_var_screeninfo new_var; + memcpy(&new_var, &fbi->var, sizeof(new_var)); + r = check_fb_var(fbi, &new_var); + if (r) + goto err; + memcpy(&fbi->var, &new_var, sizeof(fbi->var)); + set_fb_fix(fbi); + } + + return 0; +err: + omapfb_free_fbmem(fbi); + clear_fb_info(fbi); + return r; +} + +/* initialize fb_info, var, fix to something sane based on the display */ +int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi) +{ + struct fb_var_screeninfo *var = &fbi->var; + struct omap_dss_device *display = fb2display(fbi); + struct omapfb_info *ofbi = FB2OFB(fbi); + int r = 0; + + fbi->fbops = &omapfb_ops; + fbi->flags = FBINFO_FLAG_DEFAULT; + fbi->pseudo_palette = fbdev->pseudo_palette; + +/* strncpy(fix->id, MODULE_NAME, sizeof(fix->id)); */ + + if (ofbi->region.size == 0) { + memset(&fbi->fix, 0, sizeof(fbi->fix)); + memset(&fbi->var, 0, sizeof(fbi->var)); + clear_fb_info(fbi); + return 0; + } + + var->nonstd = 0; + var->bits_per_pixel = 0; + + var->rotate = def_rotate; + + /* + * Check if there is a default color format set in the board file, + * and use this format instead the default deducted from the + * display bpp. + */ + if (fbdev->dev->platform_data) { + struct omapfb_platform_data *opd; + int id = ofbi->id; + + opd = fbdev->dev->platform_data; + if (opd->mem_desc.region[id].format_used) { + enum omap_color_mode mode; + enum omapfb_color_format format; + + format = opd->mem_desc.region[id].format; + mode = fb_format_to_dss_mode(format); + if (mode < 0) { + r = mode; + goto err; + } + r = dss_mode_to_fb_mode(mode, var); + if (r < 0) + goto err; + } + } + + if (display) { + u16 w, h; + int rotation = (var->rotate + ofbi->rotation[0]) % 4; + + display->get_resolution(display, &w, &h); + + if (rotation == FB_ROTATE_CW || + rotation == FB_ROTATE_CCW) { + var->xres = h; + var->yres = w; + } else { + var->xres = w; + var->yres = h; + } + + var->xres_virtual = var->xres; + var->yres_virtual = var->yres; + + if (!var->bits_per_pixel) { + switch (display->get_recommended_bpp(display)) { + case 16: + var->bits_per_pixel = 16; + break; + case 24: + var->bits_per_pixel = 32; + break; + default: + dev_err(fbdev->dev, "illegal display " + "bpp\n"); + return -EINVAL; + } + } + } else { + /* if there's no display, let's just guess some basic values */ + var->xres = 320; + var->yres = 240; + var->xres_virtual = var->xres; + var->yres_virtual = var->yres; + if (!var->bits_per_pixel) + var->bits_per_pixel = 16; + } + + r = check_fb_var(fbi, var); + if (r) + goto err; + + set_fb_fix(fbi); + + r = fb_alloc_cmap(&fbi->cmap, 256, 0); + if (r) + dev_err(fbdev->dev, "unable to allocate color map memory\n"); + +err: + return r; +} + +static void fbinfo_cleanup(struct omapfb2_device *fbdev, struct fb_info *fbi) +{ + fb_dealloc_cmap(&fbi->cmap); +} + + +static void omapfb_free_resources(struct omapfb2_device *fbdev) +{ + int i; + + DBG("free_resources\n"); + + if (fbdev == NULL) + return; + + for (i = 0; i < fbdev->num_fbs; i++) + unregister_framebuffer(fbdev->fbs[i]); + + /* free the reserved fbmem */ + omapfb_free_all_fbmem(fbdev); + + for (i = 0; i < fbdev->num_fbs; i++) { + fbinfo_cleanup(fbdev, fbdev->fbs[i]); + framebuffer_release(fbdev->fbs[i]); + } + + for (i = 0; i < fbdev->num_displays; i++) { + if (fbdev->displays[i]->state != OMAP_DSS_DISPLAY_DISABLED) + fbdev->displays[i]->disable(fbdev->displays[i]); + + omap_dss_put_device(fbdev->displays[i]); + } + + dev_set_drvdata(fbdev->dev, NULL); + kfree(fbdev); +} + +static int omapfb_create_framebuffers(struct omapfb2_device *fbdev) +{ + int r, i; + + fbdev->num_fbs = 0; + + DBG("create %d framebuffers\n", CONFIG_FB_OMAP2_NUM_FBS); + + /* allocate fb_infos */ + for (i = 0; i < CONFIG_FB_OMAP2_NUM_FBS; i++) { + struct fb_info *fbi; + struct omapfb_info *ofbi; + + fbi = framebuffer_alloc(sizeof(struct omapfb_info), + fbdev->dev); + + if (fbi == NULL) { + dev_err(fbdev->dev, + "unable to allocate memory for plane info\n"); + return -ENOMEM; + } + + clear_fb_info(fbi); + + fbdev->fbs[i] = fbi; + + ofbi = FB2OFB(fbi); + ofbi->fbdev = fbdev; + ofbi->id = i; + + /* assign these early, so that fb alloc can use them */ + ofbi->rotation_type = def_vrfb ? OMAP_DSS_ROT_VRFB : + OMAP_DSS_ROT_DMA; + ofbi->mirror = def_mirror; + + fbdev->num_fbs++; + } + + DBG("fb_infos allocated\n"); + + /* assign overlays for the fbs */ + for (i = 0; i < min(fbdev->num_fbs, fbdev->num_overlays); i++) { + struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]); + + ofbi->overlays[0] = fbdev->overlays[i]; + ofbi->num_overlays = 1; + } + + /* allocate fb memories */ + r = omapfb_allocate_all_fbs(fbdev); + if (r) { + dev_err(fbdev->dev, "failed to allocate fbmem\n"); + return r; + } + + DBG("fbmems allocated\n"); + + /* setup fb_infos */ + for (i = 0; i < fbdev->num_fbs; i++) { + r = omapfb_fb_init(fbdev, fbdev->fbs[i]); + if (r) { + dev_err(fbdev->dev, "failed to setup fb_info\n"); + return r; + } + } + + DBG("fb_infos initialized\n"); + + for (i = 0; i < fbdev->num_fbs; i++) { + r = register_framebuffer(fbdev->fbs[i]); + if (r != 0) { + dev_err(fbdev->dev, + "registering framebuffer %d failed\n", i); + return r; + } + } + + DBG("framebuffers registered\n"); + + for (i = 0; i < fbdev->num_fbs; i++) { + r = omapfb_apply_changes(fbdev->fbs[i], 1); + if (r) { + dev_err(fbdev->dev, "failed to change mode\n"); + return r; + } + } + + DBG("create sysfs for fbs\n"); + r = omapfb_create_sysfs(fbdev); + if (r) { + dev_err(fbdev->dev, "failed to create sysfs entries\n"); + return r; + } + + /* Enable fb0 */ + if (fbdev->num_fbs > 0) { + struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[0]); + + if (ofbi->num_overlays > 0) { + struct omap_overlay *ovl = ofbi->overlays[0]; + + r = omapfb_overlay_enable(ovl, 1); + + if (r) { + dev_err(fbdev->dev, + "failed to enable overlay\n"); + return r; + } + } + } + + DBG("create_framebuffers done\n"); + + return 0; +} + +int omapfb_mode_to_timings(const char *mode_str, + struct omap_video_timings *timings, u8 *bpp) +{ + struct fb_info fbi; + struct fb_var_screeninfo var; + struct fb_ops fbops; + int r; + +#ifdef CONFIG_OMAP2_DSS_VENC + if (strcmp(mode_str, "pal") == 0) { + *timings = omap_dss_pal_timings; + *bpp = 0; + return 0; + } else if (strcmp(mode_str, "ntsc") == 0) { + *timings = omap_dss_ntsc_timings; + *bpp = 0; + return 0; + } +#endif + + /* this is quite a hack, but I wanted to use the modedb and for + * that we need fb_info and var, so we create dummy ones */ + + memset(&fbi, 0, sizeof(fbi)); + memset(&var, 0, sizeof(var)); + memset(&fbops, 0, sizeof(fbops)); + fbi.fbops = &fbops; + + r = fb_find_mode(&var, &fbi, mode_str, NULL, 0, NULL, 24); + + if (r != 0) { + timings->pixel_clock = PICOS2KHZ(var.pixclock); + timings->hfp = var.left_margin; + timings->hbp = var.right_margin; + timings->vfp = var.upper_margin; + timings->vbp = var.lower_margin; + timings->hsw = var.hsync_len; + timings->vsw = var.vsync_len; + timings->x_res = var.xres; + timings->y_res = var.yres; + + switch (var.bits_per_pixel) { + case 16: + *bpp = 16; + break; + case 24: + case 32: + default: + *bpp = 24; + break; + } + + return 0; + } else { + return -EINVAL; + } +} + +static int omapfb_set_def_mode(struct omap_dss_device *display, char *mode_str) +{ + int r; + u8 bpp; + struct omap_video_timings timings; + + r = omapfb_mode_to_timings(mode_str, &timings, &bpp); + if (r) + return r; + + display->panel.recommended_bpp = bpp; + + if (!display->check_timings || !display->set_timings) + return -EINVAL; + + r = display->check_timings(display, &timings); + if (r) + return r; + + display->set_timings(display, &timings); + + return 0; +} + +static int omapfb_parse_def_modes(struct omapfb2_device *fbdev) +{ + char *str, *options, *this_opt; + int r = 0; + + str = kmalloc(strlen(def_mode) + 1, GFP_KERNEL); + strcpy(str, def_mode); + options = str; + + while (!r && (this_opt = strsep(&options, ",")) != NULL) { + char *p, *display_str, *mode_str; + struct omap_dss_device *display; + int i; + + p = strchr(this_opt, ':'); + if (!p) { + r = -EINVAL; + break; + } + + *p = 0; + display_str = this_opt; + mode_str = p + 1; + + display = NULL; + for (i = 0; i < fbdev->num_displays; ++i) { + if (strcmp(fbdev->displays[i]->name, + display_str) == 0) { + display = fbdev->displays[i]; + break; + } + } + + if (!display) { + r = -EINVAL; + break; + } + + r = omapfb_set_def_mode(display, mode_str); + if (r) + break; + } + + kfree(str); + + return r; +} + +static int omapfb_probe(struct platform_device *pdev) +{ + struct omapfb2_device *fbdev = NULL; + int r = 0; + int i; + struct omap_overlay *ovl; + struct omap_dss_device *def_display; + struct omap_dss_device *dssdev; + + DBG("omapfb_probe\n"); + + if (pdev->num_resources != 0) { + dev_err(&pdev->dev, "probed for an unknown device\n"); + r = -ENODEV; + goto err0; + } + + fbdev = kzalloc(sizeof(struct omapfb2_device), GFP_KERNEL); + if (fbdev == NULL) { + r = -ENOMEM; + goto err0; + } + + mutex_init(&fbdev->mtx); + + fbdev->dev = &pdev->dev; + platform_set_drvdata(pdev, fbdev); + + fbdev->num_displays = 0; + dssdev = NULL; + for_each_dss_dev(dssdev) { + omap_dss_get_device(dssdev); + fbdev->displays[fbdev->num_displays++] = dssdev; + } + + if (fbdev->num_displays == 0) { + dev_err(&pdev->dev, "no displays\n"); + r = -EINVAL; + goto cleanup; + } + + fbdev->num_overlays = omap_dss_get_num_overlays(); + for (i = 0; i < fbdev->num_overlays; i++) + fbdev->overlays[i] = omap_dss_get_overlay(i); + + fbdev->num_managers = omap_dss_get_num_overlay_managers(); + for (i = 0; i < fbdev->num_managers; i++) + fbdev->managers[i] = omap_dss_get_overlay_manager(i); + + + /* gfx overlay should be the default one. find a display + * connected to that, and use it as default display */ + ovl = omap_dss_get_overlay(0); + if (ovl->manager && ovl->manager->device) { + def_display = ovl->manager->device; + } else { + dev_err(&pdev->dev, "cannot find default display\n"); + r = -EINVAL; + goto cleanup; + } + + if (def_mode && strlen(def_mode) > 0) { + if (omapfb_parse_def_modes(fbdev)) + dev_err(&pdev->dev, "cannot parse default modes\n"); + } + + r = omapfb_create_framebuffers(fbdev); + if (r) + goto cleanup; + + for (i = 0; i < fbdev->num_managers; i++) { + struct omap_overlay_manager *mgr; + mgr = fbdev->managers[i]; + r = mgr->apply(mgr); + if (r) { + dev_err(fbdev->dev, "failed to apply dispc config\n"); + goto cleanup; + } + } + + DBG("mgr->apply'ed\n"); + + r = def_display->enable(def_display); + if (r) { + dev_err(fbdev->dev, "Failed to enable display '%s'\n", + def_display->name); + goto cleanup; + } + + /* set the update mode */ + if (def_display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { +#ifdef CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE + if (def_display->enable_te) + def_display->enable_te(def_display, 1); + if (def_display->set_update_mode) + def_display->set_update_mode(def_display, + OMAP_DSS_UPDATE_AUTO); +#else + if (def_display->enable_te) + def_display->enable_te(def_display, 0); + if (def_display->set_update_mode) + def_display->set_update_mode(def_display, + OMAP_DSS_UPDATE_MANUAL); +#endif + } else { + if (def_display->set_update_mode) + def_display->set_update_mode(def_display, + OMAP_DSS_UPDATE_AUTO); + } + + for (i = 0; i < fbdev->num_displays; i++) { + struct omap_dss_device *display = fbdev->displays[i]; + u16 w, h; + + if (!display->get_update_mode || !display->update) + continue; + + if (display->get_update_mode(display) == + OMAP_DSS_UPDATE_MANUAL) { + + display->get_resolution(display, &w, &h); + display->update(display, 0, 0, w, h); + } + } + + DBG("display->updated\n"); + + return 0; + +cleanup: + omapfb_free_resources(fbdev); +err0: + dev_err(&pdev->dev, "failed to setup omapfb\n"); + return r; +} + +static int omapfb_remove(struct platform_device *pdev) +{ + struct omapfb2_device *fbdev = platform_get_drvdata(pdev); + + /* FIXME: wait till completion of pending events */ + + omapfb_remove_sysfs(fbdev); + + omapfb_free_resources(fbdev); + + return 0; +} + +static struct platform_driver omapfb_driver = { + .probe = omapfb_probe, + .remove = omapfb_remove, + .driver = { + .name = "omapfb", + .owner = THIS_MODULE, + }, +}; + +static int __init omapfb_init(void) +{ + DBG("omapfb_init\n"); + + if (platform_driver_register(&omapfb_driver)) { + printk(KERN_ERR "failed to register omapfb driver\n"); + return -ENODEV; + } + + return 0; +} + +static void __exit omapfb_exit(void) +{ + DBG("omapfb_exit\n"); + platform_driver_unregister(&omapfb_driver); +} + +module_param_named(mode, def_mode, charp, 0); +module_param_named(vram, def_vram, charp, 0); +module_param_named(rotate, def_rotate, int, 0); +module_param_named(vrfb, def_vrfb, bool, 0); +module_param_named(mirror, def_mirror, bool, 0); + +/* late_initcall to let panel/ctrl drivers loaded first. + * I guess better option would be a more dynamic approach, + * so that omapfb reacts to new panels when they are loaded */ +late_initcall(omapfb_init); +/*module_init(omapfb_init);*/ +module_exit(omapfb_exit); + +MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>"); +MODULE_DESCRIPTION("OMAP2/3 Framebuffer"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c new file mode 100644 index 000000000000..23cb986052bd --- /dev/null +++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c @@ -0,0 +1,506 @@ +/* + * linux/drivers/video/omap2/omapfb-sysfs.c + * + * Copyright (C) 2008 Nokia Corporation + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> + * + * Some code and ideas taken from drivers/video/omap/ driver + * by Imre Deak. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/fb.h> +#include <linux/sysfs.h> +#include <linux/device.h> +#include <linux/uaccess.h> +#include <linux/platform_device.h> +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/omapfb.h> + +#include <mach/display.h> +#include <mach/vrfb.h> + +#include "omapfb.h" + +static ssize_t show_rotate_type(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct fb_info *fbi = dev_get_drvdata(dev); + struct omapfb_info *ofbi = FB2OFB(fbi); + + return snprintf(buf, PAGE_SIZE, "%d\n", ofbi->rotation_type); +} + +static ssize_t store_rotate_type(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct fb_info *fbi = dev_get_drvdata(dev); + struct omapfb_info *ofbi = FB2OFB(fbi); + enum omap_dss_rotation_type rot_type; + int r; + + rot_type = simple_strtoul(buf, NULL, 0); + + if (rot_type != OMAP_DSS_ROT_DMA && rot_type != OMAP_DSS_ROT_VRFB) + return -EINVAL; + + lock_fb_info(fbi); + + r = 0; + if (rot_type == ofbi->rotation_type) + goto out; + + if (ofbi->region.size) { + r = -EBUSY; + goto out; + } + + ofbi->rotation_type = rot_type; + + /* + * Since the VRAM for this FB is not allocated at the moment we don't + * need to do any further parameter checking at this point. + */ +out: + unlock_fb_info(fbi); + + return r ? r : count; +} + + +static ssize_t show_mirror(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct fb_info *fbi = dev_get_drvdata(dev); + struct omapfb_info *ofbi = FB2OFB(fbi); + + return snprintf(buf, PAGE_SIZE, "%d\n", ofbi->mirror); +} + +static ssize_t store_mirror(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct fb_info *fbi = dev_get_drvdata(dev); + struct omapfb_info *ofbi = FB2OFB(fbi); + bool mirror; + int r; + struct fb_var_screeninfo new_var; + + mirror = simple_strtoul(buf, NULL, 0); + + if (mirror != 0 && mirror != 1) + return -EINVAL; + + lock_fb_info(fbi); + + ofbi->mirror = mirror; + + memcpy(&new_var, &fbi->var, sizeof(new_var)); + r = check_fb_var(fbi, &new_var); + if (r) + goto out; + memcpy(&fbi->var, &new_var, sizeof(fbi->var)); + + set_fb_fix(fbi); + + r = omapfb_apply_changes(fbi, 0); + if (r) + goto out; + + r = count; +out: + unlock_fb_info(fbi); + + return r; +} + +static ssize_t show_overlays(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct fb_info *fbi = dev_get_drvdata(dev); + struct omapfb_info *ofbi = FB2OFB(fbi); + struct omapfb2_device *fbdev = ofbi->fbdev; + ssize_t l = 0; + int t; + + omapfb_lock(fbdev); + lock_fb_info(fbi); + + for (t = 0; t < ofbi->num_overlays; t++) { + struct omap_overlay *ovl = ofbi->overlays[t]; + int ovlnum; + + for (ovlnum = 0; ovlnum < fbdev->num_overlays; ++ovlnum) + if (ovl == fbdev->overlays[ovlnum]) + break; + + l += snprintf(buf + l, PAGE_SIZE - l, "%s%d", + t == 0 ? "" : ",", ovlnum); + } + + l += snprintf(buf + l, PAGE_SIZE - l, "\n"); + + unlock_fb_info(fbi); + omapfb_unlock(fbdev); + + return l; +} + +static struct omapfb_info *get_overlay_fb(struct omapfb2_device *fbdev, + struct omap_overlay *ovl) +{ + int i, t; + + for (i = 0; i < fbdev->num_fbs; i++) { + struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]); + + for (t = 0; t < ofbi->num_overlays; t++) { + if (ofbi->overlays[t] == ovl) + return ofbi; + } + } + + return NULL; +} + +static ssize_t store_overlays(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct fb_info *fbi = dev_get_drvdata(dev); + struct omapfb_info *ofbi = FB2OFB(fbi); + struct omapfb2_device *fbdev = ofbi->fbdev; + struct omap_overlay *ovls[OMAPFB_MAX_OVL_PER_FB]; + struct omap_overlay *ovl; + int num_ovls, r, i; + int len; + bool added = false; + + num_ovls = 0; + + len = strlen(buf); + if (buf[len - 1] == '\n') + len = len - 1; + + omapfb_lock(fbdev); + lock_fb_info(fbi); + + if (len > 0) { + char *p = (char *)buf; + int ovlnum; + + while (p < buf + len) { + int found; + if (num_ovls == OMAPFB_MAX_OVL_PER_FB) { + r = -EINVAL; + goto out; + } + + ovlnum = simple_strtoul(p, &p, 0); + if (ovlnum > fbdev->num_overlays) { + r = -EINVAL; + goto out; + } + + found = 0; + for (i = 0; i < num_ovls; ++i) { + if (ovls[i] == fbdev->overlays[ovlnum]) { + found = 1; + break; + } + } + + if (!found) + ovls[num_ovls++] = fbdev->overlays[ovlnum]; + + p++; + } + } + + for (i = 0; i < num_ovls; ++i) { + struct omapfb_info *ofbi2 = get_overlay_fb(fbdev, ovls[i]); + if (ofbi2 && ofbi2 != ofbi) { + dev_err(fbdev->dev, "overlay already in use\n"); + r = -EINVAL; + goto out; + } + } + + /* detach unused overlays */ + for (i = 0; i < ofbi->num_overlays; ++i) { + int t, found; + + ovl = ofbi->overlays[i]; + + found = 0; + + for (t = 0; t < num_ovls; ++t) { + if (ovl == ovls[t]) { + found = 1; + break; + } + } + + if (found) + continue; + + DBG("detaching %d\n", ofbi->overlays[i]->id); + + omapfb_overlay_enable(ovl, 0); + + if (ovl->manager) + ovl->manager->apply(ovl->manager); + + for (t = i + 1; t < ofbi->num_overlays; t++) { + ofbi->rotation[t-1] = ofbi->rotation[t]; + ofbi->overlays[t-1] = ofbi->overlays[t]; + } + + ofbi->num_overlays--; + i--; + } + + for (i = 0; i < num_ovls; ++i) { + int t, found; + + ovl = ovls[i]; + + found = 0; + + for (t = 0; t < ofbi->num_overlays; ++t) { + if (ovl == ofbi->overlays[t]) { + found = 1; + break; + } + } + + if (found) + continue; + ofbi->rotation[ofbi->num_overlays] = 0; + ofbi->overlays[ofbi->num_overlays++] = ovl; + + added = true; + } + + if (added) { + r = omapfb_apply_changes(fbi, 0); + if (r) + goto out; + } + + r = count; +out: + unlock_fb_info(fbi); + omapfb_unlock(fbdev); + + return r; +} + +static ssize_t show_overlays_rotate(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct fb_info *fbi = dev_get_drvdata(dev); + struct omapfb_info *ofbi = FB2OFB(fbi); + ssize_t l = 0; + int t; + + lock_fb_info(fbi); + + for (t = 0; t < ofbi->num_overlays; t++) { + l += snprintf(buf + l, PAGE_SIZE - l, "%s%d", + t == 0 ? "" : ",", ofbi->rotation[t]); + } + + l += snprintf(buf + l, PAGE_SIZE - l, "\n"); + + unlock_fb_info(fbi); + + return l; +} + +static ssize_t store_overlays_rotate(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct fb_info *fbi = dev_get_drvdata(dev); + struct omapfb_info *ofbi = FB2OFB(fbi); + int num_ovls = 0, r, i; + int len; + bool changed = false; + u8 rotation[OMAPFB_MAX_OVL_PER_FB]; + + len = strlen(buf); + if (buf[len - 1] == '\n') + len = len - 1; + + lock_fb_info(fbi); + + if (len > 0) { + char *p = (char *)buf; + + while (p < buf + len) { + int rot; + + if (num_ovls == ofbi->num_overlays) { + r = -EINVAL; + goto out; + } + + rot = simple_strtoul(p, &p, 0); + if (rot < 0 || rot > 3) { + r = -EINVAL; + goto out; + } + + if (ofbi->rotation[num_ovls] != rot) + changed = true; + + rotation[num_ovls++] = rot; + + p++; + } + } + + if (num_ovls != ofbi->num_overlays) { + r = -EINVAL; + goto out; + } + + if (changed) { + for (i = 0; i < num_ovls; ++i) + ofbi->rotation[i] = rotation[i]; + + r = omapfb_apply_changes(fbi, 0); + if (r) + goto out; + + /* FIXME error handling? */ + } + + r = count; +out: + unlock_fb_info(fbi); + + return r; +} + +static ssize_t show_size(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct fb_info *fbi = dev_get_drvdata(dev); + struct omapfb_info *ofbi = FB2OFB(fbi); + + return snprintf(buf, PAGE_SIZE, "%lu\n", ofbi->region.size); +} + +static ssize_t store_size(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct fb_info *fbi = dev_get_drvdata(dev); + struct omapfb_info *ofbi = FB2OFB(fbi); + unsigned long size; + int r; + int i; + + size = PAGE_ALIGN(simple_strtoul(buf, NULL, 0)); + + lock_fb_info(fbi); + + for (i = 0; i < ofbi->num_overlays; i++) { + if (ofbi->overlays[i]->info.enabled) { + r = -EBUSY; + goto out; + } + } + + if (size != ofbi->region.size) { + r = omapfb_realloc_fbmem(fbi, size, ofbi->region.type); + if (r) { + dev_err(dev, "realloc fbmem failed\n"); + goto out; + } + } + + r = count; +out: + unlock_fb_info(fbi); + + return r; +} + +static ssize_t show_phys(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct fb_info *fbi = dev_get_drvdata(dev); + struct omapfb_info *ofbi = FB2OFB(fbi); + + return snprintf(buf, PAGE_SIZE, "%0x\n", ofbi->region.paddr); +} + +static ssize_t show_virt(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct fb_info *fbi = dev_get_drvdata(dev); + struct omapfb_info *ofbi = FB2OFB(fbi); + + return snprintf(buf, PAGE_SIZE, "%p\n", ofbi->region.vaddr); +} + +static struct device_attribute omapfb_attrs[] = { + __ATTR(rotate_type, S_IRUGO | S_IWUSR, show_rotate_type, store_rotate_type), + __ATTR(mirror, S_IRUGO | S_IWUSR, show_mirror, store_mirror), + __ATTR(size, S_IRUGO | S_IWUSR, show_size, store_size), + __ATTR(overlays, S_IRUGO | S_IWUSR, show_overlays, store_overlays), + __ATTR(overlays_rotate, S_IRUGO | S_IWUSR, + show_overlays_rotate, store_overlays_rotate), + __ATTR(phys_addr, S_IRUGO, show_phys, NULL), + __ATTR(virt_addr, S_IRUGO, show_virt, NULL), +}; + +int omapfb_create_sysfs(struct omapfb2_device *fbdev) +{ + int i; + int r; + + DBG("create sysfs for fbs\n"); + for (i = 0; i < fbdev->num_fbs; i++) { + int t; + for (t = 0; t < ARRAY_SIZE(omapfb_attrs); t++) { + r = device_create_file(fbdev->fbs[i]->dev, + &omapfb_attrs[t]); + + if (r) { + dev_err(fbdev->dev, "failed to create sysfs " + "file\n"); + return r; + } + } + } + + return 0; +} + +void omapfb_remove_sysfs(struct omapfb2_device *fbdev) +{ + int i, t; + + DBG("remove sysfs for fbs\n"); + for (i = 0; i < fbdev->num_fbs; i++) { + for (t = 0; t < ARRAY_SIZE(omapfb_attrs); t++) + device_remove_file(fbdev->fbs[i]->dev, + &omapfb_attrs[t]); + } +} + diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h new file mode 100644 index 000000000000..83be0a7d9be0 --- /dev/null +++ b/drivers/video/omap2/omapfb/omapfb.h @@ -0,0 +1,153 @@ +/* + * linux/drivers/video/omap2/omapfb.h + * + * Copyright (C) 2008 Nokia Corporation + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> + * + * Some code and ideas taken from drivers/video/omap/ driver + * by Imre Deak. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __DRIVERS_VIDEO_OMAP2_OMAPFB_H__ +#define __DRIVERS_VIDEO_OMAP2_OMAPFB_H__ + +#ifdef CONFIG_FB_OMAP2_DEBUG_SUPPORT +#define DEBUG +#endif + +#include <mach/display.h> + +#ifdef DEBUG +extern unsigned int omapfb_debug; +#define DBG(format, ...) \ + if (omapfb_debug) \ + printk(KERN_DEBUG "OMAPFB: " format, ## __VA_ARGS__) +#else +#define DBG(format, ...) +#endif + +#define FB2OFB(fb_info) ((struct omapfb_info *)(fb_info->par)) + +/* max number of overlays to which a framebuffer data can be direct */ +#define OMAPFB_MAX_OVL_PER_FB 3 + +struct omapfb2_mem_region { + u32 paddr; + void __iomem *vaddr; + struct vrfb vrfb; + unsigned long size; + u8 type; /* OMAPFB_PLANE_MEM_* */ + bool alloc; /* allocated by the driver */ + bool map; /* kernel mapped by the driver */ +}; + +/* appended to fb_info */ +struct omapfb_info { + int id; + struct omapfb2_mem_region region; + atomic_t map_count; + int num_overlays; + struct omap_overlay *overlays[OMAPFB_MAX_OVL_PER_FB]; + struct omapfb2_device *fbdev; + enum omap_dss_rotation_type rotation_type; + u8 rotation[OMAPFB_MAX_OVL_PER_FB]; + bool mirror; +}; + +struct omapfb2_device { + struct device *dev; + struct mutex mtx; + + u32 pseudo_palette[17]; + + int state; + + unsigned num_fbs; + struct fb_info *fbs[10]; + + unsigned num_displays; + struct omap_dss_device *displays[10]; + unsigned num_overlays; + struct omap_overlay *overlays[10]; + unsigned num_managers; + struct omap_overlay_manager *managers[10]; +}; + +struct omapfb_colormode { + enum omap_color_mode dssmode; + u32 bits_per_pixel; + u32 nonstd; + struct fb_bitfield red; + struct fb_bitfield green; + struct fb_bitfield blue; + struct fb_bitfield transp; +}; + +u32 omapfb_get_region_paddr(struct omapfb_info *ofbi); +void __iomem *omapfb_get_region_vaddr(struct omapfb_info *ofbi); + +void set_fb_fix(struct fb_info *fbi); +int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var); +int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type); +int omapfb_apply_changes(struct fb_info *fbi, int init); +int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi); + +int omapfb_create_sysfs(struct omapfb2_device *fbdev); +void omapfb_remove_sysfs(struct omapfb2_device *fbdev); + +int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg); + +int omapfb_mode_to_timings(const char *mode_str, + struct omap_video_timings *timings, u8 *bpp); + +int dss_mode_to_fb_mode(enum omap_color_mode dssmode, + struct fb_var_screeninfo *var); + +/* find the display connected to this fb, if any */ +static inline struct omap_dss_device *fb2display(struct fb_info *fbi) +{ + struct omapfb_info *ofbi = FB2OFB(fbi); + int i; + + /* XXX: returns the display connected to first attached overlay */ + for (i = 0; i < ofbi->num_overlays; i++) { + if (ofbi->overlays[i]->manager) + return ofbi->overlays[i]->manager->device; + } + + return NULL; +} + +static inline void omapfb_lock(struct omapfb2_device *fbdev) +{ + mutex_lock(&fbdev->mtx); +} + +static inline void omapfb_unlock(struct omapfb2_device *fbdev) +{ + mutex_unlock(&fbdev->mtx); +} + +static inline int omapfb_overlay_enable(struct omap_overlay *ovl, + int enable) +{ + struct omap_overlay_info info; + + ovl->get_overlay_info(ovl, &info); + info.enabled = enable; + return ovl->set_overlay_info(ovl, &info); +} + +#endif diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index b1ccc04f3c9a..29fd42631b19 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -187,7 +187,7 @@ config EP93XX_WATCHDOG config OMAP_WATCHDOG tristate "OMAP Watchdog" - depends on ARCH_OMAP16XX || ARCH_OMAP24XX || ARCH_OMAP34XX + depends on ARCH_OMAP16XX || ARCH_OMAP24XX || ARCH_OMAP34XX || ARCH_OMAP4 help Support for TI OMAP1610/OMAP1710/OMAP2420/OMAP3430 watchdog. Say 'Y' here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430 watchdog timer. diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c index 3ed571a2ab18..b1b23bfd28a9 100644 --- a/drivers/watchdog/omap_wdt.c +++ b/drivers/watchdog/omap_wdt.c @@ -293,17 +293,20 @@ static int __devinit omap_wdt_probe(struct platform_device *pdev) wdev->omap_wdt_users = 0; wdev->mem = mem; - wdev->ick = clk_get(&pdev->dev, "ick"); - if (IS_ERR(wdev->ick)) { - ret = PTR_ERR(wdev->ick); - wdev->ick = NULL; - goto err_clk; - } - wdev->fck = clk_get(&pdev->dev, "fck"); - if (IS_ERR(wdev->fck)) { - ret = PTR_ERR(wdev->fck); - wdev->fck = NULL; - goto err_clk; + /* FIXME: Enable this ones correct clk nodes available */ + if (!cpu_is_omap44xx()) { + wdev->ick = clk_get(&pdev->dev, "ick"); + if (IS_ERR(wdev->ick)) { + ret = PTR_ERR(wdev->ick); + wdev->ick = NULL; + goto err_clk; + } + wdev->fck = clk_get(&pdev->dev, "fck"); + if (IS_ERR(wdev->fck)) { + ret = PTR_ERR(wdev->fck); + wdev->fck = NULL; + goto err_clk; + } } wdev->base = ioremap(res->start, res->end - res->start + 1); diff --git a/include/linux/i2c/twl4030.h b/include/linux/i2c/twl.h index 0dc80ef24975..b687a8bb2718 100644 --- a/include/linux/i2c/twl4030.h +++ b/include/linux/i2c/twl.h @@ -22,8 +22,8 @@ * */ -#ifndef __TWL4030_H_ -#define __TWL4030_H_ +#ifndef __TWL_H_ +#define __TWL_H_ /* * Using the twl4030 core we address registers using a pair @@ -66,20 +66,165 @@ #define TWL4030_MODULE_RTC 0x14 #define TWL4030_MODULE_SECURED_REG 0x15 +#ifdef CONFIG_TWL4030_CORE +#define TWL_MODULE_USB TWL4030_MODULE_USB +#define TWL_MODULE_AUDIO_VOICE TWL4030_MODULE_AUDIO_VOICE +#define TWL_MODULE_GPIO TWL4030_MODULE_GPIO +#define TWL_MODULE_INTBR TWL4030_MODULE_INTBR +#define TWL_MODULE_PIH TWL4030_MODULE_PIH +#define TWL_MODULE_TEST TWL4030_MODULE_TEST +#define TWL_MODULE_KEYPAD TWL4030_MODULE_KEYPAD +#define TWL_MODULE_MADC TWL4030_MODULE_MADC +#define TWL_MODULE_INTERRUPTS TWL4030_MODULE_INTERRUPTS +#define TWL_MODULE_LED TWL4030_MODULE_LED +#define TWL_MODULE_MAIN_CHARGE TWL4030_MODULE_MAIN_CHARGE +#define TWL_MODULE_PRECHARGE TWL4030_MODULE_PRECHARGE +#define TWL_MODULE_PWM0 TWL4030_MODULE_PWM0 +#define TWL_MODULE_PWM1 TWL4030_MODULE_PWM1 +#define TWL_MODULE_PWMA TWL4030_MODULE_PWMA +#define TWL_MODULE_PWMB TWL4030_MODULE_PWMB +#define TWL_MODULE_BACKUP TWL4030_MODULE_BACKUP +#define TWL_MODULE_INT TWL4030_MODULE_INT +#define TWL_MODULE_PM_MASTER TWL4030_MODULE_PM_MASTER +#define TWL_MODULE_PM_RECEIVER TWL4030_MODULE_PM_RECEIVER +#define TWL_MODULE_PM_SLAVE_LDO TWL_MODULE_PM_RECEIVER +#define TWL_MODULE_RTC TWL4030_MODULE_RTC +#define TWL_MODULE_SECURED_REG TWL4030_MODULE_SECURED_REG + +#define GPIO_INTR_OFFSET 0 +#define KEYPAD_INTR_OFFSET 1 +#define BCI_INTR_OFFSET 2 +#define MADC_INTR_OFFSET 3 +#define USB_INTR_OFFSET 4 +#define BCI_PRES_INTR_OFFSET 9 +#define USB_PRES_INTR_OFFSET 10 +#define RTC_INTR_OFFSET 11 +#endif + +/* + * Using the twl6030 core we address registers using a pair + * { module id, relative register offset } + * which that core then maps to the relevant + * { i2c slave, absolute register address } + * + * The module IDs are meaningful only to the twl6030 core code, + * which uses them as array indices to look up the first register + * address each module uses within a given i2c slave. + */ +/* subchip/slave 0 0x48 - POWER */ +#define TWL6030_MODULE_RTC 0x00 +#define TWL6030_MODULE_MEM 0x01 +#define TWL6030_MODULE_PM_MASTER 0x02 +#define TWL6030_MODULE_PM_SLAVE_MISC 0x03 +#define TWL6030_MODULE_PM_SLAVE_SMPS 0x04 +#define TWL6030_MODULE_PM_SLAVE_LDO 0x05 +#define TWL6030_MODULE_PM_SLAVE_RES 0x06 +#define TWL6030_MODULE_PM_MISC 0x07 +#define TWL6030_MODULE_PM_PUPD 0x08 + +/* subchip/slave 1 0x49 - FEATURE */ +#define TWL6030_MODULE_USB 0x09 +#define TWL6030_MODULE_GPADC_CTRL 0x0A +#define TWL6030_MODULE_GPADC_RT 0x0B +#define TWL6030_MODULE_GPADC 0x0C +#define TWL6030_MODULE_AUX 0x0D +#define TWL6030_MODULE_PWM 0x0E +#define TWL6030_MODULE_GASGAUGE 0x0F +#define TWL6030_MODULE_PIH 0x10 +#define TWL6030_MODULE_CHARGER 0x11 + +/* subchip/slave 2 0x4A - DFT */ +#define TWL6030_MODULE_DIEID 0x12 + +/* subchip/slave 3 0x4B - AUDIO */ +#define TWL6030_MODULE_AUDIO 0x13 + +#ifdef CONFIG_TWL6030_CORE +#define TWL_MODULE_RTC TWL6030_MODULE_RTC +#define TWL_MODULE_MEM TWL6030_MODULE_MEM +#define TWL_MODULE_PM_MASTER TWL6030_MODULE_PM_MASTER +#define TWL_MODULE_PM_SLAVE_MISC TWL6030_MODULE_PM_SLAVE_MISC +#define TWL_MODULE_PM_SLAVE_SMPS TWL6030_MODULE_PM_SLAVE_SMP +#define TWL_MODULE_PM_SLAVE_LDO TWL6030_MODULE_PM_SLAVE_LDO +#define TWL_MODULE_PM_SLAVE_RES TWL6030_MODULE_PM_SLAVE_RES +#define TWL_MODULE_PM_MISC TWL6030_MODULE_PM_MISC +#define TWL_MODULE_PM_PUPD TWL6030_MODULE_PM_PUPD +#define TWL_MODULE_USB TWL6030_MODULE_USB +#define TWL_MODULE_GPADC_CTRL TWL6030_MODULE_GPADC_CTRL +#define TWL_MODULE_GPADC_RT TWL6030_MODULE_GPADC_RT +#define TWL_MODULE_GPADC TWL6030_MODULE_GPADC +#define TWL_MODULE_AUX TWL6030_MODULE_AUX +#define TWL_MODULE_PWM TWL6030_MODULE_PWM +#define TWL_MODULE_GASGAUGE TWL6030_MODULE_GASGAUGE +#define TWL_MODULE_PIH TWL6030_MODULE_PIH +#define TWL_MODULE_CHARGER TWL6030_MODULE_CHARGER +#define TWL_MODULE_DIEID TWL6030_MODULE_DIEID +#define TWL_MODULE_AUDIO TWL6030_MODULE_AUDIO + +/* INT register offsets */ +#define REG_INT_STS_A 0x00 +#define REG_INT_STS_B 0x01 +#define REG_INT_STS_C 0x02 + +#define REG_INT_MSK_LINE_A 0x03 +#define REG_INT_MSK_LINE_B 0x04 +#define REG_INT_MSK_LINE_C 0x05 + +#define REG_INT_MSK_STS_A 0x06 +#define REG_INT_MSK_STS_B 0x07 +#define REG_INT_MSK_STS_C 0x08 + +#define TWL6030_PWR_INT_MASK 0x0F +#define TWL6030_RTC_INT_MASK 0x30 +#define TWL6030_HOTDIE_INT_MASK 0x40 +#define TWL6030_SMPSLDOA_INT_MASK 0x80 + +#define TWL6030_SMPSLDOB_INT_MASK 0x03 +#define TWL6030_SIMDETECT_INT_MASK 0x04 +#define TWL6030_MMCDETECT_INT_MASK 0x08 +#define TWL6030_GPADC_INT_MASK 0x60 +#define TWL6030_GASGAUGE_INT_MASK 0x80 + +#define TWL6030_USBOTG_INT_MASK 0x0F +#define TWL6030_CHARGER_INT_MASK 0xF0 + +/* + * Offset from TWL6030_IRQ_BASE / pdata->irq_base + */ +#define PWR_INTR_OFFSET 0 +#define RTC_INTR_OFFSET 1 +#define HOTDIE_INTR_OFFSET 2 +#define SMPSLDO_INTR_OFFSET 3 +#define SIMDETECT_INTR_OFFSET 4 +#define MMCDETECT_INTR_OFFSET 5 +#define GPADC_INTR_OFFSET 6 +#define GASGAUGE_INTR_OFFSET 7 +#define USBOTG_INTR_OFFSET 8 +#define CHARGER_INTR_OFFSET 9 +#define RSV_INTR_OFFSET 0 + +#define BCI_PRES_INTR_OFFSET 4 +#define MADC_INTR_OFFSET 6 +#define BCI_INTR_OFFSET 8 +#define USB_PRES_INTR_OFFSET 8 +#define USB_INTR_OFFSET 8 +#define GPIO_INTR_OFFSET 0 /* NOT SUPPORTED IN TWL6030 */ +#define KEYPAD_INTR_OFFSET 0 /* ADDED FOR COMPILATION ONLY */ +#endif /* * Read and write single 8-bit registers */ -int twl4030_i2c_write_u8(u8 mod_no, u8 val, u8 reg); -int twl4030_i2c_read_u8(u8 mod_no, u8 *val, u8 reg); +int twl_i2c_write_u8(u8 mod_no, u8 val, u8 reg); +int twl_i2c_read_u8(u8 mod_no, u8 *val, u8 reg); /* * Read and write several 8-bit registers at once. * - * IMPORTANT: For twl4030_i2c_write(), allocate num_bytes + 1 + * IMPORTANT: For twl_i2c_write(), allocate num_bytes + 1 * for the value, and populate your data starting at offset 1. */ -int twl4030_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes); -int twl4030_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes); +int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes); +int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes); /*----------------------------------------------------------------------*/ @@ -216,6 +361,7 @@ int twl4030_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes); #define TWL4030_INT_PWR_EDR2 0x6 #define TWL4030_INT_PWR_SIH_CTRL 0x7 + /*----------------------------------------------------------------------*/ /* Power bus message definitions */ @@ -257,21 +403,27 @@ int twl4030_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes); */ #define MSG_BROADCAST(devgrp, grp, type, type2, state) \ - ( (devgrp) << 13 | 1 << 12 | (grp) << 9 | (type2) << 7 \ + ((devgrp) << 13 | 1 << 12 | (grp) << 9 | (type2) << 7 \ | (type) << 4 | (state)) #define MSG_SINGULAR(devgrp, id, state) \ ((devgrp) << 13 | 0 << 12 | (id) << 4 | (state)) +#define MSG_BROADCAST_ALL(devgrp, state) \ + ((devgrp) << 5 | (state)) + +#define MSG_BROADCAST_REF MSG_BROADCAST_ALL +#define MSG_BROADCAST_PROV MSG_BROADCAST_ALL +#define MSG_BROADCAST__CLK_RST MSG_BROADCAST_ALL /*----------------------------------------------------------------------*/ -struct twl4030_bci_platform_data { +struct twl_bci_platform_data { int *battery_tmp_tbl; unsigned int tblsize; }; /* TWL4030_GPIO_MAX (18) GPIOs, with interrupts */ -struct twl4030_gpio_platform_data { +struct twl_gpio_platform_data { int gpio_base; unsigned irq_base, irq_end; @@ -298,11 +450,11 @@ struct twl4030_gpio_platform_data { unsigned gpio, unsigned ngpio); }; -struct twl4030_madc_platform_data { +struct twl_madc_platform_data { int irq_line; }; -struct twl4030_keypad_data { +struct twl_keypad_data { int rows; int cols; int *keymap; @@ -311,35 +463,42 @@ struct twl4030_keypad_data { unsigned int rep:1; }; -enum twl4030_usb_mode { +enum twl_usb_mode { T2_USB_MODE_ULPI = 1, T2_USB_MODE_CEA2011_3PIN = 2, }; -struct twl4030_usb_data { - enum twl4030_usb_mode usb_mode; +struct twl_usb_data { + enum twl_usb_mode usb_mode; }; -struct twl4030_platform_data { +struct twl_platform_data { unsigned irq_base, irq_end; - struct twl4030_bci_platform_data *bci; - struct twl4030_gpio_platform_data *gpio; - struct twl4030_madc_platform_data *madc; - struct twl4030_keypad_data *keypad; - struct twl4030_usb_data *usb; + struct twl_bci_platform_data *bci; + struct twl_gpio_platform_data *gpio; + struct twl_madc_platform_data *madc; + struct twl_keypad_data *keypad; + struct twl_usb_data *usb; - /* LDO regulators */ + /* LDO regulators common to TWL4030/TWL6030 */ struct regulator_init_data *vdac; + struct regulator_init_data *vaux1; + struct regulator_init_data *vaux2; + struct regulator_init_data *vaux3; + /* TWL4030 LDO regulators */ struct regulator_init_data *vpll1; struct regulator_init_data *vpll2; struct regulator_init_data *vmmc1; struct regulator_init_data *vmmc2; struct regulator_init_data *vsim; - struct regulator_init_data *vaux1; - struct regulator_init_data *vaux2; - struct regulator_init_data *vaux3; struct regulator_init_data *vaux4; - + /* TWL6030 LDO regulators */ + struct regulator_init_data *vmmc; + struct regulator_init_data *vpp; + struct regulator_init_data *vusim; + struct regulator_init_data *vana; + struct regulator_init_data *vcxio; + struct regulator_init_data *vusb; /* REVISIT more to come ... _nothing_ should be hard-wired */ }; @@ -373,6 +532,7 @@ int twl4030_sih_setup(int module); * VIO is generally fixed. */ +/* TWL4030 SMPS/LDO's */ /* EXTERNAL dc-to-dc buck converters */ #define TWL4030_REG_VDD1 0 #define TWL4030_REG_VDD2 1 @@ -399,4 +559,36 @@ int twl4030_sih_setup(int module); #define TWL4030_REG_VUSB1V8 18 #define TWL4030_REG_VUSB3V1 19 +/* TWL6030 SMPS/LDO's */ +/* EXTERNAL dc-to-dc buck convertor contollable via SR */ +#define TWL6030_REG_VDD1 0 +#define TWL6030_REG_VDD2 1 +#define TWL6030_REG_VDD3 2 + +/* Non SR compliant dc-to-dc buck convertors */ +#define TWL6030_REG_VMEM 3 +#define TWL6030_REG_V2V1 4 +#define TWL6030_REG_V1V29 5 +#define TWL6030_REG_V1V8 6 + +/* EXTERNAL LDOs */ +#define TWL6030_REG_VAUX1_6030 7 +#define TWL6030_REG_VAUX2_6030 8 +#define TWL6030_REG_VAUX3_6030 9 +#define TWL6030_REG_VMMC 10 +#define TWL6030_REG_VPP 11 +#define TWL6030_REG_VUSIM 12 +#define TWL6030_REG_VANA 13 +#define TWL6030_REG_VCXIO 14 +#define TWL6030_REG_VDAC 15 +#define TWL6030_REG_VUSB 16 + +/* INTERNAL LDOs */ +#define TWL6030_REG_VRTC 17 + +int twl_int_mask_reset(u8 bit_mask, u8 offset); +int twl_int_mask_set(u8 bit_mask, u8 offset); +int twl_init_irq(int irq_num, unsigned irq_base, unsigned irq_end); +int twl_exit_irq(void); + #endif /* End of __TWL4030_H */ diff --git a/arch/arm/plat-omap/include/mach/omapfb.h b/include/linux/omapfb.h index 7b74d1255e0b..6300ea7b9054 100644 --- a/arch/arm/plat-omap/include/mach/omapfb.h +++ b/include/linux/omapfb.h @@ -24,6 +24,8 @@ #ifndef __OMAPFB_H #define __OMAPFB_H +#include <linux/fb.h> + #include <asm/ioctl.h> #include <asm/types.h> @@ -50,6 +52,10 @@ #define OMAPFB_UPDATE_WINDOW OMAP_IOW(54, struct omapfb_update_window) #define OMAPFB_SETUP_MEM OMAP_IOW(55, struct omapfb_mem_info) #define OMAPFB_QUERY_MEM OMAP_IOW(56, struct omapfb_mem_info) +#define OMAPFB_WAITFORVSYNC OMAP_IO(57) +#define OMAPFB_MEMORY_READ OMAP_IOR(58, struct omapfb_memory_read) +#define OMAPFB_GET_OVERLAY_COLORMODE OMAP_IOR(59, struct omapfb_ovl_colormode) +#define OMAPFB_WAITFORGO OMAP_IO(60) #define OMAPFB_CAPS_GENERIC_MASK 0x00000fff #define OMAPFB_CAPS_LCDC_MASK 0x00fff000 @@ -90,6 +96,13 @@ enum omapfb_color_format { OMAPFB_COLOR_CLUT_1BPP, OMAPFB_COLOR_RGB444, OMAPFB_COLOR_YUY422, + + OMAPFB_COLOR_ARGB16, + OMAPFB_COLOR_RGB24U, /* RGB24, 32-bit container */ + OMAPFB_COLOR_RGB24P, /* RGB24, 24-bit container */ + OMAPFB_COLOR_ARGB32, + OMAPFB_COLOR_RGBA32, + OMAPFB_COLOR_RGBX32, }; struct omapfb_update_window { @@ -161,11 +174,30 @@ enum omapfb_update_mode { OMAPFB_MANUAL_UPDATE }; +struct omapfb_memory_read { + __u16 x; + __u16 y; + __u16 w; + __u16 h; + size_t buffer_size; + void __user *buffer; +}; + +struct omapfb_ovl_colormode { + __u8 overlay_idx; + __u8 mode_idx; + __u32 bits_per_pixel; + __u32 nonstd; + struct fb_bitfield red; + struct fb_bitfield green; + struct fb_bitfield blue; + struct fb_bitfield transp; +}; + #ifdef __KERNEL__ #include <linux/completion.h> #include <linux/interrupt.h> -#include <linux/fb.h> #include <linux/mutex.h> #include <mach/board.h> @@ -256,7 +288,7 @@ struct lcd_ctrl_extif { void (*read_data) (void *buf, unsigned int len); void (*write_data) (const void *buf, unsigned int len); void (*transfer_area) (int width, int height, - void (callback)(void * data), void *data); + void (callback)(void *data), void *data); int (*setup_tearsync) (unsigned pin_cnt, unsigned hs_pulse_time, unsigned vs_pulse_time, int hs_pol_inv, int vs_pol_inv, int div); @@ -276,10 +308,15 @@ typedef int (*omapfb_notifier_callback_t)(struct notifier_block *, void *fbi); struct omapfb_mem_region { - dma_addr_t paddr; - void *vaddr; + u32 paddr; + void __iomem *vaddr; unsigned long size; u8 type; /* OMAPFB_PLANE_MEM_* */ + enum omapfb_color_format format;/* OMAPFB_COLOR_* */ + unsigned format_used:1; /* Must be set when format is set. + * Needed b/c of the badly chosen 0 + * base for OMAPFB_COLOR_* values + */ unsigned alloc:1; /* allocated by the driver */ unsigned map:1; /* kernel mapped by the driver */ }; @@ -332,7 +369,7 @@ struct lcd_ctrl { enum omapfb_state { OMAPFB_DISABLED = 0, - OMAPFB_SUSPENDED= 99, + OMAPFB_SUSPENDED = 99, OMAPFB_ACTIVE = 100 }; @@ -346,7 +383,7 @@ struct omapfb_plane_struct { struct omapfb_device { int state; int ext_lcdc; /* Using external - LCD controller */ + LCD controller */ struct mutex rqueue_mutex; int palette_size; @@ -356,7 +393,7 @@ struct omapfb_device { const struct lcd_ctrl *ctrl; /* LCD controller */ const struct lcd_ctrl *int_ctrl; /* internal LCD ctrl */ struct lcd_ctrl_extif *ext_if; /* LCD ctrl external - interface */ + interface */ struct device *dev; struct fb_var_screeninfo new_var; /* for mode changes */ @@ -376,6 +413,8 @@ extern struct lcd_ctrl omap1_lcd_ctrl; extern struct lcd_ctrl omap2_disp_ctrl; #endif +extern void omapfb_set_platform_data(struct omapfb_platform_data *data); + extern void omapfb_reserve_sdram(void); extern void omapfb_register_panel(struct lcd_panel *panel); extern void omapfb_write_first_pixel(struct omapfb_device *fbdev, u16 pixval); diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 74f16876f38d..3a107dba2a6c 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -554,6 +554,7 @@ struct v4l2_framebuffer { #define V4L2_FBUF_CAP_LOCAL_ALPHA 0x0010 #define V4L2_FBUF_CAP_GLOBAL_ALPHA 0x0020 #define V4L2_FBUF_CAP_LOCAL_INV_ALPHA 0x0040 +#define V4L2_FBUF_CAP_SRC_CHROMAKEY 0x0080 /* Flags for the 'flags' field. */ #define V4L2_FBUF_FLAG_PRIMARY 0x0001 #define V4L2_FBUF_FLAG_OVERLAY 0x0002 @@ -561,6 +562,7 @@ struct v4l2_framebuffer { #define V4L2_FBUF_FLAG_LOCAL_ALPHA 0x0008 #define V4L2_FBUF_FLAG_GLOBAL_ALPHA 0x0010 #define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA 0x0020 +#define V4L2_FBUF_FLAG_SRC_CHROMAKEY 0x0040 struct v4l2_clip { struct v4l2_rect c; @@ -899,9 +901,11 @@ enum v4l2_colorfx { V4L2_COLORFX_SEPIA = 2, }; #define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32) +#define V4L2_CID_ROTATE (V4L2_CID_BASE+33) +#define V4L2_CID_BG_COLOR (V4L2_CID_BASE+34) /* last CID + 1 */ -#define V4L2_CID_LASTP1 (V4L2_CID_BASE+33) +#define V4L2_CID_LASTP1 (V4L2_CID_BASE+35) /* MPEG-class control IDs defined by V4L2 */ #define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) @@ -1213,6 +1217,18 @@ struct v4l2_hw_freq_seek { }; /* + * Color conversion + * User needs to pass pointer to color conversion matrix + * defined by hardware + */ +struct v4l2_color_space_conversion { + __s32 coefficients[3][3]; + __s32 const_factor; + __s32 input_offs[3]; + __s32 output_offs[3]; +}; + +/* * A U D I O */ struct v4l2_audio { @@ -1551,6 +1567,9 @@ struct v4l2_dbg_chip_ident { #endif #define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek) +#define VIDIOC_S_COL_SPC_CONV _IOW('V', 83, struct v4l2_color_space_conversion) +#define VIDIOC_G_COL_SPC_CONV _IOR('V', 84, struct v4l2_color_space_conversion) + /* Reminder: when adding new ioctls please add support for them to drivers/media/video/v4l2-compat-ioctl32.c as well! */ diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h index 7a4529defa88..1e0698248bb0 100644 --- a/include/media/v4l2-ioctl.h +++ b/include/media/v4l2-ioctl.h @@ -242,6 +242,11 @@ struct v4l2_ioctl_ops { /* For other private ioctls */ long (*vidioc_default) (struct file *file, void *fh, int cmd, void *arg); + + int (*vidioc_s_color_space_conv)(struct file *file, void *fh, + struct v4l2_color_space_conversion *a); + int (*vidioc_g_color_space_conv)(struct file *file, void *fh, + struct v4l2_color_space_conversion *a); }; diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index bbc97fd76648..987a358714a3 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -25,6 +25,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_TLV320AIC26 if SPI_MASTER select SND_SOC_TLV320AIC3X if I2C select SND_SOC_TWL4030 if TWL4030_CORE + select SND_SOC_ABE_TWL6030 if TWL6030_CORE select SND_SOC_UDA134X select SND_SOC_UDA1380 if I2C select SND_SOC_WM8350 if MFD_WM8350 @@ -114,6 +115,9 @@ config SND_SOC_TLV320AIC3X config SND_SOC_TWL4030 tristate +config SND_SOC_ABE_TWL6030 + tristate + config SND_SOC_UDA134X tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 8b7530546f4d..f93e018841bb 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -13,6 +13,7 @@ snd-soc-tlv320aic23-objs := tlv320aic23.o snd-soc-tlv320aic26-objs := tlv320aic26.o snd-soc-tlv320aic3x-objs := tlv320aic3x.o snd-soc-twl4030-objs := twl4030.o +snd-soc-abe-twl6030-objs := abe-twl6030.o snd-soc-uda134x-objs := uda134x.o snd-soc-uda1380-objs := uda1380.o snd-soc-wm8350-objs := wm8350.o @@ -50,6 +51,7 @@ obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o +obj-$(CONFIG_SND_SOC_ABE_TWL6030) += snd-soc-abe-twl6030.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-twl6030.c b/sound/soc/codecs/abe-twl6030.c new file mode 100644 index 000000000000..7012273b8313 --- /dev/null +++ b/sound/soc/codecs/abe-twl6030.c @@ -0,0 +1,974 @@ +/* + * ALSA SoC ABE-TWL6030 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/platform_device.h> +#include <linux/i2c/twl.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 "twl6030.h" +#include "abe-twl6030.h" +#include "abe/abe_main.h" + +#define ABE_FORMATS (SNDRV_PCM_FMTBIT_S32_LE) + +/* codec private data */ +struct twl6030_priv_data { + int codec_powered; + unsigned int sysclk; +}; + +/* + * twl6030 register cache & default register settings + */ +static const u8 twl6030_reg[TWL6030_CACHEREGNUM] = { + 0x00, /* not used 0x00 */ + 0x4B, /* TWL6030_ASICID (ro) 0x01 */ + 0x00, /* TWL6030_ASICREV (ro) 0x02 */ + 0x00, /* TWL6030_INTID 0x03 */ + 0x00, /* TWL6030_INTMR 0x04 */ + 0x00, /* TWL6030_NCPCTRL 0x05 */ + 0x00, /* TWL6030_LDOCTL 0x06 */ + 0x00, /* TWL6030_HPPLLCTL 0x07 */ + 0x00, /* TWL6030_LPPLLCTL 0x08 */ + 0x00, /* TWL6030_LPPLLDIV 0x09 */ + 0x00, /* TWL6030_AMICBCTL 0x0A */ + 0x00, /* TWL6030_DMICBCTL 0x0B */ + 0x00, /* TWL6030_MICLCTL 0x0C */ + 0x00, /* TWL6030_MICRCTL 0x0D */ + 0x00, /* TWL6030_MICGAIN 0x0E */ + 0x1B, /* TWL6030_LINEGAIN 0x0F */ + 0x00, /* TWL6030_HSLCTL 0x10 */ + 0x00, /* TWL6030_HSRCTL 0x11 */ + 0x00, /* TWL6030_HSGAIN 0x12 */ + 0x06, /* TWL6030_EARCTL 0x13 */ + 0x00, /* TWL6030_HFLCTL 0x14 */ + 0x03, /* TWL6030_HFLGAIN 0x15 */ + 0x00, /* TWL6030_HFRCTL 0x16 */ + 0x03, /* TWL6030_HFRGAIN 0x17 */ + 0x00, /* TWL6030_VIBCTLL 0x18 */ + 0x00, /* TWL6030_VIBDATL 0x19 */ + 0x00, /* TWL6030_VIBCTLR 0x1A */ + 0x00, /* TWL6030_VIBDATR 0x1B */ + 0x00, /* TWL6030_HKCTL1 0x1C */ + 0x00, /* TWL6030_HKCTL2 0x1D */ + 0x00, /* TWL6030_GPOCTL 0x1E */ + 0x00, /* TWL6030_ALB 0x1F */ + 0x00, /* TWL6030_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, /* TWL6030_TRIM1 0x28 */ + 0x00, /* TWL6030_TRIM2 0x29 */ + 0x00, /* TWL6030_TRIM3 0x2A */ + 0x00, /* TWL6030_HSOTRIM 0x2B */ + 0x00, /* TWL6030_HFOTRIM 0x2C */ + 0x09, /* TWL6030_ACCCTL 0x2D */ + 0x00, /* TWL6030_STATUS (ro) 0x2E */ +}; + +/* + * read twl6030 register cache + */ +static inline unsigned int twl6030_read_reg_cache(struct snd_soc_codec *codec, + unsigned int reg) +{ + u8 *cache = codec->reg_cache; + + if (reg >= TWL6030_CACHEREGNUM) + return -EIO; + + return cache[reg]; +} + +/* + * write twl6030 register cache + */ +static inline void twl6030_write_reg_cache(struct snd_soc_codec *codec, + u8 reg, u8 value) +{ + u8 *cache = codec->reg_cache; + + if (reg >= TWL6030_CACHEREGNUM) + return; + cache[reg] = value; +} + +/* + * read from twl6030 hardware register + */ +static int twl6030_read(struct snd_soc_codec *codec, + unsigned int reg) +{ + u8 value; + + if (reg > TWL6030_CACHEREGNUM) + return -EIO; + + twl_i2c_read_u8(TWL6030_MODULE_AUDIO, &value, reg); + twl6030_write_reg_cache(codec, reg, value); + + return value; +} + +/* + * write to the twl6030 register space + */ +static int twl6030_write(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value) +{ + if ((reg < TWL6030_REG_INTID) || (reg > TWL6030_REG_ACCCTL)) + /* read-only registers */ + return -EIO; + + twl6030_write_reg_cache(codec, reg, value); + return twl_i2c_write_u8(TWL6030_MODULE_AUDIO, value, reg); +} + +static void abe_init_chip(struct snd_soc_codec *codec) +{ + abe_reset_hal(); +} + +static void twl6030_init_chip(struct snd_soc_codec *codec) +{ + u8 *cache = codec->reg_cache; + int i; + + /* allow registers to be accessed by i2c */ + twl6030_write(codec, TWL6030_REG_ACCCTL, cache[TWL6030_REG_ACCCTL]); + + /* set all audio section registers to reasonable defaults */ + /* avoid read-only (ASICID, ASICREV, STATUS) and non-used registers */ + for (i = TWL6030_REG_INTMR; i <= TWL6030_REG_DLB; i++) + twl6030_write(codec, i, cache[i]); + for (i = TWL6030_REG_TRIM1; i < TWL6030_REG_ACCCTL; i++) + twl6030_write(codec, i, cache[i]); +} + +static void twl6030_power_up(struct snd_soc_codec *codec) +{ + struct snd_soc_device *socdev = codec->socdev; + struct twl6030_priv_data *priv = codec->private_data; + struct twl6030_setup_data *setup = socdev->codec_data; + + if (priv->codec_powered) + return; + + setup->codec_enable(1); + + /* wait for ready interrupt */ + wait_for_completion(&setup->ready_completion); + + /* sync registers updated during power-up sequence */ + twl6030_read(codec, TWL6030_REG_NCPCTL); + twl6030_read(codec, TWL6030_REG_LDOCTL); + twl6030_read(codec, TWL6030_REG_LPPLLCTL); +} + +static void twl6030_power_down(struct snd_soc_codec *codec) +{ + struct snd_soc_device *socdev = codec->socdev; + struct twl6030_priv_data *priv = codec->private_data; + struct twl6030_setup_data *setup = socdev->codec_data; + + setup->codec_enable(0); + udelay(500); + + /* sync registers updated during power-down sequence */ + twl6030_read(codec, TWL6030_REG_NCPCTL); + twl6030_read(codec, TWL6030_REG_LDOCTL); + twl6030_read(codec, TWL6030_REG_LPPLLCTL); + + priv->codec_powered = 0; +} + +/* audio interrupt handler */ +irqreturn_t twl6030_naudint_handler(int irq, void *data) +{ + struct twl6030_setup_data *setup = data; + + schedule_work(&setup->audint_work); + + /* disable audint irq to let workqueue to execute */ + disable_irq_nosync(irq); + + return IRQ_HANDLED; +} + +void twl6030_naudint_work(struct work_struct *work) +{ + struct snd_soc_codec *codec; + struct twl6030_setup_data *setup; + struct twl6030_priv_data *priv; + u8 intid; + + setup = container_of(work, struct twl6030_setup_data, audint_work); + codec = setup->codec; + priv = codec->private_data; + + twl_i2c_read_u8(TWL6030_MODULE_AUDIO, &intid, TWL6030_REG_INTID); + + switch (intid) { + case TWL6030_THINT: + dev_alert(codec->dev, "die temperature over-limit detection\n"); + break; + case TWL6030_PLUGINT: + case TWL6030_UNPLUGINT: + case TWL6030_HOOKINT: + break; + case TWL6030_HFINT: + dev_alert(codec->dev, "hf drivers over current detection\n"); + break; + case TWL6030_VIBINT: + dev_alert(codec->dev, "vib drivers over current detection\n"); + break; + case TWL6030_READYINT: + priv->codec_powered = 1; + complete(&setup->ready_completion); + break; + default: + dev_err(codec->dev, "unknown twl6030 audio interrupt\n"); + } + + enable_irq(setup->irq); +} + +/* 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 = TWL6030_HSDRVMODEL | TWL6030_HSDACMODEL; + + hslctl = twl6030_read_reg_cache(codec, TWL6030_REG_HSLCTL); + hsrctl = twl6030_read_reg_cache(codec, TWL6030_REG_HSRCTL); + + if (high_perf) { + hslctl &= ~mask; + hsrctl &= ~mask; + } else { + hslctl |= mask; + hsrctl |= mask; + } + + twl6030_write(codec, TWL6030_REG_HSLCTL, hslctl); + twl6030_write(codec, TWL6030_REG_HSRCTL, hsrctl); + + return 0; +} + +/* + * 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); + +/* Left analog microphone selection */ +static const char *twl6030_amicl_texts[] = + {"Headset Mic", "Main Mic", "Aux/FM Left", "Off"}; + +/* Right analog microphone selection */ +static const char *twl6030_amicr_texts[] = + {"Headset Mic", "Sub Mic", "Aux/FM Right", "Off"}; + +static const struct soc_enum twl6030_enum[] = { + SOC_ENUM_SINGLE(TWL6030_REG_MICLCTL, 3, 3, twl6030_amicl_texts), + SOC_ENUM_SINGLE(TWL6030_REG_MICRCTL, 3, 3, twl6030_amicr_texts), +}; + +static const struct snd_kcontrol_new amicl_control = + SOC_DAPM_ENUM("Route", twl6030_enum[0]); + +static const struct snd_kcontrol_new amicr_control = + SOC_DAPM_ENUM("Route", twl6030_enum[1]); + +/* Headset DAC playback switches */ +static const struct snd_kcontrol_new hsdacl_switch_controls = + SOC_DAPM_SINGLE("Switch", TWL6030_REG_HSLCTL, 5, 1, 0); + +static const struct snd_kcontrol_new hsdacr_switch_controls = + SOC_DAPM_SINGLE("Switch", TWL6030_REG_HSRCTL, 5, 1, 0); + +/* Handsfree DAC playback switches */ +static const struct snd_kcontrol_new hfdacl_switch_controls = + SOC_DAPM_SINGLE("Switch", TWL6030_REG_HFLCTL, 2, 1, 0); + +static const struct snd_kcontrol_new hfdacr_switch_controls = + SOC_DAPM_SINGLE("Switch", TWL6030_REG_HFRCTL, 2, 1, 0); + +/* Headset driver switches */ +static const struct snd_kcontrol_new hsl_driver_switch_controls = + SOC_DAPM_SINGLE("Switch", TWL6030_REG_HSLCTL, 2, 1, 0); + +static const struct snd_kcontrol_new hsr_driver_switch_controls = + SOC_DAPM_SINGLE("Switch", TWL6030_REG_HSRCTL, 2, 1, 0); + +/* Handsfree driver switches */ +static const struct snd_kcontrol_new hfl_driver_switch_controls = + SOC_DAPM_SINGLE("Switch", TWL6030_REG_HFLCTL, 4, 1, 0); + +static const struct snd_kcontrol_new hfr_driver_switch_controls = + SOC_DAPM_SINGLE("Switch", TWL6030_REG_HFRCTL, 4, 1, 0); + +static const struct snd_kcontrol_new twl6030_snd_controls[] = { + /* Capture gains */ + SOC_DOUBLE_TLV("Capture Preamplifier (Attenuator) Volume", + TWL6030_REG_MICGAIN, 6, 7, 1, 1, mic_preamp_tlv), + SOC_DOUBLE_TLV("Capture Amplifier Volume", + TWL6030_REG_MICGAIN, 0, 3, 4, 0, mic_amp_tlv), + + /* Playback gains */ + SOC_DOUBLE_TLV("Headset Playback Volume", + TWL6030_REG_HSGAIN, 0, 4, 0xF, 1, hs_tlv), + SOC_DOUBLE_R_TLV("Handsfree Playback Volume", + TWL6030_REG_HFLGAIN, TWL6030_REG_HFRGAIN, 0, 0x1D, 1, hf_tlv), + +}; + +static const struct snd_soc_dapm_widget twl6030_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"), + + /* Analog input muxers 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), + + /* Analog capture PGAs */ + SND_SOC_DAPM_PGA("MicAmpL", + TWL6030_REG_MICLCTL, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("MicAmpR", + TWL6030_REG_MICRCTL, 0, 0, NULL, 0), + + /* ADCs */ + SND_SOC_DAPM_ADC("ADC Left", "Left Front Capture", + TWL6030_REG_MICLCTL, 2, 0), + SND_SOC_DAPM_ADC("ADC Right", "Right Front Capture", + TWL6030_REG_MICLCTL, 2, 0), + + /* Microphone bias */ + SND_SOC_DAPM_MICBIAS("Headset Mic Bias", + TWL6030_REG_AMICBCTL, 0, 0), + SND_SOC_DAPM_MICBIAS("Main Mic Bias", + TWL6030_REG_AMICBCTL, 4, 0), + SND_SOC_DAPM_MICBIAS("Digital Mic1 Bias", + TWL6030_REG_DMICBCTL, 0, 0), + SND_SOC_DAPM_MICBIAS("Digital Mic2 Bias", + TWL6030_REG_DMICBCTL, 4, 0), + + /* DACs */ + SND_SOC_DAPM_DAC("HSDAC Left", "Headset Playback", + TWL6030_REG_HSLCTL, 0, 0), + SND_SOC_DAPM_DAC("HSDAC Right", "Headset Playback", + TWL6030_REG_HSRCTL, 0, 0), + SND_SOC_DAPM_DAC("HFDAC Left", "Handsfree Playback", + TWL6030_REG_HFLCTL, 0, 0), + SND_SOC_DAPM_DAC("HFDAC Right", "Handsfree Playback", + TWL6030_REG_HFRCTL, 0, 0), + + /* 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), + + SND_SOC_DAPM_SWITCH("Headset Left Driver", + SND_SOC_NOPM, 0, 0, &hsl_driver_switch_controls), + SND_SOC_DAPM_SWITCH("Headset Right Driver", + SND_SOC_NOPM, 0, 0, &hsr_driver_switch_controls), + SND_SOC_DAPM_SWITCH("Handsfree Left Driver", + SND_SOC_NOPM, 0, 0, &hfl_driver_switch_controls), + SND_SOC_DAPM_SWITCH("Handsfree Right Driver", + SND_SOC_NOPM, 0, 0, &hfr_driver_switch_controls), + + /* Analog playback PGAs */ + SND_SOC_DAPM_PGA("HFDAC Left PGA", + TWL6030_REG_HFLCTL, 1, 0, NULL, 0), + SND_SOC_DAPM_PGA("HFDAC Right PGA", + TWL6030_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 */ + {"HSDAC Left Playback", "Switch", "HSDAC Left"}, + {"HSDAC Right Playback", "Switch", "HSDAC Right"}, + + {"Headset Left Driver", "Switch", "HSDAC Left Playback"}, + {"Headset Right Driver", "Switch", "HSDAC Right Playback"}, + + {"HSOL", NULL, "Headset Left Driver"}, + {"HSOR", NULL, "Headset Right Driver"}, + + /* Handsfree playback path */ + {"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_twl6030_add_widgets(struct snd_soc_codec *codec) +{ + snd_soc_dapm_new_controls(codec, twl6030_dapm_widgets, + ARRAY_SIZE(twl6030_dapm_widgets)); + + snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + + snd_soc_dapm_new_widgets(codec); + return 0; +} + +static int abe_twl6030_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + switch (level) { + case SND_SOC_BIAS_ON: + twl6030_power_up(codec); + break; + case SND_SOC_BIAS_PREPARE: + twl6030_power_up(codec); + break; + case SND_SOC_BIAS_STANDBY: + twl6030_power_up(codec); + break; + case SND_SOC_BIAS_OFF: + twl6030_power_down(codec); + break; + } + codec->bias_level = level; + + return 0; +} + +static int twl6030_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 twl6030_priv_data *twl6030_priv = codec->private_data; + u8 hppll, lppll; + + lppll = twl6030_read_reg_cache(codec, TWL6030_REG_LPPLLCTL); + hppll = twl6030_read_reg_cache(codec, TWL6030_REG_HPPLLCTL); + + switch (clk_id) { + case TWL6030_SYSCLK_SEL_LPPLL: + if (freq != 32768) { + dev_err(codec->dev, "invalid sysclk freq %d\n", freq); + return -EINVAL; + } + + /* CLK32K input requires low-power PLL */ + lppll |= TWL6030_LPLLENA | TWL6030_LPLLSEL; + twl6030_write(codec, TWL6030_REG_LPPLLCTL, lppll); + mdelay(5); + lppll &= ~TWL6030_HPLLSEL; + twl6030_write(codec, TWL6030_REG_LPPLLCTL, lppll); + + /* headset dac and driver must be in low-power mode */ + headset_power_mode(codec, 0); + + hppll &= ~TWL6030_HPLLENA; + twl6030_write(codec, TWL6030_REG_HPPLLCTL, hppll); + break; + case TWL6030_SYSCLK_SEL_HPPLL: + switch (freq) { + case 12000000: + hppll = TWL6030_MCLK_12000KHZ; + break; + case 26000000: + hppll = TWL6030_MCLK_26000KHZ; + break; + default: + dev_err(codec->dev, "invalid sysclk freq %d\n", freq); + return -EINVAL; + } + + /* 12 and 26 MHz freqs require high-performance PLL */ + hppll |= TWL6030_HPLLSQRBP | TWL6030_HPLLENA; + twl6030_write(codec, TWL6030_REG_HPPLLCTL, hppll); + udelay(500); + + /* headset dac and driver must be in high-performance mode */ + headset_power_mode(codec, 1); + + lppll |= TWL6030_HPLLSEL; + twl6030_write(codec, TWL6030_REG_LPPLLCTL, lppll); + lppll &= ~TWL6030_LPLLENA; + twl6030_write(codec, TWL6030_REG_LPPLLCTL, lppll); + + /* only 19.2 MHz can be generated by HPPLL */ + twl6030_priv->sysclk = 19200000; + break; + case TWL6030_SYSCLK_SEL_MCLK: + switch (freq) { + case 19200000: + hppll = TWL6030_MCLK_19200KHZ | TWL6030_HPLLSQRBP; + break; + case 38400000: + hppll = TWL6030_MCLK_38400KHZ; + break; + default: + dev_err(codec->dev, "invalid sysclk freq %d\n", freq); + return -EINVAL; + } + + /* 19.2 and 38.4 MHz freqs don't require PLL */ + hppll |= TWL6030_HPLLBP; + twl6030_write(codec, TWL6030_REG_HPPLLCTL, hppll); + udelay(500); + + /* headset dac and driver must be in high-performance mode */ + headset_power_mode(codec, 1); + + lppll |= TWL6030_HPLLSEL; + twl6030_write(codec, TWL6030_REG_LPPLLCTL, lppll); + lppll &= ~TWL6030_LPLLENA; + twl6030_write(codec, TWL6030_REG_LPPLLCTL, lppll); + + /* only 19.2 MHz can be generated by MCLK */ + twl6030_priv->sysclk = 19200000; + break; + default: + dev_err(codec->dev, "unknown sysclk rate %d\n", freq); + return -EINVAL; + } + + return 0; +} + +static int twl6030_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, + unsigned int freq_in, unsigned int freq_out) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct twl6030_priv_data *twl6030_priv = codec->private_data; + int div; + + if (!freq_in || !freq_out) + return -EINVAL; + + /* div = round(freq_out / freq_in) */ + div = (freq_out + (freq_in >> 2)) / freq_in; + + if (pll_id == TWL6030_LPPLL_ID) { + if (div < 512) { + dev_err(codec->dev, "invalid pll divider %d\n", + div); + return -EINVAL; + } + + twl6030_write(codec, TWL6030_REG_LPPLLDIV, div - 512); + twl6030_priv->sysclk = freq_out; + } + + return 0; +} + +static int abe_mm_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + abe_default_configuration(UC2_VOICE_CALL_AND_IHF_MMDL); + 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; + unsigned int *dst_ptr; + int rate, format; + + rate = params_rate(params); + switch (rate) { + case 44100: + break; + case 48000: + break; + default: + dev_err(codec->dev, "hw params: unknown rate %d\n", rate); + return -EINVAL; + } + + if (!substream->stream) { + /* Circular buffer 0 (MM_DL path) write pointer address + * increases by 2 to avoid loosing DMA request + */ + dst_ptr = (unsigned int*) (ABE_DMEM_BASE_ADDRESS_MPU + 0x100); + *dst_ptr = 0x1a004800; + + dst_ptr = (unsigned int*) (ABE_DMEM_BASE_ADDRESS_MPU + 0x108); + *dst_ptr = 0x04000c00; + } + + format = params_format(params); + if (format != SNDRV_PCM_FORMAT_S32_LE) { + dev_err(codec->dev, "hw params: unknown format %d\n", format); + return -EINVAL; + } + + return 0; +} + +static struct snd_soc_dai_ops abe_mm_dai_ops = { + .startup = abe_mm_startup, + .hw_params = abe_mm_hw_params, + .set_sysclk = twl6030_set_dai_sysclk, + .set_pll = twl6030_set_dai_pll, +}; + +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; + int rate, format; + + rate = params_rate(params); + switch (rate) { + case 8000: + break; + case 16000: + break; + default: + dev_err(codec->dev, "hw params: unknown rate %d\n", rate); + return -EINVAL; + } + + format = params_format(params); + if (format != SNDRV_PCM_FORMAT_S32_LE) { + dev_err(codec->dev, "hw params: unknown format %d\n", format); + return -EINVAL; + } + + return 0; +} + +static struct snd_soc_dai_ops abe_voice_dai_ops = { + .startup = abe_mm_startup, + .hw_params = abe_voice_hw_params, + .set_sysclk = twl6030_set_dai_sysclk, + .set_pll = twl6030_set_dai_pll, +}; + +/* Audio Backend DAIs */ +struct snd_soc_dai abe_dai[] = { + /* Multimedia: MM-UL2, MM-DL */ + { + .name = "Multimedia", + .playback = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, + .formats = ABE_FORMATS, + }, + .capture = { + .stream_name = "Capture", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_48000, + .formats = ABE_FORMATS, + }, + .ops = &abe_mm_dai_ops, + }, + /* Multimedia Extended: MM-DL2 */ + { + .name = "Multimedia Ext", + .playback = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, + .formats = ABE_FORMATS, + }, + .ops = &abe_mm_dai_ops, + }, + /* Voice: VX-UL, VX-DL */ + { + .name = "Voice", + .playback = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, + .formats = ABE_FORMATS, + }, + .capture = { + .stream_name = "Capture", + .channels_min = 2, + .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 = 8, + .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, + }, + }, + }; + +static int abe_twl6030_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_twl6030_set_bias_level(codec, SND_SOC_BIAS_OFF); + + return 0; +} + +static int abe_twl6030_resume(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->card->codec; + + abe_twl6030_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + abe_twl6030_set_bias_level(codec, codec->suspend_bias_level); + return 0; +} + +/* + * initialize the driver + */ +static int abe_twl6030_init(struct snd_soc_device *socdev) +{ + struct snd_soc_codec *codec = socdev->card->codec; + struct twl6030_setup_data *setup = socdev->codec_data; + int ret = 0; + + dev_info(codec->dev, "ABE-TWL6030 Audio Codec init\n"); + + codec->name = "abe-wl6030"; + codec->owner = THIS_MODULE; + codec->read = twl6030_read_reg_cache; + codec->write = twl6030_write; + codec->set_bias_level = abe_twl6030_set_bias_level; + codec->dai = abe_dai; + codec->num_dai = ARRAY_SIZE(abe_dai); + codec->reg_cache_size = ARRAY_SIZE(twl6030_reg); + codec->reg_cache = kmemdup(twl6030_reg, sizeof(twl6030_reg), + GFP_KERNEL); + if (codec->reg_cache == NULL) + return -ENOMEM; + + /* register pcms */ + ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); + if (ret < 0) { + dev_err(codec->dev, "failed to create pcms\n"); + goto pcm_err; + } + + /* platform setup data is required for power-off/off the device */ + if (setup == NULL) { + dev_err(codec->dev, "platform setup data missing\n"); + goto pcm_err; + } + + setup->codec = codec; + + /* power on device */ + abe_twl6030_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + abe_init_chip(codec); + twl6030_init_chip(codec); + + snd_soc_add_controls(codec, twl6030_snd_controls, + ARRAY_SIZE(twl6030_snd_controls)); + abe_twl6030_add_widgets(codec); + + ret = snd_soc_init_card(socdev); + if (ret < 0) { + dev_err(codec->dev, "failed to register card\n"); + goto card_err; + } + + return ret; + +card_err: + snd_soc_free_pcms(socdev); + snd_soc_dapm_free(socdev); +pcm_err: + kfree(codec->reg_cache); + return ret; +} + +static struct snd_soc_device *abe_twl6030_socdev; + +static int abe_twl6030_probe(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec; + struct twl6030_priv_data *twl6030_priv; + + codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); + if (codec == NULL) + return -ENOMEM; + + twl6030_priv = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); + if (twl6030_priv == NULL) + return -ENOMEM; + + codec->private_data = twl6030_priv; + codec->dev = &pdev->dev; + socdev->card->codec = codec; + mutex_init(&codec->mutex); + INIT_LIST_HEAD(&codec->dapm_widgets); + INIT_LIST_HEAD(&codec->dapm_paths); + + abe_twl6030_socdev = socdev; + abe_twl6030_init(socdev); + + return 0; +} + +static int abe_twl6030_remove(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->card->codec; + + dev_info(codec->dev, "ABE-TWL6030 Audio Codec remove\n"); + abe_twl6030_set_bias_level(codec, SND_SOC_BIAS_OFF); + snd_soc_free_pcms(socdev); + snd_soc_dapm_free(socdev); + kfree(codec->private_data); + kfree(codec); + + return 0; +} + +struct snd_soc_codec_device soc_codec_dev_abe_twl6030 = { + .probe = abe_twl6030_probe, + .remove = abe_twl6030_remove, + .suspend = abe_twl6030_suspend, + .resume = abe_twl6030_resume, +}; +EXPORT_SYMBOL_GPL(soc_codec_dev_abe_twl6030); + +static int __init abe_twl6030_modinit(void) +{ + return snd_soc_register_dais(abe_dai, ARRAY_SIZE(abe_dai)); +} +module_init(abe_twl6030_modinit); + +static void __exit abe_twl6030_exit(void) +{ + snd_soc_unregister_dais(abe_dai, ARRAY_SIZE(abe_dai)); +} +module_exit(abe_twl6030_exit); + +MODULE_DESCRIPTION("ASoC ABE-TWL6030 codec driver"); +MODULE_AUTHOR("Misael Lopez Cruz"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/abe-twl6030.h b/sound/soc/codecs/abe-twl6030.h new file mode 100644 index 000000000000..1941cfbe7aec --- /dev/null +++ b/sound/soc/codecs/abe-twl6030.h @@ -0,0 +1,39 @@ +/* + * ALSA SoC ABE-TWL6030 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_TWL6030_H__ +#define __ABE_TWL6030_H__ + +extern struct snd_soc_dai abe_dai[]; +extern struct snd_soc_codec_device soc_codec_dev_abe_twl6030; + +irqreturn_t twl6030_naudint_handler(int irq, void *data); +void twl6030_naudint_work(struct work_struct *work); + +struct twl6030_setup_data { + void (*codec_enable)(int enable); + int irq; + struct work_struct audint_work; + struct completion ready_completion; + struct snd_soc_codec *codec; +}; + +#endif /* End of __ABE_TWL6030_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..bfcb73efdbc0 --- /dev/null +++ b/sound/soc/codecs/abe/C_ABE_FW.CM @@ -0,0 +1,1664 @@ +0x001000, +0x001000, +0x001000, +0x001000, +0x001000, +0x001000, +0x001000, +0x151000, +0x001000, +0x001000, +0x141000, +0x001000, +0x000000, +0x000000, +0x000000, +0x000000, +0x001000, +0x001001, +0x000000, +0x000000, +0x000000, +0x000000, +0x001000, +0x001000, +0x001000, +0x001000, +0x001000, +0x001000, +0x001000, +0x001000, +0x000000, +0x000000, +0x001000, +0x001000, +0x001000, +0x001000, +0x001081, +0x001000, +0x000000, +0x001000, +0x001000, +0x001000, +0x001000, +0x001001, +0x001001, +0x001000, +0x001000, +0x001000, +0x001000, +0x001001, +0x001001, +0x001000, +0x001001, +0x001001, +0x001000, +0x001001, +0x001001, +0x001000, +0x001001, +0x001001, +0x001001, +0x001001, +0x001001, +0x001001, +0x001000, +0x001000, +0x001000, +0x001000, +0x001000, +0x001001, +0x001000, +0x000006, +0x000012, +0x001000, +0x001081, +0x001000, +0x001000, +0x001081, +0x001000, +0x001000, +0x001081, +0x001000, +0x001081, +0x000000, +0x001000, +0x000000, +0x001081, +0x001000, +0x001081, +0x001000, +0x001081, +0x001000, +0x001081, +0x001000, +0x000000, +0x000000, +0x001081, +0x001000, +0x000000, +0x000000, +0x000000, +0x000000, +0x001081, +0x000000, +0x000000, +0x001000, +0x000018, +0x001000, +0x001081, +0x001000, +0x001000, +0x001081, +0x001000, +0x001000, +0x001000, +0x000071, +0x000000, +0x000000, +0x000000, +0x000000, +0x001000, +0x001000, +0x000000, +0x001000, +0x001000, +0x001000, +0x001001, +0x000001, +0x001000, +0x001c9c, +0x001000, +0x001001, +0x000001, +0x001000, +0x001cdc, +0x151000, +0x000000, +0x001c9c, +0x001cdc, +0x151000, +0x001000, +0x001001, +0x000001, +0x001000, +0x001d1c, +0x001000, +0x001000, +0x000000, +0x001000, +0x001000, +0x001000, +0x001001, +0x001001, +0x0010c1, +0x001000, +0x0010c1, +0x001001, +0x001000, +0x001000, +0x001061, +0x001061, +0x000000, +0x000000, +0x001000, +0x001000, +0x001061, +0x001071, +0x000000, +0x000000, +0x001061, +0x001071, +0x001000, +0x001000, +0x001031, +0x001061, +0x000000, +0x001000, +0x001061, +0x001061, +0x000000, +0x000000, +0x001000, +0x001000, +0x001031, +0x001061, +0x000000, +0x001000, +0x001000, +0x001000, +0x001041, +0x001001, +0x000000, +0x001000, +0x001011, +0x001001, +0x000000, +0x001000, +0x001001, +0x000001, +0x001000, +0x001cdc, +0x001cdc, +0x001041, +0x001001, +0x001011, +0x001001, +0x001011, +0x001001, +0x001011, +0x021031, +0x041051, +0x061071, +0x0c10d1, +0x0e10f1, +0x101111, +0x001000, +0x001001, +0x001001, +0x001031, +0x001061, +0x001061, +0x001061, +0x151000, +0x001000, +0x001000, +0x001081, +0x001001, +0x001001, +0x001001, +0x001001, +0x0000e5, +0x001041, +0x001000, +0x001041, +0x001001, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x040002, +0x800001, +0x100001, +0x100001, +0x100001, +0x100001, +0x100001, +0x100001, +0x100001, +0x100001, +0x100001, +0x700001, +0x700001, +0x700001, +0x700001, +0x700001, +0x700001, +0x700001, +0x700001, +0x700001, +0x040002, +0x040002, +0x040002, +0x040002, +0x040002, +0x040002, +0x040002, +0x040002, +0x040002, +0x040002, +0x040002, +0x040002, +0x040002, +0x040002, +0x040002, +0x040002, +0x040002, +0x040002, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000002, +0x000002, +0x040002, +0x000002, +0x040002, +0x000002, +0x000002, +0x000002, +0x040002, +0x040002, +0x000002, +0x040002, +0x000002, +0x000002, +0x000002, +0x000002, +0x000002, +0x000002, +0x040002, +0x000002, +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, +0x040002, +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, +0x040002, +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, +0x040002, +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, +0x040002, +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, +0x040002, +0x000000, +0x000000, +0x000000, +0x000000, +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, +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, +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, +0x4a6019, +0x0d067e, +0x1f4922, +0x292aae, +0x1f4922, +0x0d067e, +0x4a6019, +0xa72cb4, +0xf6e45a, +0xe632ca, +0xd7ca12, +0xdb8fc2, +0xedbbc6, +0x06fdf0, +0x1d0018, +0x408bfc, +0x5d2e1c, +0x5d2e1c, +0x408bfc, +0x1d0018, +0x06fdf0, +0x192d68, +0x8407ec, +0x051ffe, +0xf69ac6, +0x0bb98e, +0xf412f6, +0x06fd0a, +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, +0x000003, +0x02c197, +0x05832b, +0x02c197, +0x000003, +0x000003, +0x84a705, +0x07da1a, +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, +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, 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..495cae4fc931 --- /dev/null +++ b/sound/soc/codecs/abe/C_ABE_FW.PM @@ -0,0 +1,2048 @@ +0x1600b20f, +0x0a0007b0, +0x00000000, +0x00000000, +0x07800000, +0x160194ce, +0x014000e0, +0x014000e1, +0x014000e2, +0x014000e3, +0x014000e4, +0x014000e5, +0x014000e6, +0x014000e7, +0x014000e8, +0x014000e9, +0x014000ea, +0x014000eb, +0x014000ec, +0x014000ed, +0x014000ef, +0x014000ef, +0x9e000000, +0x07800000, +0x07800000, +0x014000e0, +0x014000e1, +0x014000e2, +0x014000e3, +0x9e000040, +0x07800000, +0x07800000, +0x014000e0, +0x014000e1, +0x014000e2, +0x014000e3, +0x9e000080, +0x07800000, +0x07800000, +0x014000e0, +0x014000e1, +0x014000e2, +0x014000e3, +0x9e0000c0, +0x07800000, +0x07800000, +0x014000e0, +0x014000e1, +0x014000e2, +0x014000e3, +0x9e080000, +0x07800000, +0x07800000, +0x014000e0, +0x014000e1, +0x014000e2, +0x014000e3, +0x9e080100, +0x07800000, +0x07800000, +0x014000e0, +0x014000e1, +0x014000e2, +0x014000e3, +0x9e080200, +0x07800000, +0x07800000, +0x014000e0, +0x014000e1, +0x014000e2, +0x014000e3, +0x9e080300, +0x07800000, +0x07800000, +0x014000e0, +0x014000e1, +0x014000e2, +0x014000e3, +0x9e080400, +0x07800000, +0x07800000, +0x014000e0, +0x014000e1, +0x014000e2, +0x014000e3, +0x9e080500, +0x07800000, +0x07800000, +0x014000e0, +0x014000e1, +0x014000e2, +0x014000e3, +0x9e080600, +0x07800000, +0x07800000, +0x014000e0, +0x014000e1, +0x014000e2, +0x014000e3, +0x9e080700, +0x07800000, +0x07800000, +0x014000e0, +0x014000e1, +0x014000e2, +0x014000e3, +0x9c050800, +0x07800000, +0x07800000, +0x014000e0, +0x014000e1, +0x014000e2, +0x014000e3, +0x16000010, +0x16000001, +0x17000100, +0x014000e0, +0x17800100, +0x014000e0, +0x98020000, +0x07800000, +0x07800000, +0x08200000, +0x048004ff, +0x0a200780, +0x160116ec, +0x400000cc, +0x1600000d, +0x05800dc0, +0x0a800a90, +0x1601a0cd, +0x008001c8, +0x408000c5, +0x04c0ff88, +0x408002c9, +0x04c0ff55, +0x408003ca, +0x04c0ff99, +0xdc02c080, +0x12000155, +0x408004cb, +0x04c0ffaa, +0x408005c4, +0x04c0ffbb, +0x9e080000, +0x020005de, +0x1601d4c3, +0x00000030, +0x00000231, +0x00000435, +0x04800211, +0x04400511, +0x0300010e, +0x01000231, +0x04c0ff44, +0xdc02c990, +0x04c3ff2d, +0xdc01d2a0, +0x128002dd, +0xdc02dcb0, +0x048fffdd, +0x9c062040, +0x0b200000, +0x9d02c080, +0x9d02c990, +0x9d01d2a0, +0x9d02dcb0, +0x4a000aa0, +0x1601174c, +0x1601174c, +0x400000cd, +0x1601168e, +0x013ffcfe, +0x048008dd, +0x013ffefd, +0x400000cc, +0x1600000d, +0x160116ce, +0x000000cc, +0x410000ec, +0x05800dc0, +0x0a800db0, +0x1601a0cd, +0x008001c8, +0x408000c5, +0x04c0ff88, +0x408002c9, +0x04c0ff55, +0x408003ca, +0x04c0ff99, +0xdc02c080, +0x12000155, +0x408004cb, +0x04c0ffaa, +0x408005c4, +0x04c0ffbb, +0x9e080000, +0x020005de, +0x1601d4c3, +0x00000030, +0x00000231, +0x00000435, +0x04800211, +0x04400511, +0x0300010e, +0x01000231, +0x04c0ff44, +0xdc02c990, +0x04c3ff2d, +0xdc01d2a0, +0x128002dd, +0xdc02dcb0, +0x048fffdd, +0x9c062040, +0x0b200000, +0x9d02c080, +0x9d02c990, +0x9d01d2a0, +0x9d02dcb0, +0x403ffcfd, +0x1601174c, +0x000000ce, +0x400000dd, +0x048002d0, +0x403ffef0, +0x048ffe02, +0x413ffcf2, +0x120001dd, +0x04000ded, +0x410000cd, +0x05c000d0, +0x0ac00af0, +0x400000cd, +0x1601063e, +0x16011780, +0x05c00de0, +0x0ae01040, +0x1601d4c3, +0x00000030, +0x00000231, +0x00000432, +0x04800211, +0x04400211, +0x16055552, +0x03000102, +0x01000231, +0x08400000, +0x07800000, +0x07800000, +0x1601d4c3, +0x00000030, +0x00000231, +0x00000432, +0x04800211, +0x04400211, +0x16006502, +0x00000022, +0x03000102, +0x01000231, +0x0a0013f0, +0x4000000d, +0x1600000e, +0x05c00de0, +0x0ac01090, +0x0a001220, +0x1600000d, +0x1601178e, +0x010000ed, +0x1601d4c3, +0x00000030, +0x00000231, +0x00000432, +0x04800211, +0x04400211, +0x16055552, +0x03000102, +0x01000231, +0x08400000, +0x07800000, +0x07800000, +0x1601d4c3, +0x00000030, +0x00000231, +0x00000432, +0x04800211, +0x04400211, +0x16006502, +0x00000022, +0x03000102, +0x01000231, +0x1601176d, +0x400000de, +0x1600fa40, +0x010000c0, +0x048001ec, +0x010000dc, +0x0a204d90, +0x1601d4c3, +0x00000030, +0x00000231, +0x00000432, +0x04800211, +0x04400211, +0x16055552, +0x03000102, +0x01000231, +0x08400000, +0x07800000, +0x07800000, +0x1601d4c3, +0x00000030, +0x00000231, +0x00000432, +0x04800211, +0x04400211, +0x16006502, +0x00000022, +0x03000102, +0x01000231, +0x4a0007e0, +0x160116ec, +0x16000002, +0x05c00100, +0x0ac01450, +0x16000052, +0x07800000, +0x07800000, +0x07800000, +0x08200000, +0x0a0014b0, +0x9d0c0118, +0x9c080018, +0x988014a0, +0x9d0c0118, +0x08200000, +0x0a001510, +0x9d0c0118, +0x9c180028, +0x9c180068, +0x98801500, +0x9d0c0118, +0x08200000, +0x0a001580, +0x9d0c0108, +0x9c180028, +0x98801570, +0x9d0c0108, +0x08200000, +0x0a0015e0, +0x9d180108, +0x9c0c0038, +0x988015d0, +0x9d180108, +0x08200000, +0xdc0c0018, +0x04a001dd, +0x9f040010, +0x9f03fc10, +0x9c0c00b8, +0x9f0400b0, +0x9d188108, +0x9f065810, +0x98801650, +0x9f03fc10, +0x07800000, +0x07800000, +0x9d188108, +0x08200000, +0x0a001730, +0x9d180108, +0x9d180148, +0x9c0c0018, +0x98801710, +0x9d180108, +0x9d180148, +0x08200000, +0x010002fe, +0x010004f1, +0x010006f2, +0x010008f3, +0x0a201860, +0x000004f0, +0x0a201860, +0x000006f0, +0x0a201860, +0x000008f0, +0x0a201860, +0x000002fe, +0x07800000, +0x08200000, +0x16000006, +0x05800600, +0x0a801d30, +0x00801001, +0x4080070d, +0x12000211, +0x00800203, +0x40800c07, +0x040003dd, +0x00801105, +0x9e0e0410, +0x40800801, +0x144000d4, +0x40800902, +0x04a001dd, +0xdc180404, +0x10000744, +0xdc180480, +0x06000005, +0x00800d03, +0x0a801a30, +0x9c053960, +0x9c053b50, +0xdc039830, +0x05800610, +0x4ac01af0, +0x05800260, +0x0ae01ab0, +0x0a001b30, +0x9c043860, +0x9c043b50, +0xdc039930, +0x05800610, +0x4ac01ab0, +0x05800260, +0x0ae01af0, +0x0a001b30, +0x00800e05, +0x40800a04, +0x04800155, +0x0a001b20, +0x00800e05, +0x40800b04, +0x04a00155, +0x01800e05, +0x144000e1, +0x1601a48e, +0x00800605, +0x12000155, +0x020005ee, +0x0b200000, +0x4b400004, +0x1440001e, +0x9c100308, +0x00801105, +0x40801001, +0x06000005, +0x0a801c20, +0x9d039830, +0x0a001c30, +0x9d039930, +0x40000404, +0x12000211, +0x40800713, +0x12000244, +0x40801105, +0x04d08033, +0x9e0e0540, +0x41800713, +0x04000511, +0x00800f02, +0x9e088300, +0x07800000, +0x07800000, +0x9d140530, +0x12800277, +0x01800017, +0x08200000, +0x048004ff, +0x9c180408, +0x9c180488, +0x08000000, +0x9c018f10, +0x9c043e60, +0x048ffef7, +0x01000076, +0x003ffef7, +0x05c00730, +0x0ae01e00, +0x0a002020, +0x4a001f20, +0x16000007, +0x9c180628, +0x9c180668, +0x9c1806a8, +0x9c1806e8, +0x9d0c8018, +0x9d0c8708, +0x9d0c8758, +0x9d0c81b8, +0x9c180628, +0x9c180668, +0x9d0c87a8, +0x9d0c87f8, +0x9d0c8218, +0x9d0c8708, +0x9d0c8758, +0x04800177, +0x05c00070, +0x0ac01e20, +0x00000020, +0x12000907, +0x12000101, +0x12800977, +0x12800911, +0x04000373, +0x05c00310, +0x0ae01fd0, +0x0a001fe0, +0x04200133, +0x04c07f33, +0x04cf8000, +0x04500303, +0x01000023, +0x048ffcff, +0x08200000, +0x048004ff, +0x9c180408, +0x9c180488, +0x08000000, +0x9c039b30, +0x9c053150, +0x048ffef7, +0x01000075, +0x40000007, +0x16000004, +0x003ffef6, +0x12000177, +0x12800977, +0x05800460, +0x048fff77, +0x04200676, +0x4a802240, +0x14400037, +0x05c00620, +0x0ae02240, +0x0a002390, +0x9c0c0018, +0x9c0c02b8, +0x07800000, +0x9d188108, +0x9d188148, +0x9c0c0318, +0x9d188188, +0x9d1881c8, +0x9d188108, +0x9d188148, +0x04800144, +0x05c00140, +0x0ac02190, +0x00000201, +0x04cf7f11, +0x41000201, +0x12000113, +0x40000003, +0x12800934, +0x04000242, +0x12000133, +0x12800933, +0x05c00230, +0x0ae02320, +0x0a002330, +0x04200322, +0x04c07f22, +0x16080ff3, +0x04400311, +0x12000822, +0x04500212, +0x01000202, +0x9d03bb70, +0x048ffcff, +0x08200000, +0x048004ff, +0x9c180208, +0x08000000, +0x9c180288, +0x08000000, +0x08000000, +0x9c053960, +0x048ffef7, +0x01000076, +0x00000027, +0x003ffef6, +0x12000177, +0x12800977, +0x04200677, +0x048fff77, +0x413ffef7, +0x05c00730, +0x0ae024f0, +0x0a0027d0, +0x12000107, +0x04000710, +0x16000007, +0x14400076, +0x9e0f0070, +0x00000017, +0x9e0e8070, +0x4a0025e0, +0x14400014, +0x9c0c0010, +0x14400047, +0x04800244, +0x9d188108, +0x00000277, +0x9e0e8070, +0x05c00040, +0x0ac02580, +0x9d040008, +0x04800167, +0x05c00d70, +0x0ae02520, +0x16000007, +0x9e0f0070, +0x0000022d, +0x00000027, +0x120001d0, +0x12000177, +0x12800900, +0x12800977, +0x04000303, +0x05c00370, +0x0ac02700, +0x0a002710, +0x04200733, +0x408006cc, +0x16080ff7, +0x04c07f33, +0x044007dd, +0x12000833, +0x045003d3, +0x41000223, +0x04c0ffc6, +0x16000007, +0x08000000, +0x08000000, +0x9d140370, +0x048ffcff, +0x08200000, +0x048004ff, +0x9c180408, +0x08000000, +0x9c180488, +0x08000000, +0x08000000, +0x9c043e60, +0x048ffef7, +0x01000076, +0x403ffef4, +0x12000107, +0x05c00470, +0x0ae028d0, +0x0a002a60, +0x4a002960, +0x16000004, +0x9c180628, +0x08000000, +0x9c180668, +0x08000000, +0x08000000, +0x9d0c8118, +0x04800144, +0x05c00040, +0x0ac028f0, +0x00000020, +0x12000904, +0x12000106, +0x12800944, +0x12800966, +0x04000747, +0x05c00760, +0x0ae02a10, +0x0a002a20, +0x04200677, +0x04c07f77, +0x04cf8000, +0x04500700, +0x01000020, +0x048ffcff, +0x08200000, +0x048004ff, +0x9c180208, +0x08000000, +0x9c180288, +0x08000000, +0x08000000, +0x9c053e60, +0x048ffef7, +0x01000076, +0x00000027, +0x12000177, +0x12800977, +0x413ffef7, +0x05c00700, +0x0ae02b80, +0x0a002dc0, +0x12800107, +0x4a002c10, +0x16000004, +0x9c0c0018, +0x08000000, +0x08000000, +0x9d188608, +0x9d188648, +0x04800144, +0x05c00740, +0x0ac02bb0, +0x00000227, +0x00000024, +0x12000176, +0x12000144, +0x12800966, +0x12800944, +0x04000060, +0x05c00040, +0x0ae02cd0, +0x0a002ce0, +0x04200400, +0x16080ff4, +0x04c07f00, +0x04400477, +0x12000800, +0x04500070, +0x04cf7f00, +0x41000220, +0x16002104, +0x14400012, +0x16000003, +0x9e0e0540, +0x07800000, +0x07800000, +0x9d140530, +0x048ffcff, +0x08200000, +0x16011741, +0x40000011, +0x16000000, +0x07800000, +0x01000010, +0x08200000, +0x00000003, +0x04500131, +0x01000001, +0x00000201, +0x04500212, +0x01000202, +0x08200000, +0x40000473, +0x16000004, +0x00000072, +0x04200233, +0x05800430, +0x0ae02f20, +0x0a002f40, +0x00000874, +0x04000433, +0x00000a74, +0x05c00340, +0x0ac02f80, +0x08200000, +0x01000025, +0x00000075, +0x04800252, +0x01000072, +0x01000256, +0x00000076, +0x00000675, +0x04800266, +0x41000076, +0x05c00650, +0x0ac03040, +0x08200000, +0x00000276, +0x01000076, +0x08200000, +0x07800000, +0x07800000, +0x08200000, +0x00400202, +0x00400204, +0x00000200, +0x12000100, +0x4a003140, +0x04000020, +0x40000046, +0x04800244, +0x41000026, +0x04800222, +0x05c00020, +0x0ac03100, +0x08200000, +0x40400201, +0x16000003, +0x40400402, +0x1440000d, +0x14400004, +0x12000222, +0x40d00021, +0x12000210, +0x14400001, +0x08000000, +0x08000000, +0x9e0c0600, +0x400004d0, +0x16000003, +0x003ffe41, +0x12000200, +0x12000102, +0x00d00020, +0x14400010, +0x08000000, +0x08000000, +0x9e0c0700, +0x000004dd, +0x9c180728, +0x9c180768, +0x07800000, +0x07800000, +0x9d0c8618, +0x988032e0, +0x08200000, +0x40400202, +0x16000003, +0x40400401, +0x1440000d, +0x14400004, +0x12000220, +0x12000212, +0x00d00021, +0x14400001, +0x08000000, +0x08000000, +0x9e0c0600, +0x400004d0, +0x16000003, +0x003ffe41, +0x12000202, +0x00d00020, +0x14400010, +0x08000000, +0x08000000, +0x9e0c0700, +0x000004dd, +0x9c180728, +0x07800000, +0x07800000, +0x9d108608, +0x988034b0, +0x08200000, +0x40400202, +0x16000003, +0x40400401, +0x1440000d, +0x14400004, +0x12000220, +0x12000212, +0x00d00021, +0x14400001, +0x08000000, +0x08000000, +0x9e0c0600, +0x000004d0, +0x003ffe43, +0x12000202, +0x40d00020, +0x12000231, +0x14400010, +0x16000003, +0x08000000, +0x08000000, +0x9e0c0700, +0x000004dd, +0x9c0c0718, +0x07800000, +0x07800000, +0x9d0c8618, +0x98803680, +0x08200000, +0x40400202, +0x16000003, +0x40400401, +0x1440000d, +0x14400004, +0x12000220, +0x12000212, +0x00d00021, +0x14400001, +0x08000000, +0x08000000, +0x9e0c0600, +0x000004d0, +0x003ffe43, +0x12000202, +0x40d00020, +0x12000231, +0x14400010, +0x16000003, +0x08000000, +0x08000000, +0x9e0c0700, +0x000004dd, +0x9c100708, +0x07800000, +0x07800000, +0x9d108608, +0x98803850, +0x08200000, +0x40400202, +0x16000003, +0x4000040d, +0x14400004, +0x12000220, +0x120002d2, +0x40d0002d, +0x14400001, +0x08000000, +0x08000000, +0x9e0c0600, +0x0000044d, +0x9c0c0010, +0x07800000, +0x07800000, +0x9d108608, +0x988039a0, +0x08200000, +0x40400202, +0x16000003, +0x4000040d, +0x14400004, +0x12000220, +0x120002d2, +0x40d0002d, +0x14400001, +0x08000000, +0x08000000, +0x9e0c0600, +0x0000044d, +0x9c0c0010, +0x07800000, +0x07800000, +0x9d0c8618, +0x98803ac0, +0x08200000, +0x40400201, +0x16000003, +0x40400402, +0x1440000d, +0x14400004, +0x12000222, +0x12000122, +0x00d00020, +0x14400010, +0x08000000, +0x08000000, +0x9e0c0600, +0x400004d1, +0x16000003, +0x003ffe40, +0x12000212, +0x40d00020, +0x12000201, +0x14400010, +0x08000000, +0x08000000, +0x9e0c0700, +0x000004dd, +0x9c0c0718, +0x07800000, +0x07800000, +0x9d188608, +0x9d188648, +0x98803c60, +0x08200000, +0x40400201, +0x16000003, +0x40400402, +0x1440000d, +0x14400004, +0x12000222, +0x00d00020, +0x14400010, +0x08000000, +0x08000000, +0x9e0c0600, +0x400004d1, +0x16000003, +0x003ffe40, +0x12000212, +0x40d00020, +0x12000201, +0x14400010, +0x08000000, +0x08000000, +0x9e0c0700, +0x000004dd, +0x9c100708, +0x07800000, +0x07800000, +0x9d188608, +0x98803e30, +0x08200000, +0x40400202, +0x048004ff, +0x00400201, +0x40000202, +0x14400020, +0x013ffcfe, +0x0a202e40, +0x403ffcfe, +0x048ffcff, +0x08200000, +0x9c0c0018, +0x1440001d, +0x04a001dd, +0x9d0c8318, +0x07800000, +0x9c0c0018, +0xa00602ba, +0x07800000, +0x9d0c8318, +0x9d0c81b8, +0x9d0c82b8, +0x98803f80, +0x07800000, +0xa00602ba, +0x07800000, +0x07800000, +0x9d0c81b8, +0x9d0c82b8, +0x08200000, +0x9c0c0038, +0x1440001d, +0x04a001dd, +0x9d0c8338, +0x07800000, +0xa00602ba, +0xa006821a, +0x9c0c0038, +0x07800000, +0x9d0c8298, +0x9d0c8338, +0x9d0c8198, +0x988040b0, +0x07800000, +0xa00602ba, +0xa006821a, +0x07800000, +0x07800000, +0x9d0c8298, +0x9d0c8198, +0x08200000, +0x9f160028, +0x9f168298, +0x07800000, +0x07800000, +0x9d0c8128, +0x988041b0, +0x08200000, +0x9c0c03b0, +0x9f160020, +0x9f168098, +0x07800000, +0x9d0c8138, +0x9d0c8278, +0x98804230, +0x08200000, +0xdc0c0018, +0x04a00201, +0x04a001dd, +0xdd040008, +0x06000001, +0x04a00111, +0x0aa042c0, +0x9d0c8118, +0x988042a0, +0x08200000, +0x9c0c02b0, +0x9c0c0018, +0x04a00205, +0x07800000, +0x9d0c8118, +0xdd0c81b8, +0x06000005, +0x04a00155, +0x0aa04390, +0x98804350, +0x08200000, +0x9f15001a, +0x9f11041a, +0x07800000, +0x07800000, +0x9d0c8118, +0x988043f0, +0x08200000, +0x9c038300, +0x9c038d10, +0x9f16001a, +0x9f12021a, +0x9f12031a, +0x9f12051a, +0x07800000, +0x07800000, +0x9d0c8118, +0x98804480, +0x9d038300, +0x9d038d10, +0x08200000, +0x9f160010, +0x9f168068, +0x07800000, +0x07800000, +0x9d0c8128, +0x98804530, +0x08200000, +0x00000023, +0x048fff1d, +0x04a00133, +0x9c1803a0, +0x06000003, +0x0aa046c0, +0x9c0c0018, +0x07800000, +0x07800000, +0x9d0c8118, +0x9f020810, +0x9f040020, +0x9f040060, +0x07800000, +0x9d108208, +0x9d108248, +0x98804600, +0x0a002de0, +0x9f16801a, +0x9f120112, +0x07800000, +0x07800000, +0x9d0c8118, +0x9f03a010, +0x9f026810, +0x9f040020, +0x9f040060, +0x07800000, +0x9d108208, +0x9d108248, +0x988046c0, +0x08200000, +0x1600004d, +0x144000e2, +0x0a204810, +0x04800200, +0x988047c0, +0x1440002e, +0x08200000, +0x00800003, +0x00800105, +0x144000d7, +0x1440001d, +0x9c039830, +0x9c03aa50, +0x07800000, +0x9c0c0018, +0x9c0c02b8, +0x07800000, +0x07800000, +0x9d0c8128, +0x98804880, +0x1440007d, +0x08200000, +0x07800000, +0x07800000, +0x07800000, +0x07800000, +0x08200000, +0x048010ff, +0x413ff0fb, +0x0480100d, +0x013ff2fd, +0x013ff4fa, +0x013ff6fc, +0x013ff8f8, +0x013ffaf9, +0x013ffcfe, +0x4000000c, +0x1600000e, +0x04800200, +0x413ffef0, +0x05800ec0, +0x0a804cc0, +0x1601a0cd, +0x008001c8, +0x408000c5, +0x04c0ff88, +0x408002c9, +0x04c0ff55, +0x408003ca, +0x04c0ff99, +0xdc02c080, +0x12000155, +0x408004cb, +0x04c0ffaa, +0x408005c4, +0x04c0ffbb, +0x9e080000, +0x020005de, +0x1601d4c3, +0x00000030, +0x00000231, +0x00000435, +0x04800211, +0x04400511, +0x0300010e, +0x01000231, +0x04c0ff44, +0xdc02c990, +0x04c3ff2d, +0xdc01d2a0, +0x128002dd, +0xdc02dcb0, +0x048fffdd, +0x9c062040, +0x0b200000, +0x9d02c080, +0x9d02c990, +0x9d01d2a0, +0x9d02dcb0, +0x003ffefc, +0x003ff2fe, +0x0a004ce0, +0x003ffefc, +0x003ff2fe, +0x003ffef0, +0x05c00ec0, +0x0ac049e0, +0x003ffcfe, +0x003ff0fb, +0x003ff4fa, +0x003ff6fc, +0x003ff8f8, +0x403ffaf9, +0x048ff0ff, +0x08200000, +0x048010ff, +0x413ff0fb, +0x1600000b, +0x413ff4f9, +0x1601218d, +0x413ff6fc, +0x16009e83, +0x413ff2fb, +0x144000d9, +0x413ff8fa, +0x1440003c, +0x013ffaf8, +0x013ffcfe, +0x40400490, +0x14400098, +0x0000008e, +0x058000e0, +0x0a805110, +0x0000000e, +0x05800be0, +0x0a804f10, +0x048fffee, +0x0100000e, +0x0a005110, +0x4a005020, +0x0480028a, +0x0080090e, +0x04c0ffee, +0x120001ee, +0x02000ece, +0x0b200000, +0x00000480, +0x04800c00, +0x01000480, +0x0000029e, +0x05c000e0, +0x0ae04ff0, +0x0a005010, +0x00000280, +0x010002a0, +0x00000480, +0x0000000e, +0x05800be0, +0x0aa05090, +0x0000048e, +0x00000081, +0x05800e10, +0x0aa04f30, +0x0000048e, +0x00000080, +0x05800e00, +0x0aa05110, +0x403ff2f1, +0x160117c0, +0x144000b2, +0x0a202e40, +0x403ff2fe, +0x16000020, +0x04800899, +0x048001ee, +0x413ff2fe, +0x05c000e0, +0x0ac04e60, +0x003ffcfe, +0x003ff0fb, +0x003ff4f9, +0x003ff6fc, +0x003ff8fa, +0x403ffaf8, +0x048ff0ff, +0x08200000, +0x40000206, +0x16000005, +0x40000007, +0x048004ff, +0x413ffcfe, +0x05800560, +0x1440003d, +0x0aa052b0, +0x1600000e, +0x05800e70, +0x0a805380, +0x04cfff75, +0x14400027, +0x0a202eb0, +0x40000006, +0x16000007, +0x14400074, +0x04cfff66, +0x08000000, +0x08000000, +0x9d140070, +0x01000204, +0x01000004, +0x0a005390, +0x16000004, +0x00000216, +0x00000010, +0x05800460, +0x0aa053f0, +0x05800400, +0x0a8054d0, +0x144000d7, +0x04cfff05, +0x1440004d, +0x0a202eb0, +0x40000016, +0x16000007, +0x003ffcfe, +0x04cfff66, +0x08000000, +0x08000000, +0x9d140170, +0x0100021d, +0x0100001d, +0x0a0054e0, +0x003ffcfe, +0x048ffcff, +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, +0x98805620, +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, +0x40000024, +0x048002ff, +0x41000224, +0x16000005, +0x413ffefe, +0x04000400, +0x01000025, +0x0a2059e0, +0x003ffefe, +0x048ffeff, +0x08200000, +0x048002ff, +0x413ffefe, +0x16000005, +0x01000025, +0x0a2059e0, +0x40000024, +0x16000005, +0x403ffefe, +0x04200454, +0x41000224, +0x048ffeff, +0x08200000, +0x048008ff, +0x413ff8f8, +0x1440000d, +0x9c038e10, +0x413ffaf9, +0x04a001dd, +0x413ffcfa, +0x16000001, +0x413ffefb, +0x160000f0, +0x9c100400, +0x9c100480, +0x9c1d06c8, +0x9f085030, +0x9c180678, +0x9c180650, +0x058001a0, +0x0aa05db0, +0x04800144, +0x04400044, +0x07800000, +0x05800040, +0x9d180658, +0x0a805bc0, +0x9d040008, +0x9e090000, +0x07800000, +0x07800000, +0x9e0d0500, +0x0a005c90, +0x05800160, +0x0ac05c40, +0x9e090000, +0x07800000, +0x07800000, +0x9e0d0500, +0x9d040508, +0x0a005c90, +0x9d040008, +0x9e090000, +0x07800000, +0x9d040008, +0x9e0d0500, +0x05800160, +0x0ac05cf0, +0x0480014b, +0x044000bb, +0x4a005d20, +0x1440004a, +0x0420040a, +0x04a001ab, +0x044000bb, +0x120001aa, +0x42000a38, +0x120001bb, +0x42000b39, +0x12000288, +0x12000299, +0x9e0e8280, +0xca005ec0, +0x1e0e8390, +0xdd040608, +0x05800160, +0x0ac05e60, +0x9d040008, +0x9e090000, +0x07800000, +0x05800040, +0x9e0d0500, +0x0aa05ec0, +0x9d040508, +0x0a005ec0, +0x9e090000, +0x05800040, +0x9d040008, +0x9e0d0500, +0x0a805ec0, +0x9d040508, +0x9c1d06c8, +0xdc1d0648, +0x1f0400b0, +0x9c100700, +0xdc1d06c8, +0x1f040010, +0x9d108480, +0x9f0940b0, +0x9d108700, +0x000006c9, +0x06000008, +0x0aa060b0, +0xdc1d0688, +0x14400005, +0x9c1d0608, +0x04a00255, +0xdd108480, +0x16000017, +0xdd108700, +0x160ffff8, +0x05800540, +0x0aa06070, +0x05800160, +0x0ac06060, +0x01000027, +0x0a006070, +0x01000028, +0x9e088000, +0xa0054dba, +0xa005c81a, +0x0a006150, +0xdd040608, +0x1e088000, +0xa0054dba, +0xa005c81a, +0x9f1f80b0, +0x9f1e0010, +0x9f040020, +0x9f040070, +0x9f020810, +0x9d040608, +0x9e0f0070, +0x9d0c8118, +0x98805a80, +0x003ffefb, +0x003ffcfa, +0x003ffaf9, +0x003ff8f8, +0x048ff8ff, +0x08200000, +0x9c0c0018, +0x9f0b0010, +0x00000426, +0x40000627, +0x04a001dd, +0x9d0c8318, +0x16000004, +0xa00602ba, +0x9c0c0018, +0x9f0b0010, +0x9d0c81b8, +0x9d0c82b8, +0x9d0c8318, +0x98806250, +0x07800000, +0xa00602ba, +0x16000015, +0xdc1d0508, +0x05800460, +0x9d0c81b8, +0x9d0c82b8, +0xdc1d0548, +0x1f0400b0, +0x0a8063f0, +0x9f093020, +0x07800000, +0x07800000, +0x05800460, +0x0a806490, +0x01000025, +0x01000424, +0x01000625, +0x0a006490, +0x05800470, +0x0a806490, +0x9f083860, +0x07800000, +0x07800000, +0x05800470, +0x0a806490, +0x01000225, +0x01000425, +0x01000624, +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, +0x0a806660, +0x9c0c0510, +0x0a006670, +0x9c0c0618, +0x16000014, +0x9d0c81e8, +0x9d0c8148, +0x0a8066e0, +0x9c0c05b0, +0x9c0c0510, +0x0a006700, +0x9c0c06b8, +0x9c0c0618, +0x07800000, +0x9d0c81e8, +0x9d0c8148, +0x988064e0, +0x9d180750, +0x08200000, +0x9d019220, +0x048002ff, +0x14400004, +0x413ffefe, +0x16000040, +0x9c010910, +0x0a204340, +0x14400040, +0x9c030810, +0x16000171, +0x9c009f30, +0x9c019220, +0x0a203f30, +0x9c009830, +0x003ffefe, +0x048ffeff, +0x08200000, +0x048004ff, +0x413ffcfe, +0x1601a0cd, +0x1600be4c, +0x008001c8, +0x408000c5, +0x04c0ff88, +0x408002c9, +0x04c0ff55, +0x408003ca, +0x04c0ff99, +0xdc02c080, +0x12000155, +0x408004cb, +0x04c0ffaa, +0x408005c4, +0x04c0ffbb, +0x9e080000, +0x020005de, +0x1601d4c3, +0x00000030, +0x00000231, +0x00000435, +0x04800211, +0x04400511, +0x0300010e, +0x01000231, +0x04c0ff44, +0xdc02c990, +0x04c3ff2d, +0xdc01d2a0, +0x128002dd, +0xdc02dcb0, +0x048fffdd, +0x9c062040, +0x0b200000, +0x9d02c080, +0x9d02c990, +0x9d01d2a0, +0x9d02dcb0, +0x16000000, +0x16000001, +0x16000002, +0x16000003, +0x9c0c0710, +0x07800000, +0x07800000, +0x9e040000, +0x07800000, +0x07800000, +0x9d0c8510, +0x1601a0cd, +0x1600e5cc, +0x008001c8, +0x408000c5, +0x04c0ff88, +0x408002c9, +0x04c0ff55, +0x408003ca, +0x04c0ff99, +0xdc02c080, +0x12000155, +0x408004cb, +0x04c0ffaa, +0x408005c4, +0x04c0ffbb, +0x9e080000, +0x020005de, +0x1601d4c3, +0x00000030, +0x00000231, +0x00000435, +0x04800211, +0x04400511, +0x0300010e, +0x01000231, +0x04c0ff44, +0xdc02c990, +0x04c3ff2d, +0xdc01d2a0, +0x128002dd, +0xdc02dcb0, +0x048fffdd, +0x9c062040, +0x0b200000, +0x9d02c080, +0x9d02c990, +0x9d01d2a0, +0x9d02dcb0, +0x16000161, +0x07800000, +0x07800000, +0x07800000, +0x9c038e10, +0x07800000, +0x07800000, +0x07800000, +0x9c180604, +0x9c180680, +0x07800000, +0x07800000, +0x07800000, +0x9c043e60, +0x9c043f60, +0x07800000, +0x07800000, +0x9c0c01b0, +0x9c180628, +0x9c180668, +0x07800000, +0x07800000, +0x9f040030, +0x9f040070, +0x07800000, +0x07800000, +0x9d188708, +0x9d188748, +0x403ffcfe, +0x048ffcff, +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, +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..993c89305dd5 --- /dev/null +++ b/sound/soc/codecs/abe/C_ABE_FW.SM32 @@ -0,0 +1,3920 @@ +0x00000000, +0x00049F03, +0x00000000, +0x0004A202, +0x00000000, +0x00072603, +0x00000000, +0x00053005, +0x00000000, +0x00053504, +0x00000000, +0x00072105, +0x00000000, +0x00012B0C, +0x00000000, +0x00053928, +0x00000000, +0x00049F03, +0x00000000, +0x00053005, +0x00000000, +0x00058928, +0x00000000, +0x0001D118, +0x0000F200, +0x0000F200, +0x0000F300, +0x0000F200, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x0005BB00, +0x00010612, +0x0000F409, +0x0000FD09, +0x00090012, +0x0019D800, +0x00000000, +0x0000F200, +0x00000002, +0x00000000, +0x000B0011, +0x00000000, +0x00000000, +0x00000402, +0x00000000, +0x0001370C, +0x00000000, +0x0001430C, +0x00000000, +0x00011F0C, +0x00000000, +0x0001130C, +0x00000000, +0x0001070C, +0x00000000, +0x00012404, +0x00000000, +0x00012804, +0x001B001A, +0x00000000, +0x00001124, +0x00000000, +0x00000000, +0x00014F0C, +0x00000000, +0x00012C02, +0x00000000, +0x0001670C, +0x00000000, +0x0001730C, +0x00017F11, +0x00017F11, +0x00000000, +0x00013811, +0x000B0011, +0x00000000, +0x00000000, +0x00015B0C, +0x00000000, +0x0007290C, +0x00000000, +0x00012E02, +0x00000000, +0x0001E90C, +0x0001D118, +0x0002310C, +0x0001D118, +0x00023D0C, +0x00000000, +0x0001F50C, +0x0001D100, +0x0002490C, +0x0001D100, +0x0002550C, +0x00000000, +0x0002010C, +0x0001D118, +0x0002610C, +0x0001D118, +0x00026D0C, +0x00000000, +0x00020D0C, +0x0001D118, +0x0002790C, +0x0001D118, +0x0002850C, +0x00000000, +0x0002190C, +0x0001D118, +0x0002910C, +0x0001D118, +0x00029D0C, +0x00000000, +0x0002250C, +0x0001D118, +0x0002A90C, +0x0001D118, +0x0002B50C, +0x0001D118, +0x0002C10C, +0x0001D118, +0x0002CD0C, +0x0001D118, +0x0002D90C, +0x0001D118, +0x0002E50C, +0x00000000, +0x0002F13C, +0x00000000, +0x00032D18, +0x00000000, +0x00034518, +0x00000000, +0x00035D18, +0x00000000, +0x00037518, +0x0006DF01, +0x00000202, +0x00000000, +0x00038D06, +0x00460001, +0x00000800, +0x00460003, +0x00000800, +0x00000000, +0x00039318, +0x0003F311, +0x0003F311, +0x00000000, +0x00015A11, +0x00000000, +0x0003AB18, +0x00040B11, +0x00040B11, +0x00000000, +0x00015A11, +0x00000000, +0x0003C318, +0x00041C11, +0x00041C11, +0x00000000, +0x0003DB18, +0x00042D11, +0x00042D11, +0x00170011, +0x00000000, +0x00000000, +0x00043E0C, +0x00000002, +0x00000000, +0x00044A11, +0x00044A11, +0x00000000, +0x00018D11, +0x00045B11, +0x00045B11, +0x00000000, +0x00019E11, +0x00046C11, +0x00046C11, +0x00000000, +0x0001AF11, +0x00047D11, +0x00047D11, +0x00000000, +0x0001C011, +0x000B0019, +0x00000000, +0x000B0011, +0x00000000, +0x00048E11, +0x00048E11, +0x00000000, +0x0001D111, +0x00000006, +0x00000000, +0x00001318, +0x00000000, +0x00001304, +0x00000000, +0x00001354, +0x00000000, +0x0004A411, +0x0004A411, +0x00000006, +0x00000000, +0x000012F0, +0x00000000, +0x00000000, +0x00000602, +0x00000018, +0x00001800, +0x00000000, +0x0004B518, +0x0004FD11, +0x0004FD11, +0x00000000, +0x00015A11, +0x00000000, +0x0004CD18, +0x00050E11, +0x00050E11, +0x00000000, +0x00015A11, +0x00000000, +0x0004E518, +0x00000000, +0x0004B518, +0x000C0010, +0x00004800, +0x000B1C74, +0x00000000, +0x000B1C72, +0x00000000, +0x000B1C68, +0x00000000, +0x00080078, +0x00011800, +0x00000000, +0x00004602, +0x00000000, +0x0002007A, +0x00100018, +0x00012000, +0x00000000, +0x00004802, +0x00000000, +0x0006E01A, +0x00000000, +0x00053928, +0x00032713, +0x00031413, +0x00053928, +0x00044400, +0x00044500, +0x00071F08, +0x00800002, +0x00130400, +0x00000000, +0x00056128, +0x0001F513, +0x0001E213, +0x00056128, +0x00031200, +0x00031300, +0x00072F08, +0x00850002, +0x00131800, +0x00000000, +0x00056128, +0x00000003, +0x00000000, +0x00800004, +0x00130400, +0x00850004, +0x00131800, +0x00000000, +0x00056128, +0x00000000, +0x00058928, +0x00045812, +0x00044612, +0x00058928, +0x00056600, +0x00056700, +0x00073F08, +0x008F000C, +0x0012F000, +0x00000000, +0x0005B10C, +0x00000000, +0x00013004, +0x001A0022, +0x00000000, +0x00000000, +0x0005BD0C, +0x00000000, +0x0005BD0C, +0x00000000, +0x00013404, +0x0001D118, +0x0005D50C, +0x0001D118, +0x0005E10C, +0x00060619, +0x00060619, +0x00000000, +0x00059A19, +0x0005ED19, +0x0005ED19, +0x00058119, +0x00056819, +0x00000000, +0x0005DC0D, +0x00000000, +0x0005CF0D, +0x00061F0D, +0x00061F0D, +0x00062C0D, +0x00062C0D, +0x0001000D, +0x00000000, +0x000B000D, +0x00000000, +0x00000000, +0x0005B30D, +0x00000000, +0x0005C00F, +0x0006390D, +0x0006390D, +0x0006460F, +0x0006460F, +0x000B000D, +0x00000000, +0x000B000F, +0x00000000, +0x0006550D, +0x0006550D, +0x0006620F, +0x0006620F, +0x00000000, +0x0005F607, +0x00000000, +0x0005FD0D, +0x00067107, +0x00067107, +0x0006780D, +0x0006780D, +0x00030007, +0x00000000, +0x00000000, +0x0005E90D, +0x0006850D, +0x0006850D, +0x0006920D, +0x0006920D, +0x0001000D, +0x00000000, +0x000B000D, +0x00000000, +0x00000000, +0x00069F02, +0x00000000, +0x00060A0D, +0x0006A107, +0x0006A107, +0x0006A80D, +0x0006A80D, +0x00030007, +0x00000000, +0x00000000, +0x0006B504, +0x00000000, +0x0000F509, +0x00000000, +0x0000FE09, +0x0006E109, +0x0006E109, +0x00063F09, +0x00063F09, +0x000B0009, +0x00000000, +0x00000000, +0x0006ED0C, +0x0006EA03, +0x0006EA03, +0x00074F02, +0x00064803, +0x00000003, +0x001D4400, +0x00000000, +0x0006F928, +0x0001F513, +0x0001E213, +0x0006F928, +0x00066300, +0x00066400, +0x00075508, +0x00C70002, +0x00131800, +0x00C70004, +0x00131800, +0x00073509, +0x00073509, +0x00065409, +0x00064B09, +0x00073E03, +0x00073E03, +0x00074F02, +0x00065D03, +0x00074103, +0x00074103, +0x00074F02, +0x00066003, +0x00010612, +0x00010612, +0x00010612, +0x00010612, +0x00010612, +0x00010612, +0x00010612, +0x00010612, +0x00010612, +0x00010612, +0x00010612, +0x00010612, +0x00010612, +0x00010612, +0x00000000, +0x0007440C, +0x0001D118, +0x0007500C, +0x0001D118, +0x00075C0C, +0x00078207, +0x00078207, +0x0007890D, +0x0007890D, +0x0007680D, +0x0007680D, +0x0007750D, +0x0007750D, +0x00000000, +0x0006F928, +0x00000000, +0x0006DF01, +0x00000000, +0x0006E001, +0x0006B911, +0x0006B911, +0x0006CA15, +0x0006CA15, +0x00061702, +0x00061915, +0x0006E001, +0x0006CA15, +0x00062E11, +0x0006DF01, +0x00E30011, +0x0000E400, +0x00079609, +0x00079609, +0x00000000, +0x00066509, +0x00079F09, +0x00079F09, +0x00067709, +0x00066E09, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00010000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +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..77f242ded29f --- /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, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x03170307, +0x03510335, +0x03AF036E, +0x038B03CD, +0x03E9039D, +0x0000030A, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000509, +0x00010C01, +0x04030F01, +0x0E0E0E00, +0x00000F0E, +0x0E0E0E09, +0x00001F0E, +0x19170608, +0x00001E1C, +0x19180608, +0x00001E1D, +0x21201707, +0x00000F18, +0x24232202, +0x00002625, +0x29272307, +0x00000F17, +0x44434211, +0x00004745, +0x44434211, +0x00004845, +0x4A494102, +0x0000534B, +0x0E544905, +0x0000550E, +0x56365402, +0x00005F57, +0x4D4C4202, +0x0000534E, +0x0E544C05, +0x0000550E, +0x582A5402, +0x00005F59, +0x504F4302, +0x0000534E, +0x0E544F05, +0x0000550E, +0x5A2D5402, +0x00005F5B, +0x52514402, +0x0000534E, +0x0E545105, +0x0000550E, +0x5C305402, +0x00005F5D, +0x2C2B2A04, +0x00000FD0, +0x2F2E2D04, +0x00000FD1, +0x32313004, +0x00000FD2, +0x38373604, +0x00000FD3, +0x0E0E0E10, +0x00000E0E, +0x0E0E0E10, +0x00000E0E, +0x0E0E0E10, +0x0000630E, +0x0E0E0E10, +0x0000640E, +0x0E0E0E10, +0x0000650E, +0x0E0E0E10, +0x0000680E, +0x0E0E0E10, +0x00000E0E, +0x0E410E12, +0x00006A69, +0x6E0E720F, +0x00007316, +0x0E220E13, +0x0000740E, +0x0E190E13, +0x0000750E, +0x0E400E14, +0x0000760E, +0x7879401A, +0x0000770E, +0x7B7C191A, +0x00007A0E, +0x7E017D18, +0x0013817F, +0x83008219, +0x00138684, +0x7E047D18, +0x0013897F, +0x83038219, +0x00138A84, +0x8D068C18, +0x0012908E, +0x1B910608, +0x00009392, +0x95949104, +0x00000FD6, +0x1B220608, +0x00009396, +0x3F3E0604, +0x00000FD6, +0x9F010102, +0x0000A19E, +0x0B1A0106, +0x0000670E, +0xA01A1A02, +0x0000A29D, +0xAD040402, +0x0000AFAB, +0x0B1A0406, +0x0000880E, +0xAE1A1A02, +0x0000A2AC, +0x99282702, +0x00005E9A, +0x0E28D70C, +0x00000FD4, +0xA5282802, +0x0000A7A3, +0x136B2806, +0x0000140E, +0xA66B6B02, +0x0000A8A4, +0x9B18181C, +0x00005E9C, +0x0E18D80C, +0x00000FD5, +0xA9181802, +0x0000A7A3, +0x136E1806, +0x0000140E, +0xAA6E6E02, +0x0000A8A4, +0xB2542202, +0x0000B4B0, +0x0EB55405, +0x0000670E, +0xB187B502, +0x0000B39E, +0xB8542202, +0x0000B4B6, +0x0EBA5405, +0x0000880E, +0xB78BBA02, +0x0000B9AB, +0x10BCBB1B, +0x00001211, +0x0F0F0F0A, +0x00000F0F, +0xC502C419, +0x0013C8C6, +0xC505C419, +0x0013C9C6, +0xBDD72802, +0x0000BFBE, +0xC1C0D717, +0x0000C3C2, +0xCAD8181C, +0x0000BFCB, +0xD9D8D804, +0x00000FD6, +0xCCC0D817, +0x0000C3CD, +0xCCC0D917, +0x0000C3CD, +0xDD542002, +0x0000B4B0, +0x0EB55405, +0x0000670E, +0xDCDEB502, +0x0000B39E, +0xDB542002, +0x0000B4B6, +0x0EBA5405, +0x0000880E, +0xDADEBA02, +0x0000B9AB, +0xE1E0DF0D, +0x0000E6E2, +0xDFE0461D, +0x00000F0E, +0xE7D72802, +0x0000BFE8, +0xE9D8181C, +0x0000BFEA, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000001, +0x00000000, +0x00000000, +0x00000FA4, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x11841184, +0x119B1184, +0x00040018, +0x119C119C, +0x11B3119C, +0x00040018, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x12301230, +0x128F1230, +0x000C0060, +0x12901290, +0x12EF1290, +0x000C0060, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000200, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +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, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x01410490, +0x041B03F3, +0x042A0422, +0x043F0434, +0x04950446, +0x052004D9, +0x05500453, +0x0204023C, +0x01D40178, +0x0481027F, +0x064A047A, +0x061E0676, +0x05870592, +0x045A02A8, +0x06870406, +0x014F0149, +0x015C0156, +0x01700162, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000004, +0x00000001, +0x00000000, +0x00000000, +0x00000000, +0x003FFFF0, +0x00000000, +0x00400000, +0x03270314, +0x034D033A, +0x03730360, +0x03990386, +0x03BF03AC, +0x03E503D2, +0x040B03F8, +0x0431041E, +0x00000004, +0x00000001, +0x00000000, +0x00000000, +0x00000000, +0x003FFFF0, +0x00000000, +0x00400000, +0x01F501E2, +0x021B0208, +0x0241022E, +0x02670254, +0x028D027A, +0x02B302A0, +0x02D902C6, +0x02FF02EC, +0x00000004, +0x00000001, +0x00000000, +0x00000000, +0x00000000, +0x003FFFF0, +0x00000000, +0x00400000, +0x04580446, +0x047C046A, +0x04A0048E, +0x04C404B2, +0x04E804D6, +0x050C04FA, +0x0530051E, +0x05540542, +0x00008363, +0x00000428, +0x00000000, +0x00000001, +0x00002000, +0x000003FF, +0x00000004, +0x00000001, +0x00000000, +0x00000000, +0x00000000, +0x003FFFF0, +0x00000000, +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, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +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/Makefile b/sound/soc/codecs/abe/Makefile new file mode 100644 index 000000000000..cbab19261274 --- /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_TWL6030) += 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..0939c3642a21 --- /dev/null +++ b/sound/soc/codecs/abe/abe_api.c @@ -0,0 +1,1740 @@ +/* + * 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_API.C + * + * All the visible API for the audio drivers + * @path + * @rev 01.00 +*! +*! Revision History +*! 27-Nov-2008 Original +*! 05-Jun-2009 V05 release +*/ + + +#include "abe_main.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 BE_API.h +*/ + +void abe_reset_hal (void) +{ + abe_dbg_output = TERMINAL_OUTPUT; +/* reset features */ + abe_reset_all_features (); + +/* load default port values */ + abe_reset_all_ports (); + +/* load default sequence list */ + abe_reset_all_sequence (); + +/* build the scheduler tables */ + abe_build_scheduler_table (); + +/* init the buffer addresses */ + abe_reset_all_fifo (); + +/* load firmware */ + abe_load_fw (); + +/* 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 (void) +{ + abe_block_copy (COPY_FROM_HOST_TO_ABE, ABE_PMEM, 0, + (abe_uint32 *)ABE_FW_PM, sizeof (ABE_FW_PM)); + abe_block_copy (COPY_FROM_HOST_TO_ABE, ABE_CMEM, 0, + (abe_uint32 *)ABE_FW_CM, sizeof (ABE_FW_CM)); + abe_block_copy (COPY_FROM_HOST_TO_ABE, ABE_SMEM, 0, + (abe_uint32 *)ABE_FW_SM, sizeof (ABE_FW_SM)); + abe_block_copy (COPY_FROM_HOST_TO_ABE, ABE_DMEM, 0, + (abe_uint32 *)ABE_FW_DM, sizeof (ABE_FW_DM)); + +} + +/* + * ABE_DEFAULT_CONFIGURATION + * + * Parameter : + * use-case-ID : "LP player", "voice-call" use-cases as defined in the paragraph + * "programming use-case sequences" + * 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) +{ + short D_multiFrame[PROCESSING_SLOTS][TASKS_IN_SLOT]; + abe_uint32 event; + abe_satcdescriptor_aess desc; + abe_uint32 atc_reg; + abe_uint16 i; + abe_uint8 *ptr; + abe_port_protocol_t *protocol; + abe_data_format_t *format; + + #define SIZEOFIODESC 20 + + /* clear local tables */ + for (ptr = (abe_uint8 *)&(D_multiFrame[0][0]), i=0; + i < sizeof (D_multiFrame); i++) + *ptr++ = 0; + for (ptr = (abe_uint8 *)&desc, i=0; i < sizeof (desc); i++) *ptr++ = 0; + + switch (use_case) { + /* enables voice ul/dl on earpiece + MM_DL on IHF */ + case UC2_VOICE_CALL_AND_IHF_MMDL : + abe_reset_port(PDM_UL_PORT); + abe_reset_port(PDM_DL1_PORT); + abe_reset_port(VX_DL_PORT); + abe_reset_port(VX_UL_PORT); + abe_reset_port(MM_DL_PORT); + /* 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); + + /* enables EVENT_GENERATOR_START=6C from McPDM */ + atc_reg = 0x01; + abe_block_copy (COPY_FROM_HOST_TO_ABE, ABE_ATC, 0x6C, + &atc_reg, 4); + + /* set McPDM_DL as EVENT_SOURCE_SELECTION */ + event = 0L; /* source = DMAreq */ + abe_block_copy (COPY_FROM_HOST_TO_ABE, ABE_ATC, 0x70, + &event, 4); + + event = 2L; /* source = MCPDM_DL to AUDIO_ENGINE_SCHED */ + abe_block_copy (COPY_FROM_HOST_TO_ABE, ABE_ATC, 0x74, + &event, 4); + for (ptr = (abe_uint8 *)&(D_multiFrame[0][0]), + i=0; i < sizeof (D_multiFrame); i++) *ptr++ = 0; + + /* Scheduling table for Voice UL/DL 8kHz + MM DL 48 kHz */ + D_multiFrame[0][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_AMIC; + D_multiFrame[0][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_VX_DL; + + D_multiFrame[1][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_ASRC_VX_DL_8; + D_multiFrame[1][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_VX_DL_8_48_BP; + D_multiFrame[1][2] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_VX_DL_8_48_0SR; + D_multiFrame[1][3] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_MM_DL; + + D_multiFrame[2][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_VX_DL_8_48_LP; + D_multiFrame[2][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_ASRC_MM_DL; + D_multiFrame[2][2] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_DL1Mixer; + D_multiFrame[2][3] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2Mixer; + + D_multiFrame[3][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_EchoMixer; + D_multiFrame[3][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_SideTone; + D_multiFrame[3][2] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_SDTMixer; + D_multiFrame[3][3] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2_EQ; + + D_multiFrame[4][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_DL1_EQ; + D_multiFrame[4][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_DL1_APS_EQ; + D_multiFrame[4][3] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_DL1_GAIN; + + D_multiFrame[5][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_VXRECMixer; + D_multiFrame[5][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_VXREC_SPLIT; + + D_multiFrame[8][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2_APS_EQ; + D_multiFrame[8][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2_GAIN; + + D_multiFrame[9][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_EARP_48_96_LP0; + D_multiFrame[9][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_EARP_48_96_0SR; + D_multiFrame[9][2] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_EARP_48_96_LP1; + D_multiFrame[9][3] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_EARP_48_96_LP1; + + D_multiFrame[10][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_IHF_48_96_LP0; + D_multiFrame[10][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_IHF_48_96_0SR; + D_multiFrame[10][2] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_IHF_48_96_LP1; + D_multiFrame[10][3] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_IHF_48_96_LP1; + + D_multiFrame[11][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_McPDM_DL; + + D_multiFrame[12][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_AMIC_96_48_IIR; + D_multiFrame[12][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_AMIC_96_48_DEC; + D_multiFrame[12][2] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_AMIC_EQ; + D_multiFrame[12][3] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_AMIC_SPLIT; + + D_multiFrame[14][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_DL1_APS_IIR; + D_multiFrame[14][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_DL1_APS_CORE; + + D_multiFrame[15][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2_L_APS_CORE; + D_multiFrame[15][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2_APS_IIR; + D_multiFrame[15][2] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2_APS_SPLIT; + D_multiFrame[15][3] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2_R_APS_CORE; + + D_multiFrame[21][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_VX_UL_ROUTING; + D_multiFrame[21][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_ULMixer; + + D_multiFrame[22][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_VX_UL_48_8_LP; + D_multiFrame[22][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_VX_UL_48_8_DEC1; + D_multiFrame[22][2] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_VX_UL_48_8_BP; + D_multiFrame[22][3] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_ASRC_VX_UL_8; + + D_multiFrame[23][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_McPDM_DL; + D_multiFrame[23][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_VX_UL; + D_multiFrame[23][2] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_GAIN_UPDATE; + + abe_block_copy (COPY_FROM_HOST_TO_ABE, ABE_DMEM, + D_multiFrame_ADDR, (abe_uint32*)D_multiFrame, + sizeof (D_multiFrame)); + + /* initializes the ATC descriptors in DMEM */ + 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); + + protocol = &(abe_port[PDM_DL1_PORT].protocol); + format = &(abe_port[PDM_DL1_PORT].format); + abe_init_atc (PDM_DL1_PORT); + abe_init_io_tasks (PDM_DL1_PORT, format, protocol); + + protocol = &(abe_port[VX_DL_PORT].protocol); + format = &(abe_port[VX_DL_PORT].format); + abe_init_atc (VX_DL_PORT); + abe_init_io_tasks (VX_DL_PORT, format, protocol); + + protocol = &(abe_port[VX_UL_PORT].protocol); + format = &(abe_port[VX_UL_PORT].format); + abe_init_atc (VX_UL_PORT); + abe_init_io_tasks (VX_UL_PORT, format, protocol); + + protocol = &(abe_port[MM_DL_PORT].protocol); + format = &(abe_port[MM_DL_PORT].format); + abe_init_atc (MM_DL_PORT); + abe_init_io_tasks (MM_DL_PORT, format, protocol); + + /* Voice and multimedia audio router init */ + abe_block_copy (COPY_FROM_HOST_TO_ABE, + ABE_DMEM, D_aUplinkRouting_ADDR + 12, + (abe_uint32 *)abe_router_ul_table_init_1, + sizeof (abe_router_ul_table_init_1)); + + case UC4_EANC : + 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_monitoring (); +} + +/* + * ABE_EVENT_GENERATOR_SWITCH + * + * Parameter : + * e: Event Generation Counter, McPDM, DMIC or default. + * p: pointer to the main port + * + * 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 50% OPP is (32768kHz x3000) = 98304kHz, + * then the closest ratio to + * 96kHz is 1023. The counter will be loaded with 2x1023=2046. + * + * Return value : + * None. + */ + +void abe_event_generator_switch (abe_event_id e, abe_port_id *p) +{ + abe_uint32 event, selection, counter, start; + counter = EVENT_GENERATOR_COUNTER_DEFAULT; + + switch (e) { + case EVENT_MCPDM : + selection = EVENT_SOURCE_DMA; + start = EVENT_GENERATOR_ON; event = ABE_ATC_MCPDMDL_DMA_REQ; + break; + case EVENT_DMIC : + selection = EVENT_SOURCE_DMA; + start = EVENT_GENERATOR_ON; event = ABE_ATC_DMIC_DMA_REQ; + break; + case EVENT_TIMER : + selection = EVENT_SOURCE_COUNTER; + start = EVENT_GENERATOR_ON; event = 0; + break; + case EVENT_McBSP : + selection = EVENT_SOURCE_COUNTER; + start = EVENT_GENERATOR_ON; event = 0; + break; + case EVENT_McASP : + selection = EVENT_SOURCE_COUNTER; + start = EVENT_GENERATOR_ON; event = 0; + break; + case EVENT_SLIMBUS: + selection = EVENT_SOURCE_COUNTER; + start = EVENT_GENERATOR_ON; event = 0; + break; + case EVENT_DEFAULT: + selection = EVENT_SOURCE_COUNTER; + start = EVENT_GENERATOR_ON; + 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); + + /* @@@ Tell the scheduler for Slot #24 in case of McBSP/McASP !!! */ +} + +/* + * 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 = OPP100; /* @@@ RELEASE 5 allows only 100% OPP */ +} + +/* + * 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) +{ +#if 0 /*@@@ FW 05 supports only OPP100 */ + abe_uint32 scheduler_task_steps; + + switch (opp) { + case OPP25: + scheduler_task_steps = TASKS_IN_SLOT/4; + break; + case OPP50: + scheduler_task_steps = TASKS_IN_SLOT/2; + break; + case OPP100: + scheduler_task_steps = TASKS_IN_SLOT/1; + break; + case OPP0: + default: + abe_dbg_param |= ERR_API; + abe_dbg_error_log (ABE_BLOCK_COPY_ERR); + break; + } + + abe_block_copy (COPY_FROM_HOST_TO_ABE, ABE_DMEM, D_taskStep_ADDR, + &scheduler_task_steps, sizeof (scheduler_task_steps)); +#endif +} + + +/* + * 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. + * + * Return value : + * error code when the Port is not activated. + */ + +void abe_set_ping_pong_buffer (abe_port_id port, abe_uint32 rw, abe_uint32 n) +{ + +} + + +/* + * ABE_PLUG_SUBROUTINE + * + * Parameter : + * id: returned sequence index after plugging a new subroutine + * f : subroutine address to be inserted + * + * 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_UNPLUG_SUBROUTINE + * + * Prototype : void abe_unplug_subroutine (uint32 id); + * + * Parameter : + * Id: index of the call-back to be removed + * + * Returned value : error code + * + * Operations : unregister a subroutine used for call-back. + * + */ + +void abe_unplug_subroutine (abe_uint32 id) +{ +} + + + +/* + * 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_seq_t *s) +{ + abe_seq_t *seq_ptr; + abe_uint32 i; + extern abe_uint32 sequence_write_pointer; + extern abe_uint32 sequence_id_pointer; + extern abe_seq_t all_sequence[MAXNBSEQUENCE]; + extern abe_uint32 sequence_id[MAXNBSEQUENCE]; + + seq_ptr = s; + + for (i = 0; i < MAXLINESEQUENCE; i++) { + /* sequence copied line by line */ + all_sequence [sequence_write_pointer++] = (*seq_ptr); + + if ((*(abe_int32 *)seq_ptr) == (-1)) { + sequence_id [sequence_id_pointer++] = + sequence_write_pointer -1; + *id = (sequence_id_pointer -1); + /* return the index to pointer table */ + } + } + + abe_dbg_error_log (ABE_SEQTOOLONG); +} + + +/* + * 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) +{ + +} + + +/* + * 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) +{ + +} + + + +/* + * ABE_SET_ANALOG_CONTROL + * + * Parameter : + * Pointer to the list of control codes (similar to the I2C control bytes) + * + * Operations : + * sends the commands to the analog part. Detects if the command is a gain + * control + * in order to assign the gain value between digital and analog processing. + * + * Return value : + * None. + */ + +void abe_set_analog_control (abe_uint32 data) +{ + +} + + +/* + * 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) +{ + +} + + +/* + * 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) +{ + +} + + + +/* + * 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) +{ + +} + + + +/* + * 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) +{ + /* @@@ FW 05.xx do not support ping-pong protocols */ +} + + + +/* + * ABE_DISABLE_DATA_TRANSFER + * + * Parameter : + * p: port indentifier + * + * Operations : + * disables the ATC descriptor and stop IO/port activities + * + * Return value : + * None. + */ + +void abe_disable_data_transfer (abe_port_id *p) +{ + abe_port_protocol_t *protocol; + abe_data_format_t *format; + + protocol = &(abe_port[PDM_DL1_PORT].protocol); + format = &(abe_port[PDM_UL_PORT].format); + + abe_init_io_tasks (PDM_UL_PORT, format, protocol); + abe_init_atc (*p); + abe_port[PDM_DL1_PORT].status = IDLE_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 id) +{ + abe_port_protocol_t *protocol; + abe_data_format_t *format; + + protocol = &(abe_port[id].protocol); + format = &(abe_port[id].format); + /* AESS/ATC descriptor disabled, enabled in the IO task */ + abe_init_atc (id); + /* install a new IO task descriptor */ + abe_init_io_tasks (id, format, protocol); + + /* local host variable status= "port is running" */ + abe_port[PDM_DL1_PORT].status = RUN_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 config. + * + * 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 *returned_dma_t) +{ + 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_iter_factor(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]).format), + &((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 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_mcbsp_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_mcbsp_port (abe_port_id id, abe_data_format_t *f, abe_uint32 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 *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; + abe_port [id].format = (*format); + abe_port [id].drift = 0; + abe_port [id].callback = NOCALLBACK; + abe_port [id].protocol = (*prot); + + /* load AE memory space */ + abe_init_io_tasks (id, format, prot); + abe_init_dma_t (id, format, prot); + abe_init_atc (id); + abe_read_port_address (id, dma); + +#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) +{ + +} + +/* + * 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: + dma1.data = (abe_uint32) (dma1.data + ABE_DMEM_BASE_ADDRESS_MPU); + break; + case DMAREQ_PORT_PROT : + if (MM_UL_PORT == port) + dma1.data = dma1.data + ABE_DMEM_BASE_ADDRESS_L3; + else + dma1.data = dma1.data + ABE_ATC_BASE_ADDRESS_L3; + break; + case CIRCULAR_PORT_PROT: + dma1.data = dma1.data + ABE_ATC_BASE_ADDRESS_L3; + break; + + case SLIMBUS_PORT_PROT : + case SERIAL_PORT_PROT : + case DMIC_PORT_PROT : + case MCPDMDL_PORT_PROT : + case MCPDMUL_PORT_PROT : + default : + break; + } + + (*dma2).data = (void *)(dma1.data); + (*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, etc) + * 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_port_t *dig_gain_port) +{ + _log(id_write_port_gain); +} + + +/* + * ABE_READ_GAIN + * + * Parameter : + * port : name of the port (VX_DL_PORT, MM_DL_PORT, MM_EXT_DL_PORT, + * TONES_DL_PORT, etc) + * 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_port_t *dig_gain_port) +{ + + +} + + + +/* + * 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_ext + * 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) +{ +#if 0 + int dTempValue; + int 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 2 + * - MinusDeltaAlpha + * - OneMinusEpsilon = 1-DeltaAlpha/2. + * + * PPM = 250 + * - 1000000/250=4000 + * - DeltaAlpha = 4194.3 ~ 4195 => 0x00418C + */ + if (dPpm != 0) { + /* Default value 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 */ + else + aTempValue32[1] = -1; /* D_DriftSign */ + dTempValue = (int)(ceil(262144.0/15625.0*abs(dPpm))); + aTempValue32[3] = dTempValue<<2; + aTempValue32[4] = (-dTempValue)<<2; + aTempValue32[5] = (0x00100000-(dTempValue/2))<<2; + + switch (dPath) { + case 0x0000: + /* Voice Uplink */ + /* Init CMem */ + dTempValue = 0x00000000; + setCM(C_AlphaCurrent_UL_VX_ADDR, + C_AlphaCurrent_UL_VX_ADDR,&dTempValue, Sth); + dTempValue = 0x00400000; + setCM(C_BetaCurrent_UL_VX_ADDR, + C_BetaCurrent_UL_VX_ADDR, &dTempValue, Sth); + + /* Init DMem */ + setlDM(D_AsrcVars_UL_VX_ADDR, D_AsrcVars_UL_VX_ADDR+28, + &aTempValue32[0], Sth); + break; + case 0x0001: + /* Voice Downlink */ + /* Init CMem */ + dTempValue = 0x00000000; + setCM(C_AlphaCurrent_DL_VX_ADDR, + C_AlphaCurrent_DL_VX_ADDR, &dTempValue, Sth); + dTempValue = 0x00400000; + setCM(C_BetaCurrent_DL_VX_ADDR, + C_BetaCurrent_DL_VX_ADDR, &dTempValue, Sth); + + /* Init DMem */ + setlDM(D_AsrcVars_DL_VX_ADDR, D_AsrcVars_DL_VX_ADDR+28, + &aTempValue32[0], Sth); + break; + case 0x0002: + /* Multimedia Downlink */ + /* Init CMem */ + dTempValue = 0x00000000; + setCM(C_AlphaCurrent_DL_MM_ADDR, + C_AlphaCurrent_DL_MM_ADDR, &dTempValue, Sth); + dTempValue = 0x00400000; + setCM(C_BetaCurrent_DL_MM_ADDR, + C_BetaCurrent_DL_MM_ADDR, &dTempValue, Sth); + + /* Init DMem */ + setlDM(D_AsrcVars_DL_MM_ADDR, D_AsrcVars_DL_MM_ADDR+28, + &aTempValue32[0], Sth); + break; + } +#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 and output gains of the mixer + * + * 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_mixer_t *param) +{ +#if 0 + Audio_fInitMixerDl1 + setCM(C_Gains_DL1M_ADDR, C_Gains_DL1M_ADDR+3, pGain, Sth); + setCM(C_Gains_DL2M_ADDR, C_Gains_DL2M_ADDR+3, pGain, Sth); + setCM(C_Gains_EchoM_ADDR, C_Gains_EchoM_ADDR+1, pGain, Sth) + setCM(C_Gains_SDTM_ADDR, C_Gains_SDTM_ADDR+1, pGain, Sth); + setCM(C_Gains_ULM_ADDR, C_Gains_ULM_ADDR+3, pGain, Sth); + + setCM(C_Gains_VxRecM_ADDR, C_Gains_VxRecM_ADDR+3, pGain, Sth); @MIXER_UL + + + __int64 dValue; + + dValue = (__int64)(pGain[1] & 0x00FFFFFFL) | + (((__int64)(pGain[0]))<<32); + +DMIC1 + setSM(S_GTarget_ADDR+0, S_GTarget_ADDR+0, &dValue, Sth) +DMIC2 + setSM(S_GTarget_ADDR+1, S_GTarget_ADDR+1, &dValue, Sth); +DMIC3 + setSM(S_GTarget_ADDR+2, S_GTarget_ADDR+2, &dValue, Sth); +AMIC + setSM(S_GTarget_ADDR+3, S_GTarget_ADDR+3, &dValue, Sth); +#endif + +} + + + +/* + * 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_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) +{ +#if 0 +VOICE ROUTER + + char aUplinkMuxing[16]; + unsigned addr; + + addr = D_aUplinkRouting_ADDR; + + /* Read routing table */ + getlDM(addr, addr+sizeof(aUplinkMuxing)-4, (int*)&aUplinkMuxing, Sth); + + /* Update routing table */ + aUplinkMuxing[12] = pVoiceRouting[0]; + aUplinkMuxing[13] = pVoiceRouting[1]; + + /* Write routing table */ + setlDM(addr, addr+sizeof(aUplinkMuxing)-4, (int*)&aUplinkMuxing, Sth); + +MULTIMEDIA ROUTER + + char aUplinkMuxing[16]; + unsigned addr; + int dIndex; + + addr = D_aUplinkRouting_ADDR; + + /* Read routing table */ + getlDM(addr, addr+sizeof(aUplinkMuxing)-4, (int*)&aUplinkMuxing, Sth); + + /* Update routing table */ + for (dIndex=0;dIndex<10; dIndex++) { + aUplinkMuxing[dIndex] = pMmRouting[dIndex]; + } + + /* Write routing table */ + setlDM(addr, addr+sizeof(aUplinkMuxing)-4, (int*)&aUplinkMuxing, Sth); + +MM_UL2 ROUTER + char aUplinkMuxing[16]; + unsigned addr; + + addr = D_aUplinkRouting_ADDR; + + /* Read routing table */ + getlDM(addr, addr+sizeof(aUplinkMuxing)-4, (int*)&aUplinkMuxing, Sth); + + /* Update routing table */ + aUplinkMuxing[10] = pMmRouting[0]; + aUplinkMuxing[11] = pMmRouting[1]; + + /* Write routing table */ + setlDM(addr, addr+sizeof(aUplinkMuxing)-4, (int*)&aUplinkMuxing, Sth); + abe_block_copy (COPY_FROM_HOST_TO_ABE, ABE_DMEM + + D_aUplinkRouting_ADDR+12, 0, + (abe_uint32 *)abe_router_ul_table_init_1, + sizeof (abe_router_ul_table_init_1)); +#endif + +} + + +/* + * 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 : table of gains + * + * + * Return value : + * None. + */ +void abe_read_mixer (abe_mixer_id id, abe_mixer_t *param) +{ +} + + +/* + * 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) +{ + +} diff --git a/sound/soc/codecs/abe/abe_api.h b/sound/soc/codecs/abe/abe_api.h new file mode 100644 index 000000000000..ad8596af8dac --- /dev/null +++ b/sound/soc/codecs/abe/abe_api.h @@ -0,0 +1,1132 @@ +/* + * 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. + * ABE_API.H + * + * 'ABE_API.H' all the APIs used by the Audio driver + * + * @path + * @rev 01.00 + *! + *! Revision History + *! =================================== + *! 27-Nov-2008 Original (LLF) + *! 05-Jun-2009 V05 release + */ + + +#ifndef __APIDEF_ +#define __APIDEF_ + +#include "abe_ext.h" + +/* + * HAL 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_microsecond *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); +/** + * 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_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" + * + * 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_event_generator_switch() 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. + * @param p: pointer to the main port + * @pre no pre-condition + * @post + * @return error code + * @see + */ +void abe_event_generator_switch (abe_event_id e, abe_port_id *p); + + + + +/* + * 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 + */ +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 + */ +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 + */ +void abe_set_ping_pong_buffer (abe_port_id port, abe_uint32 rw, abe_uint32 n); + + + + +/* + * 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 + + */ +void abe_plug_subroutine (abe_uint32 id, abe_subroutine2 *f); + + + + + +/* + * abe_unplug_subroutine() description for void abe_unplug_subroutine(). + * + * Parameter : + * Id: index of the call-back to be removed + * + * Operations : + * unregister a subroutine used for call-back. + * @param + * @pre no pre-condition + * @post + * @return error code + */ + +void abe_unplug_subroutine (abe_uint32 id); + + + + +/* + * 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 + */ +void abe_plug_sequence (abe_uint32 *id, abe_seq_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 + */ +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 + */ + +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_set_analog_control() description for abe_set_analog_control(). + * + * Parameter : + * Pointer to the list of control codes (similar to the I2C control bytes); + * + * Operations : + * sends the commands to the analog part. Detects if the command is a gain + * control + * in order to assign the gain value between digital and analog processing. + * + * @param + * @pre no pre-condition + * @post + * @return error code + * @see + */ + +void abe_set_analog_control (abe_uint32 data); + + + +/* + * 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 + */ +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 + */ +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 + */ +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 + */ +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. + */ + +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_mcbsp_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_mcbsp_port (abe_port_id id, abe_data_format_t *f, abe_uint32 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, etc); + * 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_port_t *abe_dig_gain_port); + + + + +/* + * ABE_READ_GAIN + * + * Parameter : + * port : name of the port (VX_DL_PORT, MM_DL_PORT, MM_EXT_DL_PORT, + * TONES_DL_PORT, etc); + * 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_port_t *dig_gain_port); + + + + + +/* + * 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_ext + * 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); + + + + +/* + * 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 and output gains of the mixer + * + * 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_mixer_t *param); + + + + + +/* + * 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_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_mixer_t *param); + + + + +/* + * 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); + +#endif /* #ifndef APIDEF */ 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..09aafa033776 --- /dev/null +++ b/sound/soc/codecs/abe/abe_cm_addr.h @@ -0,0 +1,420 @@ +/* + * 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 241 +#define init_CM_sizeof 242 + +#define C_Coef1_ADDR 242 +#define C_Coef1_ADDR_END 242 +#define C_Coef1_sizeof 1 + +#define C_CoefM1_ADDR 243 +#define C_CoefM1_ADDR_END 243 +#define C_CoefM1_sizeof 1 + +#define C_1_Alpha_ADDR 244 +#define C_1_Alpha_ADDR_END 252 +#define C_1_Alpha_sizeof 9 + +#define C_Alpha_ADDR 253 +#define C_Alpha_ADDR_END 261 +#define C_Alpha_sizeof 9 + +#define C_GainsWRamp_ADDR 262 +#define C_GainsWRamp_ADDR_END 279 +#define C_GainsWRamp_sizeof 18 + +#define C_Gains_ADDR 280 +#define C_Gains_ADDR_END 291 +#define C_Gains_sizeof 12 + +#define C_Gains_DL1M_ADDR 292 +#define C_Gains_DL1M_ADDR_END 295 +#define C_Gains_DL1M_sizeof 4 + +#define C_Gains_DL2M_ADDR 296 +#define C_Gains_DL2M_ADDR_END 299 +#define C_Gains_DL2M_sizeof 4 + +#define C_Gains_EchoM_ADDR 300 +#define C_Gains_EchoM_ADDR_END 301 +#define C_Gains_EchoM_sizeof 2 + +#define C_Gains_SDTM_ADDR 302 +#define C_Gains_SDTM_ADDR_END 303 +#define C_Gains_SDTM_sizeof 2 + +#define C_Gains_VxRecM_ADDR 304 +#define C_Gains_VxRecM_ADDR_END 307 +#define C_Gains_VxRecM_sizeof 4 + +#define C_Gains_ULM_ADDR 308 +#define C_Gains_ULM_ADDR_END 311 +#define C_Gains_ULM_sizeof 4 + +#define C_SDT_Coefs_ADDR 312 +#define C_SDT_Coefs_ADDR_END 328 +#define C_SDT_Coefs_sizeof 17 + +#define C_MM96_F_Coefs_ADDR 329 +#define C_MM96_F_Coefs_ADDR_END 345 +#define C_MM96_F_Coefs_sizeof 17 + +#define C_DMIC0_96F_Coefs_ADDR 346 +#define C_DMIC0_96F_Coefs_ADDR_END 362 +#define C_DMIC0_96F_Coefs_sizeof 17 + +#define C_DMIC_96_48_Coefs_ADDR 363 +#define C_DMIC_96_48_Coefs_ADDR_END 379 +#define C_DMIC_96_48_Coefs_sizeof 17 + +#define C_AMIC_96_48_Coefs_ADDR 380 +#define C_AMIC_96_48_Coefs_ADDR_END 396 +#define C_AMIC_96_48_Coefs_sizeof 17 + +#define C_AMIC_EQ_Coefs_ADDR 397 +#define C_AMIC_EQ_Coefs_ADDR_END 413 +#define C_AMIC_EQ_Coefs_sizeof 17 + +#define C_DMIC1_EQ_Coefs_ADDR 414 +#define C_DMIC1_EQ_Coefs_ADDR_END 430 +#define C_DMIC1_EQ_Coefs_sizeof 17 + +#define C_DMIC2_EQ_Coefs_ADDR 431 +#define C_DMIC2_EQ_Coefs_ADDR_END 447 +#define C_DMIC2_EQ_Coefs_sizeof 17 + +#define C_DMIC3_EQ_Coefs_ADDR 448 +#define C_DMIC3_EQ_Coefs_ADDR_END 464 +#define C_DMIC3_EQ_Coefs_sizeof 17 + +#define C_Voice_F_Coefs_ADDR 465 +#define C_Voice_F_Coefs_ADDR_END 481 +#define C_Voice_F_Coefs_sizeof 17 + +#define C_CoefASRC1_UL_VX_ADDR 482 +#define C_CoefASRC1_UL_VX_ADDR_END 500 +#define C_CoefASRC1_UL_VX_sizeof 19 + +#define C_CoefASRC2_UL_VX_ADDR 501 +#define C_CoefASRC2_UL_VX_ADDR_END 519 +#define C_CoefASRC2_UL_VX_sizeof 19 + +#define C_CoefASRC3_UL_VX_ADDR 520 +#define C_CoefASRC3_UL_VX_ADDR_END 538 +#define C_CoefASRC3_UL_VX_sizeof 19 + +#define C_CoefASRC4_UL_VX_ADDR 539 +#define C_CoefASRC4_UL_VX_ADDR_END 557 +#define C_CoefASRC4_UL_VX_sizeof 19 + +#define C_CoefASRC5_UL_VX_ADDR 558 +#define C_CoefASRC5_UL_VX_ADDR_END 576 +#define C_CoefASRC5_UL_VX_sizeof 19 + +#define C_CoefASRC6_UL_VX_ADDR 577 +#define C_CoefASRC6_UL_VX_ADDR_END 595 +#define C_CoefASRC6_UL_VX_sizeof 19 + +#define C_CoefASRC7_UL_VX_ADDR 596 +#define C_CoefASRC7_UL_VX_ADDR_END 614 +#define C_CoefASRC7_UL_VX_sizeof 19 + +#define C_CoefASRC8_UL_VX_ADDR 615 +#define C_CoefASRC8_UL_VX_ADDR_END 633 +#define C_CoefASRC8_UL_VX_sizeof 19 + +#define C_CoefASRC9_UL_VX_ADDR 634 +#define C_CoefASRC9_UL_VX_ADDR_END 652 +#define C_CoefASRC9_UL_VX_sizeof 19 + +#define C_CoefASRC10_UL_VX_ADDR 653 +#define C_CoefASRC10_UL_VX_ADDR_END 671 +#define C_CoefASRC10_UL_VX_sizeof 19 + +#define C_CoefASRC11_UL_VX_ADDR 672 +#define C_CoefASRC11_UL_VX_ADDR_END 690 +#define C_CoefASRC11_UL_VX_sizeof 19 + +#define C_CoefASRC12_UL_VX_ADDR 691 +#define C_CoefASRC12_UL_VX_ADDR_END 709 +#define C_CoefASRC12_UL_VX_sizeof 19 + +#define C_CoefASRC13_UL_VX_ADDR 710 +#define C_CoefASRC13_UL_VX_ADDR_END 728 +#define C_CoefASRC13_UL_VX_sizeof 19 + +#define C_CoefASRC14_UL_VX_ADDR 729 +#define C_CoefASRC14_UL_VX_ADDR_END 747 +#define C_CoefASRC14_UL_VX_sizeof 19 + +#define C_CoefASRC15_UL_VX_ADDR 748 +#define C_CoefASRC15_UL_VX_ADDR_END 766 +#define C_CoefASRC15_UL_VX_sizeof 19 + +#define C_CoefASRC16_UL_VX_ADDR 767 +#define C_CoefASRC16_UL_VX_ADDR_END 785 +#define C_CoefASRC16_UL_VX_sizeof 19 + +#define C_AlphaCurrent_UL_VX_ADDR 786 +#define C_AlphaCurrent_UL_VX_ADDR_END 786 +#define C_AlphaCurrent_UL_VX_sizeof 1 + +#define C_BetaCurrent_UL_VX_ADDR 787 +#define C_BetaCurrent_UL_VX_ADDR_END 787 +#define C_BetaCurrent_UL_VX_sizeof 1 + +#define C_CoefASRC1_DL_VX_ADDR 788 +#define C_CoefASRC1_DL_VX_ADDR_END 806 +#define C_CoefASRC1_DL_VX_sizeof 19 + +#define C_CoefASRC2_DL_VX_ADDR 807 +#define C_CoefASRC2_DL_VX_ADDR_END 825 +#define C_CoefASRC2_DL_VX_sizeof 19 + +#define C_CoefASRC3_DL_VX_ADDR 826 +#define C_CoefASRC3_DL_VX_ADDR_END 844 +#define C_CoefASRC3_DL_VX_sizeof 19 + +#define C_CoefASRC4_DL_VX_ADDR 845 +#define C_CoefASRC4_DL_VX_ADDR_END 863 +#define C_CoefASRC4_DL_VX_sizeof 19 + +#define C_CoefASRC5_DL_VX_ADDR 864 +#define C_CoefASRC5_DL_VX_ADDR_END 882 +#define C_CoefASRC5_DL_VX_sizeof 19 + +#define C_CoefASRC6_DL_VX_ADDR 883 +#define C_CoefASRC6_DL_VX_ADDR_END 901 +#define C_CoefASRC6_DL_VX_sizeof 19 + +#define C_CoefASRC7_DL_VX_ADDR 902 +#define C_CoefASRC7_DL_VX_ADDR_END 920 +#define C_CoefASRC7_DL_VX_sizeof 19 + +#define C_CoefASRC8_DL_VX_ADDR 921 +#define C_CoefASRC8_DL_VX_ADDR_END 939 +#define C_CoefASRC8_DL_VX_sizeof 19 + +#define C_CoefASRC9_DL_VX_ADDR 940 +#define C_CoefASRC9_DL_VX_ADDR_END 958 +#define C_CoefASRC9_DL_VX_sizeof 19 + +#define C_CoefASRC10_DL_VX_ADDR 959 +#define C_CoefASRC10_DL_VX_ADDR_END 977 +#define C_CoefASRC10_DL_VX_sizeof 19 + +#define C_CoefASRC11_DL_VX_ADDR 978 +#define C_CoefASRC11_DL_VX_ADDR_END 996 +#define C_CoefASRC11_DL_VX_sizeof 19 + +#define C_CoefASRC12_DL_VX_ADDR 997 +#define C_CoefASRC12_DL_VX_ADDR_END 1015 +#define C_CoefASRC12_DL_VX_sizeof 19 + +#define C_CoefASRC13_DL_VX_ADDR 1016 +#define C_CoefASRC13_DL_VX_ADDR_END 1034 +#define C_CoefASRC13_DL_VX_sizeof 19 + +#define C_CoefASRC14_DL_VX_ADDR 1035 +#define C_CoefASRC14_DL_VX_ADDR_END 1053 +#define C_CoefASRC14_DL_VX_sizeof 19 + +#define C_CoefASRC15_DL_VX_ADDR 1054 +#define C_CoefASRC15_DL_VX_ADDR_END 1072 +#define C_CoefASRC15_DL_VX_sizeof 19 + +#define C_CoefASRC16_DL_VX_ADDR 1073 +#define C_CoefASRC16_DL_VX_ADDR_END 1091 +#define C_CoefASRC16_DL_VX_sizeof 19 + +#define C_AlphaCurrent_DL_VX_ADDR 1092 +#define C_AlphaCurrent_DL_VX_ADDR_END 1092 +#define C_AlphaCurrent_DL_VX_sizeof 1 + +#define C_BetaCurrent_DL_VX_ADDR 1093 +#define C_BetaCurrent_DL_VX_ADDR_END 1093 +#define C_BetaCurrent_DL_VX_sizeof 1 + +#define C_CoefASRC1_DL_MM_ADDR 1094 +#define C_CoefASRC1_DL_MM_ADDR_END 1111 +#define C_CoefASRC1_DL_MM_sizeof 18 + +#define C_CoefASRC2_DL_MM_ADDR 1112 +#define C_CoefASRC2_DL_MM_ADDR_END 1129 +#define C_CoefASRC2_DL_MM_sizeof 18 + +#define C_CoefASRC3_DL_MM_ADDR 1130 +#define C_CoefASRC3_DL_MM_ADDR_END 1147 +#define C_CoefASRC3_DL_MM_sizeof 18 + +#define C_CoefASRC4_DL_MM_ADDR 1148 +#define C_CoefASRC4_DL_MM_ADDR_END 1165 +#define C_CoefASRC4_DL_MM_sizeof 18 + +#define C_CoefASRC5_DL_MM_ADDR 1166 +#define C_CoefASRC5_DL_MM_ADDR_END 1183 +#define C_CoefASRC5_DL_MM_sizeof 18 + +#define C_CoefASRC6_DL_MM_ADDR 1184 +#define C_CoefASRC6_DL_MM_ADDR_END 1201 +#define C_CoefASRC6_DL_MM_sizeof 18 + +#define C_CoefASRC7_DL_MM_ADDR 1202 +#define C_CoefASRC7_DL_MM_ADDR_END 1219 +#define C_CoefASRC7_DL_MM_sizeof 18 + +#define C_CoefASRC8_DL_MM_ADDR 1220 +#define C_CoefASRC8_DL_MM_ADDR_END 1237 +#define C_CoefASRC8_DL_MM_sizeof 18 + +#define C_CoefASRC9_DL_MM_ADDR 1238 +#define C_CoefASRC9_DL_MM_ADDR_END 1255 +#define C_CoefASRC9_DL_MM_sizeof 18 + +#define C_CoefASRC10_DL_MM_ADDR 1256 +#define C_CoefASRC10_DL_MM_ADDR_END 1273 +#define C_CoefASRC10_DL_MM_sizeof 18 + +#define C_CoefASRC11_DL_MM_ADDR 1274 +#define C_CoefASRC11_DL_MM_ADDR_END 1291 +#define C_CoefASRC11_DL_MM_sizeof 18 + +#define C_CoefASRC12_DL_MM_ADDR 1292 +#define C_CoefASRC12_DL_MM_ADDR_END 1309 +#define C_CoefASRC12_DL_MM_sizeof 18 + +#define C_CoefASRC13_DL_MM_ADDR 1310 +#define C_CoefASRC13_DL_MM_ADDR_END 1327 +#define C_CoefASRC13_DL_MM_sizeof 18 + +#define C_CoefASRC14_DL_MM_ADDR 1328 +#define C_CoefASRC14_DL_MM_ADDR_END 1345 +#define C_CoefASRC14_DL_MM_sizeof 18 + +#define C_CoefASRC15_DL_MM_ADDR 1346 +#define C_CoefASRC15_DL_MM_ADDR_END 1363 +#define C_CoefASRC15_DL_MM_sizeof 18 + +#define C_CoefASRC16_DL_MM_ADDR 1364 +#define C_CoefASRC16_DL_MM_ADDR_END 1381 +#define C_CoefASRC16_DL_MM_sizeof 18 + +#define C_AlphaCurrent_DL_MM_ADDR 1382 +#define C_AlphaCurrent_DL_MM_ADDR_END 1382 +#define C_AlphaCurrent_DL_MM_sizeof 1 + +#define C_BetaCurrent_DL_MM_ADDR 1383 +#define C_BetaCurrent_DL_MM_ADDR_END 1383 +#define C_BetaCurrent_DL_MM_sizeof 1 + +#define C_DL2_L_Coefs_ADDR 1384 +#define C_DL2_L_Coefs_ADDR_END 1408 +#define C_DL2_L_Coefs_sizeof 25 + +#define C_DL2_R_Coefs_ADDR 1409 +#define C_DL2_R_Coefs_ADDR_END 1433 +#define C_DL2_R_Coefs_sizeof 25 + +#define C_DL1_Coefs_ADDR 1434 +#define C_DL1_Coefs_ADDR_END 1458 +#define C_DL1_Coefs_sizeof 25 + +#define C_48_96_LP0_Coefs_ADDR 1459 +#define C_48_96_LP0_Coefs_ADDR_END 1471 +#define C_48_96_LP0_Coefs_sizeof 13 + +#define C_48_96_LP1_Coefs_ADDR 1472 +#define C_48_96_LP1_Coefs_ADDR_END 1486 +#define C_48_96_LP1_Coefs_sizeof 15 + +#define C_VX_8_48_BP_Coefs_ADDR 1487 +#define C_VX_8_48_BP_Coefs_ADDR_END 1499 +#define C_VX_8_48_BP_Coefs_sizeof 13 + +#define C_VX_8_48_LP_Coefs_ADDR 1500 +#define C_VX_8_48_LP_Coefs_ADDR_END 1512 +#define C_VX_8_48_LP_Coefs_sizeof 13 + +#define C_VX_48_8_LP_Coefs_ADDR 1513 +#define C_VX_48_8_LP_Coefs_ADDR_END 1525 +#define C_VX_48_8_LP_Coefs_sizeof 13 + +#define C_VX_16_48_HP_Coefs_ADDR 1526 +#define C_VX_16_48_HP_Coefs_ADDR_END 1532 +#define C_VX_16_48_HP_Coefs_sizeof 7 + +#define C_VX_16_48_LP_Coefs_ADDR 1533 +#define C_VX_16_48_LP_Coefs_ADDR_END 1545 +#define C_VX_16_48_LP_Coefs_sizeof 13 + +#define C_VX_48_16_LP_Coefs_ADDR 1546 +#define C_VX_48_16_LP_Coefs_ADDR_END 1558 +#define C_VX_48_16_LP_Coefs_sizeof 13 + +#define C_EANC_WarpCoeffs_ADDR 1559 +#define C_EANC_WarpCoeffs_ADDR_END 1560 +#define C_EANC_WarpCoeffs_sizeof 2 + +#define C_EANC_FIRcoeffs_ADDR 1561 +#define C_EANC_FIRcoeffs_ADDR_END 1581 +#define C_EANC_FIRcoeffs_sizeof 21 + +#define C_EANC_IIRcoeffs_ADDR 1582 +#define C_EANC_IIRcoeffs_ADDR_END 1598 +#define C_EANC_IIRcoeffs_sizeof 17 + +#define C_APS_coeffs1_ADDR 1599 +#define C_APS_coeffs1_ADDR_END 1607 +#define C_APS_coeffs1_sizeof 9 + +#define C_APS_coeffs2_ADDR 1608 +#define C_APS_coeffs2_ADDR_END 1610 +#define C_APS_coeffs2_sizeof 3 + +#define C_APS_DL2_L_coeffs1_ADDR 1611 +#define C_APS_DL2_L_coeffs1_ADDR_END 1619 +#define C_APS_DL2_L_coeffs1_sizeof 9 + +#define C_APS_DL2_R_coeffs1_ADDR 1620 +#define C_APS_DL2_R_coeffs1_ADDR_END 1628 +#define C_APS_DL2_R_coeffs1_sizeof 9 + +#define C_APS_DL2_L_coeffs2_ADDR 1629 +#define C_APS_DL2_L_coeffs2_ADDR_END 1631 +#define C_APS_DL2_L_coeffs2_sizeof 3 + +#define C_APS_DL2_R_coeffs2_ADDR 1632 +#define C_APS_DL2_R_coeffs2_ADDR_END 1634 +#define C_APS_DL2_R_coeffs2_sizeof 3 + +#define C_AlphaCurrent_ECHO_REF_ADDR 1635 +#define C_AlphaCurrent_ECHO_REF_ADDR_END 1635 +#define C_AlphaCurrent_ECHO_REF_sizeof 1 + +#define C_BetaCurrent_ECHO_REF_ADDR 1636 +#define C_BetaCurrent_ECHO_REF_ADDR_END 1636 +#define C_BetaCurrent_ECHO_REF_sizeof 1 + +#define C_APS_DL1_EQ_ADDR 1637 +#define C_APS_DL1_EQ_ADDR_END 1645 +#define C_APS_DL1_EQ_sizeof 9 + +#define C_APS_DL2_L_EQ_ADDR 1646 +#define C_APS_DL2_L_EQ_ADDR_END 1654 +#define C_APS_DL2_L_EQ_sizeof 9 + +#define C_APS_DL2_R_EQ_ADDR 1655 +#define C_APS_DL2_R_EQ_ADDR_END 1663 +#define C_APS_DL2_R_EQ_sizeof 9 + + +#endif /* _ABECM_ADDR_H_ */ diff --git a/sound/soc/codecs/abe/abe_dat.h b/sound/soc/codecs/abe/abe_dat.h new file mode 100644 index 000000000000..a8e546225bd3 --- /dev/null +++ b/sound/soc/codecs/abe/abe_dat.h @@ -0,0 +1,620 @@ +/* + * 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_DAT.H + * + * All the visible API for the audio drivers + * + * @path + * @rev 01.00 + *! + *! Revision History + *! 27-Nov-2008 Original (LLF) + *! 05-Jun-2009 V05 release + */ + + +#ifndef __abe_dat_def_ +#define __abe_dat_def_ + +/* + * Call-backs + */ +/* 2 parameters subroutine pointers */ +abe_subroutine2 callbacks [MAXCALLBACK]; + + + +/* + * HAL/FW ports status / format / sampling / protocol(call_back) / features / + * gain / name + */ + + abe_port_t abe_port [MAXNBABEPORTS];/* list of ABE ports */ +const abe_port_t abe_port_init [MAXNBABEPORTS] ={ + +/* +* Status Data Format Drift Call-Back Protocol+selector +* desc_addr; buf_addr; buf_size; iter; thr_low; irq_addr rq_data DMA_T +* #Features reseted at start +* Port Name for the debug trace */ +/* DMIC1 */ +{ IDLE_P, + {96000, STEREO_MSB}, + NODRIFT, NOCALLBACK, + smem_dmic1, + 0, + {SNK_P, DMIC_PORT_PROT,{{dmem_dmic, dmem_dmic_size, DMIC_ITER}}}, + {0, 0}, + {EQDMIC1, 0}, + "DMIC_UL" +}, +/* DMIC2 */ +{ + IDLE_P, + {96000, STEREO_MSB}, + NODRIFT, NOCALLBACK, + smem_dmic2, + 0, + {SNK_P, DMIC_PORT_PROT, {{dmem_dmic, dmem_dmic_size, DMIC_ITER}}}, + {0, 0}, + {EQDMIC2, 0},"DMIC_UL" +}, +/* DMIC3 */ +{ + IDLE_P, + {96000, STEREO_MSB}, + NODRIFT, NOCALLBACK, + smem_dmic3, + 0, + {SNK_P, DMIC_PORT_PROT,{{dmem_dmic, dmem_dmic_size, DMIC_ITER}}}, + {0, 0}, + {EQDMIC3, 0}, + "DMIC_UL" +}, +/* 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}, + "AMIC_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, DEFAULT_THR_WRITE}}}, + {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, DEFAULT_THR_WRITE,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, DEFAULT_THR_WRITE, + 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, DEFAULT_THR_WRITE,ABE_DMASTATUS_RAW, + (1<<2)}}}, + {CIRCULAR_BUFFER_PERIPHERAL_R__2, 4}, + {ASRC2, 0}, + "VX_UL" +}, +/* MM_DL */ +{ + IDLE_P, + {48000, STEREO_MSB}, + NODRIFT, NOCALLBACK, + smem_mm_dl, + 0, + {SNK_P, DMAREQ_PORT_PROT, + {{CBPr_DMA_RTX0*ATC_SIZE,dmem_mm_dl,dmem_mm_dl_size, + 2 * SCHED_LOOP_48kHz, DEFAULT_THR_READ , + 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, DEFAULT_THR_READ ,ABE_DMASTATUS_RAW, + (1<<1)}}}, + {CIRCULAR_BUFFER_PERIPHERAL_R__1, 4}, + {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, DEFAULT_THR_READ ,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, DEFAULT_THR_READ ,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, DEFAULT_THR_WRITE}}}, + {0, 0}, + {0}, + "BT_VX_DL" +}, +/* PDM_DL1 */ +{ + IDLE_P, + {96000, STEREO_MSB}, + NODRIFT, NOCALLBACK, + 0, + 0, + {SRC_P, MCPDMDL_PORT_PROT, {{dmem_mcpdm, dmem_mcpdm_size}}}, + {0, 0}, + {MIXDL1, EQ1, APS1, 0}, + "PDM_DL1" +}, +/* MM_EXT_OUT*/ +{ + IDLE_P, + {48000, STEREO_MSB}, + NODRIFT, + NOCALLBACK, + smem_mm_ext_out, + 0, + {SRC_P, SERIAL_PORT_PROT, + {{MCBSP1_DMA_RX*ATC_SIZE,dmem_mm_ext_out,dmem_mm_ext_out_size, + 2 * SCHED_LOOP_48kHz, DEFAULT_THR_WRITE}}}, + {0, 0}, + {0}, + "MM_EXT_OUT" +}, +/* PDM_DL2 */ +{ + IDLE_P, + {96000, STEREO_MSB}, + NODRIFT, + NOCALLBACK, + 0, + 0, + {SRC_P, MCPDMDL_PORT_PROT,{{0,0,0,0,0,0,0}}}, + {0, 0}, + {MIXDL2, EQ2L, APS2L, EQ2R, APS2R, 0}, + "PDM_DL2" +}, +/* PDM_VIB */ +{ + IDLE_P, + {24000, STEREO_MSB}, + NODRIFT, NOCALLBACK, + 0, + 0, + {SRC_P, MCPDMDL_PORT_PROT, {{0,0,0,0,0,0,0}}}, + {0, 0}, + {0}, + "PDM_VIB" +}, +/* SCHD_DBG_PORT*/ +{ + RUN_P, + { 8000, MONO_MSB}, + NODRIFT, + NOCALLBACK, + 0, + 0, + {0, 0,{{0,0,0,0,0,0,0}}}, + {0, 0}, + {SEQUENCE, CONTROL, GAINS, 0}, + "SCHD_DBG" +}, +}; + +/* + * Firmware features + */ + abe_feature_t all_feature [MAXNBFEATURE]; +const abe_feature_t all_feature_init [] = { + +/* ON_reset OFF READ WRITE + STATUS INPUT OUTPUT SLOT/S OPP NAME */ +/* EQ1 */ +{ + c_feat_init_eq, c_feat_init_eq, c_feat_read_eq1, c_write_eq1, 0, + 0x1000, 0x1010, 2, 0, 1,"DLEQ1" +}, /* equalizer downlink path headset + earphone */ +/* EQ2L */ +{ + c_feat_init_eq, c_feat_init_eq, c_feat_read_eq2, c_write_eq2, 0, + 0x1000, 0x1010, 2, 0, 1, " DLEQ2L" +}, /* equalizer downlink path integrated handsfree LEFT */ +/* EQ2R */ +{ + c_feat_init_eq, c_feat_init_eq, c_feat_read_eq3, c_write_eq3, 0, + 0x1000, 0x1010, 2, 0, 1, " DLEQ2R" +}, /* equalizer downlink path integrated handsfree RIGHT */ +/* EQSDT */ +{ + c_feat_init_eq, c_feat_init_eq, c_feat_read_eq3, c_write_eq3, 0, + 0x1000, 0x1010, 2, 0, 1, " DLEQ3" +}, /* equalizer downlink path side-tone */ +/* EQDMIC1 */ +{ + c_feat_init_eq, c_feat_init_eq, c_feat_read_eq3, c_write_eq3, 0, + 0x1000, 0x1010, 2, 0, 1, " DLEQ3" +}, /* SRC+equalizer uplink DMIC 1st pair */ +/* EQDMIC2 */ +{ + c_feat_init_eq, c_feat_init_eq, c_feat_read_eq3, c_write_eq3, 0, + 0x1000, 0x1010, 2, 0, 1, " DLEQ3" +}, /* SRC+equalizer uplink DMIC 2nd pair */ +/* EQDMIC3 */ +{ + c_feat_init_eq, c_feat_init_eq, c_feat_read_eq3, c_write_eq3, 0, + 0x1000, 0x1010, 2, 0, 1, " DLEQ3" +}, /* SRC+equalizer uplink DMIC 3rd pair */ +/* EQAMIC */ +{ + c_feat_init_eq, c_feat_init_eq, c_feat_read_eq3, c_write_eq3, 0, + 0x1000, 0x1010, 2, 0, 1, " DLEQ3" +}, /* SRC+equalizer uplink AMIC */ +/* APS1 */ +{ + c_feat_init_eq, c_feat_init_eq, c_feat_read_eq3, c_write_eq3, 0, + 0x1000, 0x1010, 2, 0, 1, " DLEQ3" +}, /* Acoustic protection for headset */ +/* APS2 */ +{ + c_feat_init_eq, c_feat_init_eq, c_feat_read_eq3, c_write_eq3, 0, + 0x1000, 0x1010, 2, 0, 1, " DLEQ3" +}, /* acoustic protection high-pass filter for handsfree "Left" */ +/* APS3 */ +{ + c_feat_init_eq, c_feat_init_eq, c_feat_read_eq3, c_write_eq3, 0, + 0x1000, 0x1010, 2, 0, 1, " DLEQ3" +}, /* acoustic protection high-pass filter for handsfree "Right" */ +/* ASRC1 */ +{ + c_feat_init_eq, c_feat_init_eq, c_feat_read_eq3, c_write_eq3, 0, + 0x1000, 0x1010, 2, 0, 1, " DLEQ3" +}, /* asynchronous sample-rate-converter for the downlink voice path */ +/* ASRC2 */ +{ + c_feat_init_eq, c_feat_init_eq, c_feat_read_eq3, c_write_eq3, 0, + 0x1000, 0x1010, 2, 0, 1, " DLEQ3" +}, /* asynchronous sample-rate-converter for the uplink voice path */ +/* ASRC3 */ +{ + c_feat_init_eq, c_feat_init_eq, c_feat_read_eq3, c_write_eq3, 0, + 0x1000, 0x1010, 2, 0, 1, " DLEQ3" +}, /* asynchronous sample-rate-converter for the multimedia player */ +/* MXDL1 */ +{ + c_feat_init_eq, c_feat_init_eq, c_feat_read_eq3, c_write_eq3, 0, + 0x1000, 0x1010, 2, 0, 1, " DLEQ3" +}, /* mixer of the headset and earphone path */ +/* MXDL2 */ +{ + c_feat_init_eq, c_feat_init_eq, c_feat_read_eq3, c_write_eq3, 0, + 0x1000, 0x1010, 2, 0, 1, " DLEQ3" +}, /* mixer of the hands-free path */ +/* MXSDT */ +{ + c_feat_init_eq, c_feat_init_eq, c_feat_read_eq3, c_write_eq3, 0, + 0x1000, 0x1010, 2, 0, 1, " DLEQ3" +}, /* mixer for side-tone */ +/* MXECHO */ +{ + c_feat_init_eq, c_feat_init_eq, c_feat_read_eq3, c_write_eq3, 0, + 0x1000, 0x1010, 2, 0, 1, " DLEQ3" +}, /* mixer for echo reference */ +/* UPROUTE */ +{ + c_feat_init_eq, c_feat_init_eq, c_feat_read_eq3, c_write_eq3, 0, + 0x1000, 0x1010, 2, 0, 1, " DLEQ3" +}, /* router of the uplink path */ +/* GAINS */ +{ + c_feat_init_eq, c_feat_init_eq, c_feat_read_eq3, c_write_eq3, 0, + 0x1000, 0x1010, 2, 0, 1, " DLEQ3" +}, /* all gains */ +/* EANC */ +{ + c_feat_init_eq, c_feat_init_eq, c_feat_read_eq3, c_write_eq3, 0, + 0x1000, 0x1010, 2, 0, 1, " DLEQ3" +}, /* active noise canceller */ +/* VIB1 */ +{ + c_feat_init_eq, c_feat_init_eq, c_feat_read_eq3, c_write_eq3, 0, + 0x1000, 0x1010, 2, 0, 1, " DLEQ3" +}, /* noise shaper of the Vibra1 path */ +/* GAINS */ +{ + c_feat_init_eq, c_feat_init_eq, c_feat_read_eq3, c_write_eq3, 0, + 0x1000, 0x1010, 2, 0, 1, " DLEQ3" +}, /* all gains */ +/* SEQ */ +{ + c_feat_init_eq, c_feat_init_eq, c_feat_read_eq3, c_write_eq3, 0, + 0x1000, 0x1010, 2, 0, 1, " DLEQ3" +}, /* sequencing queue of micro tasks */ +/* CTL */ +{ + c_feat_init_eq, c_feat_init_eq, c_feat_read_eq3, c_write_eq3, 0, + 0x1000, 0x1010, 2, 0, 1, " DLEQ3" +}, /* Phoenix control queue through McPDM */ +}; + + +/* + * table indexed by the PORT_ID and returning the index to the D_IODescr table + * of structures + */ +const abe_uint32 sio_task_index [LAST_PORT_ID] = +{ + /* AE sink ports - Uplink */ + 7, /* DMIC_PORT - specific protocol */ + 7, /* DMIC_PORT - specific protocol */ + 7, /* DMIC_PORT - specific protocol */ + 8, /* PDM_UL_PORT - specific protocol */ + 14, /* BT_VX_UL_PORT BT uplink */ + + /* AE source ports - Uplink */ + 3, /* MM_UL_PORT up to 5 stereo channels */ + 4, /* MM_UL2_PORT stereo FM record path */ + 2, /* VX_UL_PORT stereo FM record path */ + + /* AE sink ports - Downlink */ + 0, /* MM_DL_PORT multimedia player audio path */ + 1, /* VX_DL_PORT */ + 5, /* TONES_DL_PORT */ + 6, /* VIB_DL_PORT */ + + /* AE source ports - Downlink */ + 13, /* BT_VX_DL_PORT */ + 9, /* PDM_DL1_PORT */ + 12, /* MM_EXT_OUT_PORT */ + 10, /* PDM_DL2_PORT */ + 11, /* PDM_VIB_PORT */ + + SCHD_DBG_PORT /* dummy port used to declare the other tasks of + the scheduler */ + +}; + + +/* + * ports memory config with largest buffer allocated to the audio player-- + */ + const abe_uint32 abe_map_dmem_init_1 [] = { /* DMEM port map for the case #1*/ + /* AMIC_UL_PORT */ 0x800, + /* DMIC_UL_PORT */ 0x820, + /* CTRL_PORT */ 0x840, + /* BT_VX_UL_PORT */ 0x880, + /* BT_VX_DL_PORT */ 0x8c0, + /* EANC_REF_PORT */ 0x900, + /* ECHOREF_UL_PORT */ 0x940, + /* MM_DL_PORT */ 0x980, + /* MM_UL_PORT */ 0x9c0, + /* MM_EXT_OUT_PORT */ 0x1000, + /* MM_EXT_DL_PORT */ 0x1001, + /* MM_EXT_UL_PORT */ 0x1002, + /* MM_VX_DL_PORT */ 0x1003, + /* MM_IHF_DL_PORT */ 0x1004, + /* TONES_PORT */ 0x1005, + /* VIB1_DL_PORT */ 0x1006, + /* VIB2_DL_PORT */ 0x1007, + /* VX_REC_PORT */ 0x1008, + /* VX_DL_PORT */ 0x1009, + /* VX_UL_PORT */ 0x100a, + /* PDM_DL1 */ 0x1009, + /* PDM_DL2 */ 0x100a, +}; +const abe_uint32 abe_map_dmem_size_init_1 [] = { + /* DMEM port buffer sizes for the case #1*/ + /* AMIC_UL_PORT */ 0x10, + /* DMIC_UL_PORT */ 0x10, + /* CTRL_PORT */ 0x10, + /* BT_VX_UL_PORT */ 0x10, + /* BT_VX_DL_PORT */ 0x10, + /* EANC_REF_PORT */ 0x10, + /* ECHOREF_UL_PORT */ 0x10, + /* MM_DL_PORT */ 0x10, + /* MM_UL_PORT */ 0x10, + /* MM_EXT_OUT_PORT */ 0x10, + /* MM_EXT_DL_PORT */ 0x10, + /* MM_EXT_UL_PORT */ 0x10, + /* MM_VX_DL_PORT */ 0x10, + /* MM_IHF_DL_PORT */ 0x10, + /* TONES_PORT */ 0x10, + /* VIB1_DL_PORT */ 0x10, + /* VIB2_DL_PORT */ 0x10, + /* VX_REC_PORT */ 0x10, + /* VX_DL_PORT */ 0x10, + /* VX_UL_PORT */ 0x10, + /* PDM_DL1 */ 0x10, + /* PDM_DL2 */ 0x10, +}; + +/* + * MEMORY MAPPING OF THE 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 + */ + + /* VX_UL, MM_UL2 and MM_UL router */ + abe_router_t abe_router_ul_table [NBROUTE_UL]; +const abe_router_t abe_router_ul_table_init_1 [NBROUTE_UL] = +{ + ZERO_labelID, ZERO_labelID, ZERO_labelID, ZERO_labelID, /* 0 .. 3 */ + ZERO_labelID, ZERO_labelID, ZERO_labelID, ZERO_labelID, /* 4 .. 7 */ + ZERO_labelID, ZERO_labelID, ZERO_labelID, ZERO_labelID, /* 8 .. 11 */ + AMIC_L_labelID, AMIC_R_labelID, ZERO_labelID, ZERO_labelID, /* 12 15 */ +}; + +/* + * ABE_GLOBAL DATA ------------------------------------------------------------ + */ + +/* flag, indicates the allowed control of Phoenix through McPDM slot #6 */ +abe_uint32 abe_global_mcpdm_control; + +/* + * ABE_DEBUG DATA ------------------------------------------------------------- + */ + +/* + * 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]; + +#endif // abe_dat_def diff --git a/sound/soc/codecs/abe/abe_dbg.c b/sound/soc/codecs/abe/abe_dbg.c new file mode 100644 index 000000000000..da010ac5ddb0 --- /dev/null +++ b/sound/soc/codecs/abe/abe_dbg.c @@ -0,0 +1,111 @@ +/* + * 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_DBG.C + * + * 'ABE_DBG.C' interface to the remote debugger and local debug features + * + * @path + * @rev 01.00 + *! Revision History + *! =================================== + *! 27-Nov-2008 Original + *! 05-Jun-2009 V05 release + */ + + +#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_microsecond 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) +{ +} + + +/* + * ABE_DBG_ERROR_LOG + * + * Parameter : + * x : d + * + * Operations : + * log the error codes + * + * Return value : + * + */ +void abe_dbg_error_log (abe_uint32 x) +{ +} + + +/* + * ABE_DEBUGGER + * + * Parameter : + * x : d + * + * Operations : + * + * + * Return value : + * + */ +void abe_debugger (abe_uint32 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..d4ba27eabd63 --- /dev/null +++ b/sound/soc/codecs/abe/abe_dbg.h @@ -0,0 +1,196 @@ +/* +* 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_DBG.H + * + * 'ABE_DBG.H' global data definitions for debug + * + * @path + * @rev 01.00 + *! + *! Revision History + *! =================================== + *! 27-Nov-2008 Original (LLF) + *! 05-Jun-2009 V05 release + */ +#ifndef __ABE_DBG_H_ +#define __ABE_DBG_H_ + +#include "abe_main.h" + +/* generates the time-stamps used for the AESS verification */ +#define HAL_TIME_STAMP 0 + +/* pipe connection to the TARGET simulator */ +#define ABE_DEBUG_CHECKERS 0 +/* simulator data extracted from a text-file */ +#define ABE_DEBUG_HWFILE 0 +/* low-level log files */ +#define ABE_DEBUG_LL_LOG 0 + +#define ABE_DEBUG (ABE_DEBUG_CHECKERS | ABE_DEBUG_HWFILE | ABE_DEBUG_LL_LOG) + +#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_external_data_access 1 +#define dbg_mdata (1L << (dbg_external_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) +/* port programmed while still running */ +#define ABE_PORT_REPROGRAMMING (8 + 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 + */ + + +#if 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); + +#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..64b482ba98da --- /dev/null +++ b/sound/soc/codecs/abe/abe_def.h @@ -0,0 +1,276 @@ +/* + * 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_DEF.H + * + * Constants definitions + * + * @path + * @rev 01.00 + *! + *! Revision History + *! 27-Nov-2008 Original (LLF) + *! 05-Jun-2009 V05 release + */ + +#ifndef __ABEDEF_ +#define __ABEDEF_ + +/* + * 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_ABE_REVISION 0x00 +/* revision number */ +#define ABE_DUMMY_ADDRESS ABE_ABE_REVISION +/* used as dummy register for generic IO tasks */ +#define ABE_MCU_IRQSTATUS_RAW 0x24 +/* holds the MCU Irq signal */ +#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 2046 +/* see computation in "abe_event_generator_switch" */ + +#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 */ + +#define ABE_DMAREQ_REGISTER(desc) \ +(abe_uint32 *)((desc/8) + CIRCULAR_BUFFER_PERIPHERAL_R__0) + + +#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) + + +/* + * DMA requests + */ +#define External_DMA_0 0 +#define DMIC_DMA_REQ 1 /*tx 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 - tx request*/ +#define MCBSP1_DMA_RX 5 /*MCBSP module 1 - rx request */ +#define MCBSP2_DMA_TX 6 /*MCBSP module 2 - tx request */ +#define MCBSP2_DMA_RX 7 /*MCBSP module 2 - rx request */ +#define MCBSP3_DMA_TX 8 /*MCBSP module 3 - tx request */ +#define MCBSP3_DMA_RX 9 /*MCBSP module 3 - rx request */ +#define SLIMBUS1_DMA_TX0 10 /*SLIMBUS mod1 - tx request channel 0 */ +#define SLIMBUS1_DMA_TX1 11 /*SLIMBUS mod1 - tx request channel 1 */ +#define SLIMBUS1_DMA_TX2 12 /*SLIMBUS mod1 - tx request channel 2 */ +#define SLIMBUS1_DMA_TX3 13 /*SLIMBUS mod1 - tx request channel 3 */ +#define SLIMBUS1_DMA_TX4 14 /*SLIMBUS mod1 - tx request channel 4 */ +#define SLIMBUS1_DMA_TX5 15 /*SLIMBUS mod1 - tx request channel 5 */ +#define SLIMBUS1_DMA_TX6 16 /*SLIMBUS mod1 - tx request channel 6 */ +#define SLIMBUS1_DMA_TX7 17 /*SLIMBUS mod1 - tx request channel 7 */ +#define SLIMBUS1_DMA_RX0 18 /*SLIMBUS mod1 - rx request channel 0 */ +#define SLIMBUS1_DMA_RX1 19 /*SLIMBUS mod1 - rx request channel 1 */ +#define SLIMBUS1_DMA_RX2 20 /*SLIMBUS mod1 - rx request channel 2 */ +#define SLIMBUS1_DMA_RX3 21 /*SLIMBUS mod1 - rx request channel 3 */ +#define SLIMBUS1_DMA_RX4 22 /*SLIMBUS mod1 - rx request channel 4 */ +#define SLIMBUS1_DMA_RX5 23 /*SLIMBUS mod1 - rx request channel 5 */ +#define SLIMBUS1_DMA_RX6 24 /*SLIMBUS mod1 - rx request channel 6 */ +#define SLIMBUS1_DMA_RX7 25 /*SLIMBUS mod1 - rx request channel 7 */ +#define McASP1_AXEVT 26 /*McASP - Data tx DMA request line */ +#define McASP1_AREVT 29 /*McASP - Data receive DMA req line */ +#define CBPr_DMA_RTX0 32 /*DMA of the Cbuf peripheral 0 */ +#define CBPr_DMA_RTX1 33 /*DMA of the Cbuf peripheral 1 */ +#define CBPr_DMA_RTX2 34 /*DMA of the Cbuf peripheral 2 */ +#define CBPr_DMA_RTX3 35 /*DMA of the Cbuf peripheral 3 */ +#define CBPr_DMA_RTX4 36 /*DMA of the Cbuf peripheral 4 */ +#define CBPr_DMA_RTX5 37 /*DMA of the Cbuf peripheral 5 */ +#define CBPr_DMA_RTX6 38 /*DMA of the Cbuf peripheral 6 */ +#define CBPr_DMA_RTX7 39 /*DMA of the Cbuf 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 + +/* + *INTERNAL DEFINITIONS + */ + +#define NBEANC1 20 /* 20 Q6.26 coef for the FIR */ +#define NBEANC2 16 /* 16 Q6.26 coef for the IIR */ + +#define NBEQ1 16 /* 16 Q6.26 coefficients */ +#define NBEQ2 8 /* 2x8 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 for send tones to the ul vx 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 */ +#define ABE_MAXNBGAIN_MIXER 4 + +#define NBROUTE_UL 16 /* nb of samples to route */ + +#define UC1_LP 1 /* MP3 low-power player use-case */ +#define UC2_VOICE_CALL_AND_IHF_MMDL 2 /* en vx ul/dl on ep + MM_DL on IHF */ +#define UC3_VOICE_CALL 3 /* basic voice-call use-case */ +#define UC4_EANC 4 /* EANC test */ + + +#define COPY_FROM_ABE_TO_HOST 1 /* ID used for LIB memory copy subroutines */ +#define COPY_FROM_HOST_TO_ABE 2 + +#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 MAXNBSEQUENCE 100 /* time controlled sequenced */ +#define MAXFEATUREPORT 8 /* max num of feature associated to a port */ + +#define NBCHARFEATURENAME 16 +#define NBCHARPORTNAME 16 +#define MAXNBABEPORTS LAST_PORT_ID +#define MAX_MAP_DMEM LAST_PORT_ID + +#define MAXLINESEQUENCE 32 + +#define SNK_P ABE_ATC_DIRECTION_IN +#define SRC_P ABE_ATC_DIRECTION_OUT + +#define NODRIFT 0 +#define GAIN_0dB 0 + +#define IDLE_P 1 +#define RUN_P 2 +#define NOCALLBACK 0 +#define NOPARAMETER 0 + +#define MCPDM_UL_ITER 2 +#define MCPDM_DL_ITER 6 +#define DMIC_ITER 6 + + +#define DEFAULT_THR_READ 1 +#define DEFAULT_THR_WRITE 1 + + +#define DEFAULT_CONTROL_MCPDMDL 1 + +/* + * 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)) + + +#endif /* ifndef ABEDEF */ diff --git a/sound/soc/codecs/abe/abe_define.h b/sound/soc/codecs/abe/abe_define.h new file mode 100644 index 000000000000..b6d0af3c5342 --- /dev/null +++ b/sound/soc/codecs/abe/abe_define.h @@ -0,0 +1,49 @@ +/* + * 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 24 +#define TASKS_IN_SLOT 4 +#define TASK_POOL_LENGTH 128 +#define MCU_IRQ 0x44 +#define DSP_IRQ 0x5c +#define DMA_REQ 0x84 +#define DCMD_FIFO_NUMBER 2 +#define DCMD_FIFO_LENGTH 8 +#define DEBUG_FIFO_LENGTH 16 +#define IRQ_FIFO_LENGTH 6 +#define SIGNAL_L_MF_COPIED 0x0010 +#define SIGNAL_L_MMDL_PP 0x0020 +#define IO_DESCR_NUMBER 19 +#define IO_DESCR_LIST_NELEM 4 +#define IO_DESCR_LIST_SIZE 6 +#define PING_PONG_NUMBER 8 +#define MAX_MM_BUFFERS 2 +#define DEBUG_BUF_LENGTH 32 +#define PHOENIX_FIFO_LENGTH 8 +#define EQUALIZATION_F_ORDER 8 +#define DEFAULT_FILTER_ORDER 8 +#define GAINS_WITH_RAMP 18 +#define GAINS_NO_RAMP 12 +#define McPDM_OUT_FIFO_LENGTH 18 +#define McPDM_IN_FIFO_LENGTH 127 +#define TASK_CLUSTER_NUMBER 4 +#define TASK_CLUSTER_LENGTH 8 +#define MASK_NB_PHASES 15 +#define EANC_IIR_MEMSIZE 17 +#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 EANC_IIR_MEMSIZE 17 + +#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..404f48e5146c --- /dev/null +++ b/sound/soc/codecs/abe/abe_dm_addr.h @@ -0,0 +1,292 @@ +/* + * 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 D_McPDM_UL_Fifo_ADDR 512 +#define D_McPDM_UL_Fifo_ADDR_END 1019 +#define D_McPDM_UL_Fifo_sizeof 508 + +#define D_McPDM_DL_Fifo_ADDR 1024 +#define D_McPDM_DL_Fifo_ADDR_END 1531 +#define D_McPDM_DL_Fifo_sizeof 508 + +#define D_DMIC_UL_Fifo_ADDR 1536 +#define D_DMIC_UL_Fifo_ADDR_END 2043 +#define D_DMIC_UL_Fifo_sizeof 508 + +#define D_MM_UL_FIFO_ADDR 2048 +#define D_MM_UL_FIFO_ADDR_END 2535 +#define D_MM_UL_FIFO_sizeof 488 + +#define D_MM_DL_ADDR 2560 +#define D_MM_DL_ADDR_END 2847 +#define D_MM_DL_sizeof 288 + +#define stack_ADDR 2848 +#define stack_ADDR_END 2975 +#define stack_sizeof 128 + +#define D_version_ADDR 2976 +#define D_version_ADDR_END 2979 +#define D_version_sizeof 4 + +#define D_tasksList_ADDR 2980 +#define D_tasksList_ADDR_END 4003 +#define D_tasksList_sizeof 1024 + +#define D_multiFrame_ADDR 4004 +#define D_multiFrame_ADDR_END 4195 +#define D_multiFrame_sizeof 192 + +#define D_nextMultiFrame_ADDR 4196 +#define D_nextMultiFrame_ADDR_END 4387 +#define D_nextMultiFrame_sizeof 192 + +#define D_taskClusters_ADDR 4388 +#define D_taskClusters_ADDR_END 4451 +#define D_taskClusters_sizeof 64 + +#define D_idleTask_ADDR 4452 +#define D_idleTask_ADDR_END 4453 +#define D_idleTask_sizeof 2 + +#define D_typeLengthCheck_ADDR 4454 +#define D_typeLengthCheck_ADDR_END 4455 +#define D_typeLengthCheck_sizeof 2 + +#define D_taskStep_ADDR 4456 +#define D_taskStep_ADDR_END 4459 +#define D_taskStep_sizeof 4 + +#define D_pCurrentTask_ADDR 4460 +#define D_pCurrentTask_ADDR_END 4461 +#define D_pCurrentTask_sizeof 2 + +#define D_pFastLoopBack_ADDR 4462 +#define D_pFastLoopBack_ADDR_END 4463 +#define D_pFastLoopBack_sizeof 2 + +#define D_pNextFastLoopBack_ADDR 4464 +#define D_pNextFastLoopBack_ADDR_END 4467 +#define D_pNextFastLoopBack_sizeof 4 + +#define D_ppCurrentTask_ADDR 4468 +#define D_ppCurrentTask_ADDR_END 4469 +#define D_ppCurrentTask_sizeof 2 + +#define D_loopCounter_ADDR 4470 +#define D_loopCounter_ADDR_END 4471 +#define D_loopCounter_sizeof 2 + +#define D_idleSlotsReq_ADDR 4472 +#define D_idleSlotsReq_ADDR_END 4473 +#define D_idleSlotsReq_sizeof 2 + +#define D_PostMcuIrq_ADDR 4476 +#define D_PostMcuIrq_ADDR_END 4479 +#define D_PostMcuIrq_sizeof 4 + +#define D_PostDspIrq_ADDR 4480 +#define D_PostDspIrq_ADDR_END 4483 +#define D_PostDspIrq_sizeof 4 + +#define D_McuIrqFifo_ADDR 4484 +#define D_McuIrqFifo_ADDR_END 4507 +#define D_McuIrqFifo_sizeof 24 + +#define D_DspIrqFifo_ADDR 4508 +#define D_DspIrqFifo_ADDR_END 4531 +#define D_DspIrqFifo_sizeof 24 + +#define D_McuIrqFifoDesc_ADDR 4532 +#define D_McuIrqFifoDesc_ADDR_END 4543 +#define D_McuIrqFifoDesc_sizeof 12 + +#define D_DspIrqFifoDesc_ADDR 4544 +#define D_DspIrqFifoDesc_ADDR_END 4555 +#define D_DspIrqFifoDesc_sizeof 12 + +#define D_debugFifo_ADDR 4556 +#define D_debugFifo_ADDR_END 4619 +#define D_debugFifo_sizeof 64 + +#define D_debugFifoDesc_ADDR 4620 +#define D_debugFifoDesc_ADDR_END 4631 +#define D_debugFifoDesc_sizeof 12 + +#define D_DCFifoDesc_ADDR 4632 +#define D_DCFifoDesc_ADDR_END 4655 +#define D_DCFifoDesc_sizeof 24 + +#define D_DCFifo_ADDR 4656 +#define D_DCFifo_ADDR_END 4847 +#define D_DCFifo_sizeof 192 + +#define D_IODescr_ADDR 4848 +#define D_IODescr_ADDR_END 5227 +#define D_IODescr_sizeof 380 + +#define D_IODescrList_ADDR 5228 +#define D_IODescrList_ADDR_END 5275 +#define D_IODescrList_sizeof 48 + +#define D_PingPongDesc_ADDR 5276 +#define D_PingPongDesc_ADDR_END 5467 +#define D_PingPongDesc_sizeof 192 + +#define D_IRQMask_ADDR 5468 +#define D_IRQMask_ADDR_END 5499 +#define D_IRQMask_sizeof 32 + +#define D_DebugAbe2hal_ADDR 5500 +#define D_DebugAbe2hal_ADDR_END 5627 +#define D_DebugAbe2hal_sizeof 128 + +#define D_Debug_hal2abe_ADDR 5628 +#define D_Debug_hal2abe_ADDR_END 5755 +#define D_Debug_hal2abe_sizeof 128 + +#define D_Cmd2PhenixFifoDesc_ADDR 5756 +#define D_Cmd2PhenixFifoDesc_ADDR_END 5767 +#define D_Cmd2PhenixFifoDesc_sizeof 12 + +#define D_ctrlPortFifo_ADDR 5776 +#define D_ctrlPortFifo_ADDR_END 5791 +#define D_ctrlPortFifo_sizeof 16 + +#define D_StatusFromPhoenixFifoDesc_ADDR 5792 +#define D_StatusFromPhoenixFifoDesc_ADDR_END 5803 +#define D_StatusFromPhoenixFifoDesc_sizeof 12 + +#define D_Cmd2PhoenixFifo_ADDR 5804 +#define D_Cmd2PhoenixFifo_ADDR_END 5835 +#define D_Cmd2PhoenixFifo_sizeof 32 + +#define D_StatusFromPhoenixFifo_ADDR 5836 +#define D_StatusFromPhoenixFifo_ADDR_END 5867 +#define D_StatusFromPhoenixFifo_sizeof 32 + +#define D_Data_LSB_2_ADDR 5868 +#define D_Data_LSB_2_ADDR_END 5871 +#define D_Data_LSB_2_sizeof 4 + +#define D_Ref0_ADDR 5872 +#define D_Ref0_ADDR_END 5881 +#define D_Ref0_sizeof 10 + +#define D_Ping_ADDR 5884 +#define D_Ping_ADDR_END 6083 +#define D_Ping_sizeof 200 + +#define D_VIB_DL_ADDR 6084 +#define D_VIB_DL_ADDR_END 6275 +#define D_VIB_DL_sizeof 192 + +#define D_Pong_ADDR 6276 +#define D_Pong_ADDR_END 6475 +#define D_Pong_sizeof 200 + +#define D_DebugRegister_ADDR 6476 +#define D_DebugRegister_ADDR_END 6615 +#define D_DebugRegister_sizeof 140 + +#define D_Gcount_ADDR 6616 +#define D_Gcount_ADDR_END 6617 +#define D_Gcount_sizeof 2 + +#define D_BufbaseAddr_ADDR 6618 +#define D_BufbaseAddr_ADDR_END 6641 +#define D_BufbaseAddr_sizeof 24 + +#define D_BufLstDescr_ADDR 6644 +#define D_BufLstDescr_ADDR_END 6667 +#define D_BufLstDescr_sizeof 24 + +#define D_VX_UL_ADDR 6784 +#define D_VX_UL_ADDR_END 6879 +#define D_VX_UL_sizeof 96 + +#define D_VX_DL_ADDR 6912 +#define D_VX_DL_ADDR_END 7007 +#define D_VX_DL_sizeof 96 + +#define D_MM_UL2_FIFO_ADDR 7040 +#define D_MM_UL2_FIFO_ADDR_END 7143 +#define D_MM_UL2_FIFO_sizeof 104 + +#define D_TONES_DL_ADDR 7168 +#define D_TONES_DL_ADDR_END 7271 +#define D_TONES_DL_sizeof 104 + +#define D_aUplinkRouting_ADDR 7272 +#define D_aUplinkRouting_ADDR_END 7287 +#define D_aUplinkRouting_sizeof 16 + +#define D_VirtAudioLoop_ADDR 7288 +#define D_VirtAudioLoop_ADDR_END 7291 +#define D_VirtAudioLoop_sizeof 4 + +#define D_AsrcVars_DL_VX_ADDR 7292 +#define D_AsrcVars_DL_VX_ADDR_END 7323 +#define D_AsrcVars_DL_VX_sizeof 32 + +#define D_CoefAddresses_DL_VX_ADDR 7324 +#define D_CoefAddresses_DL_VX_ADDR_END 7355 +#define D_CoefAddresses_DL_VX_sizeof 32 + +#define D_AsrcVars_UL_VX_ADDR 7356 +#define D_AsrcVars_UL_VX_ADDR_END 7387 +#define D_AsrcVars_UL_VX_sizeof 32 + +#define D_CoefAddresses_UL_VX_ADDR 7388 +#define D_CoefAddresses_UL_VX_ADDR_END 7419 +#define D_CoefAddresses_UL_VX_sizeof 32 + +#define D_AsrcVars_DL_MM_ADDR 7420 +#define D_AsrcVars_DL_MM_ADDR_END 7451 +#define D_AsrcVars_DL_MM_sizeof 32 + +#define D_CoefAddresses_DL_MM_ADDR 7452 +#define D_CoefAddresses_DL_MM_ADDR_END 7483 +#define D_CoefAddresses_DL_MM_sizeof 32 + +#define D_APS_thresholds_ADDR 7484 +#define D_APS_thresholds_ADDR_END 7491 +#define D_APS_thresholds_sizeof 8 + +#define D_APS_IRQ_ADDR 7492 +#define D_APS_IRQ_ADDR_END 7499 +#define D_APS_IRQ_sizeof 8 + +#define D_TraceBufAdr_ADDR 7500 +#define D_TraceBufAdr_ADDR_END 7501 +#define D_TraceBufAdr_sizeof 2 + +#define D_TraceBufOffset_ADDR 7502 +#define D_TraceBufOffset_ADDR_END 7503 +#define D_TraceBufOffset_sizeof 2 + +#define D_TraceBufLength_ADDR 7504 +#define D_TraceBufLength_ADDR_END 7505 +#define D_TraceBufLength_sizeof 2 + +#define D_AsrcVars_ECHO_REF_ADDR 7508 +#define D_AsrcVars_ECHO_REF_ADDR_END 7539 +#define D_AsrcVars_ECHO_REF_sizeof 32 + +#define D_MemoryPool_ADDR 8192 +#define D_MemoryPool_ADDR_END 65535 +#define D_MemoryPool_sizeof 57344 + + +#endif /* _ABEDM_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..1e4a1959d24f --- /dev/null +++ b/sound/soc/codecs/abe/abe_ext.c @@ -0,0 +1,93 @@ +/* + * 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_EXT.C + * + * 'ABE_EXT.C' external interfaces + * + * @path + * @rev 01.00 + *! Revision History + *! 27-Nov-2008 Original (LLF) + *! 05-Jun-2009 V05 release + */ + + +#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_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_microsecond *time) +{ + static abe_microsecond clock; + + *time = clock; + clock ++; + +} + + + +/* + * ABE_APS_TUNING + * + * Parameter : + * + * + * Operations : + * + * + * Return value : + * + */ +void abe_aps_tuning (void) +{ +} + +/** +* @fn abe_set_semaphore() +* +* Operations : set a spin-lock and wait in case of collision +*/ + +void abe_set_semaphore (void) +{ +} + +/* + * @fn abe_reset_semaphore() + * + * Operations : reset a spin-lock (end of subroutine) + * + * + * @see ABE_API.h + */ +void abe_reset_semaphore (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..afab309ba3b4 --- /dev/null +++ b/sound/soc/codecs/abe/abe_ext.h @@ -0,0 +1,41 @@ +/* + * 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_EXT.H + * + * Constants definitions + * + * @path + * @rev 01.00 + */ + +#ifndef __ABEEXT_ +#define __ABEEXT_ + +#include <linux/io.h> +#define PC_SIMULATION 0 /* Tuning is done on PC ? */ + +/* + * OS DEPENDENT MMU CONFIGURATION + */ + + +#define ABE_ATC_BASE_ADDRESS_L3 L3_ABE_44XX_PHYS + 0xf1000 + /* base address used for L3/DMA access */ +#define ABE_DMEM_BASE_ADDRESS_L3 L3_ABE_44XX_PHYS + 0x80000 + /* 64kB as seen from DMA access */ +#define ABE_PMEM_BASE_ADDRESS_MPU IO_ADDRESS(L3_ABE_44XX_PHYS) + 0xe0000 + /* 8kB as seen from MPU access */ +#define ABE_CMEM_BASE_ADDRESS_MPU IO_ADDRESS(L3_ABE_44XX_PHYS) + 0xa0000 + /* 8kB */ +#define ABE_SMEM_BASE_ADDRESS_MPU IO_ADDRESS(L3_ABE_44XX_PHYS) + 0xc0000 + /* 24kB */ +#define ABE_DMEM_BASE_ADDRESS_MPU IO_ADDRESS(L3_ABE_44XX_PHYS) + 0x80000 + /* 64kB */ +#define ABE_ATC_BASE_ADDRESS_MPU IO_ADDRESS(L3_ABE_44XX_PHYS) + 0xf1000 + + +#endif /* ifndef ABEEXT */ diff --git a/sound/soc/codecs/abe/abe_functionsId.h b/sound/soc/codecs/abe/abe_functionsId.h new file mode 100644 index 000000000000..a8c97216ab44 --- /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. +* ========================================================================== */ +/** +* @file abe_functionsId.h +* +* ABE Firmware functions prototype +* +* @path $(ABEPATH)\firmware\src\ +* +*/ +#ifndef __ABE_FUNCTIONSID_H_ +#define __ABE_FUNCTIONSID_H_ + +/* + * TASK function ID definitions + */ +#define C_ABE_FW_FUNCTION_nullCall 0 +#define C_ABE_FW_FUNCTION_test 1 +#define C_ABE_FW_FUNCTION_IIR 2 +#define C_ABE_FW_FUNCTION_monoToStereoPack 3 +#define C_ABE_FW_FUNCTION_stereoToMonoSplit 4 +#define C_ABE_FW_FUNCTION_decimator 5 +#define C_ABE_FW_FUNCTION_OS0Fill 6 +#define C_ABE_FW_FUNCTION_mixer2 7 +#define C_ABE_FW_FUNCTION_mixer4 8 +#define C_ABE_FW_FUNCTION_taskCluster 9 +#define C_ABE_FW_FUNCTION_treatDelayedTasksFifo 10 +#define C_ABE_FW_FUNCTION_treatPostedIrq 11 +#define C_ABE_FW_FUNCTION_inplaceGain 12 +#define C_ABE_FW_FUNCTION_EANC 13 +#define C_ABE_FW_FUNCTION_IO_MM_UL_old 14 +#define C_ABE_FW_FUNCTION_fillMcPDMOutFifo 15 +#define C_ABE_FW_FUNCTION_IO_generic 16 +#define C_ABE_FW_FUNCTION_IO_DMIC_UL 17 +#define C_ABE_FW_FUNCTION_IO_AMIC_UL 18 +#define C_ABE_FW_FUNCTION_StreamRouting 19 +#define C_ABE_FW_FUNCTION_StreamRoutingLoop 20 +#define C_ABE_FW_FUNCTION_VIBRA2 21 +#define C_ABE_FW_FUNCTION_VIBRA1 22 +#define C_ABE_FW_FUNCTION_APS_core 23 +#define C_ABE_FW_FUNCTION_ASRC_DL_wrapper 24 +#define C_ABE_FW_FUNCTION_ASRC_UL_wrapper 25 +#define C_ABE_FW_FUNCTION_IO_MM_UL 26 +#define C_ABE_FW_FUNCTION_gainConverge 27 +#define C_ABE_FW_FUNCTION_dualIir 28 +#define C_ABE_FW_FUNCTION_EANC_wrapper 29 + +/* + * COMMAND function ID definitions + */ +#define nullCommand_CMDID 0 +#define cmdMemcpyDM2SM_CMDID 1 +#define cmdMemcpyDM2CM_CMDID 2 +#define cmdMemcpySM2SM_CMDID 3 +#define cmdMemcpyCM2CM_CMDID 4 +#define cmdMemcpySM2DM_CMDID 5 +#define cmdMemcpyCM2DM_CMDID 6 +#define cmdClearCM_CMDID 7 +#define cmdClearSM_CMDID 8 +#define cmdSendIRQ_CMDID 9 +#define cmdMemcpyDM2DM_CMDID 10 + +/* + * COPY function ID definitions + */ +#define COPY_D2S_LR_CFPID 0 +#define COPY_D2S_2_CFPID 1 +#define COPY_D2S_MONO_CFPID 2 +#define COPY_S1D_MONO_CFPID 3 +#define COPY_S2D_MONO_CFPID 4 +#define COPY_S2D_2_CFPID 5 + +#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..e14169490156 --- /dev/null +++ b/sound/soc/codecs/abe/abe_fw.h @@ -0,0 +1,517 @@ +/* + * 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_FW.H + * + * Firmware's dependent data + * @path + * @rev 01.00 + *! Revision History + *! =================================== + *! 27-Nov-2008 Original (LLF) + *! 05-Jun-2009 V05 release + */ +#ifndef __ABE_FW_H_ +#define __ABE_FW_H_ + +/*g + * global definition + */ +#define FW_SCHED_LOOP_FREQ 4000 +/* one scheduler loop = 4kHz = 12 samples at 48kHz */ + +#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) + +/* + * dmem area scheduler + */ + +/* ATC descriptors not using the AESS naming convention +typedef struct abeatcdescTag { + unsigned readPointer : 7; // Desc0 + unsigned reserved0 : 1; + unsigned bufSize : 7; + unsigned IRQdest : 1; + unsigned error : 1; + unsigned reserved1 : 5; + unsigned direction : 1; + unsigned empty : 1; + unsigned writePointer : 7; + unsigned reserved2 : 1; + unsigned baseAddr : 12; // Desc1 + unsigned iteration_lower4 : 4; // iteration field overlaps the 16 bits boundary + unsigned iteration_upper3 : 3; + unsigned source : 6; + unsigned dest : 6; + unsigned DescrAct : 1; +} ABE_SAtcDescriptor; +*/ + +#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; + 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_next_scheduler_table D_nextMultiFrame_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 + * o 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_desc1 D_PingPpongDesc_ADDR +#define dmem_ping_pong_buffer_desc2 (D_PingPpongDesc_ADDR + \ + sizeof(ABE_SPingPongDescr)) + + +/* + * IRQ mask used with ports with IRQ (DMA or host) + * uint32 dmem_irq_masks [8] + */ +#define dmem_irq_masks D_IRQMask_ADDR + +#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] + */ + + +/* + * 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 + */ + +/* + * 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 + */ +#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_bt_vx_dl 0 +#define dmem_bt_vx_dl_size 0 +#define smem_bt_vx_ul S_BT_UL_ADDR + +#define dmem_bt_vx_ul 0 +#define dmem_bt_vx_ul_size 0 +#define smem_bt_vx_dl 0 + +#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 0 + +#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 0 + +#define dmem_mm_dl D_MM_DL_ADDR +#define dmem_mm_dl_size ((D_MM_DL_ADDR_END-D_MM_DL_ADDR+1)/4) +#define smem_mm_dl IO_MM_DL_ASRC_labelID + +#define dmem_vx_dl D_VX_DL_ADDR +#define dmem_vx_dl_size ((D_VX_DL_ADDR_END-D_VX_DL_ADDR+1)/4) +#define smem_vx_dl IO_VX_DL_ASRC_labelID + +#define dmem_vx_ul D_VX_UL_ADDR +#define dmem_vx_ul_size ((D_VX_UL_ADDR_END-D_VX_UL_ADDR+1)/4) +#define smem_vx_ul IO_VX_UL_8k_ASRC_labelID + +#define dmem_tones_dl 0 +#define dmem_tones_dl_size 0 +#define smem_tones_dl 0 + +#define dmem_vib_dl 0 +#define dmem_vib_dl_size 0 +#define smem_vib 0 + +#define dmem_mm_ext_out 0 +#define dmem_mm_ext_out_size 0 +#define smem_mm_ext_out 0 + + +/* + * 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) + */ + +#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 +#if 0 + DMIC_PORT1, /* digital microphones pairs */ + DMIC_PORT2, + DMIC_PORT3, + PDM_UL_PORT, /* analog MICs */ + BT_VX_UL_PORT, /* BT uplink */ + + /* AE source ports - Uplink */ + MM_UL_PORT, /* up to 5 stereo channels */ + MM_UL2_PORT, /* stereo FM record path */ + VX_UL_PORT, /* stereo FM record path */ + + /* AE sink ports - Downlink */ + MM_DL_PORT, /* multimedia player audio path */ + VX_DL_PORT, + TONES_DL_PORT, + VIB_DL_PORT, + + BT_VX_DL_PORT, /* AE source ports - Downlink */ + PDM_DL1_PORT, + MM_EXT_OUT_PORT, + PDM_DL2_PORT, + PDM_VIB_PORT, + + SCHD_DBG_PORT, +#endif +/* + * 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_delay_iir1 +#define cmem_gain_alpha C_Alpha_ADDR // [9] +#define cmem_gain_1_alpha C_1_Alpha_ADDR + +/* + * true gain values in the multiplier format (shift +6), left and right + * int24 cmem_gains [18] + */ +#define cmem_gain_ramp C_GWithRamp_ADDR // [18] + +/* + * Coefficients used in the non-smoothed ports + * int24 cmem_gain_no_ramp [12] + * + * 2 for VX_DL L R + * 2 for MM_DL L R + * 2 for TONES L R + * 4 for PORT1/2_TX L R + * 2 for VIBRA1/2 + * --------------- + * 12 = TOTAL + */ +#define cmem_gain_no_ramp C_Gains_ADDR + + +/* + * GAIN OF MIXERS : input gains ... + * int24 cmem_gains_mixer_sdt [2] + * int24 cmem_gains_mixer_rec1 [3] + * int24 cmem_gains_mixer_dl1 [4] + * int24 cmem_gains_mixer_dl2 [4] + * int24 cmem_gains_mixer_dl3 [2] + */ +#define cmem_gains_mixer_sdt +#define cmem_gains_mixer_rec1 +#define cmem_gains_mixer_dl1 +#define cmem_gains_mixer_dl2 +#define cmem_gains_mixer_dl3 + + +/* + * 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_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 + +#define ERR_DEFAULT_DATA_READ sub_copy_d2s +#define ERR_DEFAULT_DATA_WRITE sub_copy_s2d + +#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..8b00019882da --- /dev/null +++ b/sound/soc/codecs/abe/abe_ini.c @@ -0,0 +1,659 @@ +/* +* 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_INI.C + * + * All the visible API for the audio drivers + * + * @path + * @rev 01.00 + *! Revision History + *! 27-Nov-2008 Original (LLF) + *! 05-Jun-2009 V05 release + */ + + + +#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 (void) +{ + abe_uint32 event; + abe_uint32 atc_reg; + + /* 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); + + + /* enables EVENT_GENERATOR_START=6C from McPDM */ + atc_reg = 0x01; + abe_block_copy (COPY_FROM_HOST_TO_ABE, ABE_ATC, 0x6C, &atc_reg, 4); + + + /* set McPDM_DL as EVENT_SOURCE_SELECTION */ + event = 0L; + abe_block_copy (COPY_FROM_HOST_TO_ABE, ABE_ATC, 0x70, &event, 4); + + event = 2L; + abe_block_copy (COPY_FROM_HOST_TO_ABE, ABE_ATC, 0x74, &event, 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]; + + for (ptr = (abe_uint8 *)&(VirtAudio_aMultiFrame[0][0]), + i=0; i < sizeof (VirtAudio_aMultiFrame); i++) + *ptr++ = 0; + + /* Scheduling table for Voice UL/DL 8kHz */ + VirtAudio_aMultiFrame[0][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_AMIC; + VirtAudio_aMultiFrame[0][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_VX_DL; + + VirtAudio_aMultiFrame[1][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_ASRC_VX_DL_8; + VirtAudio_aMultiFrame[1][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_VX_DL_8_48_BP; + VirtAudio_aMultiFrame[1][2] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_VX_DL_8_48_0SR; + VirtAudio_aMultiFrame[1][3] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_MM_DL; + + VirtAudio_aMultiFrame[2][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_VX_DL_8_48_LP; + VirtAudio_aMultiFrame[2][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_ASRC_MM_DL; + VirtAudio_aMultiFrame[2][2] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_DL1Mixer; + VirtAudio_aMultiFrame[2][3] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2Mixer; + + VirtAudio_aMultiFrame[3][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_EchoMixer; + VirtAudio_aMultiFrame[3][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_SideTone; + VirtAudio_aMultiFrame[3][2] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_SDTMixer; + VirtAudio_aMultiFrame[3][3] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2_EQ; + + VirtAudio_aMultiFrame[4][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_DL1_EQ; + VirtAudio_aMultiFrame[4][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_DL1_APS_EQ; + VirtAudio_aMultiFrame[4][3] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_DL1_GAIN; + + VirtAudio_aMultiFrame[5][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_VXRECMixer; + VirtAudio_aMultiFrame[5][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_VXREC_SPLIT; + + VirtAudio_aMultiFrame[8][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2_APS_EQ; + VirtAudio_aMultiFrame[8][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2_GAIN; + + VirtAudio_aMultiFrame[9][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_EARP_48_96_LP0; + VirtAudio_aMultiFrame[9][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_EARP_48_96_0SR; + VirtAudio_aMultiFrame[9][2] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_EARP_48_96_LP1; + VirtAudio_aMultiFrame[9][3] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_EARP_48_96_LP1; + + VirtAudio_aMultiFrame[10][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_IHF_48_96_LP0; + VirtAudio_aMultiFrame[10][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_IHF_48_96_0SR; + VirtAudio_aMultiFrame[10][2] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_IHF_48_96_LP1; + VirtAudio_aMultiFrame[10][3] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_IHF_48_96_LP1; + + VirtAudio_aMultiFrame[11][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_McPDM_DL; + + VirtAudio_aMultiFrame[12][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_AMIC_96_48_IIR; + VirtAudio_aMultiFrame[12][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_AMIC_96_48_DEC; + VirtAudio_aMultiFrame[12][2] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_AMIC_EQ; + VirtAudio_aMultiFrame[12][3] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_AMIC_SPLIT; + + VirtAudio_aMultiFrame[14][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_DL1_APS_IIR; + VirtAudio_aMultiFrame[14][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_DL1_APS_CORE; + + VirtAudio_aMultiFrame[15][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2_L_APS_CORE; + VirtAudio_aMultiFrame[15][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2_APS_IIR; + VirtAudio_aMultiFrame[15][2] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2_APS_SPLIT; + VirtAudio_aMultiFrame[15][3] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_DL2_R_APS_CORE; + + VirtAudio_aMultiFrame[21][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_VX_UL_ROUTING; + VirtAudio_aMultiFrame[21][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_ULMixer; + + VirtAudio_aMultiFrame[22][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_VX_UL_48_8_LP; + VirtAudio_aMultiFrame[22][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_VX_UL_48_8_DEC1; + VirtAudio_aMultiFrame[22][2] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_VX_UL_48_8_BP; + VirtAudio_aMultiFrame[22][3] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_ASRC_VX_UL_8; + + VirtAudio_aMultiFrame[23][0] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_McPDM_DL; + VirtAudio_aMultiFrame[23][1] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_IO_VX_UL; + VirtAudio_aMultiFrame[23][2] = D_tasksList_ADDR + + sizeof(ABE_STask)*C_ABE_FW_TASK_GAIN_UPDATE; + + abe_block_copy (COPY_FROM_HOST_TO_ABE, ABE_DMEM, + D_multiFrame_ADDR, (abe_uint32*)VirtAudio_aMultiFrame, + sizeof (VirtAudio_aMultiFrame)); + + n = D_aUplinkRouting_ADDR_END - D_aUplinkRouting_ADDR + 1; + + for(i = 0; i < n; i++) + aUplinkMuxing[i] = ZERO_labelID; + + /* VX- UL routing table */ + aUplinkMuxing[12] = AMIC_L_labelID; + aUplinkMuxing[13] = AMIC_R_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 thr, thr1, thr2, iter; + abe_int32 iterfactor; + + + /* load default values of the descriptor */ + desc.rdpt = desc.wrpt = desc.irqdest = desc.cberr = desc.desen =0; + desc.reserved0 = desc.reserved1 = desc.reserved2 = 0; + desc.srcid = desc.destid = desc.badd = desc.iter = desc.cbsize = 0; + + 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]; + desc.nw = 1; + + 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.nw = 1; + + 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]; + desc.nw = 1; + + 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; + 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]; + desc.nw = 0; + desc.wrpt = desc.iter; + desc.desen = 1; + + 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]; + desc.wrpt = MCPDM_UL_ITER; + desc.nw = 1; + desc.desen = 1; + + 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: + 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; + desc.nw = 0; + + + thr = (abe_int8) abe_port[id].protocol.p.prot_dmareq.thr_flow; + iterfactor = abe_dma_port_iter_factor (&((abe_port[id]).format)); + thr = (abe_uint8) (thr * iterfactor); + iter = + (abe_uint8) abe_dma_port_iteration (&((abe_port[id]).format)); + + if (abe_port[id].protocol.direction == ABE_ATC_DIRECTION_IN) { + thr2 = (abe_uint8)(iter - thr); + thr1 = (abe_uint8)(iter + thr); + } else { + thr2 = 0; + thr1 = (abe_uint8)(thr * 2); + } + + desc.wrpt = (thr1 + thr2) >> 1; + + if (desc.cbdir == ABE_ATC_DIRECTION_OUT) + desc.destid = + abe_atc_dstid [(abe_port[id]).protocol.p.prot_dmareq.desc_addr >> 3]; + else + desc.srcid = + abe_atc_srcid [(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_data_format_t *format, + abe_port_protocol_t *prot) +{ + abe_dma_t_offset dma; + + dma.data = 0; + dma.iter = 0; + + switch (prot->protocol_switch) { + case PINGPONG_PORT_PROT: + dma.data = (prot->p).prot_pingpong.buf_addr; + dma.iter = abe_dma_port_iteration (format); + break; + + case DMAREQ_PORT_PROT : + dma.data = (prot->p).prot_dmareq.buf_addr; + dma.iter = (prot->p).prot_dmareq.iter; + break; + + case CIRCULAR_PORT_PROT: + dma.data = (prot->p).prot_dmareq.buf_addr; + dma.iter = (prot->p).prot_dmareq.iter; + break; + + case SLIMBUS_PORT_PROT: + case SERIAL_PORT_PROT: + case DMIC_PORT_PROT: + case MCPDMDL_PORT_PROT: + case MCPDMUL_PORT_PROT: + default: + break; + } + + abe_port [id].dma = dma; +} + +/* + * 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_uint8 thr, thr1, thr2, iter, direction, data_shift, + iter_samples, up1, up2; + abe_int32 iterfactor, dmareq_addr, dmareq_field; + abe_int32 atc_desc_address, sio_desc_address, sio_id; + + + dmareq_addr = ABE_DUMMY_ADDRESS; + dmareq_field = 0; + thr = DEFAULT_THR_READ; + atc_desc_address = 0; + + switch (prot->protocol_switch) { + case DMIC_PORT_PROT: + atc_desc_address = ABE_ATC_DMIC_DMA_REQ; + break; + + case MCPDMDL_PORT_PROT : + atc_desc_address = ABE_ATC_MCPDMDL_DMA_REQ; + break; + + case MCPDMUL_PORT_PROT : + atc_desc_address = ABE_ATC_MCPDMUL_DMA_REQ; + break; + + case PINGPONG_PORT_PROT: + break; + + case SLIMBUS_PORT_PROT : + thr = (abe_int8) abe_port[id].protocol.p.prot_dmareq.thr_flow; + atc_desc_address = abe_port[id].protocol.p.prot_dmareq.desc_addr; + break; + + case SERIAL_PORT_PROT: /* McBSP/McASP */ + thr = (abe_int8) abe_port[id].protocol.p.prot_serial.thr_flow; + atc_desc_address = + (abe_int16) abe_port[id].protocol.p.prot_serial.desc_addr; + break; + + case DMAREQ_PORT_PROT :/* DMA w/wo CBPr */ + thr = (abe_int8) abe_port[id].protocol.p.prot_dmareq.thr_flow; + dmareq_addr = abe_port[id].protocol.p.prot_dmareq.dma_addr; + dmareq_field = abe_port[id].protocol.p.prot_dmareq.dma_data; + atc_desc_address = abe_port[id].protocol.p.prot_dmareq.desc_addr; + break; + default: + break; +} + + iterfactor = abe_dma_port_iter_factor (format); + data_shift = (abe_uint8)((iterfactor > 1)? 1:0); + + iter = (abe_uint8) abe_dma_port_iteration (format); + iter_samples = (abe_uint8) (iter / iterfactor); + + if (abe_port[id].protocol.direction == ABE_ATC_DIRECTION_IN) { + thr2 = (abe_uint8)(iter - thr); + thr1 = (abe_uint8)(iter + thr); + direction = 0; + } else { + thr2 = 0; + thr1 = (abe_uint8)(thr * 2); + direction = 3; + } + + up1 = (abe_uint8) (iter + thr); + up2 = (abe_uint8) (MAXIMUM(0, (abe_int8)iter - (abe_int8)thr)); + + desc.drift_ASRC = 0; + desc.drift_io = 0; + desc.hw_ctrl_addr = (abe_uint8) dmareq_addr; + desc.copy_func_index = + (abe_uint8) abe_dma_port_copy_subroutine_id(format, + abe_port[id].protocol.direction); + desc.x_io = iter_samples; + desc.threshold_1 = thr1; + desc.threshold_2 = thr2; + desc.update_1 = up1; + desc.update_2 = up2; + desc.data_size = data_shift; + desc.smem_addr = (abe_uint8) abe_port[id].smem_buffer1; + desc.flow_counter = 0; + desc.atc_irq_data = (abe_uint8) dmareq_field; + desc.atc_address = (abe_uint8) (atc_desc_address >> 2); + desc.direction_rw = direction; + desc.padding16[0] = 0; + desc.padding16[1] = 0; + + sio_id = sio_task_index [id]; + sio_desc_address = dmem_port_descriptors + + (sio_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) +{ +} + +/* + * ABE_INIT_MCPDM + * + * Parameter : + * x : d + * Operations : + * Return value : + */ +void abe_init_mcpdm (abe_uint32 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]; + abe_call_subroutine ((all_feature[x]).disable_feature, 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 < MAXNBFEATURE; 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); +} + +/* + * ABE_RESET_ALL_FIFO + * + * Parameter : + * none + * Operations : + * load default configuration for the buffer addresses + * Return value : + * + */ +void abe_reset_all_fifo (void) +{ + +} + + 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..0b12bd622e61 --- /dev/null +++ b/sound/soc/codecs/abe/abe_initxxx_labels.h @@ -0,0 +1,251 @@ +/* +* 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. + +* @file ABE_INITxxx_labels.h +* +* +*/ +#ifndef __ABE_INITXXX_LABELS_H_ +#define __ABE_INITXXX_LABELS_H_ + +#define Voice_8k_UL_labelID 0 +#define Voice_8k_DL_labelID 1 +#define ECHO_REF_8K_labelID 2 +#define Voice_16k_UL_labelID 3 +#define Voice_16k_DL_labelID 4 +#define ECHO_REF_16K_labelID 5 +#define MM_DL_labelID 6 +#define IO_VX_DL_ASRC_labelID 7 +#define IO_VX_UL_8k_ASRC_labelID 8 +#define IO_VX_UL_16k_ASRC_labelID 9 +#define IO_MM_DL_ASRC_labelID 10 +#define ZERO_labelID 11 +#define Z_1_labelID 12 +#define Z_M1_labelID 13 +#define Dummy_AM_labelID 14 +#define Dummy_Regs_labelID 15 +#define Gr_1_labelID 16 +#define Gr_2_labelID 17 +#define Gr_Regs_labelID 18 +#define OSR96_2_labelID 19 +#define UP_DOWN_48_96_labelID 20 +#define EQ_96K_labelID 21 +#define McPDMout_3_labelID 22 +#define DL1_M_labelID 23 +#define DL2_M_labelID 24 +#define MM_UL2_labelID 25 +#define VX_DL_labelID 26 +#define Tones_labelID 27 +#define DL1_M_G_labelID 28 +#define DL2_M_G_labelID 29 +#define DLx_M_Regs_labelID 30 +#define TC_Regs_labelID 31 +#define Echo_M_labelID 32 +#define Echo_M_G_labelID 33 +#define VX_UL_labelID 34 +#define SDT_F_labelID 35 +#define SDT_F_data_labelID 36 +#define SDT_Coef_labelID 37 +#define SDT_Regs_labelID 38 +#define SDT_M_labelID 39 +#define DL1_labelID 40 +#define SDT_M_G_labelID 41 +#define DMIC1_labelID 42 +#define DMIC1_L_labelID 43 +#define DMIC1_R_labelID 44 +#define DMIC2_labelID 45 +#define DMIC2_L_labelID 46 +#define DMIC2_R_labelID 47 +#define DMIC3_labelID 48 +#define DMIC3_L_labelID 49 +#define DMIC3_R_labelID 50 +#define BT_UL_labelID 51 +#define BT_L_labelID 52 +#define BT_R_labelID 53 +#define AMIC_labelID 54 +#define AMIC_L_labelID 55 +#define AMIC_R_labelID 56 +#define EANC_FBK_labelID 57 +#define EANC_FBK_L_labelID 58 +#define EANC_FBK_R_labelID 59 +#define EchoRef_L_labelID 60 +#define EchoRef_R_labelID 61 +#define MM_DL_L_labelID 62 +#define MM_DL_R_labelID 63 +#define MM_UL_labelID 64 +#define AMIC_96_labelID 65 +#define DMIC0_96_labelID 66 +#define DMIC1_96_labelID 67 +#define DMIC2_96_labelID 68 +#define DMIC_desc_labelID 69 +#define DMIC_eanc_labelID 70 +#define DMIC_Regs_labelID 71 +#define DMIC_Regs2_labelID 72 +#define AMIC_96_F_labelID 73 +#define AMIC_96_data_labelID 74 +#define AMIC_96F_Coefs_labelID 75 +#define DMIC0_96_F_labelID 76 +#define DMIC0_96_data_labelID 77 +#define DMIC0_96F_Coefs_labelID 78 +#define DMIC1_96_F_labelID 79 +#define DMIC1_96_data_labelID 80 +#define DMIC2_96_F_labelID 81 +#define DMIC2_96_data_labelID 82 +#define DMIC0_F_labelID 83 +#define UL_MIC_48K_labelID 84 +#define DMIC0_dec_labelID 85 +#define AMIC_EQ_data_labelID 86 +#define AMIC_EQ_Coefs_labelID 87 +#define DMIC1_EQ_data_labelID 88 +#define DMIC1_EQ_Coefs_labelID 89 +#define DMIC2_EQ_data_labelID 90 +#define DMIC2_EQ_Coefs_labelID 91 +#define DMIC3_EQ_data_labelID 92 +#define DMIC3_EQ_Coefs_labelID 93 +#define EQ_DL_48K_labelID 94 +#define EQ_48K_labelID 95 +#define Voice_F_data_labelID 96 +#define Voice_F_Coefs_labelID 97 +#define Voice_F_labelID 98 +#define SIO_VX_UL_labelID 99 +#define SIO_VX_DL_labelID 100 +#define SIO_TONES_DL_labelID 101 +#define VX_DL_data_labelID 102 +#define UP_DOWN_8_48_labelID 103 +#define SIO_MM_DL_labelID 104 +#define AMIC_desc_labelID 105 +#define AMIC_Regs_labelID 106 +#define McPDM_Out1_labelID 107 +#define McPDM_Out1_data_labelID 108 +#define McPDM_Out1_Coefs_labelID 109 +#define McPDM_Out2_labelID 110 +#define McPDM_Out2_data_labelID 111 +#define McPDM_Out2_Coefs_labelID 112 +#define McPDM_Out3_labelID 113 +#define McPDM_DL_Out1_labelID 114 +#define McPDM_DL_Regs_labelID 115 +#define VX_UL_MUX_labelID 116 +#define MM_UL2_MUX_labelID 117 +#define MM_UL_MUX_labelID 118 +#define IO_MM_UL_Regs_labelID 119 +#define MM_UL_desc_labelID 120 +#define MM_UL_FIFO_labelID 121 +#define IO_MM_UL2_Regs_labelID 122 +#define MM_UL2_desc_labelID 123 +#define MM_UL2_FIFO_labelID 124 +#define XinASRC_DL_VX_labelID 125 +#define ASRC_DL_VX_Coefs_labelID 126 +#define ASRC_DL_VX_Alpha_labelID 127 +#define ASRC_DL_VX_VarsBeta_labelID 128 +#define ASRC_DL_VX_8k_Regs_labelID 129 +#define XinASRC_UL_VX_labelID 130 +#define ASRC_UL_VX_Coefs_labelID 131 +#define ASRC_UL_VX_Alpha_labelID 132 +#define ASRC_UL_VX_VarsBeta_labelID 133 +#define ASRC_UL_VX_8k_Regs_labelID 134 +#define UL_48_8_DEC_labelID 135 +#define UP_DOWN_16_48_labelID 136 +#define ASRC_DL_VX_16k_Regs_labelID 137 +#define ASRC_UL_VX_16k_Regs_labelID 138 +#define UL_48_16_DEC_labelID 139 +#define XinASRC_DL_MM_labelID 140 +#define ASRC_DL_MM_Coefs_labelID 141 +#define ASRC_DL_MM_Alpha_labelID 142 +#define ASRC_DL_MM_VarsBeta_labelID 143 +#define ASRC_DL_MM_Regs_labelID 144 +#define VX_REC_labelID 145 +#define VXREC_M_G_labelID 146 +#define VXREC_M_Regs_labelID 147 +#define VX_REC_L_labelID 148 +#define VX_REC_R_labelID 149 +#define UL_M_G_labelID 150 +#define DL2_M_L_labelID 151 +#define DL2_M_R_labelID 152 +#define DL1_M_data_labelID 153 +#define DL1_M_Coefs_labelID 154 +#define DL2_M_LR_data_labelID 155 +#define DL2_M_LR_Coefs_labelID 156 +#define VX_DL_8_48_LP_COEFS_labelID 157 +#define VX_DL_8_48_BP_COEFS_labelID 158 +#define VX_DL_8_48_BP_DATA_labelID 159 +#define VX_DL_8_48_LP_DATA_labelID 160 +#define EQ_VX_DL_8K_labelID 161 +#define EQ_VX_DL_48K_labelID 162 +#define UP_48_96_LP0_COEFS_labelID 163 +#define UP_48_96_LP1_COEFS_labelID 164 +#define EARP_48_96_LP0_DATA_labelID 165 +#define EARP_48_96_LP1_DATA_labelID 166 +#define EQ_48_96_LP0_labelID 167 +#define EQ_48_96_LP1_labelID 168 +#define IHF_48_96_LP0_DATA_labelID 169 +#define IHF_48_96_LP1_DATA_labelID 170 +#define VX_DL_16_48_HP_COEFS_labelID 171 +#define VX_DL_16_48_LP_COEFS_labelID 172 +#define VX_DL_16_48_HP_DATA_labelID 173 +#define VX_DL_16_48_LP_DATA_labelID 174 +#define EQ_VX_DL_16K_labelID 175 +#define VX_UL_48_8_LP_COEFS_labelID 176 +#define VX_UL_48_8_BP_DATA_labelID 177 +#define VX_UL_48_8_LP_DATA_labelID 178 +#define EQ_VX_UL_8K_labelID 179 +#define EQ_VX_UL_48K_labelID 180 +#define VX_UL_8_TEMP_labelID 181 +#define VX_UL_48_16_LP_COEFS_labelID 182 +#define VX_UL_48_16_HP_DATA_labelID 183 +#define VX_UL_48_16_LP_DATA_labelID 184 +#define EQ_VX_UL_16K_labelID 185 +#define VX_UL_16_TEMP_labelID 186 +#define GTarget_labelID 187 +#define GCurrent_labelID 188 +#define pAPS_iir1_p23_labelID 189 +#define pAPS_iir1_p45_labelID 190 +#define APS_IIR_Regs_labelID 191 +#define pAPS_core_p1_labelID 192 +#define pAPS_core_p23_labelID 193 +#define pAPS_core_p45_labelID 194 +#define pAPS_core_r_labelID 195 +#define XinASRC_ECHO_REF_labelID 196 +#define ASRC_ECHO_REF_Coefs_labelID 197 +#define ASRC_ECHO_REF_Alpha_labelID 198 +#define ASRC_ECHO_REF_VarsBeta_labelID 199 +#define ASRC_ECHO_REF_8k_Regs_labelID 200 +#define ASRC_ECHO_REF_16k_Regs_labelID 201 +#define DL2_APS_IIR_p23_labelID 202 +#define DL2_APS_IIR_p45_labelID 203 +#define DL2_L_APS_CORE_p23_labelID 204 +#define DL2_L_APS_CORE_p45_labelID 205 +#define DL2_R_APS_CORE_p23_labelID 206 +#define DL2_R_APS_CORE_p45_labelID 207 +#define DMIC1_Gain_labelID 208 +#define DMIC2_Gain_labelID 209 +#define DMIC3_Gain_labelID 210 +#define AMIC_Gain_labelID 211 +#define DL1_Gain_labelID 212 +#define DL2_Gain_labelID 213 +#define DEFAULT_Gain_labelID 214 +#define DL1_APS_labelID 215 +#define DL2_L_APS_labelID 216 +#define DL2_R_APS_labelID 217 +#define ECHO_REF_48_16_HP_DATA_labelID 218 +#define ECHO_REF_48_16_LP_DATA_labelID 219 +#define ECHO_REF_48_8_BP_DATA_labelID 220 +#define ECHO_REF_48_8_LP_DATA_labelID 221 +#define ECHO_REF_DEC_labelID 222 +#define pEANC_p0_labelID 223 +#define pEANC_p1_labelID 224 +#define pEANC_p23_labelID 225 +#define pEANC_p45_labelID 226 +#define pEANC_reg1_labelID 227 +#define pEANC_reg2_labelID 228 +#define pEANC_reg3_labelID 229 +#define pEANC_r_labelID 230 +#define DL1_APS_EQ_p23_labelID 231 +#define DL1_APS_EQ_p45_labelID 232 +#define DL2_APS_EQ_p23_labelID 233 +#define DL2_APS_EQ_p45_labelID 234 + +#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..1bff8d8e10b4 --- /dev/null +++ b/sound/soc/codecs/abe/abe_irq.c @@ -0,0 +1,31 @@ +/* + * 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_IRQ.C + * + * Interrupt routines + * + * @path + * @rev 01.00 +*! +*! Revision History +*! =================================== +*! 27-Nov-2008 Original (LLF) +*! 05-Jun-2009 V05 release + */ + + + +#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 + */ diff --git a/sound/soc/codecs/abe/abe_lib.c b/sound/soc/codecs/abe/abe_lib.c new file mode 100644 index 000000000000..66b07b96239e --- /dev/null +++ b/sound/soc/codecs/abe/abe_lib.c @@ -0,0 +1,409 @@ +/* + * 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_LIB.C + * + * 'ABE_LIB.C' internal computations libraries + * + * @path + * @rev 01.00 +*! +*! Revision History +*! 27-Nov-2008 Original (LLF) +*! 05-Jun-2009 V05 release +*/ + + + +#include "abe_main.h" + + + +/* + * ABE_TRANSLATE_GAIN_FORMAT + * + * Parameter : + * Operations : + * f: original format name for gain or frequency. + * 1=linear Q8, max=0x80 (0dB) + * 2=linear Q16, max=0x8000 (0dB) + * 3=linear Q16, max=0xFFFF (0dB) + * 4=percentage, max=0x64 (0dB) + * 5=dB in Q14.1 (-50dB = 0xFF9C) + * 6=floating point (IEEE 64bits) linear format + * 7=audio 16bits format +127.9 dB (0x7FFF) down to -127.9 dB (0x8001) + * in steps of 1/256 dB. + * 8=audio 8bits format +31.75 dB (0x7F) down to -32.00 dB (0x80) + * in steps of 0.25 dB (0x01). + * + * g1: pointer to the original data + * g2: pointer to the translated gain data + * + * Return value : + * None. + */ + void abe_translate_gain_format (abe_uint32 f, void *g1, abe_gain_t *g2) + { + + } + +/* + * ABE_FPRINTF + * Parameter : + * character line to be printed + * Operations : + * Return value : + * None. + */ + 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; + } + + } + + +/* + * ABE_GAIN_TRANSLATE + * Parameter : + * x : d + * Operations : + * Return value : + */ +void abe_gain_translate (abe_uint32 x) +{ +} + +/* + * 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_bytes) +{ + abe_uint32 i; + abe_uint32 base_address = 0, *src_ptr, *dst_ptr, n; + + nb_bytes = (nb_bytes + 3) & (-4L); + if (address & (3L)) + abe_dbg_param |= ERR_LIB; abe_dbg_error_log(ABE_BLOCK_COPY_ERR); + + switch (memory_bank) { + case ABE_PMEM: + base_address = (abe_uint32) ABE_PMEM_BASE_ADDRESS_MPU; + break; + case ABE_CMEM: + base_address = (abe_uint32) ABE_CMEM_BASE_ADDRESS_MPU; + break; + case ABE_SMEM: + base_address = (abe_uint32) ABE_SMEM_BASE_ADDRESS_MPU; + break; + case ABE_DMEM: + base_address = (abe_uint32) ABE_DMEM_BASE_ADDRESS_MPU; + break; + case ABE_ATC: + base_address = (abe_uint32) ABE_ATC_BASE_ADDRESS_MPU; + break; + default: + 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++; +} + +/* + * 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 *param1, abe_uint32 *param2) +{ + abe_dbg_log (id_call_subroutine); + + if (idx == 0) + return; + if (idx > c_max_subroutine_index) + + switch (idx) { + case c_feat_init_eq : + abe_fprintf ("AAA"); + break; + case c_feat_read_eq1 : + abe_fprintf ("BBB"); + break; + case c_write_eq1 : + abe_fprintf ("CCC"); + break; + default : + (callbacks[idx]) (*param1, *param2); + break; + } +} + +/* + * 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 *move_type) +{ + abe_uint32 n_freq, n_samp; + + n_freq = (f->f) / FW_SCHED_LOOP_FREQ; + + switch (f->samp_format) { + case MONO_16_LSB: + *mulfac = 1; n_samp = 2; + break; + case MONO_MSB: + *mulfac = 1; n_samp = 2; + break; + case TWO_MONO_MSB: + *mulfac = 1; n_samp = 1; + break; + case STEREO_16_16: + *mulfac = 1; n_samp = 2; + break; + case STEREO_MSB: + *mulfac = 2; n_samp = 4; + break; + case THREE_MSB: + *mulfac = 3; n_samp = 6; + break; + case FOUR_MSB: + *mulfac = 4; n_samp = 8; + break; + case FIVE_MSB: + *mulfac = 5; n_samp = 10; + break; + case SIX_MSB: + *mulfac = 6; n_samp = 12; + break; + case SEVEN_MSB: + *mulfac = 7; n_samp = 14; + break; + case EIGHT_MSB: + *mulfac = 8; n_samp = 16; + break; + default: + *mulfac = 1; n_samp = 2; + break; + } + *iter = (n_freq * n_samp) / 2; +} + +/* + * 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, move_type; + abe_format_switch (f, &iter, &mulfac, &move_type); + + 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, move_type; + abe_format_switch (f, &iter, &mulfac, &move_type); + + 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_data_format_t *f, abe_uint32 direction) +{ + abe_uint32 id; + + if (direction == ABE_ATC_DIRECTION_IN) { + switch (f->samp_format) { + case THREE_MSB: + case FOUR_MSB: + case FIVE_MSB: + case SIX_MSB: + case SEVEN_MSB: + case EIGHT_MSB: + case TWO_MONO_MSB: + case MONO_16_LSB: + id = ERR_DEFAULT_DATA_READ; + break; + case MONO_MSB: + id = sub_copy_d2s_mono; + break; + case STEREO_16_16: + id = sub_copy_d2s_1616; + break; + default: + case STEREO_MSB: + id = sub_copy_d2s; + break; + } + } else { + switch (f->samp_format) { + case THREE_MSB: + case FOUR_MSB: + case FIVE_MSB: + case SIX_MSB: + case SEVEN_MSB: + case EIGHT_MSB: + case TWO_MONO_MSB: + case STEREO_16_16: + case MONO_16_LSB: + id = ERR_DEFAULT_DATA_WRITE; + break; + case MONO_MSB: + id = sub_copy_s2d_mono; + break; + id = ERR_DEFAULT_DATA_WRITE; + break; + default: + id = sub_copy_s2d; break; + } + } +return 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..eae87b7fb2cb --- /dev/null +++ b/sound/soc/codecs/abe/abe_lib.h @@ -0,0 +1,157 @@ +/* +* 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_LIB.H + * + * Library APIs + * + * @path + * @rev 01.00 +*! +*! Revision History +*! 27-Nov-2008 Original +*! 05-Jun-2009 V05 release +*/ +#ifndef __ABE_LIB_H_ +#define __ABE_LIB_H_ + + +/* + * ABE_TRANSLATE_GAIN_FORMAT + * + * Parameter : + * Operations : + * f: original format name for gain or frequency. + * 1=linear Q8, max=0x80 (0dB) + * 2=linear Q16, max=0x8000 (0dB) + * 3=linear Q16, max=0xFFFF (0dB) + * 4=percentage, max=0x64 (0dB) + * 5=dB in Q14.1 (-50dB = 0xFF9C) + * 6=floating point (IEEE 64bits) linear format + * 7=audio 16bits format +127.9 dB (0x7FFF) down to -127.9 dB (0x8001) + * in steps of 1/256 dB. + * 8=audio 8bits format +31.75 dB (0x7F) down to -32.00 dB (0x80) + * in steps of 0.25 dB (0x01). + * + * g1: pointer to the original data + * g2: pointer to the translated gain data + * + * Return value : + * None. + */ +void abe_translate_gain_format (abe_uint32 f, void *g1, abe_gain_t *g2); + + + +/* + * ABE_FPRINTF + * + * Parameter : + * character line to be printed + * + * Operations : + * + * Return value : + * None. + */ +void abe_fprintf (char *line); + + +/* + * ABE_GAIN_TRANSLATE + * + * Parameter : + * x : d + * + * Operations : + * + * + * Return value : + * + */ +void abe_gain_translate (abe_uint32 x); + +/* + * 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); + +#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..2d6dcb8f0185 --- /dev/null +++ b/sound/soc/codecs/abe/abe_main.c @@ -0,0 +1,73 @@ +/* +* 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 + */ + + +#include "abe_main.h" + +/* + * + */ + +#if !PC_SIMULATION + + +void main (void) +{ + + abe_dma_t dma_sink, dma_source; + abe_data_format_t format; + + abe_reset_hal (); + /* + 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 + */ + + format.f = 48000; format.samp_format = STEREO_MSB; + abe_connect_cbpr_dmareq_port (MM_DL_PORT, &format, ABE_CBPR0_IDX, + &dma_sink); + /* + Here : connect a DMA channel to MM_DL port + */ + + format.f = 8000; format.samp_format = MONO_MSB; + abe_connect_cbpr_dmareq_port (VX_DL_PORT, &format, ABE_CBPR0_IDX, + &dma_sink); + /* + Here : connect a DMA channel to VX_DL port + */ + + format.f = 8000; format.samp_format = MONO_MSB; + abe_connect_cbpr_dmareq_port (VX_UL_PORT, &format, ABE_CBPR0_IDX, + &dma_source); + /* + Here : connect a DMA channel to VX_UL 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 (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..e94953d98d07 --- /dev/null +++ b/sound/soc/codecs/abe/abe_main.h @@ -0,0 +1,45 @@ +/* + * 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.H + * @path + * @rev 01.00 + *! + *! Revision History + *! 27-Nov-2008 Original (LLF) + *! 05-Jun-2009 V05 release + */ + + + +#ifndef __abe_main_h_ +#define __abe_main_h_ + +#include "abe_ext.h" +#include "abe_def.h" +#include "abe_typ.h" +#include "abe_dbg.h" +#include "abe_lib.h" +#include "abe_ref.h" +#include "abe_api.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" + +#define ABE_HAL_VERSION 0x00000002L +#define ABE_FW_VERSION 0x00000000L +#define ABE_HW_VERSION 0x00000000L + +#endif diff --git a/sound/soc/codecs/abe/abe_ref.h b/sound/soc/codecs/abe/abe_ref.h new file mode 100644 index 000000000000..584788b5b32f --- /dev/null +++ b/sound/soc/codecs/abe/abe_ref.h @@ -0,0 +1,98 @@ +/* +* 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_REF.H + * + * Variable references + * + * @path + * @rev 01.00 +*! +*! Revision History +*! 27-Nov-2008 Original (LLF) +*! 05-Jun-2009 V05 release +*/ + +#ifndef __abe_ref_def_ +#define __abe_ref_def_ +/* + * 'ABE_PRO.H' all non-API prototypes for INI, IRQ, SEQ ... + */ + +/* + * HAL internal API + */ + +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_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_microsecond *time); +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_data_format_t *format, + 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_data_format_t *format, + abe_uint32 direction); +void abe_call_subroutine (abe_uint32 idx, abe_uint32 *param1, + abe_uint32 *param2); +void abe_monitoring (void); +void abe_set_semaphore (void); +void abe_reset_semaphore (void); +void abe_hw_configuration (void); + + +/* + * 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_router_t abe_router_ul_table [NBROUTE_UL]; +extern const abe_router_t abe_router_ul_table_init_1 [NBROUTE_UL]; + +extern abe_seq_t all_sequence []; +extern const abe_seq_t all_sequence_init[]; + +extern abe_uint32 abe_map_dmem []; +extern abe_uint32 abe_map_dmem_secondary []; +extern abe_uint32 abe_map_dmem_size []; + +extern const abe_uint32 abe_map_dmem_init_1 []; +extern const abe_uint32 abe_map_dmem_size_init_1 []; +extern const abe_uint32 abe_map_dmem_init_2 []; +extern const abe_uint32 abe_map_dmem_size_init_2 []; + +extern abe_uint32 abe_dma_map []; +extern const abe_uint32 abe_dma_map_init_1 []; +extern const abe_uint32 abe_dma_map_init_2 []; + +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; + + +#endif /* REFDEF */ diff --git a/sound/soc/codecs/abe/abe_seq.c b/sound/soc/codecs/abe/abe_seq.c new file mode 100644 index 000000000000..9d0ef3092ae4 --- /dev/null +++ b/sound/soc/codecs/abe/abe_seq.c @@ -0,0 +1,90 @@ +/* + * 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_SEQ.C + * + * 'ABE_SEQ.C' manages the time-sequenced operations + * + * @path + * @rev 01.00 + *! Revision History + *! 27-Nov-2008 Original (LLF) + *! 05-Jun-2009 V05 release + */ + +#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 + * int32 param[2] Two parameters + * char param_tag[2] Flags used for params when launching the seq + * } seq_t + * + */ + +abe_seq_t all_sequence[MAXNBSEQUENCE]; +abe_uint32 sequence_id[MAXNBSEQUENCE]; +abe_uint32 sequence_write_pointer; +abe_uint32 sequence_id_pointer; +/* time call_idx param1 param2 */ +const abe_seq_t seq_null = +{ + 0, 0, 0, 0, +}; +const abe_seq_t seq_power_on_phoenix = +{ + 0, 0, 0, 0, +}; +const abe_seq_t seq_set_uplink_phoenix = +{ + 0, 0, 0, 0, +}; +const abe_seq_t seq_set_downlink_phoenix = +{ + 0, 0, 0, 0, +}; + + + +/* + * 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) +{ +} + +/* + * 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) +{ + sequence_id_pointer = sequence_write_pointer = 0; + +} diff --git a/sound/soc/codecs/abe/abe_seq.h b/sound/soc/codecs/abe/abe_seq.h new file mode 100644 index 000000000000..1b2c2b0eb112 --- /dev/null +++ b/sound/soc/codecs/abe/abe_seq.h @@ -0,0 +1,135 @@ +/* + * 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_SEQ.H + * 'ABE_SEQ.H' time-sequenced activations + * + * @path + * @rev 01.00 + *! + *! Revision History + *! 27-Nov-2008 Original (LLF) + *! 05-Jun-2009 V05 release + */ + + + + +/* + * 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..e21371909fab --- /dev/null +++ b/sound/soc/codecs/abe/abe_sm_addr.h @@ -0,0 +1,496 @@ +/* + * 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 241 +#define init_SM_sizeof 242 + +#define S_Data0_ADDR 242 +#define S_Data0_ADDR_END 242 +#define S_Data0_sizeof 1 + +#define S_Temp_ADDR 243 +#define S_Temp_ADDR_END 243 +#define S_Temp_sizeof 1 + +#define S_PhoenixOffset_ADDR 244 +#define S_PhoenixOffset_ADDR_END 244 +#define S_PhoenixOffset_sizeof 1 + +#define S_GTarget_ADDR 245 +#define S_GTarget_ADDR_END 253 +#define S_GTarget_sizeof 9 + +#define S_GCurrent_ADDR 254 +#define S_GCurrent_ADDR_END 262 +#define S_GCurrent_sizeof 9 + +#define S_Tones_ADDR 263 +#define S_Tones_ADDR_END 274 +#define S_Tones_sizeof 12 + +#define S_VX_DL_ADDR 275 +#define S_VX_DL_ADDR_END 286 +#define S_VX_DL_sizeof 12 + +#define S_MM_UL2_ADDR 287 +#define S_MM_UL2_ADDR_END 298 +#define S_MM_UL2_sizeof 12 + +#define S_MM_DL_ADDR 299 +#define S_MM_DL_ADDR_END 310 +#define S_MM_DL_sizeof 12 + +#define S_DL1_M_Out_ADDR 311 +#define S_DL1_M_Out_ADDR_END 322 +#define S_DL1_M_Out_sizeof 12 + +#define S_DL2_M_Out_ADDR 323 +#define S_DL2_M_Out_ADDR_END 334 +#define S_DL2_M_Out_sizeof 12 + +#define S_Echo_M_Out_ADDR 335 +#define S_Echo_M_Out_ADDR_END 346 +#define S_Echo_M_Out_sizeof 12 + +#define S_SDT_M_Out_ADDR 347 +#define S_SDT_M_Out_ADDR_END 358 +#define S_SDT_M_Out_sizeof 12 + +#define S_VX_UL_ADDR 359 +#define S_VX_UL_ADDR_END 370 +#define S_VX_UL_sizeof 12 + +#define S_SDT_F_ADDR 371 +#define S_SDT_F_ADDR_END 382 +#define S_SDT_F_sizeof 12 + +#define S_SDT_F_data_ADDR 383 +#define S_SDT_F_data_ADDR_END 399 +#define S_SDT_F_data_sizeof 17 + +#define S_MM_DL_OSR_ADDR 400 +#define S_MM_DL_OSR_ADDR_END 423 +#define S_MM_DL_OSR_sizeof 24 + +#define S_MM_96_F_ADDR 424 +#define S_MM_96_F_ADDR_END 447 +#define S_MM_96_F_sizeof 24 + +#define S_MM96_F_data_ADDR 448 +#define S_MM96_F_data_ADDR_END 464 +#define S_MM96_F_data_sizeof 17 + +#define S_24_zeros_ADDR 465 +#define S_24_zeros_ADDR_END 488 +#define S_24_zeros_sizeof 24 + +#define S_DMIC1_ADDR 489 +#define S_DMIC1_ADDR_END 500 +#define S_DMIC1_sizeof 12 + +#define S_DMIC2_ADDR 501 +#define S_DMIC2_ADDR_END 512 +#define S_DMIC2_sizeof 12 + +#define S_DMIC3_ADDR 513 +#define S_DMIC3_ADDR_END 524 +#define S_DMIC3_sizeof 12 + +#define S_BT_UL_ADDR 525 +#define S_BT_UL_ADDR_END 536 +#define S_BT_UL_sizeof 12 + +#define S_AMIC_ADDR 537 +#define S_AMIC_ADDR_END 548 +#define S_AMIC_sizeof 12 + +#define S_EANC_FBK_ADDR 549 +#define S_EANC_FBK_ADDR_END 560 +#define S_EANC_FBK_sizeof 12 + +#define S_DMIC1_L_ADDR 561 +#define S_DMIC1_L_ADDR_END 572 +#define S_DMIC1_L_sizeof 12 + +#define S_DMIC1_R_ADDR 573 +#define S_DMIC1_R_ADDR_END 584 +#define S_DMIC1_R_sizeof 12 + +#define S_DMIC2_L_ADDR 585 +#define S_DMIC2_L_ADDR_END 596 +#define S_DMIC2_L_sizeof 12 + +#define S_DMIC2_R_ADDR 597 +#define S_DMIC2_R_ADDR_END 608 +#define S_DMIC2_R_sizeof 12 + +#define S_DMIC3_L_ADDR 609 +#define S_DMIC3_L_ADDR_END 620 +#define S_DMIC3_L_sizeof 12 + +#define S_DMIC3_R_ADDR 621 +#define S_DMIC3_R_ADDR_END 632 +#define S_DMIC3_R_sizeof 12 + +#define S_BT_L_ADDR 633 +#define S_BT_L_ADDR_END 644 +#define S_BT_L_sizeof 12 + +#define S_BT_R_ADDR 645 +#define S_BT_R_ADDR_END 656 +#define S_BT_R_sizeof 12 + +#define S_AMIC_L_ADDR 657 +#define S_AMIC_L_ADDR_END 668 +#define S_AMIC_L_sizeof 12 + +#define S_AMIC_R_ADDR 669 +#define S_AMIC_R_ADDR_END 680 +#define S_AMIC_R_sizeof 12 + +#define S_EANC_FBK_L_ADDR 681 +#define S_EANC_FBK_L_ADDR_END 692 +#define S_EANC_FBK_L_sizeof 12 + +#define S_EANC_FBK_R_ADDR 693 +#define S_EANC_FBK_R_ADDR_END 704 +#define S_EANC_FBK_R_sizeof 12 + +#define S_EchoRef_L_ADDR 705 +#define S_EchoRef_L_ADDR_END 716 +#define S_EchoRef_L_sizeof 12 + +#define S_EchoRef_R_ADDR 717 +#define S_EchoRef_R_ADDR_END 728 +#define S_EchoRef_R_sizeof 12 + +#define S_MM_DL_L_ADDR 729 +#define S_MM_DL_L_ADDR_END 740 +#define S_MM_DL_L_sizeof 12 + +#define S_MM_DL_R_ADDR 741 +#define S_MM_DL_R_ADDR_END 752 +#define S_MM_DL_R_sizeof 12 + +#define S_MM_UL_ADDR 753 +#define S_MM_UL_ADDR_END 812 +#define S_MM_UL_sizeof 60 + +#define S_AMIC_96k_ADDR 813 +#define S_AMIC_96k_ADDR_END 836 +#define S_AMIC_96k_sizeof 24 + +#define S_DMIC0_96k_ADDR 837 +#define S_DMIC0_96k_ADDR_END 860 +#define S_DMIC0_96k_sizeof 24 + +#define S_DMIC1_96k_ADDR 861 +#define S_DMIC1_96k_ADDR_END 884 +#define S_DMIC1_96k_sizeof 24 + +#define S_DMIC2_96k_ADDR 885 +#define S_DMIC2_96k_ADDR_END 908 +#define S_DMIC2_96k_sizeof 24 + +#define S_DMIC4EANC_ADDR 909 +#define S_DMIC4EANC_ADDR_END 914 +#define S_DMIC4EANC_sizeof 6 + +#define S_AMIC_96_F_ADDR 915 +#define S_AMIC_96_F_ADDR_END 938 +#define S_AMIC_96_F_sizeof 24 + +#define S_DMIC0_96_F_ADDR 939 +#define S_DMIC0_96_F_ADDR_END 962 +#define S_DMIC0_96_F_sizeof 24 + +#define S_DMIC1_96_F_ADDR 963 +#define S_DMIC1_96_F_ADDR_END 986 +#define S_DMIC1_96_F_sizeof 24 + +#define S_DMIC2_96_F_ADDR 987 +#define S_DMIC2_96_F_ADDR_END 1010 +#define S_DMIC2_96_F_sizeof 24 + +#define S_AMIC_96_data_ADDR 1011 +#define S_AMIC_96_data_ADDR_END 1034 +#define S_AMIC_96_data_sizeof 24 + +#define S_DMIC0_96_data_ADDR 1035 +#define S_DMIC0_96_data_ADDR_END 1051 +#define S_DMIC0_96_data_sizeof 17 + +#define S_DMIC1_96_data_ADDR 1052 +#define S_DMIC1_96_data_ADDR_END 1068 +#define S_DMIC1_96_data_sizeof 17 + +#define S_DMIC2_96_data_ADDR 1069 +#define S_DMIC2_96_data_ADDR_END 1085 +#define S_DMIC2_96_data_sizeof 17 + +#define S_UL_MIC_48K_ADDR 1086 +#define S_UL_MIC_48K_ADDR_END 1097 +#define S_UL_MIC_48K_sizeof 12 + +#define S_AMIC_EQ_data_ADDR 1098 +#define S_AMIC_EQ_data_ADDR_END 1114 +#define S_AMIC_EQ_data_sizeof 17 + +#define S_DMIC1_EQ_data_ADDR 1115 +#define S_DMIC1_EQ_data_ADDR_END 1131 +#define S_DMIC1_EQ_data_sizeof 17 + +#define S_DMIC2_EQ_data_ADDR 1132 +#define S_DMIC2_EQ_data_ADDR_END 1148 +#define S_DMIC2_EQ_data_sizeof 17 + +#define S_DMIC3_EQ_data_ADDR 1149 +#define S_DMIC3_EQ_data_ADDR_END 1165 +#define S_DMIC3_EQ_data_sizeof 17 + +#define S_Voice_F_data_ADDR 1166 +#define S_Voice_F_data_ADDR_END 1182 +#define S_Voice_F_data_sizeof 17 + +#define S_Voice_8k_UL_ADDR 1183 +#define S_Voice_8k_UL_ADDR_END 1185 +#define S_Voice_8k_UL_sizeof 3 + +#define S_Voice_8k_DL_ADDR 1186 +#define S_Voice_8k_DL_ADDR_END 1187 +#define S_Voice_8k_DL_sizeof 2 + +#define S_VX_DL_data_ADDR 1188 +#define S_VX_DL_data_ADDR_END 1204 +#define S_VX_DL_data_sizeof 17 + +#define S_McPDM_Out1_ADDR 1205 +#define S_McPDM_Out1_ADDR_END 1228 +#define S_McPDM_Out1_sizeof 24 + +#define S_McPDM_Out2_ADDR 1229 +#define S_McPDM_Out2_ADDR_END 1252 +#define S_McPDM_Out2_sizeof 24 + +#define S_McPDM_Out3_ADDR 1253 +#define S_McPDM_Out3_ADDR_END 1276 +#define S_McPDM_Out3_sizeof 24 + +#define S_McPDM_Out1_data_ADDR 1277 +#define S_McPDM_Out1_data_ADDR_END 1293 +#define S_McPDM_Out1_data_sizeof 17 + +#define S_McPDM_Out2_data_ADDR 1294 +#define S_McPDM_Out2_data_ADDR_END 1310 +#define S_McPDM_Out2_data_sizeof 17 + +#define S_McPDM_Out3_data_ADDR 1311 +#define S_McPDM_Out3_data_ADDR_END 1327 +#define S_McPDM_Out3_data_sizeof 17 + +#define S_Voice_16k_UL_ADDR 1328 +#define S_Voice_16k_UL_ADDR_END 1332 +#define S_Voice_16k_UL_sizeof 5 + +#define S_Voice_16k_DL_ADDR 1333 +#define S_Voice_16k_DL_ADDR_END 1336 +#define S_Voice_16k_DL_sizeof 4 + +#define S_XinASRC_DL_VX_ADDR 1337 +#define S_XinASRC_DL_VX_ADDR_END 1376 +#define S_XinASRC_DL_VX_sizeof 40 + +#define S_XinASRC_UL_VX_ADDR 1377 +#define S_XinASRC_UL_VX_ADDR_END 1416 +#define S_XinASRC_UL_VX_sizeof 40 + +#define S_XinASRC_DL_MM_ADDR 1417 +#define S_XinASRC_DL_MM_ADDR_END 1456 +#define S_XinASRC_DL_MM_sizeof 40 + +#define S_VX_REC_ADDR 1457 +#define S_VX_REC_ADDR_END 1468 +#define S_VX_REC_sizeof 12 + +#define S_VX_REC_L_ADDR 1469 +#define S_VX_REC_L_ADDR_END 1480 +#define S_VX_REC_L_sizeof 12 + +#define S_VX_REC_R_ADDR 1481 +#define S_VX_REC_R_ADDR_END 1492 +#define S_VX_REC_R_sizeof 12 + +#define S_DL2_M_L_ADDR 1493 +#define S_DL2_M_L_ADDR_END 1504 +#define S_DL2_M_L_sizeof 12 + +#define S_DL2_M_R_ADDR 1505 +#define S_DL2_M_R_ADDR_END 1516 +#define S_DL2_M_R_sizeof 12 + +#define S_DL2_M_LR_EQ_data_ADDR 1517 +#define S_DL2_M_LR_EQ_data_ADDR_END 1541 +#define S_DL2_M_LR_EQ_data_sizeof 25 + +#define S_DL1_M_EQ_data_ADDR 1542 +#define S_DL1_M_EQ_data_ADDR_END 1566 +#define S_DL1_M_EQ_data_sizeof 25 + +#define S_VX_DL_8_48_BP_data_ADDR 1567 +#define S_VX_DL_8_48_BP_data_ADDR_END 1579 +#define S_VX_DL_8_48_BP_data_sizeof 13 + +#define S_VX_DL_8_48_LP_data_ADDR 1580 +#define S_VX_DL_8_48_LP_data_ADDR_END 1592 +#define S_VX_DL_8_48_LP_data_sizeof 13 + +#define S_EARP_48_96_LP0_data_ADDR 1593 +#define S_EARP_48_96_LP0_data_ADDR_END 1605 +#define S_EARP_48_96_LP0_data_sizeof 13 + +#define S_EARP_48_96_LP1_data_ADDR 1606 +#define S_EARP_48_96_LP1_data_ADDR_END 1620 +#define S_EARP_48_96_LP1_data_sizeof 15 + +#define S_IHF_48_96_LP0_data_ADDR 1621 +#define S_IHF_48_96_LP0_data_ADDR_END 1633 +#define S_IHF_48_96_LP0_data_sizeof 13 + +#define S_IHF_48_96_LP1_data_ADDR 1634 +#define S_IHF_48_96_LP1_data_ADDR_END 1648 +#define S_IHF_48_96_LP1_data_sizeof 15 + +#define S_VX_DL_16_48_HP_data_ADDR 1649 +#define S_VX_DL_16_48_HP_data_ADDR_END 1655 +#define S_VX_DL_16_48_HP_data_sizeof 7 + +#define S_VX_DL_16_48_LP_data_ADDR 1656 +#define S_VX_DL_16_48_LP_data_ADDR_END 1668 +#define S_VX_DL_16_48_LP_data_sizeof 13 + +#define S_VX_UL_48_8_BP_data_ADDR 1669 +#define S_VX_UL_48_8_BP_data_ADDR_END 1681 +#define S_VX_UL_48_8_BP_data_sizeof 13 + +#define S_VX_UL_48_8_LP_data_ADDR 1682 +#define S_VX_UL_48_8_LP_data_ADDR_END 1694 +#define S_VX_UL_48_8_LP_data_sizeof 13 + +#define S_VX_UL_8_TEMP_ADDR 1695 +#define S_VX_UL_8_TEMP_ADDR_END 1696 +#define S_VX_UL_8_TEMP_sizeof 2 + +#define S_VX_UL_48_16_HP_data_ADDR 1697 +#define S_VX_UL_48_16_HP_data_ADDR_END 1703 +#define S_VX_UL_48_16_HP_data_sizeof 7 + +#define S_VX_UL_48_16_LP_data_ADDR 1704 +#define S_VX_UL_48_16_LP_data_ADDR_END 1716 +#define S_VX_UL_48_16_LP_data_sizeof 13 + +#define S_VX_UL_16_TEMP_ADDR 1717 +#define S_VX_UL_16_TEMP_ADDR_END 1720 +#define S_VX_UL_16_TEMP_sizeof 4 + +#define S_EANC_IIR_data_ADDR 1721 +#define S_EANC_IIR_data_ADDR_END 1737 +#define S_EANC_IIR_data_sizeof 17 + +#define S_EANC_SignalTemp_ADDR 1738 +#define S_EANC_SignalTemp_ADDR_END 1758 +#define S_EANC_SignalTemp_sizeof 21 + +#define S_EANC_Input_ADDR 1759 +#define S_EANC_Input_ADDR_END 1759 +#define S_EANC_Input_sizeof 1 + +#define S_EANC_Output_ADDR 1760 +#define S_EANC_Output_ADDR_END 1760 +#define S_EANC_Output_sizeof 1 + +#define S_APS_IIRmem1_ADDR 1761 +#define S_APS_IIRmem1_ADDR_END 1769 +#define S_APS_IIRmem1_sizeof 9 + +#define S_APS_IIRmem2_ADDR 1770 +#define S_APS_IIRmem2_ADDR_END 1772 +#define S_APS_IIRmem2_sizeof 3 + +#define S_APS_OutSamples_ADDR 1773 +#define S_APS_OutSamples_ADDR_END 1784 +#define S_APS_OutSamples_sizeof 12 + +#define S_XinASRC_ECHO_REF_ADDR 1785 +#define S_XinASRC_ECHO_REF_ADDR_END 1824 +#define S_XinASRC_ECHO_REF_sizeof 40 + +#define S_ECHO_REF_16K_ADDR 1825 +#define S_ECHO_REF_16K_ADDR_END 1829 +#define S_ECHO_REF_16K_sizeof 5 + +#define S_ECHO_REF_8K_ADDR 1830 +#define S_ECHO_REF_8K_ADDR_END 1832 +#define S_ECHO_REF_8K_sizeof 3 + +#define S_DL1_ADDR 1833 +#define S_DL1_ADDR_END 1844 +#define S_DL1_sizeof 12 + +#define S_APS_DL2_IIRmem1_ADDR 1845 +#define S_APS_DL2_IIRmem1_ADDR_END 1853 +#define S_APS_DL2_IIRmem1_sizeof 9 + +#define S_APS_DL2_L_IIRmem2_ADDR 1854 +#define S_APS_DL2_L_IIRmem2_ADDR_END 1856 +#define S_APS_DL2_L_IIRmem2_sizeof 3 + +#define S_APS_DL2_R_IIRmem2_ADDR 1857 +#define S_APS_DL2_R_IIRmem2_ADDR_END 1859 +#define S_APS_DL2_R_IIRmem2_sizeof 3 + +#define S_DL1_APS_ADDR 1860 +#define S_DL1_APS_ADDR_END 1871 +#define S_DL1_APS_sizeof 12 + +#define S_DL2_L_APS_ADDR 1872 +#define S_DL2_L_APS_ADDR_END 1883 +#define S_DL2_L_APS_sizeof 12 + +#define S_DL2_R_APS_ADDR 1884 +#define S_DL2_R_APS_ADDR_END 1895 +#define S_DL2_R_APS_sizeof 12 + +#define S_ECHO_REF_48_8_BP_data_ADDR 1896 +#define S_ECHO_REF_48_8_BP_data_ADDR_END 1908 +#define S_ECHO_REF_48_8_BP_data_sizeof 13 + +#define S_ECHO_REF_48_8_LP_data_ADDR 1909 +#define S_ECHO_REF_48_8_LP_data_ADDR_END 1921 +#define S_ECHO_REF_48_8_LP_data_sizeof 13 + +#define S_ECHO_REF_48_16_HP_data_ADDR 1922 +#define S_ECHO_REF_48_16_HP_data_ADDR_END 1928 +#define S_ECHO_REF_48_16_HP_data_sizeof 7 + +#define S_ECHO_REF_48_16_LP_data_ADDR 1929 +#define S_ECHO_REF_48_16_LP_data_ADDR_END 1941 +#define S_ECHO_REF_48_16_LP_data_sizeof 13 + +#define S_APS_DL1_EQ_data_ADDR 1942 +#define S_APS_DL1_EQ_data_ADDR_END 1950 +#define S_APS_DL1_EQ_data_sizeof 9 + +#define S_APS_DL2_EQ_data_ADDR 1951 +#define S_APS_DL2_EQ_data_ADDR_END 1959 +#define S_APS_DL2_EQ_data_sizeof 9 + + +#endif /* _ABESM_ADDR_H_ */ diff --git a/sound/soc/codecs/abe/abe_taskId.h b/sound/soc/codecs/abe/abe_taskId.h new file mode 100644 index 000000000000..03af8ab4ec5f --- /dev/null +++ b/sound/soc/codecs/abe/abe_taskId.h @@ -0,0 +1,110 @@ +/* + * 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. + * + * @file abe_taskid.h + * ABE Firmware Task ID for HAL control + * + * @path $(ABEPATH)\firmware\src\ + * + */ + +#ifndef __ABE_TASKID_H_ +#define __ABE_TASKID_H_ + +#define C_ABE_FW_TASK_test 0 +#define C_ABE_FW_TASK_void 1 +#define C_ABE_FW_TASK_cluster 2 +#define C_ABE_FW_TASK_DL1Mixer 3 +#define C_ABE_FW_TASK_DL2Mixer 4 +#define C_ABE_FW_TASK_EchoMixer 5 +#define C_ABE_FW_TASK_SideTone 6 +#define C_ABE_FW_TASK_SDTMixer 7 +#define C_ABE_FW_TASK_IO_DMIC 8 +#define C_ABE_FW_TASK_IO_DMIC2 9 +#define C_ABE_FW_TASK_AMIC_96_48_IIR 10 +#define C_ABE_FW_TASK_AMIC_96_48_DEC 11 +#define C_ABE_FW_TASK_AMIC_EQ 12 +#define C_ABE_FW_TASK_DMIC1_96_48_IIR 13 +#define C_ABE_FW_TASK_DMIC1_96_48_DEC 14 +#define C_ABE_FW_TASK_DMIC1_EQ 15 +#define C_ABE_FW_TASK_DMIC2_96_48_IIR 16 +#define C_ABE_FW_TASK_DMIC2_96_48_DEC 17 +#define C_ABE_FW_TASK_DMIC2_EQ 18 +#define C_ABE_FW_TASK_DMIC3_96_48_IIR 19 +#define C_ABE_FW_TASK_DMIC3_96_48_DEC 20 +#define C_ABE_FW_TASK_DMIC3_EQ 21 +#define C_ABE_FW_TASK_DMIC1_SPLIT 22 +#define C_ABE_FW_TASK_DMIC2_SPLIT 23 +#define C_ABE_FW_TASK_DMIC3_SPLIT 24 +#define C_ABE_FW_TASK_AMIC_SPLIT 25 +#define C_ABE_FW_TASK_IO_MM_UL_test 26 +#define C_ABE_FW_TASK_IO_MM_UL2_test 27 +#define C_ABE_FW_TASK_IO_VX_UL 28 +#define C_ABE_FW_TASK_IO_VX_DL 29 +#define C_ABE_FW_TASK_IO_TONES_DL 30 +#define C_ABE_FW_TASK_IO_MM_DL 31 +#define C_ABE_FW_TASK_IO_VIB_DL_test 32 +#define C_ABE_FW_TASK_IO_AMIC 33 +#define C_ABE_FW_TASK_McPDM_DL 34 +#define C_ABE_FW_TASK_VX_UL_ROUTING 35 +#define C_ABE_FW_TASK_MM_UL2_ROUTING 36 +#define C_ABE_FW_TASK_MM_UL_ROUTING 37 +#define C_ABE_FW_TASK_IO_MM_UL 38 +#define C_ABE_FW_TASK_IO_MM_UL2 39 +#define C_ABE_FW_TASK_ASRC_VX_DL_8 40 +#define C_ABE_FW_TASK_ASRC_VX_UL_8 41 +#define C_ABE_FW_TASK_ASRC_VX_DL_16 42 +#define C_ABE_FW_TASK_ASRC_VX_UL_16 43 +#define C_ABE_FW_TASK_ASRC_MM_DL 44 +#define C_ABE_FW_TASK_VXRECMixer 45 +#define C_ABE_FW_TASK_VXREC_SPLIT 46 +#define C_ABE_FW_TASK_ULMixer 47 +#define C_ABE_FW_TASK_MM_SPLIT 48 +#define C_ABE_FW_TASK_VX_DL_8_48_BP 49 +#define C_ABE_FW_TASK_VX_DL_8_48_0SR 50 +#define C_ABE_FW_TASK_VX_DL_8_48_LP 51 +#define C_ABE_FW_TASK_VX_DL_16_48_HP 52 +#define C_ABE_FW_TASK_VX_DL_16_48_0SR 53 +#define C_ABE_FW_TASK_VX_DL_16_48_LP 54 +#define C_ABE_FW_TASK_DL1_EQ 55 +#define C_ABE_FW_TASK_DL1_GAIN 56 +#define C_ABE_FW_TASK_EARP_48_96_LP0 57 +#define C_ABE_FW_TASK_EARP_48_96_0SR 58 +#define C_ABE_FW_TASK_EARP_48_96_LP1 59 +#define C_ABE_FW_TASK_DL2_EQ 60 +#define C_ABE_FW_TASK_DL2_GAIN 61 +#define C_ABE_FW_TASK_IHF_48_96_LP0 62 +#define C_ABE_FW_TASK_IHF_48_96_0SR 63 +#define C_ABE_FW_TASK_IHF_48_96_LP1 64 +#define C_ABE_FW_TASK_VX_UL_48_8_LP 65 +#define C_ABE_FW_TASK_VX_UL_48_8_DEC1 66 +#define C_ABE_FW_TASK_VX_UL_48_8_BP 67 +#define C_ABE_FW_TASK_VX_UL_48_16_LP 68 +#define C_ABE_FW_TASK_VX_UL_48_16_DEC1 69 +#define C_ABE_FW_TASK_VX_UL_48_16_HP 70 +#define C_ABE_FW_TASK_GAIN_UPDATE 71 +#define C_ABE_FW_TASK_DELAY_CMD 72 +#define C_ABE_FW_TASK_ASRC_ECHO_REF_8 73 +#define C_ABE_FW_TASK_ASRC_ECHO_REF_16 74 +#define C_ABE_FW_TASK_DL1_APS_IIR 75 +#define C_ABE_FW_TASK_DL1_APS_CORE 76 +#define C_ABE_FW_TASK_DL2_APS_IIR 77 +#define C_ABE_FW_TASK_DL2_APS_SPLIT 78 +#define C_ABE_FW_TASK_DL2_L_APS_CORE 79 +#define C_ABE_FW_TASK_DL2_R_APS_CORE 80 +#define C_ABE_FW_TASK_ECHO_REF_48_8_LP 81 +#define C_ABE_FW_TASK_ECHO_REF_48_8_DEC1 82 +#define C_ABE_FW_TASK_ECHO_REF_48_8_BP 83 +#define C_ABE_FW_TASK_ECHO_REF_48_16_LP 84 +#define C_ABE_FW_TASK_ECHO_REF_48_16_DEC1 85 +#define C_ABE_FW_TASK_ECHO_REF_48_16_HP 86 +#define C_ABE_FW_TASK_EANC 87 +#define C_ABE_FW_TASK_EANC_WRAP 88 +#define C_ABE_FW_TASK_DL1_APS_EQ 89 +#define C_ABE_FW_TASK_DL2_APS_EQ 90 + +#endif /* _ABE_TASKID_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..889e08aa4153 --- /dev/null +++ b/sound/soc/codecs/abe/abe_typ.h @@ -0,0 +1,716 @@ +/* + * 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_TYP.H + * + * AESS/ABE types + * + * @path + * @rev 01.00 + *! Revision History + *! 27-Nov-2008 Original (LLF) + *! 05-Jun-2009 V05 release + */ + + +#ifndef __ABETYP_ +#define __ABETYP_ + +/* + * 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 abe_uint32 abe_errc_t; + +/* + * OPENSL_ES TYPES + */ + +typedef abe_int8 SLint8; +typedef abe_uint8 SLuint8; +typedef abe_int16 SLint16; +typedef abe_uint16 SLuint16; +typedef abe_int32 SLint32; +typedef abe_uint32 SLuint32; + +typedef SLint16 abe_millibel; +typedef SLuint32 abe_millisecond; +typedef SLuint32 abe_milliHertz; +typedef SLint32 abe_millimeter; +typedef SLint32 abe_millidegree; +typedef SLint16 abe_permille; +typedef SLuint32 abe_microsecond; +typedef SLuint32 abe_result; + +typedef abe_int16 abe_gain_t; /* 2 bytes millibel (OPENSL_ES) */ +typedef abe_int32 abe_freq_t; /* 4 bytes millihertz */ +typedef abe_int32 abe_millis_t; /* 4 bytes milliseconds */ +typedef abe_int32 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 */ +/* sched task loops (250us / 272us with respectively 48kHz/44.1kHz on Phoenix)*/ + +typedef abe_int32 abe_fw_code_id; /* OMX type */ +typedef abe_int32 abe_dbg_t; /* debug filter */ + +typedef void (* abe_subroutine0) (void); /* subroutine with two parameters */ +typedef void (* abe_subroutine2) (abe_uint32, abe_uint32); +/* subroutine with two 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 { + OMAP4_1 = 1, + OMAP4_2 + } abe_memconf_t; + + +/* + * 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 { + OPP0 = 0, + OPP25, OPP50, OPP100 + } abe_opp_t; + + +/* + * DMIC DECIMATION RATIO + * + */ +typedef enum { + DEC16 = 16, + DEC25 = 25, + DEC32 = 32, + DEC40 = 40 +} abe_dmic_ratio_t; + +/* + * SEQUENCE CODE TYPE + * + * Index to the table of subroutines called in the sequence + */ +typedef enum { S1 = 1, + } abe_seq_code_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_16_LSB = 1, + MONO_MSB, TWO_MONO_MSB, STEREO_16_16, + STEREO_MSB, THREE_MSB, FOUR_MSB, FIVE_MSB, + SIX_MSB, SEVEN_MSB, EIGHT_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, + CIRCULAR_PORT_PROT, +} abe_port_protocol_switch_id; + +/* + * PORT IDs + */ +typedef enum { +/* AE sink ports - Uplink */ + DMIC_PORT1, /* digital microphones pairs */ + DMIC_PORT2, + DMIC_PORT3, + PDM_UL_PORT, /* analog MICs */ + BT_VX_UL_PORT, /* BT uplink */ + + /* AE source ports - Uplink */ + MM_UL_PORT, /* up to 5 stereo channels */ + MM_UL2_PORT, /* stereo FM record path */ + VX_UL_PORT, /* stereo FM record path */ + + /* AE sink ports - Downlink */ + MM_DL_PORT, /* multimedia player audio path */ + VX_DL_PORT, + TONES_DL_PORT, + VIB_DL_PORT, + + BT_VX_DL_PORT, /* AE source ports - Downlink */ + PDM_DL1_PORT, + MM_EXT_OUT_PORT, + PDM_DL2_PORT, + PDM_VIB_PORT, + + SCHD_DBG_PORT, /* dummy port used to declare the other tasks + of the scheduler */ + + LAST_PORT_ID + +} abe_port_id; + + +/* + * GAIN IDs + */ +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, // = 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, // = gain on AMIC pair + ECHO_REF_GAIN, + BT_VX_DL_OUT_GAIN, + BT_VX_UL_IN_GAIN, +} abe_gain_id; + +/* + * 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 anlg 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_EANC FEAT_GAINS+1 +/* active noise canceller */ +#define FEAT_SEQ FEAT_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, /* asr-converter for the vxdl path */ + ASRC2 = FEAT_ASRC2, /* asr-converter for the vxul path */ + ASRC3 = FEAT_ASRC3, /* asr-converter for the mm player */ + ASRC4 = FEAT_ASRC4, /* asr-converter for the vxul echo_ref*/ +} abe_asrc_id; + +typedef enum { + MIXDL1 = FEAT_MIXDL1, + MIXDL2 = FEAT_MIXDL2, + MIXSDT = FEAT_MIXSDT, + MIXECHO = FEAT_MIXECHO, + MIXEANC = FEAT_EANC, + MIXAUDUL = FEAT_MIXAUDUL, + MIXVXREC = FEAT_MIXVXREC, +} abe_mixer_id; + +typedef enum { + UPROUTE = FEAT_UPROUTE, +} abe_router_id; + +typedef enum { + GAINS = FEAT_GAINS, /* Misc tasks of the scheduler */ + SEQUENCE = FEAT_SEQ, + CONTROL = FEAT_CTL + } abe_schd_id; +/* + * EVENT GENERATORS + */ +typedef enum { + EVENT_MCPDM = 1, + EVENT_DMIC, EVENT_TIMER, + EVENT_McBSP, EVENT_McASP, EVENT_SLIMBUS, EVENT_DEFAULT, +} abe_event_id; + +/* + * types for API + */ + + + +/* + * GAIN_PORT_T + * + * 6 bytes The gains on ports have a programmable slope. This slope corresponds to a + * first order IIR filter. The micros_t field is translated to an IIR coefficient by the HAL. + */ +typedef struct { + abe_gain_t g0; + abe_micros_t ramp_time; +} abe_gain_port_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_uint8 equ_param1; + abe_uint8 equ_param2; + union { /* parameters are the direct and recursive coefficients in */ + abe_int32 type1 [NBEQ1]; /* Q6.26 integer fixed-point format. */ + struct { + abe_int32 freq [NBEQ2];/* params are the freq + (type "freq") and Q factors */ + abe_int32 gain [NBEQ2]; /* (type "gain") of each band. */ + } 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; + abe_millibel e2; +} abe_aps_energy_t; + + + +/* + * MIXER_T + * + * MIXER coeffs, Table of gain_t for the input gains of the mixer. + */ +typedef struct { + abe_gain_t gl [ABE_MAXNBGAIN_MIXER]; +} abe_mixer_t; + + +/* + * ROUTER_T + * + * table of indexes in unsigned bytes + */ +typedef abe_uint8 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; + /* Snd ATC index for SlimBus rx (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 */ + abe_uint32 thr_flow; + /* Data threshold for flow management */ + } 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 */ + abe_uint32 thr_flow; + /* Data threshold for flow management */ + } 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 iface to the Host using cache-flush */ + abe_uint32 cb_addr; + /* Address of the read/write pointers + size */ + abe_uint32 buf_addr; + /* DMEM buffer base address in bytes */ + abe_uint32 buf_size; + /* DMEM buffer size in bytes */ + abe_uint32 thr_irq; + /* Data thrshold before sending an IRQ to host or DMA */ + 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 thr_flow; + /* Data threshold for flow management */ + abe_uint32 dma_addr; + /* DMAreq address */ + abe_uint32 dma_data; + /* DMA/AESS = 1 << #DMA */ + } prot_dmareq; + + struct {/* DMAreq line for large Ping-Pong buffers */ + abe_uint32 buf_addr; + /* DMEM buffer address in bytes */ + abe_uint32 buf_size; + /* DMEM buffer size size in bytes */ + abe_uint32 irq_data; + /* DMA/AESS = 1 << #DMA */ + } prot_pingpong_lp; + + + struct {/* Circular buffer - dirt addressing to DMEM */ + abe_uint32 desc_addr; + /* Address of the read/write pointers */ + abe_uint32 buf_addr; + /* DMEM buffer base address in bytes */ + abe_uint32 buf_size; + /* DMEM buffer size in bytes */ + abe_uint32 thr_irq; + /* Data threshold before sending an IRQ to host or DMA */ + abe_uint32 irq_addr; + /* IRQ address (either MCU or DSP) */ + abe_uint32 irq_data; + /* IRQ data content loaded in the AESS IRQ register */ + abe_uint32 callback; + /* Call-back function upon IRQ reception */ + } prot_circular_buffer; + }p; + } abe_port_protocol_t; + + + +/* + * IO_task_descriptor + * + */ +typedef struct { + char type;/* (0 = disabled, R/W, ATC,PingPong,DMAreq,Slimbus) */ + char format;/* data formats */ + char smem_buffer; + char cmem_gain; + char atc1; + char atc2; + char n; + char IRQ; + char thr1; + char thr2; + char dma_address; + char dma_data; + char irq_route; + char asrc; +} abe_io_task_descriptor_t; + + +/* + * DMA_T + * + * dma structure for easing programming + */ +typedef struct { + void *data; /* Pointer to the first address of the */ + /* destination buffer (either DMA or Ping-Pong read/write pointers). */ + 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 time; + abe_seq_code_t code; + abe_int32 param1; + abe_int32 param2; +} abe_seq_t; + + +/* + * DRIFT_T + * + * ASRC drift parameter in [ppm] value + */ +typedef abe_int32 abe_drift_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; /* opt call-back indx 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;/* ptr and iteration countr of the xDMA */ + abe_uint16 feature_index [MAXFEATUREPORT]; + /* list of features associated to a port (EQ, APS, ... , ends with 0) */ +#if 0 + abe_millibel gain_calibration;/* gain tuning, default=0dB */ + +#endif + char name[NBCHARPORTNAME]; +} abe_port_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_uint16 min_opp; + char name[NBCHARFEATURENAME]; +} abe_feature_t; + + + +/* + * CALL-BACK AND OTHER SUBROUTINES + * + */ + +#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 +#define c_max_subroutine_index 1000 + + +#endif /* ifndef ABETYP */ diff --git a/sound/soc/codecs/abe/abe_typedef.h b/sound/soc/codecs/abe/abe_typedef.h new file mode 100644 index 000000000000..f80cf63d2182 --- /dev/null +++ b/sound/soc/codecs/abe/abe_typedef.h @@ -0,0 +1,333 @@ +/* + *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. +* @file ABE_typedef.h +* +* ABE Firmware generic types definition +* +* @path $(ABEPATH)\firmware\src\ +* +* @rev 00.05.01 +*/ + +#ifndef __ABE_TYPEDEF_H_ +#define __ABE_TYPEDEF_H_ + +#include "abe_define.h" +//------------------------------------------------------------- +// Basic types definition +//------------------------------------------------------------- +#ifdef __chess__ +typedef unsigned char ABE_uchar; +typedef signed char ABE_char; +typedef unsigned ABE_uint16; +typedef int ABE_int16; +typedef long ABE_int32; +typedef unsigned long ABE_uint32; +#else +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; +#endif + + +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; + +//------------------------------------------------------------- +// Commonly used structures +//------------------------------------------------------------- + +#ifdef __chess__ + +/** +* This is a structure description for ABE_SAtcDescriptor. This structuce contains +* descriptor for ATC regristers +* +* @param readPointer 7 bits for read pointer index +* @param bufSize 7 bits for circular buffer size +* @param IRQdest IRQ destination 0:DSP 1:MCU +* @param error report buffer access errors +* @param direction Circular buffer direction 0:IN 1:OUT +* @param empty Set to 1 is circular buffer empty +* @param writePointer 7 bits for write pointer index +* @param baseAddr 12 bits for circular buffer base address +* @param iteration_lower4 4 lower bits of iteration flied +* @param iteration_upper3 3 upper bits of iteration flied +* @param source Source ID +* @param dest Destination ID +* @param DescrAct 0: descriptor is not active 1:descriptor is active +*/ +/* ========================================================================== */ +typedef struct abeatcdescTag { + unsigned readPointer : 7; // Desc0 + unsigned reserved0 : 1; + unsigned bufSize : 7; + unsigned IRQdest : 1; + unsigned error : 1; + unsigned reserved1 : 5; + unsigned direction : 1; + unsigned empty : 1; + unsigned writePointer : 7; + unsigned reserved2 : 1; + unsigned baseAddr : 12; // Desc1 + unsigned iteration_lower4 : 4; // iteration field overlaps the 16 bits boundary + unsigned iteration_upper3 : 3; + unsigned source : 6; + unsigned dest : 6; + unsigned DescrAct : 1; +} ABE_SAtcDescriptor; +#else + +/* +* This is a structure description for ABE_SAtcDescriptor. This structuce contains +* descriptor for ATC regristers +* +* @param readPointer 7 bits for read pointer index +* @param bufSize 7 bits for circular buffer size +* @param IRQdest IRQ destination 0:DSP 1:MCU +* @param error report buffer access errors +* @param direction Circular buffer direction 0:IN 1:OUT +* @param empty Set to 1 is circular buffer empty +* @param writePointer 7 bits for write pointer index +* @param baseAddr 12 bits for circular buffer base address +* @param iteration 7 bits of iteration flied +* @param source Source ID +* @param dest Destination ID +* @param DescrAct 0: descriptor is not active 1:descriptor is active +*/ + +typedef struct abeatcdescTag{ + unsigned readPointer : 7; // Desc0 + unsigned reserved0 : 1; + unsigned bufSize : 7; + unsigned IRQdest : 1; + unsigned error : 1; + unsigned reserved1 : 5; + unsigned direction : 1; + unsigned empty : 1; + unsigned writePointer : 7; + unsigned reserved2 : 1; + unsigned baseAddr : 12; // Desc1 + unsigned iteration : 7; // iteration field overlaps the 16 bits boundary + unsigned source : 6; + unsigned dest : 6; + unsigned DescrAct : 1; +} ABE_SAtcDescriptor; +#endif +typedef ABE_SAtcDescriptor* pABE_SAtcDescriptor; + + +typedef struct abetaskTag{ + ABE_uchar iF; // Index of called function + ABE_uchar A0, A1, A2_3, A4_5; // Pointers for initprt + ABE_uchar R; // Pointer for initreg + ABE_uchar misc0, misc1; // Filling data to 32 bits alignment +} ABE_STask; +typedef ABE_STask* pABE_STask; +typedef ABE_STask** ppABE_STask; + +typedef struct abefifodescrTag{ //General purpose FIFO descriptor + union{ + struct{ + ABE_uint16 writePtr; + ABE_uint16 fifoStartAddr; + } s16; + ABE_uint32 writePtr_fifoStartAddr; + } Wp; + union{ + struct{ + ABE_uint16 readPtr; + ABE_uint16 fifoEndAddr; + } s16; + ABE_uint32 readPtr_fifoEndAddr; + } Rp; + ABE_uint16 fifoSize; + ABE_uint16 elementSize; +} ABE_SFiFoDescr; +typedef ABE_SFiFoDescr* pABE_SFiFoDescr; + +/* most of the times: p0 = dest addr, p1 = src addr, p2 = count */ +typedef struct abedelayedcommandTag{ + ABE_uint16 delay; // 0: immediat action, count down otherwise + ABE_uint16 p0; + ABE_uint16 p1; + ABE_uint16 p2; + ABE_uchar p3; // Added p3 param so that structure size is even + ABE_uchar code; // Action ID + ABE_uchar misc0, misc1; // Filling data to 32 bits alignment +} ABE_SDelayedCmd; +typedef ABE_SDelayedCmd* pABE_SDelayedCmd; + +typedef ABE_SDelayedCmd ABE_TDelayedCmdFifo[DCMD_FIFO_LENGTH]; +typedef ABE_TDelayedCmdFifo* pABE_TDelayedCmdFifo; +/* +typedef struct abedelayedcommandfifo{ + pABE_SDelayedCmd writePtr; + ABE_uint16 fill; // Filling data to 32 bits alignment + pABE_SDelayedCmd readPtr; + pABE_SDelayedCmd fifoEndAddr; +} ABE_SDelayedCmdFiFoDescr; +typedef ABE_SDelayedCmdFiFoDescr* pABE_SDelayedCmdFiFoDescr; +*/ +//------------------------------------------------------------- +//------------------------------------------------------------- +#ifdef __chess__ +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)(pABE_SDelayedCmd) clobbers(R0, R1, R2, R3, R4, R5, R6, R7, R13); +typedef void (*pABE_cmdFunctionsList[])(pABE_SDelayedCmd) 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 +//------------------------------------------------------------- +//------------------------------------------------------------- +// ABE Enum IO defines +enum ABE_EIOAction {ABE_IOAction_disabled, ABE_IOAction_read, ABE_IOAction_write}; +enum ABE_EIOType {ABE_EIOType_ATC, ABE_EIOType_pingPong, ABE_EIOType_DMAreq, ABE_EIOType_slimbus}; +enum ABE_EIOFormat {ABE_EIOFormat_32_lsb, ABE_EIOFormat_32_msb, ABE_EIOFormat_32_2x16, ABE_EIOFormat_32_2xMono}; + + +typedef struct abeiodescriptorTag{ + 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 threshold_1; //8 /* THR1; For stereo data, THR1 is provided by HAL as THR1<<1 */ + ABE_uchar threshold_2; //9 /* THR2; For stereo data, THR2 is provided by HAL as THR2<<1 */ + ABE_uchar update_1; //10 /* UP_1; For stereo data, UP_1 is provided by HAL as UP_1<<1 */ + ABE_uchar update_2; //11 /* UP_2; For stereo data, UP_2 is provided by HAL as UP_2<<1 */ + ABE_uchar data_size; //12 /* 0 for mono data, 1 for stereo data */ + ABE_uchar smem_addr; //13 /* internal SMEM buffer INITPTR pointer index */ + ABE_uchar flow_counter; //14 /* Flow error counter */ + ABE_uchar atc_irq_data; //15 /* data content to be loaded to "hw_ctrl_addr" */ + ABE_uchar atc_address; //16 /* ATC descriptor address */ + ABE_uchar direction_rw; //17 /* Read DMEM =0, Write DMEM =3 (ATC offset of the access pointer) */ + ABE_uchar padding16[2]; // To keep 32bits alignment, +} ABE_SIODescriptor; + +typedef ABE_SIODescriptor* pABE_SIODescriptor; +typedef ABE_SIODescriptor** ppABE_SIODescriptor; + +#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 threshold_1 8 /* THR1; For stereo data, THR1 is provided by HAL as THR1<<1 */ +#define threshold_2 9 /* THR2; For stereo data, THR2 is provided by HAL as THR2<<1 */ +#define update_1 10 /* UP_1; For stereo data, UP_1 is provided by HAL as UP_1<<1 */ +#define update_2 11 /* UP_2; For stereo data, UP_2 is provided by HAL as UP_2<<1 */ +#define data_size 12 /* 0 for mono data, 1 for stereo data */ +#define smem_addr 13 /* internal SMEM buffer INITPTR pointer index */ +#define flow_counter 14 /* Flow error counter */ +#define atc_irq_data 15 /* data content to be loaded to "hw_ctrl_addr" */ +#define atc_address 16 /* ATC descriptor address */ +#define direction_rw 17 /* Read DMEM =0, Write DMEM =3 (ATC offset of the access pointer) */ +#endif + +//------------------------------------------------------------- +//------------------------------------------------------------- +typedef struct abepackedbasesizetag{ + ABE_uint16 baseAddr; // Buffer base address in DM + ABE_uint16 samples; // number of samples (as written in SM) +} ABE_SPackedBaseSamples; +typedef ABE_SPackedBaseSamples* pABE_SPackedBaseSamples; +typedef union { + ABE_SPackedBaseSamples s16; + ABE_uint32 base_size; +} ABE_UBufferBaseSamples; +typedef ABE_UBufferBaseSamples* pABE_UBufferBaseSamples; + +/*typedef struct abepackedirqflagtag{ + ABE_uint16 flag; +} ABE_SPackedIrqFlag; +typedef ABE_SPackedIrqFlag* pABE_SPackedIrqFlag; +typedef union { + ABE_SPackedIrqFlag s16; + ABE_uint32 IrqFlag; +} ABE_UIrqFlag; +typedef ABE_UIrqFlag* pABE_UIrqFlag; +*/ +enum ABE_EPPNotificationMode {ABE_PP_IRQ = 1, ABE_PP_DMAReq}; +typedef struct abebuflistdescrTag { + ABE_uchar itCount; // + ABE_uchar itLimit; // Control IT sent + ABE_char drift_IO; // Filled by ASRC -1/0/+1, cleared by IO_task + ABE_uchar copy_subroutineID; // DM -> SM copy proc id + ABE_uchar notificationMode; // ABE_EPPNotificationMode + ABE_uchar dummy; // Used for 32 bits alignment + ABE_uint16 IRQ_DMA; // &postedIRQ or DMA flag (2^k, k=0..7) + ABE_uint16 sampleCount; // Number of samples to transfer each call + ABE_uint16 remainingSamples; // number of samples available in current buffer + ABE_uint16 workingBufAddr; // Not a pointer as it should be compiled by different systems... + ABE_uint16 lastBufAddr; // &B[lastUsedBuffer + 1] + ABE_UBufferBaseSamples B[MAX_MM_BUFFERS]; +} ABE_SBufferListDescriptor; +typedef ABE_SBufferListDescriptor* pABE_SBufferListDescriptor; +//------------------------------------------------------------- +//------------------------------------------------------------- +/* +typedef struct abedatafifodescrTag{ + ABE_int32* writePtr; + ABE_int32* readPtr; + ABE_int32* fifoStartAddr; + ABE_int32* fifoEndAddr; +} ABE_SDataFiFoDescr; +typedef ABE_SDataFiFoDescr* pABE_SDataFiFoDescr; +//------------------------------------------------------------- +//------------------------------------------------------------- +typedef struct abedebugitemTag{ + ABE_uint16 time; + ABE_uint16 data; +} ABE_SDebugItem; +typedef ABE_SDebugItem* pABE_SDebugItem; + +typedef ABE_SDebugItem ABE_TDebugFifo[DEBUG_FIFO_LENGTH]; +typedef ABE_TDebugFifo* pABE_TDebugFifo; + +typedef struct abedebugfifo{ + pABE_SDebugItem readPtr; + ABE_uint16 fill; // Filling data to 32 bits alignment + pABE_SDebugItem writePtr; + pABE_SDebugItem fifoEndAddr; +} ABE_SDebugFifoDescr; +typedef ABE_SDebugFifoDescr* pABE_SDebugFifoDescr; +//------------------------------------------------------------- +//------------------------------------------------------------- +typedef struct abesettaskTag{ // Used for multiFrame update + ABE_uint16 index; // index in multiFrame table + pABE_STask taskPtr; // task pointer to be set at multiFrame[0][index] +} ABE_SSetTask; +typedef ABE_SSetTask* pABE_SSetTask; +//------------------------------------------------------------- +//------------------------------------------------------------- +typedef struct abebigcircbufTag{ // + ABE_int16 tableAddr; // Byte address + ABE_int16 tableLength; // In samples + ABE_int16 writeIndex; // + ABE_uint16 fill; // Filling data to 32 bits alignment + ABE_int16 readIndex; // + ABE_int16 threshold; // + ABE_int16 IRQ; // + ABE_int16 IRQValue; // +} ABE_SBigCircularBufferDescr; +typedef ABE_SBigCircularBufferDescr* pABE_SBigCircularBufferDescr; +//------------------------------------------------------------- +//------------------------------------------------------------- +*/ + +#endif /* _ABE_TYPEDEF_H_ */ diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 4dbb853eef5a..efe38a404b96 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -26,7 +26,7 @@ #include <linux/pm.h> #include <linux/i2c.h> #include <linux/platform_device.h> -#include <linux/i2c/twl4030.h> +#include <linux/i2c/twl.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> @@ -174,7 +174,7 @@ static int twl4030_write(struct snd_soc_codec *codec, { twl4030_write_reg_cache(codec, reg, value); if (likely(reg < TWL4030_REG_SW_SHADOW)) - return twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, + return twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, reg); else return 0; @@ -230,25 +230,25 @@ static void twl4030_codec_mute(struct snd_soc_codec *codec, int mute) * Things to mute: Earpiece, PreDrivL/R, CarkitL/R */ reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_EAR_CTL); - twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, + twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, reg_val & (~TWL4030_EAR_GAIN), TWL4030_REG_EAR_CTL); reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PREDL_CTL); - twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, + twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, reg_val & (~TWL4030_PREDL_GAIN), TWL4030_REG_PREDL_CTL); reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PREDR_CTL); - twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, + twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, reg_val & (~TWL4030_PREDR_GAIN), TWL4030_REG_PREDL_CTL); reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PRECKL_CTL); - twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, + twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, reg_val & (~TWL4030_PRECKL_GAIN), TWL4030_REG_PRECKL_CTL); reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PRECKR_CTL); - twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, + twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, reg_val & (~TWL4030_PRECKR_GAIN), TWL4030_REG_PRECKR_CTL); @@ -304,7 +304,7 @@ static void twl4030_power_up(struct snd_soc_codec *codec) do { /* this takes a little while, so don't slam i2c */ udelay(2000); - twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, + twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, TWL4030_REG_ANAMICL); } while ((i++ < 100) && ((byte & TWL4030_CNCL_OFFSET_START) == @@ -645,7 +645,7 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp) mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] / twl4030->sysclk) + 1); /* Bypass the reg_cache to mute the headset */ - twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, + twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, hs_gain & (~0x0f), TWL4030_REG_HS_GAIN_SET); diff --git a/sound/soc/codecs/twl6030.h b/sound/soc/codecs/twl6030.h new file mode 100644 index 000000000000..7ba0bd3c8e15 --- /dev/null +++ b/sound/soc/codecs/twl6030.h @@ -0,0 +1,115 @@ +/* + * ALSA SoC TWL6030 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 __TWL6030_H__ +#define __TWL6030_H__ + +#define TWL6030_REG_ASICID 0x01 +#define TWL6030_REG_ASICREV 0x02 +#define TWL6030_REG_INTID 0x03 +#define TWL6030_REG_INTMR 0x04 +#define TWL6030_REG_NCPCTL 0x05 +#define TWL6030_REG_LDOCTL 0x06 +#define TWL6030_REG_HPPLLCTL 0x07 +#define TWL6030_REG_LPPLLCTL 0x08 +#define TWL6030_REG_LPPLLDIV 0x09 +#define TWL6030_REG_AMICBCTL 0x0A +#define TWL6030_REG_DMICBCTL 0x0B +#define TWL6030_REG_MICLCTL 0x0C +#define TWL6030_REG_MICRCTL 0x0D +#define TWL6030_REG_MICGAIN 0x0E +#define TWL6030_REG_LINEGAIN 0x0F +#define TWL6030_REG_HSLCTL 0x10 +#define TWL6030_REG_HSRCTL 0x11 +#define TWL6030_REG_HSGAIN 0x12 +#define TWL6030_REG_EARCTL 0x13 +#define TWL6030_REG_HFLCTL 0x14 +#define TWL6030_REG_HFLGAIN 0x15 +#define TWL6030_REG_HFRCTL 0x16 +#define TWL6030_REG_HFRGAIN 0x17 +#define TWL6030_REG_VIBCTLL 0x18 +#define TWL6030_REG_VIBDATL 0x19 +#define TWL6030_REG_VIBCTLR 0x1A +#define TWL6030_REG_VIBDATR 0x1B +#define TWL6030_REG_HKCTL1 0x1C +#define TWL6030_REG_HKCTL2 0x1D +#define TWL6030_REG_GPOCTL 0x1E +#define TWL6030_REG_ALB 0x1F +#define TWL6030_REG_DLB 0x20 +#define TWL6030_REG_TRIM1 0x28 +#define TWL6030_REG_TRIM2 0x29 +#define TWL6030_REG_TRIM3 0x2A +#define TWL6030_REG_HSOTRIM 0x2B +#define TWL6030_REG_HFOTRIM 0x2C +#define TWL6030_REG_ACCCTL 0x2D +#define TWL6030_REG_STATUS 0x2E + +#define TWL6030_CACHEREGNUM (TWL6030_REG_STATUS + 1) + +/* INTID (0x03) fields */ + +#define TWL6030_THINT 0x01 +#define TWL6030_PLUGINT 0x02 +#define TWL6030_UNPLUGINT 0x04 +#define TWL6030_HOOKINT 0x08 +#define TWL6030_HFINT 0x10 +#define TWL6030_VIBINT 0x20 +#define TWL6030_READYINT 0x40 + +/* HPPLLCTL (0x07) fields */ + +#define TWL6030_HPLLENA 0x01 +#define TWL6030_HPLLRST 0x02 +#define TWL6030_HPLLBP 0x04 +#define TWL6030_HPLLSQRENA 0x08 +#define TWL6030_HPLLSQRBP 0x10 +#define TWL6030_MCLK_12000KHZ (0 << 5) +#define TWL6030_MCLK_19200KHZ (1 << 5) +#define TWL6030_MCLK_26000KHZ (2 << 5) +#define TWL6030_MCLK_38400KHZ (3 << 5) +#define TWL6030_MCLK_MSK 0x60 + +#define TWL6030_SYSCLK_SEL_LPPLL 1 +#define TWL6030_SYSCLK_SEL_HPPLL 2 +#define TWL6030_SYSCLK_SEL_MCLK 3 + +/* LPPLLCTL (0x08) fields */ + +#define TWL6030_LPLLENA 0x01 +#define TWL6030_LPLLRST 0x02 +#define TWL6030_LPLLSEL 0x04 +#define TWL6030_LPLLFIN 0x08 +#define TWL6030_HPLLSEL 0x10 + +#define TWL6030_HPPLL_ID 1 +#define TWL6030_LPPLL_ID 2 + +/* HSLCTL (0x10) fields */ + +#define TWL6030_HSDACMODEL 0x02 +#define TWL6030_HSDRVMODEL 0x08 + +/* HSRCTL (0x11) fields */ + +#define TWL6030_HSDACMODER 0x02 +#define TWL6030_HSDRVMODER 0x08 + +#endif /* End of __TWL6030_H__ */ diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig index b771238662b6..e672850287e3 100644 --- a/sound/soc/omap/Kconfig +++ b/sound/soc/omap/Kconfig @@ -6,6 +6,9 @@ config SND_OMAP_SOC_MCBSP tristate select OMAP_MCBSP +config SND_OMAP_SOC_ABE + tristate + config SND_OMAP_SOC_N810 tristate "SoC Audio support for Nokia N810" depends on SND_OMAP_SOC && MACH_NOKIA_N810 && I2C @@ -56,6 +59,15 @@ 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 TWL6030_CORE && SND_OMAP_SOC && MACH_OMAP_4430SDP + select SND_OMAP_SOC_ABE + select SND_SOC_ABE_TWL6030 + help + Say Y if you want to add support for SoC audio on Texas Instruments + 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 a37f49862389..48e3fa5039b5 100644 --- a/sound/soc/omap/Makefile +++ b/sound/soc/omap/Makefile @@ -1,9 +1,11 @@ # OMAP Platform Support snd-soc-omap-objs := omap-pcm.o snd-soc-omap-mcbsp-objs := omap-mcbsp.o +snd-soc-omap-abe-objs := mcpdm.o omap-abe.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 # OMAP Machine Support snd-soc-n810-objs := n810.o @@ -12,6 +14,7 @@ snd-soc-overo-objs := overo.o snd-soc-omap2evm-objs := omap2evm.o snd-soc-omap3evm-objs := omap3evm.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 @@ -21,5 +24,6 @@ obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o obj-$(CONFIG_MACH_OMAP2EVM) += snd-soc-omap2evm.o obj-$(CONFIG_MACH_OMAP3EVM) += snd-soc-omap3evm.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 diff --git a/sound/soc/omap/mcpdm.c b/sound/soc/omap/mcpdm.c new file mode 100755 index 000000000000..ccfe9af5faa2 --- /dev/null +++ b/sound/soc/omap/mcpdm.c @@ -0,0 +1,491 @@ +/* + * mcpdm.c -- McPDM interface 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 + * + */ + +#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 void omap_mcpdm_write(u16 reg, u32 val) +{ + __raw_writel(val, mcpdm->io_base + reg); +} + +static int omap_mcpdm_read(u16 reg) +{ + return __raw_readl(mcpdm->io_base + reg); +} + +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"); +} +EXPORT_SYMBOL(omap_mcpdm_reg_dump); + +void omap_mcpdm_reset(int links, int reset) +{ + int ctrl = omap_mcpdm_read(MCPDM_CTRL); + + if (links & MCPDM_UPLINK) { + if (reset) + ctrl |= SW_UP_RST; + else + ctrl &= ~SW_UP_RST; + } + + if (links & MCPDM_DOWNLINK) { + if (reset) + ctrl |= SW_DN_RST; + else + ctrl &= ~SW_DN_RST; + } + + omap_mcpdm_write(MCPDM_CTRL, ctrl); +} +EXPORT_SYMBOL(omap_mcpdm_reset); + +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); +} +EXPORT_SYMBOL(omap_mcpdm_start); + +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); +} +EXPORT_SYMBOL(omap_mcpdm_stop); + +static int omap_mcpdm_get_channels(int links, int channels) +{ + int count; + + if (links & MCPDM_UPLINK) + channels &= PDM_UP_MASK | PDM_STATUS_MASK; + + if (links & MCPDM_DOWNLINK) + channels &= PDM_DN_MASK | PDM_CMD_MASK; + + /* Brian Kernighan's method for counting set bits */ + for (count = 0; channels; count++) + channels &= channels - 1; + + return count; +} + +int omap_mcpdm_set_uplink(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 & 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; +} +EXPORT_SYMBOL(omap_mcpdm_set_uplink); + +int omap_mcpdm_set_downlink(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 & 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; +} +EXPORT_SYMBOL(omap_mcpdm_set_downlink); + +int omap_mcpdm_clr_uplink(struct omap_mcpdm_link *uplink) +{ + int irq_mask = 0; + + if (!uplink) + return -EINVAL; + + /* Disable irq request generation */ + irq_mask |= uplink->irq_mask & 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; +} +EXPORT_SYMBOL(omap_mcpdm_clr_uplink); + +int omap_mcpdm_clr_downlink(struct omap_mcpdm_link *downlink) +{ + int irq_mask = 0; + + if (!downlink) + return -EINVAL; + + /* Disable irq request generation */ + irq_mask |= downlink->irq_mask & 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; +} +EXPORT_SYMBOL(omap_mcpdm_clr_downlink); + +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); + + switch (irq_status) { + case DN_IRQ_FULL: + case DN_IRQ_EMTPY: + dev_err(mcpdm_irq->dev, "DN FIFO error %x\n", irq_status); + omap_mcpdm_reset(MCPDM_DOWNLINK, 1); + omap_mcpdm_set_downlink(mcpdm_irq->downlink); + omap_mcpdm_reset(MCPDM_DOWNLINK, 0); + break; + case DN_IRQ: + dev_dbg(mcpdm_irq->dev, "DN write request\n"); + break; + case UP_IRQ_FULL: + case UP_IRQ_EMPTY: + dev_err(mcpdm_irq->dev, "UP FIFO error %x\n", irq_status); + omap_mcpdm_reset(MCPDM_UPLINK, 1); + omap_mcpdm_set_uplink(mcpdm_irq->uplink); + omap_mcpdm_reset(MCPDM_UPLINK, 0); + break; + case UP_IRQ: + dev_dbg(mcpdm_irq->dev, "UP write request\n"); + break; + } + + return IRQ_HANDLED; +} + +int omap_mcpdm_request(void) +{ + int ret; + + clk_enable(mcpdm->clk); + + spin_lock(&mcpdm->lock); + + if (!mcpdm->free) { + dev_err(mcpdm->dev, "McPDM interface is in use\n"); + spin_unlock(&mcpdm->lock); + return -EBUSY; + } + 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"); + return ret; + } + + return 0; +} +EXPORT_SYMBOL(omap_mcpdm_request); + +void omap_mcpdm_free(void) +{ + clk_disable(mcpdm->clk); + + 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); + + free_irq(mcpdm->irq, (void *)mcpdm); +} +EXPORT_SYMBOL(omap_mcpdm_free); + +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); + + /* Enable/disable offset cancellation for downlink channel 1 */ + if (offset1) + offset |= DN_OFST_RX1_EN; + else + offset &= ~DN_OFST_RX1_EN; + + /* Enable/disable offset cancellation for downlink channel 2 */ + if (offset2) + offset |= DN_OFST_RX2_EN; + else + offset &= ~DN_OFST_RX2_EN; + + omap_mcpdm_write(MCPDM_DN_OFFSET, offset); + + return 0; +} +EXPORT_SYMBOL(omap_mcpdm_set_offset); + +static int __devinit omap_mcpdm_probe(struct platform_device *pdev) +{ + struct omap_mcpdm_platform_data *pdata = pdev->dev.platform_data; + int ret = 0; + + if (!pdata) { + dev_err(&pdev->dev, "McPDM device initialized without " + "platform data\n"); + ret = -EINVAL; + goto exit; + } + dev_dbg(&pdev->dev, "Initializing OMAP McPDM driver \n"); + + mcpdm = kzalloc(sizeof(struct omap_mcpdm), GFP_KERNEL); + if (!mcpdm) { + ret = -ENOMEM; + goto exit; + } + + spin_lock_init(&mcpdm->lock); + mcpdm->free = 1; + mcpdm->phys_base = pdata->phys_base; + mcpdm->io_base = ioremap(mcpdm->phys_base, SZ_4K); + if (!mcpdm->io_base) { + ret = -ENOMEM; + goto err_ioremap; + } + + mcpdm->irq = pdata->irq; + + /* FIXME: Enable this ones correct clk nodes available */ + if (!cpu_is_omap44xx()) { + mcpdm->clk = clk_get(&pdev->dev, "fclk"); + if (IS_ERR(mcpdm->clk)) { + ret = PTR_ERR(mcpdm->clk); + dev_err(&pdev->dev, "unable to get fclk: %d\n", ret); + goto err_clk; + } + } + + mcpdm->pdata = pdata; + mcpdm->dev = &pdev->dev; + platform_set_drvdata(pdev, mcpdm); + + + return 0; + +err_clk: + iounmap(mcpdm->io_base); +err_ioremap: + kfree(mcpdm); +exit: + return ret; +} + +static int __devexit omap_mcpdm_remove(struct platform_device *pdev) +{ + struct omap_mcpdm *mcpdm_ptr = platform_get_drvdata(pdev); + + platform_set_drvdata(pdev, NULL); + + if (mcpdm_ptr) { + clk_disable(mcpdm_ptr->clk); + clk_put(mcpdm_ptr->clk); + + iounmap(mcpdm_ptr->io_base); + + mcpdm_ptr->clk = NULL; + mcpdm_ptr->free = 0; + mcpdm_ptr->dev = NULL; + } + + printk(KERN_INFO "McPDM driver removed \n"); + + return 0; +} + +static struct platform_driver omap_mcpdm_driver = { + .probe = omap_mcpdm_probe, + .remove = omap_mcpdm_remove, + .driver = { + .name = "omap-mcpdm", + }, +}; + +static struct platform_device *omap_mcpdm_device; + +static struct omap_mcpdm_platform_data mcpdm_pdata = { + .phys_base = OMAP44XX_MCPDM_BASE, + .irq = INT_44XX_MCPDM_IRQ, +}; + +static int __init omap_mcpdm_init(void) +{ + int ret; + struct platform_device *device; + + device = platform_device_alloc("omap-mcpdm", -1); + device->dev.platform_data = &mcpdm_pdata; + + omap_mcpdm_device = device; + (void) platform_device_add(omap_mcpdm_device); + + ret = platform_driver_register(&omap_mcpdm_driver); + if (ret) + goto error; + return 0; + +error: + printk(KERN_ERR "OMAP McPDM initialization error\n"); + return ret; +} +arch_initcall(omap_mcpdm_init); diff --git a/sound/soc/omap/mcpdm.h b/sound/soc/omap/mcpdm.h new file mode 100755 index 000000000000..c953e9519a29 --- /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 + * + */ + +#define OMAP44XX_MCPDM_BASE 0x40132000 +#define OMAP44XX_MCPDM_L3_BASE 0x49032000 + +/* 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 DN_IRQ (1 << 0) +#define DN_IRQ_EMTPY (1 << 1) +#define DN_IRQ_ALMST_EMPTY (1 << 2) +#define DN_IRQ_FULL (1 << 3) + +#define UP_IRQ (1 << 8) +#define UP_IRQ_EMPTY (1 << 9) +#define UP_IRQ_ALMST_FULL (1 << 10) +#define UP_IRQ_FULL (1 << 11) + +#define DOWNLINK_IRQ_MASK 0x00F +#define 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; +}; + +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; +}; + +void omap_mcpdm_reg_dump(void); +void omap_mcpdm_reset(int links, int reset); +void omap_mcpdm_start(int stream); +void omap_mcpdm_stop(int stream); +int omap_mcpdm_set_uplink(struct omap_mcpdm_link *uplink); +int omap_mcpdm_set_downlink(struct omap_mcpdm_link *downlink); +int omap_mcpdm_clr_uplink(struct omap_mcpdm_link *uplink); +int omap_mcpdm_clr_downlink(struct omap_mcpdm_link *downlink); +int omap_mcpdm_request(void); +void omap_mcpdm_free(void); +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..c4b0eec35413 --- /dev/null +++ b/sound/soc/omap/omap-abe.c @@ -0,0 +1,314 @@ +/* + * 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 <mach/control.h> +#include <mach/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; +}; + +static struct omap_mcpdm_link omap_mcpdm_links[] = { + /* downlink */ + { + .irq_mask = DN_IRQ_EMTPY | DN_IRQ_FULL, + .threshold = 1, + .format = PDMOUTFORMAT_LJUST, + .channels = PDM_DN_MASK | PDM_CMD_MASK, + }, + /* uplink */ + { + .irq_mask = UP_IRQ_EMPTY | UP_IRQ_FULL, + .threshold = 1, + .format = PDMOUTFORMAT_LJUST, + .channels = PDM_UP_MASK | PDM_STATUS_MASK, + }, +}; + +static struct omap_mcpdm_data mcpdm_data = { + .links = omap_mcpdm_links, + .active = 0, +}; + +/* + * Stream DMA parameters + */ +static struct omap_pcm_dma_data omap_abe_dai_dma_params[] = { + { + .name = "Audio downlink", + .dma_req = OMAP44XX_DMM_ABE_DMAREQ0, + .data_type = OMAP_DMA_DATA_TYPE_S32, + .sync_mode = OMAP_DMA_SYNC_PACKET, + }, + { + .name = "Audio uplink", + .dma_req = OMAP44XX_DMM_ABE_DMAREQ2, + .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; + int err = 0; + + if (!cpu_dai->active) + 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; + + if (!cpu_dai->active) + omap_mcpdm_free(); +} + +static int omap_abe_dai_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_dai *cpu_dai = rtd->dai->cpu_dai; + struct omap_mcpdm_data *mcpdm_priv = cpu_dai->private_data; + int stream = substream->stream; + int err = 0; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + if (!mcpdm_priv->active++) + omap_mcpdm_start(stream); + break; + + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + if (!--mcpdm_priv->active) + omap_mcpdm_stop(stream); + break; + default: + err = -EINVAL; + } + + return err; +} + +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; + abe_dma_t dma_params; + + /* get abe dma data */ + switch (cpu_dai->id) { + case OMAP_ABE_MM_DAI: + if (stream) + abe_read_port_address(MM_UL2_PORT, &dma_params); + else + abe_read_port_address(MM_DL_PORT, &dma_params); + break; + case OMAP_ABE_MM_EXT_DAI: + if (stream) + return -EINVAL; + else + abe_read_port_address(TONES_DL_PORT, &dma_params); + break; + case OMAP_ABE_VOICE_DAI: + if (stream) + abe_read_port_address(VX_UL_PORT, &dma_params); + else + abe_read_port_address(VX_DL_PORT, &dma_params); + break; + case OMAP_ABE_DIG_UPLINK_DAI: + if (stream) + abe_read_port_address(MM_UL_PORT, &dma_params); + else + return -EINVAL; + break; + case OMAP_ABE_VIB_DAI: + if (stream) + return -EINVAL; + else + abe_read_port_address(VIB_DL_PORT, &dma_params); + default: + return -EINVAL; + } + + 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) + err = omap_mcpdm_set_uplink(&mcpdm_links[stream]); + else + err = omap_mcpdm_set_downlink(&mcpdm_links[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 err; + + if (substream->stream) + err = omap_mcpdm_clr_uplink(&mcpdm_links[substream->stream]); + else + err = omap_mcpdm_clr_downlink(&mcpdm_links[substream->stream]); + + return err; +} + +static struct snd_soc_dai_ops omap_abe_dai_ops = { + .startup = omap_abe_dai_startup, + .shutdown = omap_abe_dai_shutdown, + .trigger = omap_abe_dai_trigger, + .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 = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, + .formats = OMAP_ABE_FORMATS, + }, + .capture = { + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_48000, + .formats = OMAP_ABE_FORMATS, + }, + .ops = &omap_abe_dai_ops, + .private_data = &mcpdm_data, + }, + { + .name = "omap-abe-mm-ext", + .id = OMAP_ABE_MM_EXT_DAI, + .playback = { + .channels_min = 2, + .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 = 2, + .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..1c23b3b7fe36 --- /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_MM_EXT_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-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index a5d46a7b196a..72de1eb47ed0 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -238,6 +238,10 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, substream->stream ? "Audio Capture" : "Audio Playback"; 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].data_type = + OMAP_DMA_DATA_TYPE_S16; + omap_mcbsp_dai_dma_params[id][substream->stream].sync_mode = + OMAP_DMA_SYNC_ELEMENT; cpu_dai->dma_data = &omap_mcbsp_dai_dma_params[id][substream->stream]; if (mcbsp_data->configured) { diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index 84a1950880eb..fd8e6f2d6af5 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, @@ -135,6 +136,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 */ @@ -146,9 +148,9 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream) * 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 = OMAP_DMA_SYNC_ELEMENT; + dma_params.sync_mode = dma_data->sync_mode; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { dma_params.src_amode = OMAP_DMA_AMODE_POST_INC; dma_params.dst_amode = OMAP_DMA_AMODE_CONSTANT; @@ -156,6 +158,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; @@ -163,6 +166,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 @@ -170,7 +174,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); diff --git a/sound/soc/omap/omap-pcm.h b/sound/soc/omap/omap-pcm.h index 8d9d26916b05..d58082d568a8 100644 --- a/sound/soc/omap/omap-pcm.h +++ b/sound/soc/omap/omap-pcm.h @@ -29,6 +29,9 @@ struct omap_pcm_dma_data { char *name; /* stream identifier */ int dma_req; /* DMA request line */ unsigned long port_addr; /* transmit/receive register */ + int data_type; /* data type 8,16,32 */ + int sync_mode; /* sync mode: element, packet */ + 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..4bf7466bf70a --- /dev/null +++ b/sound/soc/omap/sdp4430.c @@ -0,0 +1,281 @@ +/* + * 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/irq.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 <mach/hardware.h> +#include <mach/gpio.h> +#include <mach/mux.h> +#include <mach/irqs.h> + +#include "mcpdm.h" +#include "omap-abe.h" +#include "omap-pcm.h" +#include "../codecs/twl6030.h" +#include "../codecs/abe-twl6030.h" + +#define TWL6030_AUDPWRON_GPIO 127 + +static struct snd_soc_card snd_soc_sdp4430; + +static int sdp4430_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; + int rate, clk_id, pll_id, freq_in, freq_out; + int ret; + + rate = params_rate(params); + switch (rate) { + case 44100: + clk_id = TWL6030_SYSCLK_SEL_LPPLL; + pll_id = TWL6030_LPPLL_ID; + freq_in = 32768; + freq_out = 17640000; + break; + case 48000: + clk_id = TWL6030_SYSCLK_SEL_HPPLL; + pll_id = TWL6030_HPPLL_ID; + freq_in = 12000000; + freq_out = 19200000; + break; + default: + printk(KERN_ERR "unknown rate %d\n", rate); + return -EINVAL; + } + + /* Set the codec pll divider */ + ret = snd_soc_dai_set_pll(codec_dai, pll_id, freq_in, freq_out); + if (ret < 0) { + printk(KERN_ERR "can't set codec pll frequency\n"); + return ret; + } + + /* Set the codec system clock for DAC and ADC */ + ret = snd_soc_dai_set_sysclk(codec_dai, clk_id, freq_in, SND_SOC_CLOCK_IN); + if (ret < 0) { + printk(KERN_ERR "can't set codec system clock\n"); + return ret; + } + + return 0; +} + +static struct snd_soc_ops sdp4430_ops = { + .hw_params = sdp4430_hw_params, +}; + +/* SDP4430 machine DAPM */ +static const struct snd_soc_dapm_widget sdp4430_twl6030_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), +}; + +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"}, +}; + +static int sdp4430_twl6030_init(struct snd_soc_codec *codec) +{ + int ret; + + /* Add SDP4430 specific widgets */ + ret = snd_soc_dapm_new_controls(codec, sdp4430_twl6030_dapm_widgets, + ARRAY_SIZE(sdp4430_twl6030_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"); + + /* TWL6030 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; +} + +/* Digital audio interface glue - connects codec <--> CPU */ +static struct snd_soc_dai_link sdp4430_dai[] = { + { + .name = "abe-twl6030", + .stream_name = "Multimedia", + .cpu_dai = &omap_abe_dai[OMAP_ABE_MM_DAI], + .codec_dai = &abe_dai[0], + .init = sdp4430_twl6030_init, + .ops = &sdp4430_ops, + }, + { + .name = "abe-twl6030", + .stream_name = "Multimedia Extended", + .cpu_dai = &omap_abe_dai[OMAP_ABE_MM_EXT_DAI], + .codec_dai = &abe_dai[1], + .ops = &sdp4430_ops, + }, + { + .name = "abe-twl6030", + .stream_name = "Voice", + .cpu_dai = &omap_abe_dai[OMAP_ABE_VOICE_DAI], + .codec_dai = &abe_dai[2], + .ops = &sdp4430_ops, + }, + { + .name = "abe-twl6030", + .stream_name = "Digital Uplink", + .cpu_dai = &omap_abe_dai[OMAP_ABE_DIG_UPLINK_DAI], + .codec_dai = &abe_dai[3], + }, + { + .name = "abe-twl6030", + .stream_name = "Vibrator", + .cpu_dai = &omap_abe_dai[OMAP_ABE_VIB_DAI], + .codec_dai = &abe_dai[4], + }, +}; + +static void twl6030_codec_enable(int enable) +{ + gpio_set_value(TWL6030_AUDPWRON_GPIO, enable); +} + +static struct twl6030_setup_data twl6030_setup = { + .codec_enable = twl6030_codec_enable, + .irq = INT_44XX_SYS_NIRQ2, +}; + +/* 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_twl6030, + .codec_data = &twl6030_setup, +}; + +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"); + + 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; + + /* twl6030 audio power-on gpio */ + ret = gpio_request(TWL6030_AUDPWRON_GPIO, "audpwron"); + if (ret) + goto err1; + + gpio_direction_output(TWL6030_AUDPWRON_GPIO, 0); + + /* audio interrupt */ + INIT_WORK(&twl6030_setup.audint_work, twl6030_naudint_work); + + init_completion(&(twl6030_setup.ready_completion)); + + ret = request_irq(twl6030_setup.irq, + twl6030_naudint_handler, + IRQF_TRIGGER_LOW | IRQF_DISABLED, + "soc-audio", + &twl6030_setup); + if (ret) + goto err2; + + ret = platform_device_add(sdp4430_snd_device); + if (ret) + goto err3; + + return 0; +err3: + free_irq(twl6030_setup.irq, &twl6030_setup); +err2: + gpio_free(TWL6030_AUDPWRON_GPIO); +err1: + 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) +{ + free_irq(twl6030_setup.irq, &twl6030_setup); + gpio_free(TWL6030_AUDPWRON_GPIO); + 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"); + |