From 242fd63f54eba0c7ca6e5fb3b5a55412cc9d9dbf Mon Sep 17 00:00:00 2001 From: David Brown Date: Thu, 10 Jan 2013 16:25:33 -0800 Subject: [PATCH] msm: vidc: Video driver support for MSM SOCs Including the following commits: commit 827990a603b5cc329396d4050259b4df13c8a936 Author: Deepak Verma Date: Wed Dec 5 12:55:01 2012 +0530 msm: vidc: Separate meta buffers support in secure mode Extradata is appended at the end of each output buffer in non secure video use case but in secure video playback, the client/CPU don't have access to the output buffer to parse the extradata. This change allows the client/CPU to parse the extradata by allocating separate buffers for video hardware to store extradata. Change-Id: Iace175ae8ee81ab02a2bac2810d1bb13b51e5a0b Signed-off-by: Deepak Verma commit 1af9051387bad64a5b6469464de5182d3f0d1265 Author: Maheshwar Ajja Date: Sat Oct 20 16:51:22 2012 +0530 msm: vidc: Add LTR feature for H264 encoder This change adds Long Term Reference picture selection feature for H264 video encoder. Change-Id: I7b9ba82d25a249e5663f25d6f7c81e5f1aefc071 Signed-off-by: Maheshwar Ajja commit c165675bf03feb182bfd46d2ac5ceebcf4987f74 Author: Rajeshwar Kurapaty Date: Tue Dec 11 19:26:49 2012 +0530 msm: vidc: Amend the check to reset data corrupt flag We should reset the data corrupt flag only for codecs other than H264 and MPEG-2 in line with the video firmware support. Hence, modify the conditional check. Change-Id: I7c4d5557a3f9b1d1762fe7cfcd5693a6760188f0 Signed-off-by: Rajeshwar Kurapaty commit 784a03e0694d6409a30fdf3a3c32ea3412126fe1 Author: Gopikrishnaiah Anandan Date: Wed Dec 5 17:53:12 2012 -0500 vidc: Disable error logs in video driver. Change disables error logs in the video driver which was enabled by default. CRs-fixed: 429938 Change-Id: I9288b4e49f87c01fd4e8e9aef74471dac696adce Signed-off-by: Gopikrishnaiah Anandan commit 8084f4f40b8b6d66d2b5c6a572b4f22c6817d75b Author: Shobhit Pandey Date: Tue Nov 27 11:12:54 2012 +0530 msm: vidc: Add support for H263 PlusPType flag Some video players does not support pluptype flag in H263 video format. This change adds support in video driver to enable or disable plusptype flag for H263 format. CRs-fixed: 420970 Change-Id: Ie0a78cba289227d51be1c83b83f633c75b446de9 Signed-off-by: Shobhit Pandey commit ce5f973881c11491c3fa35ceb8c945a6c8ee2b8f Author: Shobhit Pandey Date: Mon Nov 5 10:44:37 2012 +0530 msm: vidc: Modify the MPEG-2 aspect ratio calculation MPEG-2 display aspect ratio calculation was done similar to MPEG-4 standard. Correct it as per the MPEG-2 standard and video core interface specification. Change-Id: I1aa98ca238c7b38e35c78905b29457cfa59edd45 Signed-off-by: Shobhit Pandey commit d29699f68f348bf0a20be90b4c167e57c901a913 Author: Hariram Purushothaman Date: Mon Oct 29 16:46:26 2012 -0700 msm: Add camera special effects Add new camera special effects vintage warm, vintage cool, faded, accent green, accent blue and accent orange. Change-Id: Ie8a06ca64812834db05b2b81e3bc041a960463c1 Signed-off-by: Hariram Purushothaman commit 4f8bc3a092e88ffcefbbd1079e933dbd7680c1cb Author: Srinu Gorle Date: Thu Nov 15 09:36:38 2012 +0530 msm: vidc: Adds VUI timing info support for AVC encoding. Poor video quality is observed as VUI fps information is not present in the encoded bit stream. Add support for VUI timing info in video driver and an additional V4L2 control to set from user space. Change-Id: I3594903cb897920ea2ef93208644ac8c6ca5d5d9 CRs-Fixed: 399017 Signed-off-by: Srinu Gorle commit c84a451e5e540120ece63d9156d592fa523e410d Author: Maheshwar Ajja Date: Mon Nov 26 11:37:24 2012 +0530 vidc: Fix EOS handling if video h/w has a frame in transaction In case of video hardware is encoding a frame and EOS buffer with with zero data length arrived, set the EOS flag to the transaction available in the transaction table which will be passed to the client in frame done callback from the video hardware. CRs-fixed: 406950 Change-Id: I094c0cb46906873092044ee64fc1f1299df7a426 Signed-off-by: Maheshwar Ajja commit 8105df366cf6b9f1ddbc15d561fb6a5f12540416 Author: Srinu Gorle Date: Wed Nov 7 01:19:06 2012 +0530 msm: vidc: Avoid memset of list elements in the buffer entry. - Due to race condition between free buffer and flush output buffers, invalid buffer is getting accessed sometimes. - Reset all the members in buffer entry except list elements. Change-Id: Ia2a3bc4343fc557a6e6d7d9ad93a29a7ab3dfb81 CRs-Fixed: 411197 Signed-off-by: Srinu Gorle commit d68ca84da4a5c68eb2caf1f9e4dbb665bba5a05c Author: Rajeshwar Kurapaty Date: Mon Nov 19 19:15:50 2012 +0530 msm: vidc: Add support for Mpeg-2 open-gop handling ISDB-T client requires flags indicating the correctness of output YUV data from MPEG-2 decoder. With this commit, DATA_CORRUPT flag is sent from the driver if the output YUV is either INCORRECT or APPROX_CORRECT. Change-Id: I72e8ba81f45200715a195497d4eae140cbe86616 Signed-off-by: Rajeshwar Kurapaty commit ad602ee37a66d0dd2e23991fbc6a65f3cb296c12 Author: Riaz Rahaman Date: Wed Nov 14 10:15:57 2012 +0530 vidc: skip meta buffer header initialization in secure session Accessing meta buffer allocated from secure heap causes EBI errors due to permissions. Meta buffer header initialization not required in secure session, skip to initialize. Change-Id: I191dcc73ad84be98d832b69ebde60c0e13c89350 CRs-Fixed: 418217 Signed-off-by: Riaz Ur Rahaman commit 7f723dc68499812c492de39ca0577c1986dbd790 Author: Sreesudhan Ramakrish Ramkumar Date: Fri Oct 12 22:58:13 2012 -0700 msm: camera: Create v4l2 subdevice for flash modules All hardware module drivers except flash are created as v4l2 subdevices in msm camera architecture. This creates inconsistencies in treating hardware drivers at msm media controller layer. To have transparent framework and call flow, Create v4l2 sudevice for flash modules and register with msm mctl. Create drivers for individual flash modules and trigger flash functionalities based on wrapper functions initialized in function table. Create i2c driver for flash modules driven by i2c and platform driver otherwise. Change-Id: I15cf00f3f443edb2aeb8cf21ba41ce977c3d4c86 Signed-off-by: Sreesudhan Ramakrish Ramkumar commit c4a5719e6e1b68319daef8ee218b379bd415566f Author: Srinu Gorle Date: Sat Nov 3 21:08:56 2012 +0530 msm: vidc: port heap mask change to ion for secure session Changes to pass ION_SECURE in the correct argument field while calling ion_alloc. Without this change secure session fails. Change-Id: Ifa4878b1c312beafc735cb649570913159799d7c Signed-off-by: Srinu Gorle commit df2e15c49775f68d0af4db030e59e070663e02ff Author: Maheshwar Ajja Date: Thu Nov 1 06:29:56 2012 +0530 Vidc: Treat Non-IDR frame type error as bit stream error Hardware error is being generated from driver when video core returns NON IDR frame type error during thumbnail decoding. This change handles this error by treating it as BIT_STREAM_ERR. Change-Id: I16a19eea679d42a22b336d6ebbd0bd1f57c0a8a4 CRs-fixed: 414858 Signed-off-by: Maheshwar Ajja commit 77db8bb9741de2d09f52947a7f6dff89110f3f99 Author: Stephen Boyd Date: Wed Jun 27 15:15:16 2012 -0700 treewide: Replace pil_get()/put() with subsystem_get()/put() Do a tree wide sed to replace pil_get and pil_put() with their subsystem counterpart. With all the pil drivers migrated over to the new subsystem start/stop API this is essentially a no-op. We rename "q6" to "adsp" to be more in line with how future chipsets name the low power audio subsystem. This requires minor changes to userspace; hopefully no more changes will be necessary. Change-Id: I22dbbdcf7f5aaaa80394a6d70b5cfc24cdb32044 Signed-off-by: Stephen Boyd commit b17e0929632bbd5c9d228ae4d12c51b31afca057 Author: Deepak Verma Date: Tue Oct 23 14:30:30 2012 +0530 msm:vidc:Reset average decode time after setting DPB buffers In case of VGA/720p clips with higher frame rates, when average decode time taken by the core is found to be greater than 33ms, the clocks are bumped to the next level. But the calculation of average decode time was erroneous, due to which clocks started bumping up for other clips also. This change resets the average decode time after setting the DPB buffers and thus it corrects the calculation for average decode time. Change-Id: I3d7ab5a63e202a70a8e05f42dd4f989ce92b4bac CRs-fixed: 409475 Signed-off-by: Deepak Verma commit 31bb7dc8e3a4d01262727349b30bb3007fd474bd Author: Maheshwar Ajja Date: Wed Oct 31 10:04:28 2012 +0530 msm:vidc: Amend error checks on ION API failures This change will validate the ION API failures to fix target freeze issues. Change-Id: I00fee94955ba9f0e72734daccd22aa7d0bf86dda CRs-fixed: 412958 Signed-off-by: Maheshwar Ajja commit 5a60819aeb698b9d27937329bb5559a7a787a06e Author: Shobhit Pandey Date: Tue Oct 9 17:51:53 2012 +0530 msm: vidc: Correct the decoder profile info assignment Update the profile info in the sequence header with the info which the core returns in the shared memory register. CRs-fixed: 408349 Change-Id: Id8a284d048f8ca68f080fd59403c995b7a9e4637 Signed-off-by: Shobhit Pandey commit efc1225298ab93d5bb5c9894324804d6c6a6a0a3 Author: Peter Liu Date: Thu Sep 13 12:19:13 2012 -0700 msm: camera: add BE stats support for vfe40 1.Configure VFE Bayer Exposure(BE) stats registers to collect BE stats for 3A to decide total gain to apply on camera. 2.Add buffer support to collect Bayer Exposure stats for 3A to use. 3.Allocate and release buffer properly for BE stats. Change-Id: Ib857173aa195b9ff1d8b44cf7ba5f9a4a0d30621 Signed-off-by: Peter Liu commit a6e56522c41fe69a82a34ed99e03ba40b333e77c Author: Gopikrishnaiah Anandan Date: Wed Oct 3 16:39:50 2012 -0400 vidc: Turbo mode for multiple instances. If macroblock count per second goes beyond 1080p 30fps bump clock to turbo mode on supported platforms Change-Id: I48c34c9b6987706ea3e6b412b57791e2ae07ba52 Signed-off-by: Gopikrishnaiah Anandan Signed-off-by: Mohan Kumar Gubbihalli Lachma Naik commit 8c7e367a5ccd1c78c728657a14f08d6956b72e50 Author: Mohan Kumar Gubbihalli Lachma Naik Date: Wed Oct 3 20:23:47 2012 -0700 msm:vidc: Fix buffer pool index While searching for the available buffer entry in the buffer pool the search should begin from index 1 as zeroth entry is reserved. CRs-fixed: 366361 Change-Id: I051b0232bb782f073ba9ad0b757a799703814df3 Signed-off-by: Mohan Kumar Gubbihalli Lachma Naik commit 06079c8bfe77e8f2952396de1bfcd4711494a1de Author: Ankit Premrajka Date: Wed Aug 22 14:10:27 2012 -0700 msm: camera: remove 512 bytes limitation from ctrlcmd payload. This change removes the 512 bytes length limitation from the payload data passed to the server thread, as part of the control commands Change-Id: I871b6a6d467f86431bb5d701784231d7142d60d2 Signed-off-by: Ankit Premrajka commit 2cd6f1a77d845c162966b974b0e9dd4db0878020 Author: Arun Menon Date: Mon Oct 1 16:44:56 2012 -0700 msm: vidc: enable video core clock to 266Mhz This change will ensure that video core clock is set to 266Mhz on supported devices, else fallback to 228Mhz. Change-Id: Ia37271f5c762e6f5528f386077c90ec4a5034ca4 Signed-off-by: Arun Menon commit ed1430f0336a587a63729d2b698f9e23de46c95d Author: Aravind Venkateswaran Date: Wed Sep 12 17:00:27 2012 -0700 msm_fb: HDMI: Remove HDCP Kernelconfig Remove the kernel config parameter for HDCP since enabling or disabling HDCP will now be controlled using a corresponding module parameter. Change-Id: Iae23b8fa66ca75d99423547e77f850f3c86615ee Signed-off-by: Aravind Venkateswaran commit 7ea965018a5c758048f3e96d2ec50366def69997 Author: Aditya Jonnalagadda Date: Wed Sep 12 12:45:18 2012 +0530 msm : camera : Fix Livesnapshot issue Create a seperate image mode for vfe2x liveshot to select buffer from the proper queue based on proper image mode Change-Id: If98ba5ff200f8527bb2cb327f4693e54cd865dd3 Signed-off-by: Aditya Jonnalagadda commit efe5bf34b4a98849ab2dcd34945815e218308eaa Author: Srinu Gorle Date: Wed Sep 5 13:02:13 2012 +0530 msm: vidc: Adds AU delimiter support for AVC. Add new V4L2 control to set AU delimiter for AVC. Change-Id: I099c016de941b16c7e646474e371315224abe6bf CRs-Fixed: 389030 Signed-off-by: Srinu Gorle commit 76b9b4d881b32c13356c736a07b2ee363d5ddd9b Author: Mitchel Humpherys Date: Mon Sep 17 14:33:22 2012 -0700 ion: remove obsolete ion flags The symbols CACHED and UNCACHED have been replaced by ION_FLAG_CACHED upstream. This removes them from the kernel. Change-Id: I565dcc4595298ce6a0e81dd8cb98b86a1b38fdb2 Signed-off-by: Mitchel Humpherys commit 911b4b702a63fbd241863966cad45909e40e4665 Author: Mitchel Humpherys Date: Wed Sep 12 14:42:50 2012 -0700 ion: change ion kernel map function to not take flags argument Buffer flags are going to be specified at allocation time rather than map time. This removes the flags argument from the ion kernel map function. Change-Id: I91589ca7b1ab142bb5ac8e6b0f4c06fa1305f23a Signed-off-by: Mitchel Humpherys commit 7d72bad55a0e03392d81eee77a9a8c9df6b73a9a Author: Hanumant Singh Date: Wed Aug 29 18:39:44 2012 -0700 ion: Port heap mask change to ion Heap mask field passes as argument at allocation time to specify ion heap. Change-Id: I8881dfc491dc0f8f70581ad97b35756a6a33dd6d Signed-off-by: Hanumant Singh Signed-off-by: Mitchel Humpherys commit fde67e239d8ac3a1e983b7d82d0c37af47464138 Author: Rajeshwar Kurapaty Date: Fri Sep 14 16:18:34 2012 +0530 msm: vidc: Reset data corrupt flag for non-H264 decoder Core does not set display correctness flag on decoder output buffers for non H264 video codec. With this change, we reset the data corrupt flag for non-H264 codec. CRs-Fixed: 397599 Change-Id: Ibc7f701cf39e41ba6059ab1c1e09f83e77528a69 Signed-off-by: Rajeshwar Kurapaty commit e85abe76d75890d9a7c34d8e3b085d3787e37d7f Author: Gopikrishnaiah Anandan Date: Tue Sep 11 19:44:53 2012 -0400 vidc: Memset context buffers for non-secure playback. Driver will memset context buffers for non-secure playback. Change-Id: I6669481da3076a392061868475fc9844f2c41064 Signed-off-by: Gopikrishnaiah Anandan commit 43b203869814fe5f0ddcb265a8f859aebdaa652f Author: Gopikrishnaiah Anandan Date: Wed Sep 12 12:03:21 2012 -0400 vidc: Handle EOS with Codec config buffer. Change will handle codec config buffer with EOS. Video driver will make sure that the codec config buffer with EOS will be requeued in case of reconfig and non-reconfig paths. CRs-fixed: 399347 Change-Id: I94ed460b04b76663895c6690c2f866590ac51c7d Signed-off-by: Gopikrishnaiah Anandan commit f3658e53b1cf551dfbfe1544369beed80626b1c5 Author: Deepak Verma Date: Fri Sep 14 16:44:00 2012 +0530 msm: vidc: Correct the display size of small resolution clips We change the frame height in the decoder to MDP_MIN_TILE_HEIGHT for the videos with frame height less than 96. Due to which these videos were not being displayed properly. This change fixes the display change. Change-Id: I7acc74742a8cfbdfc79b02bd20bb9109f4389fa2 Signed-off-by: Deepak Verma commit 252fa6a4149870642b66a6b858754e280b01612d Author: Mitchel Humpherys Date: Thu Sep 6 10:28:47 2012 -0700 msm: camera: include msm-specific ion header All msm_ion clients need to use instead of Change-Id: I38fb66bb9d0cf4d279fc4536c4d165d798076968 Signed-off-by: Mitchel Humpherys commit 1356b5826e2f9c75ac3feef61ff31fa272a97232 Author: Srinu Gorle Date: Wed Sep 5 18:14:24 2012 +0530 msm: vidc: Enable turbo mode based on client request. - video core is bumped up to turbo mode, if more performance level required from multiple clients. - Enable turbo mode atleast one of client set turbo mode. Change-Id: Ied777463fdfe54ea6ff3b2a29cbaf0d27a9586cb CRs-Fixed: 385454 Signed-off-by: Srinu Gorle commit 221a948caac6f9e4132e0fd35c439b78aaa123f1 Author: Nishant Pandit Date: Mon Sep 3 05:36:04 2012 +0530 msm: camera: Enable RDI snapshot. Add support for snapshot through raw dump interface which bypasses image processing pipeline. This will be used in case of concurrent camera when PIX interface is used by one camera. Do a bus reload for ping pong buffers individually for each write master for every mode that it is started with, as a global reset command may not have been issued. Add separate bus scale parameter and keep the crystal clock unmodified in case of RDI camera snapshot operation in parallel with PIX camera. Change-Id: I8b1eb70e623ecd9cc8fe02b5a58e496aa2c016c4 Signed-off-by: Nishant Pandit Signed-off-by: Kiran Kumar H N commit b2295e885966a000cceedcfd4a6462113fe3be4a Author: Maheshwar Ajja Date: Tue Sep 11 21:18:12 2012 +0530 vidc: 1080p: IDR picture type support for H264 format Read IDR picture type from 1080p core register set and propagate it to user space using IDR frame type enumeration in api header file. The IDR frame type info is used in SYNCFRAME logic for H264 format in userspace. Change-Id: Ic677eb4d28469f6712832b7e09050467420eb70b Signed-off-by: Maheshwar Ajja commit 83a79a554d0039b94666f90d86409059700d6ec0 Author: Mitchel Humpherys Date: Thu Sep 6 10:49:02 2012 -0700 msm: vidc: include msm-specific ion header All msm_ion clients need to use instead of Change-Id: Iaea1b2949cbb1e58a33609f50bc2f96e8583245a Signed-off-by: Mitchel Humpherys commit 86ec84fd00c8d6d51ddf0acc2e03cb0f29d15e91 Author: Mingcheng Zhu Date: Sat Sep 8 21:20:51 2012 -0700 msm: camera: enhance global media controller lookup table The existing global lookup table cannot handle the use case that two camera devices uses the same image mode. Actually, for the SoC camera its pixel image mode are only used for post processing. Protection is added to enable this use case. Change-Id: I2b560bdc32417a22f0198c948e9734381c2e8f70 Signed-off-by: Mingcheng Zhu Signed-off-by: Kiran Kumar H N commit 4f9d27fa52364737a97f16f9379da3c515b49fd2 Author: Sreesudhan Ramakrish Ramkumar Date: Tue Aug 28 23:51:38 2012 -0700 msm: camera: Enable front camera or cam1 for 8974 Add support for CSID cores to enable CSID0 clocks by default since CSID1, CSID2 and CSID3 cores requires CSID0 clocks. Add support to extract phy-sel value from device tree node and pass it to CSID core. With phy-sel value in device tree node, sensor can choose CSIPHY core and CSID core to use for streaming. Reading buffer if probe fails causes CCI to enter into bad state and future I2C call fails. Avoid CCI from reading buffer if probe fails. Change-Id: I18334db0526c1b86f3f2713b63cd7e7c0d1ddb84 Signed-off-by: Sreesudhan Ramakrish Ramkumar commit f250c0e7b35bc1348d37721a1870bd4c9b27ba3a Author: Gopikrishnaiah Anandan Date: Fri Aug 17 17:15:02 2012 -0400 vidc: Handle descriptor buffer error as warning Driver will consider descriptor buffer empty error as warning and will continue to decode next frame. Change-Id: Ia89ea520131f9b3e1bbe68727c34fb72685d5af9 Signed-off-by: Gopikrishnaiah Anandan commit f01274b904a4899b13c64f35f2479a1080bfb2c4 Author: Deepak Verma Date: Fri Aug 24 18:15:58 2012 +0530 msm:vdec: Correct filled length of the output buffer Filled length of the output buffer at FBD for videos with frame height less than 96 was incorrect. With this change, we get the proper filled length. CRs-fixed: 395179 Change-Id: I12d60ef653225b0bf2f0088e515cac19a19ed80a Signed-off-by: Deepak Verma commit 9683019e54e8a8c38b6019b781a9cbdf41b84b29 Author: Gopikrishnaiah Anandan Date: Tue Sep 4 13:13:28 2012 -0400 vidc: Free client context in error cases. Video driver should free client context when an error is encoutered. Change-Id: I80255334ddbcb55a655795c0a7a10eb0cbf66cde Signed-off-by: Gopikrishnaiah Anandan commit d07478ceb1d9cb92dad90d64c507941bac3886e7 Author: Shobhit Pandey Date: Mon Aug 27 12:30:28 2012 +0530 msm:vidc: Add temporary buffer for MPEG-2 extension and user data. Support is added to enable temporary buffer for processing the MPEG-2 extension and user data for the first sequence done. Change-Id: I2274f87b43f4d193da7edb464918ec214ec12563 Signed-off-by: Shobhit Pandey commit 24631e349a3f306cc3b06fb411d5fb1f7ac8f0ae Author: Arun Menon Date: Thu Aug 16 13:53:19 2012 -0700 msm: vidc: suppress non-fatal error messages. These messages are non-fatal and appear frequently during video session. Hence suppressing them. CRs-Fixed: 389408 Change-Id: Ic77c9b57fdda58dd4eaf0fff2762df58335c7beb Signed-off-by: Arun Menon commit 4dd8c627764b9bd362f78085ed469969c2ddbe7f Author: Gopikrishnaiah Anandan Date: Tue Aug 28 14:21:32 2012 -0400 vidc: Error handling for memory heap mapping. Memory heap should be unsecured if secure call is successful. This change will make sure that an unsecure will be called only if securing of the memory heap went through fine. CRs-Fixed: 393041 Change-Id: I49dd81d1846fc6936518c750a32921c8498ddb95 Signed-off-by: Gopikrishnaiah Anandan Signed-off-by: Riaz Ur Rahaman commit 7f5ad416d565fb84766e4b0944bab5ee3dd2b42a Author: Deepak Verma Date: Thu Aug 30 18:03:26 2012 +0530 Revert "msm: vidc: Correct calculation of yuv buffer size" This change is giving side effect if frame height is non multiple of 16 for video encoder. This reverts commit 3a2945ef2385ae934ab4df98f26651d132b7b4fc. Change-Id: I522b8777b233faf8da736d6c62456fbc96262b0a Signed-off-by: Deepak Verma commit 909aebf7bd4d89fb5acccd64b27349cf93a736e0 Author: Maheshwar Ajja Date: Tue Jul 17 17:17:12 2012 +0530 vidc: fix wrong number of slices in slice delivery mode The slices completed is not matching with the expected number of slices in frame done. The fix is available in July firmware release and this commit will have the corresponding video driver changes. CRs-fixed: 380629 Change-Id: Ia5c2cce2e95e31deac023a6c855fd385494ee56b Signed-off-by: Maheshwar Ajja commit 51dbdc50dfb565d9ec15a1b3299fda3d928f83a5 Author: Mingcheng Zhu Date: Sun Aug 19 22:01:09 2012 -0700 msm-camera: adding new image mode for VFE streaming Added two more VFE stand along streaming modes. Change-Id: Ifd4c9647c66bcba41438ea11636f030519ed6511 Signed-off-by: Mingcheng Zhu commit d0003770b8cc828ab54adf115e0daf09ec47639c Author: Deva Ramasubramanian Date: Wed Aug 8 19:36:21 2012 -0700 msm: vidc: Use MM heap for prediction buffer during secure encode We are incorrectly using the firmware heap to allocate prediction buffers. This violates an agreement between TZ and HLOS that only the firmware will reside in the FW heap. As such, move the buffer to MM heap. Change-Id: I2c91499c38043abfa21ae3443d3a8f22d6474eaa CRs-fixed: 380161 Signed-off-by: Deva Ramasubramanian commit da817ebe8a4dea682b2cc9beaa582e0f0f0f0112 Author: Maheshwar Ajja Date: Thu Aug 23 18:53:49 2012 +0530 msm:vidc: add support for pause in eos state This commit will add support for pause command in eos state along with run state of the video driver. CRs-fixed: 387562 Change-Id: I2640badb59411757105d59fba276c466d4717e72 Signed-off-by: Maheshwar Ajja commit bdcf7ef9f4c83f138fe4f4d4e147a28bbe4463a0 Author: Kevin Chan Date: Fri Aug 24 08:33:33 2012 -0700 msm: camera: Sensors changes for 8974 Enable camera sensors for 8974 by changing clocks, regulator and gpio configuration in msm sensor modules. Change-Id: Ieed5e44e072fd4fb33c1b15b8d0ab0337c6fa865 Signed-off-by: Kevin Chan commit 7baf72acea6d6409eac18713ab9c66f418ce5aa4 Author: Maheshwar Ajja Date: Tue Jul 17 16:42:07 2012 +0530 vidc: 1080p: Copy input frame tag to the output frame tag In slice delivery mode, sometimes video hardware is giving zero frame tag on output slices instead of input frame tag value. This commit will fix the issue by copying the input frame tag value to the output slice frame tag when video hardware gives zero frame tag values. Change-Id: Id766a4801422d0d1f769f15a35dfd948d5c51535 Signed-off-by: Maheshwar Ajja Signed-off-by: Ramakrishna Prasad N commit 8688368ce3afbd1f3a80c7fa688c6a2f467247d3 Author: Arun Menon Date: Thu Aug 23 15:55:38 2012 -0700 msm: vidc: error handling for ion_map_iommu calls Added a check for non-zero virtual address. Without this change, when ion_map_iommu returns a zero virtual address, video core continuous ahead without error check and later target reset happens when trying to do a ion_unmap_iommu on the above fd, which was never mapped. Change-Id: Ifb400c5dd2cb859c43a0fe712298acaa6a663fec Signed-off-by: Arun Menon commit 2e68e3394a7f2f7ca9124d56c67252a9035d7cd7 Author: Kiran Kumar H N Date: Tue Aug 7 21:07:30 2012 -0700 msm: camera: Map/Unmap the VPE I/O buffers. Currently the input buffers and the output buffers configured to VPE are directly picked up from the v4l2 buffer queue, when a particular frame is sent to VPE for processing. This adds a condition that the input/output buffer should be present in the v4l2 buffer queue at all times. If the user wants to do some processing (for eg: Image stabilization) on the frame and then send it for VPE processing, this can not be achieved, since the frame would be dequeued by the user for processing. Add support to map these buffers when they are sent for processing and unmap them, when the user is receiving the processed buffer. Add two generic APIs msm_mctl_map_user_frame and msm_mctl_unmap_user_frame to perform the necessary map/unmap functionality. Change-Id: I5f1489b38844b5d2bcacb67a17f6d63e1aced342 Signed-off-by: Kiran Kumar H N commit b88c8c2de9479a9448325fc3887e47231577eefe Author: Jack Wang Date: Thu Jul 26 11:33:36 2012 -0700 msm: camera: Sensor kernel restructure Add new sensor utility functions for I2C write, I2C read, EEPROM read and gpio operation. This is to provide better control and flexibility for user space sensor module. Change-Id: I534c9c51768fcd8d00713bdcf87b63083a606ced Signed-off-by: Jack Wang commit 254f7e728d4ed366d1d783f23b75cf29b92c3f34 Author: Sreesudhan Ramakrish Ramkumar Date: Sat Mar 17 17:27:34 2012 -0700 msm: camera: Restructure CSI components Instead of sensor controlling CSI modules, move it user space and configure it through media controller. This is to make all v4l2 sub devs to function independently without the knowledge of other sub devs. Change-Id: Ie37dad8cb393f0b8deb65f330469e38eb374ba40 Signed-off-by: Sreesudhan Ramakrish Ramkumar commit 47e5657507e793ea00c3938c14edfb662af9ef93 Author: Lakshmi Narayana Kalavala Date: Fri Aug 10 20:05:55 2012 -0700 msm: camera: Add vb2 buffer support for parsed stats Add video buffer support for parsed vfe stats Change-Id: I14f1814a57187a0d80f0aa1b781762058bb62ad5 Signed-off-by: Lakshmi Narayana Kalavala commit 8c9bf5dcd7c1fdaa32a0855f3aa76ef45a8cc7c6 Author: Ankit Premrajka Date: Tue Aug 7 15:45:31 2012 -0700 msm: camera: add support for private general ioctl and event This change adds support for private commands going to the plugin and private events with payload going to HAL. Change-Id: Iceb3c3ad1fdc5f45f3bd552b727456ccf54bc006 Signed-off-by: Ankit Premrajka Signed-off-by: Mingcheng Zhu commit 5d00d6665dfe96e5b9c0da7a37ab6f8414a5cd0b Author: Ankit Premrajka Date: Mon Jul 30 09:42:26 2012 -0700 msm: camera: update rdi frame count from ISPIF SOF. The RDI frame id count needs to be updated based on SOF interrupts from ISPIF. This is unlike the PIX count which can(possibly) depend on SOF interrupts from CAMIF. Change-Id: I5a69f1d4dcc8aadc6defe896835c59415b84a445 Signed-off-by: Ankit Premrajka commit d778571b17baf792ef63f31cf9539722361818fc Author: Nishant Pandit Date: Tue Jul 31 19:09:11 2012 +0530 msm: camera: Enhance start stop logic in axi - Handle RDI start stop separately from PIX - Add separate call for axi halt - START_ACK is now redundant because PIX0_REG_UPDATE_ACK implies START_ACK. Change-Id: I84fa25310c4eb27feda65a224bea5bb3f7e32945 Signed-off-by: Nishant Pandit commit 4a60799ce946a4ab2a340a3f4557118eeb1603bc Author: Shobhit Pandey Date: Wed Aug 1 14:02:20 2012 +0530 msm:vidc: Add the support for MPEG-2 extension and user data Support is added for MPEG-2 extension and user data. With this changes Core returns extension and user data as an extradata. Change-Id: Icdb9da359d90799391b5b9751df2e735ff93475e Signed-off-by: Shobhit Pandey commit ca0b72b8a3b4b65250f517175fa4e3e0256c83df Author: Riaz Rahaman Date: Mon Jul 23 14:28:50 2012 +0530 msm: 8660: Add config setting for enabling content protection Enable content protection by setting CONFIG_MSM_VIDC_CONTENT_PROTECTION in target config file Change-Id: I8e9b43b6eb09a11c0b5d987903b8bbffde1572e3 Signed-off-by: Riaz Ur Rahaman commit 3a2945ef2385ae934ab4df98f26651d132b7b4fc Author: Deepak Verma Date: Fri Aug 10 15:22:07 2012 +0530 msm: vidc: Correct calculation of yuv buffer size Improper yuv buffer size is being calculated using frame height directly, which is resulting into failures during encoding if the frame height is not aligned to 16. With this change, yuv buffer size calculation is done properly by using scanlines in place of frame height. Change-Id: I22602d6a0eddfa4016f4bdc3479e5b7d9b89a4e7 CRs-Fixed: 378988 Signed-off-by: Deepak Verma commit 077943c80dc82358d1d8a143f8f88613c9e925d5 Author: Deepak Verma Date: Thu Aug 9 20:44:04 2012 +0530 msm: vidc: Reduce the priority of incorrect PAR value message We get the error message for the incorrect aspect ratio with each frame of the video. By reducing the priority, error message will appear only when we enable it. Change-Id: Iacb8002383ea6c0b7ee86e9cfe14478c0e5ca5c3 Signed-off-by: Rajeshwar Kurapaty commit 16145bcbd6af8db0eebc0eedec1f01ee1b0b3635 Author: Rajeshwar Kurapaty Date: Fri Aug 10 11:43:53 2012 +0530 vidc: 1080p: Reset meta data offset to zero For multi-resolution clips, the meta data offset used while doing cache clean of meta data buffer is from the previous resolution & resulting in kernel panic. Resetting the offset to zero during meta data buffer initialization for new resolution fixes the issue. Change-Id: I06b20e10efc837fcfe44f532e90293734b4d2df8 CRs-fixed: 386245 Signed-off-by: Rajeshwar Kurapaty commit 96458e214d9d8c98a1aeb13f52ef146672f8d82b Author: Mingcheng Zhu Date: Tue Aug 7 21:45:43 2012 -0700 msm: add new image modes to support stats buffer Extend the image mode defines to include the stats buffers. Change-Id: I4c7a687cb08695d43befa15f6e18e7070d4e2976 Signed-off-by: Mingcheng Zhu commit f19f4d27088015842f9bd0945f62b34e90fd784d Author: Gopikrishnaiah Anandan Date: Mon Jul 30 12:10:37 2012 -0400 vidc: 1080p: Handle flush for interlaced clips. Video core expects one field per buffer for interlaced clip playback.If a flush is issued we should reset the need next field flag, so that new bitstream is processed after flush is completed. Reconfig flag shouldn't be reset in case of EOS. Change-Id: Idf50a24c29e904a958b0b1e850813e2d9fc4346d CRs-fixed: 382368 Signed-off-by: Gopikrishnaiah Anandan commit 22d1abd7eec3bdba91f31fe3d8a1ea86d35e8568 Author: Maheshwar Ajja Date: Fri Jul 27 19:15:01 2012 +0530 msm: vidc: Add support for ION memory on 8x55 target This commit will add support for ION memory on 8x55 target for video encoder and decoder. Change-Id: I23be61d698cf3c6ee81846bad61be15b9e3f824f Signed-off-by: Maheshwar Ajja commit 3e8a1d1c69b56198e946e2fc45d054912965178f Author: Lakshmi Narayana Kalavala Date: Tue Jul 31 15:00:09 2012 -0700 msm: camera: Move ping pong buffer and bus scale logic from vfe to axi Move the ping pong buffer configuration and bus scaling logic from vfe to axi as for concurrent camera case, vfe component will be turned off Change-Id: I39b465dcc121b83f960370b25349dc941ac8c34b Signed-off-by: Nishant Pandit Signed-off-by: Lakshmi Narayana Kalavala commit 109c211daa5771cededece028ee2026fb3d22934 Author: Shuzhen Wang Date: Mon Jul 23 17:28:11 2012 -0700 vfe32: Separate AXI reset with VFE reset. Refactor reset to axi_reset and vfe_reset. axi_reset initializes stream off/on, irq related registers. vfe_reset only handles stuff related to VFE components. VFE_RESET_2 is removed. Both axi_reset and vfe_reset are synchronous calls. Change-Id: I274c17defbfbc56056b020c48239696b0f579b0e Signed-off-by: Shuzhen Wang commit d34791bd9bf218e636d4cb7f5b8b2956d38b27b1 Author: Peter Liu Date: Mon Jun 11 18:47:36 2012 -0700 msm: camera: calculate sof_count in ISPIF instead of VFE Instead of counting the frame id inside VFE camif, obtain the sof count in ispif and then pass the count into VFE also add the capability to enable the sof count in VFE Change-Id: I90c0178d933cb4c80627eb9a5f22b4bb13b10b27 Signed-off-by: Peter Liu commit 003ba6e4ac9a461ff935a0532cc826c614c2cd6e Author: Deepak Verma Date: Thu Aug 2 16:25:39 2012 +0530 msm: vidc: Add PAR value extradata support for H264 and Mpeg2 Core gives aspect ratio information for H264/Mpeg2 in a shared memory register. This change will fetch the value of the aspect ratio from the designated register and append this information to the frame_info extradata which can be used by the client. Change-Id: Iacacaf1b1181546ba2d09362a51bbe5178a63999 Signed-off-by: Deepak Verma commit cd3d81ef876be616e94c423a2a6b0395ff687b96 Author: Lakshmi Narayana Kalavala Date: Tue Jul 31 13:04:03 2012 -0700 msm: Decouple VFE component from AXI 1. Move the logic to enable write masters from vfe to axi as vfe component may not be enabled for concurrent camera 2. Pass the vfe operation mode and port info from user space instead of storing in the global shared variable Change-Id: Ibe01bbe6a449afc3e4116c0a1c5f0d68662c5ee6 Signed-off-by: Nishant Pandit Signed-off-by: Lakshmi Narayana Kalavala commit c842b613e6e090c06574b7b3c0d0166c4dfe6fb1 Author: Sreesudhan Ramakrish Ramkumar Date: Mon May 21 17:23:24 2012 -0700 msm: camera: CCI driver for 8974 Add Camera Control Interface (CCI) driver based on V4L2 architecture. Add probe sequence, subdevice creation, hardware registers and configuration through V4L2 subdev call mechanism. This driver is responsible for communicating with sensors, actuators and EEPROM connected on I2C bus. Change-Id: I2f135798e26348740f58da223caafdd8dfbbd098 Signed-off-by: Hody Hung Signed-off-by: Sreesudhan Ramakrish Ramkumar commit d812321dcb7fe15d0c62af549f18946320380129 Author: Sreesudhan Ramakrish Ramkumar Date: Sat Jun 30 13:15:27 2012 -0700 msm: camera: ISPIF changes for 8974. ISPIF changes on 8974 to include VFE interface. Pass VFE interface from user space ISPIF module and configure accordingly. Add support to configure extra PIX and RDI interfaces. Change-Id: Idb840fa3d1ef2d1a7242fc2175b8fa64f75aa14b Signed-off-by: Sreesudhan Ramakrish Ramkumar commit 586fd1628cdd10468e0d6496a77a236f18eaf9c7 Author: Kuogee Hsieh Date: Tue Feb 14 15:24:16 2012 -0800 msm_fb: display: vsync driven screen update This patch will queue multiple surfaces and commit those surfaces into mdp at same instance so that surfaces will be blended and displayed at same time. Hardware vsync event is delivered to the user space frame work via uevent. Both queue and commit are controlled by frame work and synchonized with vsync event. Therefore frame rate will match with vsync rate. Change-Id: If630a6d94fd38483ee313f575b1a71ed8bd65a52 Signed-off-by: Kuogee Hsieh commit 3118cb077358e472adb0db8e207a63bd84fd267f Author: Carl Vanderlip Date: Fri Jun 22 18:15:18 2012 -0700 video: msm: Remove old post processing overlay integration Remove old implementation of HSIC and QSEED smoothing/sharpening overlay integration. Need to replace with new implementation that better integrates the existing functions of the two APIs. CRs-Fixed: 380750 Change-Id: Id3469fad16764ed88e74a8da75bb873f726ba366 Signed-off-by: Carl Vanderlip Signed-off-by: Pravin Tamkhane commit b2453048bca23772afae74c06972adcada68f257 Author: Gopikrishnaiah Anandan Date: Fri Jul 27 10:55:04 2012 -0400 msm: vidc: Increase video driver clients count. Video driver currently supports registration of 4 clients. Increasing number of clients count to 6 to support new usecases. Video driver will limit number of instances to 4. Change-Id: If00911ef1027b1e44917465791ef3612e6c59ed1 Signed-off-by: Gopikrishnaiah Anandan commit bc315ea3c81c545f273492d5532d62d109a3c4c7 Author: Lakshmi Narayana Kalavala Date: Tue Jul 24 09:55:48 2012 -0700 msm: camera: Add support for Bayer stats Add support for Bayer stats Change-Id: I69b408af91565581c925540bccb04708278bda05 Signed-off-by: Lakshmi Narayana Kalavala commit 58243db25ebb92f6ae812886a9b5c15106bd432b Author: Lakshmi Narayana Kalavala Date: Tue Jul 24 00:06:27 2012 -0700 msm: camera: Fix memory leak with stats buffers Buffer unprepare is not done while releasing stats buffers, hence add support for buf unprepare ioctl Change-Id: If4fa95c270363d1948b5924c2365785d1427e2f4 Signed-off-by: Lakshmi Narayana Kalavala commit 907859007ebd854b7afcfa3c14edda8efadd2e55 Author: Kiran Kumar H N Date: Thu Jul 5 13:59:38 2012 -0700 msm: camera: Add support for instance handle based buffer lookup. Currently when VFE requests for a free buffer, we search based on the image mode sent from VFE. In some cases, there can be multiple instances with the same image mode. This means the buffer lookup logic has to take into consideration other parameters like current usecase, vfe operation mode etc. To ease this, add support for buffer lookup based on the instance handle. The instance handle contains information about where to get the buffer from. So the buffer lookup logic does not have to know about other details. The instance handle is decided when the user sets the format for a particular instance. It is passed on to the VFE during AXI configuration. VFE stores this and sends it whenever it requests for a free buffer for a particular output. Keep the current image_mode based buffer lookup logic for legacy targets. Change-Id: I78c3db77ac4014365c9866ff780ec71ac4c7ff87 Signed-off-by: Kiran Kumar H N commit 4b3443f0882826f3f0de468c799e77c6477380d0 Author: Ankit Premrajka Date: Mon Jun 11 14:06:31 2012 -0700 msm: camera: resource manager related changes. Make changes to support dynamic selection of subdevs through the resource manager. Instead of choosing the subdevs to be used by the current mctl session statically during open, the VFE, AXI and VPE subdevs are now selected and initialized later as per session requirements. Change-Id: I8df951b81f0ccc77e5b4f64bf5cf620822cf0175 Signed-off-by: Ankit Premrajka commit 2ed59cf2dac9f34d07e3e6870bf3d30076386aa7 Author: Rajeshwar Kurapaty Date: Thu Jul 19 13:00:50 2012 +0530 msm:vidc: force constrained baseline profile for H264 BP encoding Core is returning improper header information for H264 128kbps, level-1b and baseline profile settings. Forcing the setting to constrained baseline profile for normal baseline profile as per the updated interface specification resolves the issue. Change-Id: Ib106b17be9453cfd80264cc2167dda919893b1e2 CRs-Fixed: 371606 Signed-off-by: Rajeshwar Kurapaty commit 6084636fbf190de0add7a0fb192a26f695fbe402 Author: Rajeshwar Kurapaty Date: Fri Jun 29 20:00:40 2012 +0530 vidc: Adjust core timeout based on input frame size Video core is dropping certain IDR frames due to timeout. This is resulting in video corruption. Computing the core timeout based on input frame size and programming it for each input frame fixes the issue. Change-Id: I75d5039bc09f9be6a3028461ee4a2f13064bf53a CRs-fixed: 370570 Signed-off-by: Rajeshwar Kurapaty commit 2db3384fa38336391ea177d7475eb7bc00627f7f Author: Lakshmi Narayana Kalavala Date: Tue Jun 26 22:41:32 2012 -0700 msm: camera: Add free status buffer queue Add support for free buffer queues for vfe statistics Change-Id: I9a791d5869aa090f661904b41b210cea51f67aa4 Signed-off-by: Mingcheng Zhu Signed-off-by: Lakshmi Narayana Kalavala commit b14ed96f74b1258b1f102831a2b0ccd56f991132 Author: Laura Abbott Date: Mon Jan 30 14:18:08 2012 -0800 gpu: ion: Pull in patches for 3.4 Pull in Ion patches for 3.4 upgrade. Inclues the following patches from google: commit 7191e9ba2508ca6f1eaab251cf3f0a2318eebe26 Author: Rebecca Schultz Zavin Date: Mon Jan 30 14:18:08 2012 -0800 ion: Switch map/unmap dma api to sg_tables Switch these api's from scatterlists to sg_tables Signed-off-by: Rebecca Schultz Zavin commit 6f9e56945d4ee3a2621968caa72b135cb07e49c4 Author: Rebecca Schultz Zavin Date: Tue Jan 31 09:40:30 2012 -0800 ion: Add reserve function to ion Rather than requiring each platform call memblock_remove or reserve from the board file, add this to ion Signed-off-by: Rebecca Schultz Zavin commit 9ae7e01de1cf03c77054da44d135a7e85863fcb0 Author: KyongHo Cho Date: Wed Sep 7 11:27:07 2011 +0900 gpu: ion: several bugfixes and enhancements of ION 1. Verifying if the size of memory allocation in ion_alloc() is aligned by PAGE_SIZE at least. If it is not, this change makes the size to be aligned by PAGE_SIZE. 2. Unmaps all mappings to the kernel and DMA address spaces when destroying ion_buffer in ion_buffer_destroy(). This prevents leaks in those virtual address spaces. 3. Makes the return value of ion_alloc() to be explicit Linux error code when it fails to allocate a buffer. 4. Makes ion_alloc() implementation simpler. Removes 'goto' statement and relavant call to ion_buffer_put(). 5. Checks if the task is valid before calling put_task_struct() due to failure on creating a ion client in ion_client_create(). 6. Returns error when buffer allocation requested by userspace is failed. Signed-off-by: KyongHo Cho commit 043a61468f395dd6d4fc518299726955e9999c59 Author: Rebecca Schultz Zavin Date: Wed Feb 1 11:09:46 2012 -0800 ion: Switch ion to use dma-buf Ion now uses dma-buf file descriptors to share buffers with userspace. Ion becomes a dma-buf exporter and any driver that can import dma-bufs can now import ion file descriptors. Signed-off-by: Rebecca Schultz Zavin commit 0d1259b5f84969bd00811ff9faa1c44cdb9fdbb5 Author: Rebecca Schultz Zavin Date: Mon Apr 30 16:45:38 2012 -0700 gpu: ion: Use alloc_pages instead of vmalloc from the system heap With this change the ion_system_heap will only use kernel address space when the memory is mapped into the kernel (rare case). Signed-off-by: Rebecca Schultz Zavin commit be4a1ee79a89da3ca705aecc2ac92cbeedd032bd Author: Rebecca Schultz Zavin Date: Thu Apr 26 20:44:10 2012 -0700 gpu: ion: support begin/end and kmap/kunmap dma_buf ops These ops were added in the 3.4 kernel. This patch adds support for them to ion. Previous ion_map/unmap_kernel api is also retained in addition to this new api. Signed-off-by: Rebecca Schultz Zavin commit 46d71337f9aa84694e4e6cca7f3beb6b033bbf76 Author: Rebecca Schultz Zavin Date: Mon May 7 16:06:32 2012 -0700 gpu: ion: Allocate the sg_table at creation time rather than dynamically Rather than calling map_dma on the allocations dynamically, this patch switches to creating the sg_table at the time the buffer is created. This is necessary because in future updates the sg_table will be used for cache maintenance. Signed-off-by: Rebecca Schultz Zavin commit 903f6c716db3d4e26952aae9717f81dd5bc9e4ba Author: Rebecca Schultz Zavin Date: Wed May 23 12:55:55 2012 -0700 gpu: ion: Get an sg_table from an ion handle This patch adds an interface to return and sg_table given a valid ion handle. Signed-off-by: Rebecca Schultz Zavin The commit also includes fixups needed for MSM specific code. Change-Id: Idbcfa9d6af0febf06f56daaa6beaa59cc08e4351 Signed-off-by: Laura Abbott commit 84f8c68bcd73f8bcd1af23b126ed052eb1598856 Author: Riaz Rahaman Date: Wed May 30 13:32:10 2012 +0530 vidc: Add required variables in platform data for content protection Add, initialize variables for firmware addr & secure write back buffers in vidc platform data. Change-Id: Ibb1e464af2e0e9038c8d43d6756d5a8481c7f618 Signed-off-by: Riaz Ur Rahaman commit 5dd5442cd6e726430ab5294149f1cff0a33ce6a2 Author: Nishant Pandit Date: Tue Jun 26 22:52:44 2012 +0530 msm: camera: Add support for concurrent Ispif interface streaming Add support for multiple ispif interfaces streaming concurrently. PIX abd RDI interface can stream at same time or two RDI interfaces may stream at one time depending on usecase Change-Id: Ib3cef418cd2816bc19891c1855e1dcae5a2a55a1 Signed-off-by: Nishant Pandit commit 5fd16f4c3d7c0a8a0a2147405e91bbfb9be6720e Author: Maheshwar Ajja Date: Sun Jun 10 20:52:22 2012 +0530 Revert "msm: vidc: Avoid reconfig if EoS is received after SPS/PPS" This reverts commit fcd8763cbf25679c999e363ac63e65a234e4192d. The above commit will break the trick mode playback functionality. CRs-fixed: 370048 Change-Id: I6b3d116e8339520ef347eb387973db6f78b560b5 Signed-off-by: Maheshwar Ajja commit 079007e45e1e9674f51ace59fa4443e5fdb020ea Author: Praveen Chavan Date: Wed Jun 20 12:38:25 2012 -0700 mm-video:vidc: Set max performance level for high framerate content Performance issue is observed with 60fps content as the vcodec clock set based on number of macroblocks and framerate is not sufficient. This fix checks for the framerate and sets max performance level if fps is more than 60 (59 to be more precise) Change-Id: I5d41643a32ec895565406fadec04dc95e04655a4 Signed-off-by: Praveen Chavan commit 73ec728288b1d30c3b967a378d0f2893d254bd67 Author: Kevin Chan Date: Thu Jun 7 01:32:00 2012 -0700 msm: camera: CPP driver Framework Initial commit for Camera Post Processor Driver. The driver contains frame queuing and process logic using v4l2 framework. Change-Id: I283c11c3de3bd121b9c3ea5af1446c13e188d329 Signed-off-by: Kevin Chan commit ed4b2afe41aa4dec5bf06823da35e33645d558a1 Author: Maheshwar Ajja Date: Thu Jun 14 12:24:18 2012 +0530 vidc:720p: Fix first buffer with EOS flag in video decoder The video driver is throwing error for erronious header input buffer with EOS flag enabled. This commit will fix the error case by amending the EOS handling for the first buffer. CRs-fixed: 370048 Change-Id: I8917aa288d6547319e8b1df54e27afd69ab36162 Signed-off-by: Maheshwar Ajja commit ddd20e2ff4e5d2d4f11d9ad54d40175d35f724e7 Author: Maheshwar Ajja Date: Fri Jun 22 12:27:04 2012 +0530 vidc:vdec: Clean extradata portion and invalidate whole buffer This commit will ensure to clean the extradata portion in output buffer changed by the CPU before sending the buffer to Video hardware and invalidate the output buffer changed by Video hardware before CPU access the buffer. Change-Id: I05ea24fb381a164f6cfd520bd9071a94349ed2df CRs-fixed: 366446 Signed-off-by: Maheshwar Ajja commit 28feb3d6001aede64d44f7aa13f364571bb25c5c Author: Nishant Pandit Date: Thu Apr 26 23:56:22 2012 +0530 msm: camera: Add support for RDI in VFE Enable RDI registers and irq handler in VFE. RDI may be used to dump sensor data directly to memory without passing through VFE. Change-Id: I1ca131c31913f62228364440bbe2cd98a6079003 Signed-off-by: Nishant Pandit commit b4a278e5206d63224c6c8dc4d46f971cc1124c4b Author: Kiran Kumar H N Date: Mon Jun 18 19:25:47 2012 -0700 msm: camera: Add IRQ Router subdev implementation. Add initial driver code for IRQ Router hardware. It shall be implemented as a v4l2 subdevice of the msm cam server node. Add logic in msm cam server to request for irqs configured to the IRQ Router, which can be individual or composite. When the individual camera hardware cores interrupt, the cam server receives them through the common interrupt handler and dispatches them to to the respective hardware core's v4l2 subdevice. If the usecase demands that the interrupts from two different hw cores be composited into a single interrupt, (for eg: VFE and ISPIF), then the cam server stores this configuration in its interrupt lookup table. When the interrupt is triggered on the composited interrupt, it is dispatched to the individual hardware cores which have been composited into that interrupt. Change-Id: Iaadd60cc24de9b5ba8d09a151474658902244d7b Signed-off-by: Kiran Kumar H N commit 5d2945dfd41de0e13a8429c921e3516540060c6e Author: Mohan Kumar Gubbihalli Lachma Naik Date: Fri Jun 22 21:22:16 2012 -0700 msm:vidc: provide support to raise video clks to turbo mode. This change provides support to raise video clks to turbo mode for mpeg4 clips with high number of slices. The firmware performance degrades if the number of slices is more than 10. Without this fix, we see lot of frame drops happening, causing a freeze effect. Change-Id: I79d0b9a438f73d87384b9e03761a65b9de3c9fc7 CRs-Fixed: 358615 Signed-off-by: Mohan Kumar Gubbihalli Lachma Naik commit 1c72b395348a0d4944e4f05e2979c80e7f8d8c52 Author: Ashray Kulkarni Date: Wed Jun 20 10:50:00 2012 -0700 msm: video: Fix compiler warnings changed array definitions, #defines and variable repetition to resolve warnings in compilation. Change-Id: Ic26f1924da389f4a8638728963c6a4c8b2f859d0 Signed-off-by: Jessica Gonzalez commit b2157c9abb7b436776f786760607126d1c9a8433 Author: Nishant Pandit Date: Wed Apr 25 01:09:28 2012 +0530 msm: camera: Decouple the ISPIF component from sensor Ispif is a separate hardware block. Decouple it from sensors so that it can be controlled for various camera usecases. Change-Id: I539fcb4166edc7a14d15a94c2f7f56b2f196a971 Signed-off-by: Nishant Pandit commit 152c3c7ba9bc0d47857534f3c7c16f6817297ae1 Author: Arun Menon Date: Wed Jun 20 11:50:08 2012 -0700 msm:vidc: provide support to raise afab and ebi1 clks to turbo mode. This change provides support to raise the clks to turbo mode for mpeg4 clips with high number of slices. The firmware performance degrades if the number of slices is more than 10. Without this fix, we see lot of frame drops happening, causing a freeze effect. Change-Id: Ia897854ef6d30bb97cd37810b22eb1ab5ad818fb CRs-Fixed: 358615 Signed-off-by: Arun Menon commit d6d2863519c2351ef790758ed134e012d4563c4e Author: Adrian Salido-Moreno Date: Tue May 29 16:52:09 2012 -0700 mdss: display: implement writeback interface for mdss Add writeback interface support, using one page of framebuffer memory for writeback output. Change-Id: I0a44c6907cbc10d97c78642f45dc018dfb2d1750 Signed-off-by: Adrian Salido-Moreno commit e55fa120321f49385973b37f8b258bf78163743b Author: Adrian Salido-Moreno Date: Tue May 29 15:36:08 2012 -0700 mdss: display: Add Mobile Display SubSystem driver - Implements Linux frame buffer interface to interact with userspace libraries and applications, based on msm_fb frame buffer. - Implement MDP driver which handles MDP core data path setup and hardware blocks programming. - Support for UI through Linux frame buffer FBIOPAN_DISPLAY ioctl. Change-Id: Ib98677b8d81d74283b27dea08a9f1a705c101bce Signed-off-by: Adrian Salido-Moreno commit e2c9c0bf3f925e9f671b5c18795ae415fed58510 Author: Ankit Premrajka Date: Thu Jun 7 17:18:25 2012 -0700 msm: camera: add ion dev fd field to frame structure. The ion dev fd field is required to represent the client that allocated the buffer represented by the frame. Change-Id: I8de791158251069275becc9f6413382fc6738492 Signed-off-by: Ankit Premrajka commit af4a0ef0c6162e89c063b04da0a037246fcc76b9 Author: Vinay Kalia Date: Sun Apr 15 17:33:03 2012 -0700 msm: vidc: Fixes bug in handling duplicate frames. Fixes bug while closing encoder which supports duplicate input frames. This fix decrements the reference count of original frames appropriately. Change-Id: Ib542cf5fd790b8ba7f77e9a748a25c3cb132f40a Signed-off-by: Deva Ramasubramanian commit 41a3870e67baceb635884c7fcc76bc7b12273418 Author: Kevin Chan Date: Wed Jun 6 22:25:41 2012 -0700 msm: camera: Add v4l2 private ioctls Add private ioctls s_ctrl, query_ctrl where we need to get ctrl data from userspace. Change-Id: I404236d072bafb3ef6ef3c0723a707f5805fe92b Signed-off-by: Kevin Chan commit bf5fc96913ab970df5c060ec2c1937fe06c99295 Author: Arun Menon Date: Fri Jun 8 19:19:03 2012 -0700 vidc: Move prediction scratch buffer to FW Heap. The encoded output was corrupted for wvga and lower resolutions during HFR. Moving the prediction scratch buffer from MM Heap to FW Heap avoids this corruption. CRs-Fixed: 353979 Change-Id: Ife3be7ccd9f19bb285c6c348721a1d54bbbd4734 Signed-off-by: Arun Menon commit 64bd23cb9d7ed79a1f18a938116112c4196772e3 Author: Kiran Kumar H N Date: Fri May 25 12:06:21 2012 -0700 msm: Allow VPE driver to be configured directly. Currently VPE hardware is being controlled through the config node. Since it is converted into a V4L2 subdevice, we could control it directly from userspace by issuing open, close and ioctl system calls. The ACK from VPE hardware shall be routed directly to userspace by putting the ACK event on the v4l2 event queue. Change-Id: I7f82a750a28732382627349da362dbee8e27b149 Signed-off-by: Kiran Kumar H N commit 9acbfb0eb688bac6a35f12b58e2e9c3de4d2d3b8 Author: Zhang Chang Ken Date: Wed Jun 6 10:00:43 2012 -0400 msm_fb: display: add support for frc Frame rate converter(frc) is treated as LVDS 1080p panel Its configuration is based on HDMI 1080p60 mode LVDS dual channel mode will be used Change-Id: Id3a17f107c8398ddb47105d064be2743a150a3b3 Signed-off-by: Ken Zhang commit 52d1c472d72b64942e5a5c99d4d2c38b968dc0db Author: Maheshwar Ajja Date: Fri Jun 8 22:55:44 2012 +0530 vidc:1080p: fix for wrong frame tags in slice delivery mode The core sends the wrong frame tag from the second slice onwards for certain resolutions.The video encode session fails if the frame tags dont match the values present in the transaction table. This workaround will use the frame tag of the first slice for the remaining slices. We need this workaround till video core fixes the issue. Change-Id: I36f2401a3b6d1ec2f9d482968f7d0946a7733572 CRs-fixed: 368678 Signed-off-by: Rajeshwar Kurapaty commit 212d97204704a2f2503a2ff7f288fb08bf2b2153 Author: Suresh Vankadara Date: Wed May 30 15:51:20 2012 +0530 msm: camera: Add effects for front camera. Added Support for Effects like saturtaion,contrast for YUV sensor CRs-Fixed: 352316 Change-Id: If278755849a866e84069ce517b2f1f6c67294980 Signed-off-by: Katta Santhisindhu commit 999a4d94539cbf3e7deb68c61b1539fcba15964d Author: Srinu Gorle Date: Wed Jun 6 03:34:14 2012 +0530 msm: vidc: Invalidate the cache before processing metadata. - Encoder output bit stream is getting corrupted if cache is not invalidated before meta data processing. - ION_IOC_INV_CACHES is called before meta data processing to make sure physical data & cached data are the same. CRs-Fixed: 358392 Change-Id: Ia4b827619e64b0bc60f74692993001e44b0bbcbe Signed-off-by: Srinu Gorle commit 837ae365bf6a2e8ee116f2e9efeadf1faa4588d2 Author: Deva Ramasubramanian Date: Sat May 12 23:26:53 2012 -0700 video: msm: wfd: Add turbo mode support Add support for userspace to push the video core clock to maximum supported by hardware. Change-Id: Ida6618fd77bc24fe043885306083249546797054 CRs-Fixed: 361108 Signed-off-by: Srinu Gorle commit 302441aef1b949312ff05573c83645ef86f29594 Author: Mohan Kumar Gubbihalli Lachma Naik Date: Thu May 31 16:00:46 2012 -0700 vidc:1080p: Add check for supported video resolution 1080p core can support max resolution upto 1920x1280. Some of the video clips have a resolution more than the supported resolution. Changes were made to check for the supported resolution and stop the playback if they exceed Change-Id: Ia3fa9c38eef60d23644e54873849d528377ff722 CRs-Fixed: 362228 Signed-off-by: Mohan Kumar Gubbihalli Lachma Naik commit 7c81518dcab881ec50ea811b6968a3031974e8fa Author: Azam Sadiq Pasha Kapatrala Syed Date: Thu May 31 19:28:09 2012 -0700 msm: Seperate VFE/AXI register programming from start and stop func. Decouple AXI and VFE. This will help to control/program VFE and AXI independently. Change-Id: Ic892f1ebe1ce0ac29bd95f0852a74de6cfbabcc5 Signed-off-by: Azam Sadiq Pasha Kapatrala Syed commit 3db6f225d9fed96d0e7f9dd7f4bd9cb200551bcf Author: Rajeshwar Kurapaty Date: Mon Jun 4 19:14:10 2012 +0530 vidc: Modify shift value for extended PAR width. Currently extended pixel aspect ratio register shift value for width is 15. Due to this the actual width value returned by core is getting doubled while sending to user space. Now correct values are returned by modifying the shift value to 16. CRs-fixed: 362985 Change-Id: I996bfc79b327492a791017fd5b33638f82240d76 Signed-off-by: Rajeshwar Kurapaty commit 740d5ad28484b42ae675721a66a1bd93081712c8 Author: Mohan Kumar Gubbihalli Lachma Naik Date: Mon Jun 4 18:10:56 2012 -0700 vidc:1080p: Set video core timeout value for Thumbnail mode Video core timeout value is set only for thumbnail mode. For normal playback senario default value is set. Change-Id: I10d43adf093a5495d9bacb84532ba3ae91920540 CRs-fixed: 367222 Signed-off-by: Mohan Kumar Gubbihalli Lachma Naik commit c34f8ad31862033eff35dd0576d4f5a016763ab1 Author: Maheshwar Ajja Date: Fri May 25 17:13:38 2012 +0530 vidc: 1080p : Add support for skip frame in slice delivery mode Slice delivery mode for H264 encoder will deliver constant number of output slice buffers for each frame. In case of CBR rate control method, core will skip frames to maintain the output quality, in which case driver need to send out the output buffers with data length as zero for skipped frame output type from the core. CRs-fixed: 362356 Change-Id: I647092d802b95558422cf1537f3e8bf69cd68b1b Signed-off-by: Maheshwar Ajja commit db02c4ebd5d7dd7c240dc96208c74eb62974eda0 Author: Mohan Kumar Gubbihalli Lachma Naik Date: Mon May 14 16:36:51 2012 -0700 vidc: Adjust core timeout based on current core frequency. Core timeout value is calculated based on the current core clock rate during video play back. Change-Id: I52f38560eda71dd0eaf208da68b4c3f74955661b CRs-fixed: 354069 Signed-off-by: Mohan Kumar Gubbihalli Lachma Naik commit 35e58e3396509c881fbbedd39e4a75eca4e662f7 Author: Deepak Kotur Date: Thu May 17 18:29:01 2012 -0700 vidc: Pass the correct parameter for cache flush Buffer handle was passed as 3rd argument, instead of buffer virtual address and this was causing a crash CRs-Fixed: 363157 Change-Id: Ic5d59d8745100bdb18454a72410ffa7e438a2c46 Signed-off-by: Deepak Kotur commit 64cf649c8e9c477bc8b62f822c68ddcdb8988730 Author: Deva Ramasubramanian Date: Tue Mar 13 19:19:37 2012 -0700 msm: vidc: Do not duplicate sequence header for secure sessions In secure sessions, we aren't allowed write into secure buffers. In these cases, do not copy the sequence header from the internal buffer into the output buffer. The firmware will prepend the sequence header to the first I-frame in these cases. Change-Id: I2e853210b6a566468ec152c6f80b411bc3e45848 Signed-off-by: Deva Ramasubramanian commit 4584b5fe6f4ed1f4b0e5131c83a767a97497b9de Author: Sunid Wilson Date: Fri Apr 13 12:48:25 2012 -0700 msm: camera: Add support for gesture driver Added gesture driver code. Gesture node is a subdevice to server node. Change-Id: I488da3dbdb502a2f78b0cd5269dd113c472ee377 Signed-off-by: Sunid Wilson commit a12c839a75255cdf62a8014bdb8adf2d01af9bf1 Author: Anil Gahlot Date: Wed May 9 14:31:32 2012 -0700 msm: vidc: Driver changes for output buffer Minimum tile height size required by MDP for rendering is 96 else rendering fails. This change would compute output buffer size big enough to have proper rendering for clips having frame height less than 96. CRs-Fixed: 351645 Change-Id: Ibc17b1ad112ad937cb4b93a307fa4432074990cd Signed-off-by: Anil Gahlot Signed-off-by: Mohan Kumar Gubbihalli Lachma Naik commit af296715bd5db6c38997d1171d079331c8650287 Author: Anil Gahlot Date: Mon Apr 23 14:34:33 2012 -0700 msm: vidc: Metadata memory release issue. Metadata memory is not freed when there is memory allocation failure in ddl open. Fixed this issue by freeing the metadata memory. CRs-Fixed: 353109 Change-Id: I3f6fd93498aea0ce78092bd3a28cf08625b0ca77 Signed-off-by: Anil Gahlot Signed-off-by: Mohan Kumar Gubbihalli Lachma Naik commit 4947d8cd8cc0889058801820d56edd9bbcb23d70 Author: Deva Ramasubramanian Date: Tue Apr 3 12:41:06 2012 -0700 msm: vidc: Use pre-computed frame delta values in WFD use case In WFD use-case with frame skipping enabled, we wish to fool the core into thinking that that the frames are coming at a consistent rate so that we don't run into any issues with the core's rate control mechanism. Introduce a client-settable property that dictates what the timestamp delta between any two frames might be. Change-Id: Iea3f97879227b7932543d3449d311758dc4a2f59 Signed-off-by: Deva Ramasubramanian commit fcd8763cbf25679c999e363ac63e65a234e4192d Author: Saikumar Kondaparthi Date: Fri May 11 18:44:40 2012 +0530 msm: vidc: Avoid reconfig if EoS is received after SPS/PPS After core init, there is a hang if the data buffers are not sent to the core as the core is not responding to the STOP command. With this commit, reconfig is avoided and EoS done message is sent to the client. CRs-Fixed: 360438 Change-Id: I3c3d22aa2ffe37fc3b9b0cf94df9cc066a4299f2 Signed-off-by: Saikumar Kondaparthi commit 734476bedc61c6faaed7038131ac63f72ef2aac4 Author: Jeyaprakash Soundrapandian Date: Thu May 3 20:08:15 2012 -0700 msm: camera: eeprom subdevice support for camera sensor The OTP data for calibration is stored in the eeprom. The eeprom is registered as a subdevice and necessary functionality is added for reading and fetching data to user space. Change-Id: I119a31fa7eccc597c92b7c418c8d04c291e294f5 Signed-off-by: Jeyaprakash Soundrapandian commit 71826a16795b9235d08ec22d7fd55d809407df51 Author: Deepak Kotur Date: Fri Apr 13 15:42:36 2012 -0700 vidc: Update the secure firmware fixed address. The secure firmware memory address is updated, to the new physical address. Change-Id: If41ea48eea9988bf130a8bd213711cdbc99bfdf2 Signed-off-by: Deepak Kotur commit 5e46aaca126d031473fdfebc07640b62f993d10d Author: Matt Wagantall Date: Thu May 3 20:20:18 2012 -0700 msm: vidc: Pass device pointers to regulator_get() Passing a device pointer instead of NULL as the first argument to regulator_get() allows the device to be taken into account when finding a matching regulator. Change-Id: I34917d18e1216be01c0cf8ccfd0b6038e5474ffd Signed-off-by: Matt Wagantall commit 17c876f259ce77ad1e47d40ed28149109a8327cb Author: Deepak Kotur Date: Fri May 4 16:12:45 2012 -0700 vidc: Flush the cached buffer only if the buffer is valid. Before flushing the cached buffer check for the following - When buffer allocation fails, do not flush the buffer report error and return. - Check if the buffer handle is valid, before flushing the buffer. CRs-Fixed: 358873 Change-Id: I58b869d2d2eb72f991649d62a5186c7b0f5adcf4 Signed-off-by: Deepak Kotur commit cbca051abe96cca82037a37dd70054132b2e8171 Author: Deepak kotur Date: Wed Apr 11 16:06:39 2012 -0700 vidc: For CP2.0 do not program the iommu. For CP2.0 do not call the ion_map_iommu api use the ion_phys api to get the physical address Change-Id: I8e39fb3bfb7f68df167b9432fbc008980e28742e Signed-off-by: Deepak Kotur commit fe1e62c15bd815af7f97d324b8fcbcced67c15a1 Author: Mohan Kumar Gubbihalli Lachma Naik Date: Wed Apr 18 19:41:21 2012 -0700 vidc: upgrade video core clock rate based on time taken to decode a frame Currently video clock rate is set based on the resolution and fps of the given clip. But some clips have a high bit rate for a given resolution which causes high decode time. Changes were made to consider frame decode time and upgrade the clock rate accordingly CRs-fixed: 346580 Change-Id: Ie89a736eb9f93286486ae7688633a828c7415fd2 Signed-off-by: Mohan Kumar Gubbihalli Lachma Naik commit cf26486f50d223cd763909b08cea04bd525e25c6 Author: Kevin Chan Date: Thu Apr 19 19:10:38 2012 -0700 msm: camera: Separate AXI from vfe This change will separate axi functionality from vfe core, in order for camera RDI (Raw dump interface) to work. When RDI is used, only axi subdev is configured. When PIX interface is used, both vfe and axi are configured. Change-Id: Id986ea1c12bbeb0664d08429acffe24d20a51028 Signed-off-by: Kevin Chan commit 17ca3688442f000d925287251456ef4a3eb63db3 Author: Deepak Kotur Date: Wed May 2 12:29:38 2012 -0700 vidc: Free shared memory when video core is in error. When the video core is in error, the core times out. At this instant, all the client buffers are freed, but the shared memory is not freed. Free the shared memory in this case. CRs-Fixed: 357990 Change-Id: I8769356cab1b57fd39d7f1c2d4458cd7e263557f Signed-off-by: Deepak Kotur commit ed9dc9161be2b0f32eeb90ffbc5d8186e6674422 Author: Mohan Kumar Gubbihalli Lachma Naik Date: Thu Mar 1 19:11:14 2012 -0800 msm: vidc: Set dpb count based on target for smooth streaming The min_dpb required for smooth streaming is set for the max requirement of 1080p playback session. For 8960 num of dpb required is 18 and for 8660 it is 8. This is set in vidc platform data in the resepective device file. Change-Id: I1e6bc3e8dcd64a00a7eb159f4600d40f5c229e45 Signed-off-by: Mohan Kumar Gubbihalli Lachma Naik commit 5f10b27e863715443e24e54bff1eec946e5d6bd8 Author: Deepak kotur Date: Thu Mar 15 22:01:39 2012 -0700 msm: vidc: Downloads firmware using pil_get. Downloads video codec firmware using pil_get for secure sessions only. Firmware is not downloaded using pil_get for non-secure sessions Change-Id: I1f870a0611b85ddfe0f34972f81e5e667387468d Signed-off-by: Deepak Kotur commit cd681bf9f50cf17b70e24852361bc67c91b116ec Author: Pradnya Chaphekar Date: Sat Feb 18 23:05:56 2012 -0800 vidc: 1080p : Add support for slice delivery mode to encoder Slice delivery mode enables confguring the encoder to deliver one slice per output buffer. This mode is valid only for h264 codec when multi slice config is set to slice by mb. Change-Id: I1bb88a67fecf4a76ad828f4c4981ff3cad648f24 Signed-off-by: Pradnya Chaphekar commit c9a9332a743459e44744e630f3e734e7788c477d Author: Rajeshwar Kurapaty Date: Thu Apr 26 19:04:49 2012 +0530 vidc: Add extra cases for error handling in vidc init Currently error conditions are not handled properly if failures occur during irq request or while creating work queue. With this commit these error conditions are properly handled. Change-Id: I618ca5c2a4f6bd09a3edd164a7867a90a9ed9f9a CRs-Fixed: 355753 Signed-off-by: Rajeshwar Kurapaty commit 94b4c83b8c27dfadc3d9756d41bcadbf4e9f090c Author: Kevin Chan Date: Fri Mar 2 21:27:16 2012 -0800 msm: camera: Change camera server into a video node Convert ioctl and server node to be compliant with v4l2 architecture. Add multiple control and event queue to support multiple camera instance Change-Id: Idcb8533e15599f7fb0ad621c3da6b19235fa64f4 Signed-off-by: Kevin Chan commit 974a96c1634659213f7d226fa5092398ddd46398 Author: Deepak Kotur Date: Thu Apr 12 16:59:35 2012 -0700 vidc: Check for proper buffer handle before free. Check for proper buffer handle and client handle before unmapping and freeing the buffer. CRs-Fixed: 351100 Change-Id: I88f5e142839f12cc19360dbe26a8d4e6a7ec99de Signed-off-by: Deepak Kotur commit 4dd43083ccd149e9b0cfd5b2f635389597105920 Author: Vinay Kalia Date: Wed Mar 28 22:11:58 2012 -0700 msm: vidc: Fixes memory protection in secure enc/dec concurrency Memory should be protected for the first secure session and unprotected for the closing of last secure session. Change-Id: I61f72bf13282bed1547fbdad0a3e3aa515e9951c Signed-off-by: Vinay Kalia Signed-off-by: Deva Ramasubramanian commit 13d82f8216593b296ef799b5d9663d3dd869959a Author: Deepak kotur Date: Mon Mar 12 11:12:32 2012 -0700 msm: vidc: Handles secure/non-secure concurrency. Handles concurrency scenarios by preventing nonsecure sessions when secure sessions are ongoing. This is required since secure and non-secure sessions cannot run concurrently. Change-Id: I197a4c437312d916c0f75e7eb026c0570fee12ff Signed-off-by: Deepak Kotur commit 602d62927c6db96f8d636f7795203b19e8c412c3 Author: Rajeshwar Kurapaty Date: Tue Apr 24 15:55:59 2012 +0530 vidc: send flush done if flush is issued in EoS while encoding There is a race condition in encoder, when an input buffer is received with an EoS flag but doesn't have an output buffer to process that and if simultaneously flush is issued. This is fixed by sending flush done if flush is issued in EoS. CRs-Fixed: 353081 Change-Id: I925f49779ed5cb91bfab805ba4b7102c1e3f728b Signed-off-by: Rajeshwar Kurapaty commit ee55c1984badacc44f716bf9dd900f815650e650 Author: Ninad Mahimkar Date: Wed Apr 25 14:36:17 2012 -0700 msm: camera: Add SOF timestamps Add a message for passing real time clock timestamp to userspace when SOF is generated Change-Id: I99cb05bb3d619c4bf6da520366bd42e7e6ac8ee2 Signed-off-by: Ninad Mahimkar commit c264eed1e7debb50c97159784307de23bdfc3a3b Author: Rajeshwar Kurapaty Date: Tue Apr 24 16:09:53 2012 +0530 vidc: Send port reconfiguration for interlaced clips Component is not getting port reconfiguration request from driver for an interlaced clip. Fix it by modifying the condition for triggering the reconfiguration request. CRs-Fixed: 352456 Change-Id: I65ce5987f31915f45a13767965918b61e32db7a7 Signed-off-by: Rajeshwar Kurapaty commit 14648740d17ca1f154222aba29a1f2946609f460 Author: Manoj Rao Date: Fri Mar 30 19:42:12 2012 -0700 msm_fb: MHL Driver for SI-8334 Transmitter The device driver for SI8334 Silicon Image's Mobile High-definition Link (MHL) Transmitter implements wake-up, discovery and communication with MHL sink. The MHL-8334 Tx is attached to MSM as an I2C-client. Change-Id: I845bc1b30dc799183357224a296215ecc1d44893 Signed-off-by: Manoj Rao Signed-off-by: Abhishek Kharbanda commit 6627b36ee06ab56a800e2b570a038423c6572b02 Author: Rajakumar Govindaram Date: Sun Jan 29 19:00:30 2012 -0800 msm: camera: 8960: Unify Autofocus actuator The actuator functionality is the same for different camera modules. So a single actuator driver module is supported. The variation is because of actuator control parameters, which are made available in user space actuator driver for better integration with tools used for autofocus tuning. Change-Id: Ibbae2ef426b570c59ec3796ac56abcf05af28259 Signed-off-by: Rajakumar Govindaram commit 44d8b26f0abf78bdfe891667d990ffea4f6a3804 Author: Maheshwar Ajja Date: Thu Mar 1 12:51:41 2012 +0530 vidc: Add support for sequence header generation This change supports sequence header generation prior to the video encoder input & output buffer allocation. After setting all the required parameters to the core, client needs to allocate sequence header buffer of appropriate size and pass it in GET_SEQUENCE_HDR ioctl to get the sequence header. Change-Id: Ia6cc6bdcea595fd63b0aa2f4c2f5c5252db9c620 Signed-off-by: Maheshwar Ajja commit 8c23e070b04aa6160681203bf431db60eb7e2e9a Author: Jeevan Shriram Date: Wed Mar 14 11:35:49 2012 +0530 msm_fb: display: Enable 32bpp framebuffer format. Enable 32bpp framebuffer format for 7x27a and 8x25. Change-Id: I38deabca45ea849710bd2edb2b6847c5309a0c9e Signed-off-by: Jeevan Shriram commit 4a3b94251460fbfc66244475a5f1a54c72a9fe97 Author: Philippe Gravel Date: Fri Mar 23 14:21:04 2012 -0700 msm: camera: v4l2 updates - Adds some protection against unexpected calls - Update ifdef guards in msm_camera.h Change-Id: I388822001159188a6c487f8c0deefa8fb5238249 Signed-off-by: Philippe Gravel Signed-off-by: Sunil Joseph commit 700f5c27d0687f96e9c4a38742b1c0b247051238 Author: Vinay Kalia Date: Wed Mar 28 17:35:28 2012 -0700 msm: vidc: Adds API to request performance level. Adds API to request for a particular performance level from video core. This is needed for Wi-fi display (WFD) to reduce end to end latency. Change-Id: Ib4133b8cd62ccad286be1984f944911754b887c5 Signed-off-by: Vinay Kalia commit a2688820ce17aa8ba1c67077c3ca9e9d5246637b Author: Sreesudhan Ramakrish Ramkumar Date: Thu Apr 5 20:22:50 2012 -0700 msm: camera: Acutuator and flash control Pass actuator and flash support to user space so that modules can be enabled and used based on availability at run time Change-Id: Ia801f17181b492d65feb7bd707d9cc344de9cfe6 Signed-off-by: Sreesudhan Ramakrish Ramkumar commit c55856c548e0cec8b29e415a08a353a0ab1ac4c8 Author: Alhad Purnapatre Date: Tue Feb 28 13:24:57 2012 -0800 msm_fb: display: MSM V4l2 video overlay driver Provides a V4L2 device that uses the MDP overlay pipes (on MDP4), or the PPP interface (MDP3) to overlay frames on top of display framebuffer. Signed-off-by: Alhad Purnapatre Change-Id: Iab69d0a5acfe993d13cb7a585e292b9a87eb90ee commit f0bd4cd4ca4114298fba41f18db9babe0533e075 Author: Zhang Chang Ken Date: Sat Mar 31 14:35:50 2012 -0400 msm_fb: display: Epson ebi2 panel support Support fb with ebi2 only(without mdp) Add Epson ebi2 qvga panel support Change-Id: If61b2c522a102133f98f27b21dcc18d057b7ef25 Signed-off-by: Zhang Chang Ken commit 198a06c95a9246a531ca65c1a98437bc6a90511e Author: Deva Ramasubramanian Date: Tue Mar 13 15:50:58 2012 -0700 msm: vidc: Remove vcd restriction of duplicate input buffer queue VCD previously had a limitation of not allowing two consecutive encode_frame calls with the same buffer. This was primarily due to the handling of buffer_entry elements in the buffer pool. This commit removes this restriction by maintaining an internal buffer_entry element that VCD keep track of. Change-Id: If1788246444d055f9fc369ebd61f57a080d8d333 Signed-off-by: Deva Ramasubramanian commit fd0df3ccda02dd1fad680735333bea7ac025abc5 Author: Zhang Chang Ken Date: Fri Mar 30 17:03:51 2012 -0400 msm_fb:display: add display support for mdm platform add setting for no mdp hw case add ebi2 epson qvga panel setting Change-Id: I91b9ef1890a66eb95c14f8a393b89baa757904a5 Signed-off-by: Zhang Chang Ken commit 50f02e2345b8a7503c85696b35c2490b3fc53fb0 Author: Mohan Kumar Gubbihalli Lachma Naik Date: Thu Mar 22 12:42:45 2012 -0700 msm:vidc: update default output buffer requirement Updated the default output buffer requirement to match worst case requirements. With this change reconfig will trigger only if the actual buffer requirement is less than the estimated requirement. Change-Id: I754a31b9a346f87e5946cad252ba1ea86530dd9e CRs-fixed: 343812 Signed-off-by: Mohan Kumar Gubbihalli Lachma Naik commit 6a72f522d445852ccbbf87294ed466f0260087c9 Author: Deepak Kotur Date: Mon Mar 12 17:41:57 2012 -0700 vidc: memset only for non secure sesion The buffers are memset only if its a non secure session. Change-Id: Idf74a6b54f39012bbe69fb5b5d27f2764d0017af Signed-off-by: Deepak Kotur commit c6802266a867fbd1e8fd03ca87b28ea8c0561f3e Author: Deepak Kotur Date: Tue Mar 27 16:33:15 2012 -0700 vidc: Move metadata shared input mem to firmware heap. Metadata shared input is used to communicate between the video code and video driver, hence make this buffer as uncached and allocate it from firmware heap. Change-Id: Ib1f4005bae1778f68d228bd3c798457c7c15d83d Signed-off-by: Deepak Kotur commit d5a0297a2ce7b4a491dd264dbef855e53d95abfa Author: Arun Menon Date: Thu Mar 1 10:51:06 2012 -0800 msm: vidc: Extract PAR info for MPEG4/DIVX. Display needs the pixel aspect ratio information from the video decoder to display the picture with the right aspect ratio. Video decoder extracts the pixel aspect ratio information from the video core and passes it to the client/display as extradata. Change-Id: I4db2b8ba827af67bc01888d13c36c1b501934ccd Signed-off-by: Arun Menon commit a1f9df15e005241ecf23069f7d345f9a943c06ef Author: Jeevan Shriram Date: Fri Mar 9 19:48:18 2012 +0530 msm_fb: display: Add panel driver for Truly IPS3P2335 client Add panel driver for TRULY IPS3P2335 client Change-Id: Ibf37f7c292593898e237329f3021f1eed8f8728d Signed-off-by: Jeevan Shriram commit 2e99bff826119272ee10734756aba3631e0226e7 Author: Deva Ramasubramanian Date: Mon Feb 13 21:12:08 2012 -0800 video: msm: wfd: IOMMU migration Migrate WFD to IOMMU APIs. Commit contains following changes: - Switch from allocate buffer model to use buffer model in order to have the flexibility to map buffers into seperate domains. - Use the ION caching APIs to flush buffers in case they are cached. Earlier on, we used uncached buffers, hence we didn't have a need to flush. Change-Id: I959027ee94a5d6074005f1de420c66cbe55db776 Signed-off-by: Deva Ramasubramanian commit ef091c924308a03ba2f5ce614faaf7b4dabd3901 Author: Deepak Kotur Date: Tue Feb 28 11:25:35 2012 -0800 vidc: Migrate to new ION cache ops API. New cache ops API are provided thru ION interface migrating the in kernel cache ops to use the new cache ops API. Change-Id: Idf152429316cec2eec8417d72160b7bd53488fc4 Signed-off-by: Deepak Kotur commit 8cd67fa36db83b5757c61de4b3bed567bc800b14 Author: Luis GarciaCalderon Date: Fri Mar 16 16:05:40 2012 -0700 vidc: Increase size of h264 encoder's mv buffer Corruption is seen in the output bitstream in hfr recording mode. The output corruption is avoided by increasing the size of the mv buffer. Change-Id: I6fed4329a9be772cb680e268cf0c618d8a350f14 CRs-Fixed: 340590 Signed-off-by: Luis GarciaCalderon commit 073e0cab00d6cf60279de167d8063c5e5f4b5715 Author: Ankit Premrajka Date: Tue Mar 6 12:26:08 2012 -0800 msm: camera: add fields to msm_stats_buf for cache operations. Add a couple of fields to the msm_stats_buf structure for cache coherence support on stats buffers from user-space. Change-Id: I3553fcf6359e4e748eb309d4a0a5979999d96f09 Signed-off-by: Ankit Premrajka commit 210061ffd99eed2235baa6904b1fbf1d7f26f9b5 Author: Kevin Chan Date: Tue Feb 14 20:56:16 2012 -0800 msm: camera: Add media device node Add media device node for each camera sensor Sensor and video node info will be used for device discovery from userspace Change-Id: Id8c2f3e952c83259bb6b273cb6b3f04ed93d0ef3 Signed-off-by: Kevin Chan commit 9313714a4d2e8675192c3294a1236fef2e0164fe Author: Deepak Kotur Date: Wed Mar 7 20:22:17 2012 -0800 vidc: Move shared memory to firmware heap if smmu is enabled then the memory needs to be mapped as cached for IOMMU heap, moving the shared mmeory to firmware heap which does not require cached mapping. Change-Id: Ic3152e63686b51ba8768dbf38a9d9f7fdec1a963 Signed-off-by: Deepak Kotur commit f4ab51cc686fb0fb792c8de98cc1682acd2eab13 Author: Deepak Kotur Date: Thu Feb 9 15:23:45 2012 -0800 vidc: Migrate to ion_map_iommu() API. Migrate video driver to use the ion_map_iommu() api, this api provides the physical address if IOMMU is not enabled. If IOMMU is enabled in the system it provides the virtual contigious address. Change-Id: I8b2871538c05986811fb565f9ebf1344e848cc10 Signed-off-by: Deepak Kotur commit c85b8ade5cb46b576eec2e5d667460d8d40cb207 Author: Mingcheng Zhu Date: Thu Mar 8 17:47:17 2012 -0800 msm-camera: enhance the camsenser query structure More information needs to pass to userspace. Change-Id: Ia7c5a5cf9a7f48e1c6167fd3ca2ddd56fbdbf8c9 Signed-off-by: Mingcheng Zhu commit 4093ccc3b1498c2e7b7bf1ac7007babeaa58396c Author: Arun Menon Date: Fri Mar 9 12:19:22 2012 -0800 mm_video: vidc: SPS PPS enable for IDR and zero stuff bytes This change includes the driver support for the latest firmware updates - SPS PPS generation for every IDR frame encode and MPEG-2 zero stuff bytes consumption. Change-Id: Icdf3728897f47c90667cd650946ca324346611c5 Signed-off-by: Arun Menon commit 416878307740e2d475511ed0f12ebbd50db8c156 Author: Pradeep Jilagam Date: Wed Feb 22 09:15:28 2012 +0530 msm_fb : display : Add support for NT35516 qHD panel This change adds the drivers for NT35516 DSI Client and Truly qHD panel. Change-Id: Ifb7e02300a8e42d7097845638b77e311e92f69d6 Signed-off-by: Pradeep Jilagam commit fd3a0274fc30e8f795365e8cd8c90d2b0b3df2d7 Author: Chandan Uddaraju Date: Mon Sep 26 17:29:37 2011 -0700 msm_fb: display: Add MIPI DSI 720P Orise panel driver support Add support to run 720p MIPI DSI Orise panel in both cmd and video modes Change-Id: Iefd5594ba2fafe7797378f3297d169ebbce9b963 Signed-off-by: Chandan Uddaraju commit 0bb7fe942f5e655d1ac1b10398ccda73ce83550e Author: Ravishangar Kalyanam Date: Thu Oct 27 16:06:30 2011 -0700 msm_fb: display: Dynamic boot support for HDMI as primary display Move boot parameter to board display file as early_param for proper allocation of PMEM and ION sizes. Change-Id: Icfb163f572e8e010550747ec83787b6da6e86ee2 Signed-off-by: Ravishangar Kalyanam commit 94626402db72f77ee6241cf69c3ec584c39951da Author: Maheshwar Ajja Date: Fri Feb 17 16:52:12 2012 +0530 msm: vidc: add slice info extradata feature for encoder One frame can have multiple slices or NAL units in the encoded bitstream output. Core can give slices information to the driver, if slice info metadata enabled, which inturn will be sent to the client as extradata in output buffer. This change will enable the core with slice information extradata feature. Change-Id: I52935a641dc7b4921da602b0132f0b81463b5cc8 Signed-off-by: Maheshwar Ajja commit 4bb6ead226a37531bf7a9c272b6a805b0d674567 Author: Kevin Chan Date: Wed Feb 29 01:01:41 2012 -0800 msm: camera: send error to HAL if daemon crashed When camera userspace daemon crashes, the server fd will be close, which trigger the msm_server_close function, we will check if there is an active camera session. If camera is active, we will send a v4l2 event to HAL layer to signal an error. Application will exit gracefully and close other open fds and exit camera session. Change-Id: I14ebc864d6cace7ca6f4dbfb935623a76eeccaa8 Signed-off-by: Kevin Chan commit 766f87ae9589bf9db1135077e9a8c03b3ba05c78 Author: Riaz Rahaman Date: Fri Feb 24 12:54:33 2012 -0800 msm: vidc: Enable CP for 8660 Set secure_session flag using a dedicated function.For secure session the order in the open call is first to open the client followed by calling the secure session. In release the unsecure of session needs to be done before closing the client. Change-Id: Ib03437d9d71358e1b2f5040ee0213ac83fa46c8a Signed-off-by: Riaz Ur Rahaman commit 0a1dfa3ebb6056c8969fd594be998b7e666a74cd Author: Arun Menon Date: Wed Feb 22 20:31:19 2012 -0800 vidc: Enable error concealment in video core Without error concealment, there is a bug in video core due to which it goes in to bad state for certain clips and times out. This change fixes the issue. Change-Id: I7452794e5901edd116acf22004bb70a7c398deed CRs-fixed: 336167 Signed-off-by: Arun Menon commit b0ded4e7fc3f7dd1c7f6468e00deff6672637f15 Author: Arun Menon Date: Wed Feb 15 13:54:10 2012 -0800 vidc: Fix incorrect return value check Without this change, if the max number of clients is exceeded then vdec_clients array accesses memory out of bounds causing a crash. Change-Id: Ia7003fbb42d92a08d4a829803b764eb8da7c8fc6 Signed-off-by: Arun Menon commit 3a7774b2d5e1b3e6967bc2456be77402cd51b239 Author: Deva Ramasubramanian Date: Fri Feb 10 12:09:50 2012 -0800 msm: vidc: Remove duplicate header files - Updated the header files in /include/media/msm to mirror the header files in drivers/video/msm/vidc/common/. - Deleting header files in drivers/video/msm/vidc/common/ as we wish to use headers in /include/media/msm going forward. Change-Id: I58f64e6168d3cc101394414400dd79b82c429ae4 Signed-off-by: Deva Ramasubramanian commit 04592007f7fd2dcff87ed034b8767dcc9550f08b Author: Jeyaprakash Soundrapandian Date: Wed Feb 8 10:29:50 2012 -0800 msm-camera: vertical and horizontal view angle of lens added. The application layer expects the view angle of the camera lens. The lens vertical and horizontal view angle of the sensors imx074 and ov2720 are added. Change-Id: I513fbbdf7fdfc5df0969fe54e05c7549123f6bcb Signed-off-by: Jeyaprakash Soundrapandian commit 6c3bb3269d8dea04a2fbdc48a5cc267589f7f4f3 Author: Su Liu Date: Tue Feb 14 02:15:05 2012 +0530 msm: camera: EVB: Add Kernel driver OV5647 & OV7692 Add Initial sensor driver support for 5MP OV5647 and 1MP OV7692 on EVB 1.0 platform. Change-Id: I8155abe1ff3c388561feed3a032c6603df892e1e Signed-off-by: Su Liu Signed-off-by: Lokesh Kumar Aakulu commit dbbefd7e3586a832447909f17e4ee99edb68bfc3 Author: Deepak Kotur Date: Tue Feb 14 08:39:04 2012 -0800 vidc: cleanup allocated ion buffers in case of crash. when a userspace process crashes, the video driver release function is called and the allocated ion buffers are cleaned up to avoid memory leaks in case of userspace process crash. Change-Id: I538381b08b27adffe64e23dcf479802fc62179a4 Signed-off-by: Deepak Kotur commit 36d8ccd620799d2ad224f22a4c4c34c0256e1d08 Author: Ravishangar Kalyanam Date: Fri Feb 10 11:53:49 2012 -0800 msm_fb: display: Add DSI Video Toshiba WUXGA(1920x1200) panel support Add DSI Video Toshiba WUXGA(1920x1200) panel support using DSI Toshiba WSVGA bridge chip for controlling panel Change-Id: I36de195a0f86acd5415f2c6a0c4f0cfe050512bb Signed-off-by: Ravishangar Kalyanam commit a4036e1a530eaa235c01c4eceadf48379964c8a4 Author: Deepak Kotur Date: Mon Feb 13 12:28:45 2012 -0800 vidc: Fix for release of secure session. When the video driver is released ,the memory is un protected by calling the unsecure heap API, It was observed that sometimes when the memory is unprotected without closing the device the video core was not responding, after testing it was found the call sequence of unprotecting and closing of the video driver was not proper, hence first close the video driver and then un protect the memory. Change-Id: I35bd2b18281d78eb8ff91925f5b989282c2b5603 Signed-off-by: Deepak Kotur commit de2d0ee764456f6fc4b77d47a021cae969a9fd6d Author: Kiran Kumar H N Date: Mon Feb 13 13:42:29 2012 -0800 msm: camera: Correct the IOCTL numbers. Two camera IOCTL types are enumerated using the same number by mistake. Rectify the mistake. Change-Id: I48ee8d0ca543c19a3f692ed2ca5baa950edacdf2 Signed-off-by: Kiran Kumar H N commit 3b6551e3642301c92a1c96a70c4905da87b268ec Author: Ravishangar Kalyanam Date: Wed Feb 15 16:11:39 2012 -0800 msm_fb: display: Add supported MIPI panels to LVDS/MIPI detect config Add supported MIPI panels to LVDS/MIPI panel detect config for backward compatibility with old targets Change-Id: I31048cd51c8e8d09e7a16c5f81eb3e6dc9c59259 Signed-off-by: Ravishangar Kalyanam commit 6861b213cc6793cb288b115afed134864c03d92d Author: Deva Ramasubramanian Date: Tue Jan 31 16:29:31 2012 -0800 vidc: Add check for ION import fd errors. ION APIs return error values rather than NULL pointers in case of failure. Hence remove the explicit NULL check and use the IS_ERR macro to identify failure. Change-Id: I38d6ce06e676dfc0f85954bf509db53295906bbe Signed-off-by: Deva Ramasubramanian commit 6cf8a749e2354cf09e564dfa8104f706dca9b437 Author: Jignesh Mehta Date: Sat Feb 4 23:40:50 2012 -0800 camera: vfe32: Enable VFE configuration for inline JPEG encoding. During inline JPEG encoding, one VFE output is routed into internal memory (IMEM) instead of external memory. The JPEG encoding hardware (GEMINI) will read from IMEM and generates JPEG bitstream. Change-Id: I12d3600524538ab85021dd8882af0404bddc488f Signed-off-by: Shuzhen Wang Signed-off-by: Kevin Chan Signed-off-by: Jignesh Mehta commit ab05f94b75a40fdd70f018a12fef1d8e0b972175 Author: Ravishangar Kalyanam Date: Thu Feb 9 19:18:45 2012 -0800 msm_fb: display: Add LVDS display & LVDS/DSI panel auto detect support Add LVDS display PHY/PLL configuration and panel backlight support. Enable auto-detect support for LVDS/DSI panels Change-Id: I36a1a3c4cee9e015ae6fd03257bd10efa81450d8 Signed-off-by: Ravishangar Kalyanam commit 70613ecf6cde306b774578b5732f992f662e599a Author: Ankit Premrajka Date: Thu Jan 26 16:24:23 2012 -0800 msm: camera: support exposure metering and HDR snapshots With this change we achieve multiple things related to correct HDR functionality. First, we do not always configure ping and pong to be the same buffer in case of the snapshot mode. This would help support taking mulitple snapshots. Second, we support for logic to skip frames in case of snapshot, a necessity for the exposure metering feature. Third, we support post processing divert of both snapshot and thumbnail buffers to be taken from either mctl queue or video queue, to be determined at runtime. Change-Id: Ibcf2bbfc171b2686ca44e6366feadf435368fa5f Signed-off-by: Ankit Premrajka commit 0cfba7b42b33cc0712d81d3ea917a235b3cd8d7c Author: Amir Samuelov Date: Mon Feb 6 11:02:12 2012 +0200 msm_fb: display: Add Chimei MIPI-DSI WUXGA panel driver. Add Chimei MIPI-DSI WUXGA (1920x1200) panel driver. Change-Id: Ie5d55309efa81e237215de4d79b0bc84ce5072ef Signed-off-by: Amir Samuelov commit 18044ce96c01a440a2ade3711aba776aa1fea64a Author: Pradeep Jilagam Date: Tue Dec 13 23:22:48 2011 +0530 msm_fb: display: Add support for MIPI NT35510 WVGA panel. Adds DSI client and panel driver files to support Command and Video modes with NT35510 client and Truly WVGA panel Change-Id: Ia41bf282d070fa5fc5e0afeb24366a540c7ca9f5 Signed-off-by: Pradeep Jilagam Signed-off-by: Jeevan Shriram commit c3cb9ea7ca154538e80c67f3ad9979833888733c Author: Kiran Kumar H N Date: Fri Jan 6 15:11:10 2012 -0800 msm: camera: Add MCTL camera node. Add support for MCTL camera node. This is a v4l2 device node which will be used by the camera daemon process to configure buffers for VFE. Change-Id: I8415288fb6881376a8c1e78ca03bb12f8f655863 Signed-off-by: Kiran Kumar H N Signed-off-by: Ujwal Patel commit dd12847121cfdc1e1a12ec5aeccff355d5d72d16 Author: Kiran Kumar H N Date: Thu Dec 1 09:35:34 2011 -0800 msm: camera: Configure VFE for two output mode. Configure upto two outputs of VFE desginated as primary and secondary. Depending on the irq, only send message type primary and secondary and allow MCTL to interpret these messages. Change-Id: I25568cb6bba5792658b0570383f64ddb58e21421 Signed-off-by: Kiran Kumar H N Signed-off-by: Ujwal Patel commit aa70f9da28370869b83afd6fad79473a7e3d141b Author: Deepak Kotur Date: Thu Jan 26 09:00:15 2012 -0800 vidc: Caching support for video encoder/decoder. Added support for cache flushing when the ion buffers are allocated in cached mode for encoder and decoder. Change-Id: Ia6c3f82fe62d6aecf7651523c6918f05b8906917 Signed-off-by: Deepak Kotur commit 318d7cbd8eaaced74293b90bec8533a280d41bdc Author: Kevin Chan Date: Tue Nov 29 14:24:26 2011 -0800 msm: camera: Correct the reserve buffer logic in mctl_pp. When the daemon asks to reserve a free buffer, get the correct address by using the image mode to get to the correct camera instance and populating the buffer address. Change-Id: I23c6e00458562ef2b9880cbffe2d6a100de80ea1 Signed-off-by: Kevin Chan Signed-off-by: Kiran Kumar H N Signed-off-by: Ujwal Patel commit 51c0e6541a6eab7510def11804fb0b379d093b89 Author: Laura Abbott Date: Wed Feb 1 16:24:39 2012 -0800 msm: video: Update macros to use readl/writel Currently, video code uses macros other than readl/writel to read/write from memory mapped registers. While technically correct, this prevents readl/writel logging from working as expected. Change the video macros to use readl/writel internally. Change-Id: Ia5b71849491b31f4c8dd04cd4228bb30602a78c4 Signed-off-by: Laura Abbott commit f365b26933818f0073aa99b2b2624c703e19a833 Author: Rajeshwar Kurapaty Date: Wed Feb 1 13:07:43 2012 +0530 vidc: 720p: Fix for H264 thumbnail generation Core is sending non frame data error for SPS and PPS, which is communicated as a fatal error to the component in case of idr only mode. Fixed this by sending it as a bit stream error. Change-Id: I79b1fb45857b3b18fa84f17dca3d8a8a2fbb1d2b CRs-Fixed: 326563 Signed-off-by: Rajeshwar Kurapaty commit 8eecbbe64be9bda61624d5d23cde9615b5ccb588 Author: Maheshwar Ajja Date: Mon Jan 30 15:24:22 2012 +0530 msm: vidc: insert break in switch-case statement Insert break statement at appropriate case statement in a switch condition. If no break statement resulting in corruption for next case statement. CRs-fixed: 333684 Change-Id: Icc617ac11d90ccfdcd33ea1d5a3f421935f595ad Signed-off-by: Maheshwar Ajja commit 0a03871991ba38c1ab5ca09a61f218fb2b9775a8 Author: Deepika Pepakayala Date: Thu Jan 26 15:25:07 2012 -0800 msm: vidc: Update to new clock APIs. Update current clk_enable and clk_disable APIs to clk_prepare_enable and clk_disable_unprepare APIs respectively. Change-Id: I7cbd5d7ed0565b777b54deab0e77b0f424675901 Signed-off-by: Deepika Pepakayala commit 49a21e0f093d8476f108f7174a09ff941ddaf4e0 Author: Luis GarciaCalderon Date: Tue Jan 24 11:34:30 2012 -0800 vidc: Fix cleanup error after a failure when importing ion fd. An invalid value in the kernel address variable causes an ion unmap error when attempting to clean up after a failure occurs when importing the ion fd in the function vidc_insert_addr_table(). When an ion import fd failure occurs, cleanup is not required. During failure we now go directly to bail out and the cleanup code is skipped. CRs-Fixed: 332841 Change-Id: I3aa99a278806b8f8031c1618ab067391909105c7 Signed-off-by: Luis GarciaCalderon commit 62f887ce4c6a52be4a4b846606768c19487742b7 Author: Ravishangar Kalyanam Date: Tue Oct 11 22:56:59 2011 -0700 msm_fb: display: Add LVDS display driver support for Chimei WXGA Add LVDS display driver support for Chimei WXGA LVDS display panel Signed-off-by: Ravishangar Kalyanam Change-Id: If8830295814d0e27f49dfffdeb96db63f73809ba commit 055cb8ecdd4aa111e24844f80c30607470de22b5 Author: Suresh Vankadara Date: Wed Jan 18 00:50:04 2012 +0530 msm: camera: Add support to V4L2 architecture New targets are following V4L2 architecture for camera. Update 7x27a camera drivers to support new V4L2 architecture to unify all camera drivers in the same architecture. Signed-off-by: Suresh Vankadara Change-Id: Ie23ac982375041c06b68537d5784d8cdbbc9bf04 commit 8a41a00c9a223ff75a53f5295d9c4931352d9cbe Author: Rajeshwar Kurapaty Date: Fri Jan 20 19:09:51 2012 +0530 vidc: 720p: Update to new clock APIs. Updated current clk_enable and clk_disable APIs to clk_prepare_enable and clk_disable_unprepare APIs respectively to be inline with the new clock APIs. Change-Id: Ie45b620a7580ac65466b922b749b5746abbe4c20 Signed-off-by: Rajeshwar Kurapaty commit 3a2cd43253cd0bc4e4451b7384dbb2ea59a078d2 Author: Deepak Kotur Date: Fri Nov 18 13:58:58 2011 -0800 vidc: check for ION flags. Get the ION flags before and pass the flag info to ion_map_kernel() api, the flags indicate if ION device is opened in cached mode or uncached mode. Change-Id: I125ba066337851ff67961edee97aca90324e9799 Signed-off-by: Deepak Kotur commit fc81e10421b055303c2459fd52e19a57e2aff31e Author: Alekhya,Monika Date: Thu Dec 29 15:17:33 2011 +0530 msm-camera: Add support for YV12 preview format Enable camera driver to output preview frames in YV12 format. Change-Id: Ib4e358460eb922c6a06314682380c4de30f81319 Signed-off-by: Alekhya,Monika commit 0da46929eb69a01fa4b1d26a317e8fcc60a024ac Author: Huaibin Yang Date: Tue Nov 29 15:08:04 2011 -0800 msm_fb: display: add mdp overlay1 writeback This feature is enabled to avoid underrun on the display external interface (HDMI). For example, if 1080p to 720p downscaling is required, and mdp clk rate already is in its max, writeback is the only solution for this situation. Change-Id: I2323272a90730da45601f1d4c7dfc2bf06337b59 Signed-off-by: Huaibin Yang commit 7c3ad69aac323ce84e3015873b0c9b18387c12d3 Author: Rajeshwar Kurapaty Date: Thu Jan 19 13:10:57 2012 +0530 vidc: Add support for video playback secure session. When video driver is opened in secure mode, buffers are allocated from secure heap. Change-Id: I813c52e65b88cc302d8f4d27fc7c5f13a6fa77a8 Signed-off-by: Olav Haugan Signed-off-by: Deva Ramasubramanian Signed-off-by: Rajeshwar Kurapaty commit cc5d20d1c1c52cb69fc4bae5bb626fd76bfe730e Author: Gopikrishnaiah Anandan Date: Tue Jan 10 18:43:50 2012 -0800 vidc: Map firmware buffers after memory clocks are ON. Change will delay mapping of buffers until bus bandwidth is requested by video driver Change-Id: Ibb6867baf6b3e821ec3ceafcdcab1e9225a5b109 Signed-off-by: Gopikrishnaiah Anandan commit 4d05ed377635f1955412c580d2e925babd0fa122 Author: Gopikrishnaiah Anandan Date: Fri Jan 13 11:08:44 2012 -0800 vidc: Enable clocks required for secure playback. The video driver should enable iommu clocks for vcodec, mdp and rotator for content protection playback. Expose clocks to video driver to enable for secure playback. Change-Id: I2037cf5825d0b9cc7f37cf7fe56396163cb1db24 Signed-off-by: Gopikrishnaiah Anandan commit c59d62226a850caf80afc04e35d0fd060e91adf4 Author: Deepak Kotur Date: Tue Jan 17 14:37:44 2012 -0800 vidc: Added proper check for ION handle. ION handle check was not correct for error case, added the proper check for ION handle to handle the error cases properly. Change-Id: I6bf3ce32d5b77d4f2c606fda1c511967156d62c0 Signed-off-by: Deepak Kotur commit e0e9e92051e2170b79713f3455c481e8defd2e47 Author: Deepika Pepakayala Date: Tue Nov 22 13:41:28 2011 -0800 msm: vidc: Remove endianness change for 1080p firmware. Endianness change is no longer required for 1080p firmware starting with Nov 30th 2011 firmware version. Change-Id: I309d63b7efb544f80b44c6fc13955f186ece934b Signed-off-by: Deepika Pepakayala commit 6fb6e94208d7eacebf159127b558515ac77ea164 Author: Rajeshwar Kurapaty Date: Wed Jan 11 04:54:51 2012 +0530 vidc: 1080p: Increase context memory size of the H.264 encoder. Increasing the context memory size of H264 encoder to 20KB as it is a requirement from 11302011 firmware. Change-Id: I944026c96c9cfc2fcf599d4697bd528fbb43ed43 Signed-off-by: Rajeshwar Kurapaty commit 699edcfca1baabcebcf6c671fdf569b54493f0c0 Author: Vinay Kalia Date: Thu Dec 1 17:43:47 2011 -0800 wfd: msm: Adds encoder sub-device. Adds encoder subdevice to Wifi display driver. Captured output from MDP can be fed to this subdevice to get encoded. Change-Id: Iacdc551ef266525dea27bb99f98833093a57fb39 Signed-off-by: Vinay Kalia commit 577d76ee513f6c09b761849dfcb4b36d1b510f8d Author: Eric Ho Date: Wed Jan 4 14:17:26 2012 -0800 vidc: Add check for ion import fd errors. ion_import_fd can return ERR_PTR(-EINVAL) on error. fix added to check whether the handle returned has an error value. Change-Id: Icaf79630c44e0ffe13c07a26fd4323201479101c Crs-Fixed: 328546 Signed-off-by: Eric Ho commit 57eeb74c2d92dd0fb9b64b6ecd5f39d4b17dd9db Author: Deepak Kotur Date: Wed Jan 11 10:22:04 2012 -0800 vidc: allocate mfc shared memory from MM heap. The mfc shared command memory was only 8k, hence ION alloc was failing for multiple instances. This change allocates the mfc command shared memory from MM heap carveout. Change-Id: Ic54d19950cd4634bb4ec5148a0629e37bec56db3 Signed-off-by: Deepak Kotur commit b559874ae9d4dafcc5eb8b628b8675a3db9fea2e Author: Vinay Kalia Date: Wed Dec 21 16:52:33 2011 -0800 msm: vidc: Adds video header files. Adds video header files in include location so that they can be included by other kernel modules, eg: by v4l2 capture driver for Wifi display. Change-Id: Ib7621d8f551e0d0e8660b19db25c2ff6a501cd67 Signed-off-by: Vinay Kalia commit 57809833f29db84f5cbd68c5af730fe57101d5c9 Author: Rajeshwar Kurapaty Date: Mon Jan 9 23:52:28 2012 +0530 msm: vidc: Add a check for fullHD playback. Added a check for fullHD playback based on the board specific platform data. Change-Id: Ib0aba63e04f86036d835b5f589d21a4af196265d Signed-off-by: Rajeshwar Kurapaty commit 59955cbce487a63792488049110857a05bbd8206 Author: Deepak Kotur Date: Thu Dec 8 10:23:01 2011 -0800 vidc: Dec/Enc ION memory allocation according to new ION heap ID Allocate ION memory from the newly defined ION heap IDs. Change-Id: I599e13f3bd983a551fa62f00247228725fac8bcb Signed-off-by: Deepak Kotur commit 075d00c8aae9422dac51d60275df6a55b82aec98 Author: Gopikrishnaiah Anandan Date: Wed Jan 4 15:28:06 2012 -0800 vidc: synchronize access to address lookup table. Video encoder driver supports meta mode. Different threads can update the table during recording. Adding mutex to restrict only one client to access lookup table. CRs-fixed: 327619 Change-Id: I776cb933aa1819d68b504e9edc66cdfe3c815211 Signed-off-by: commit 819b257a51108b3833256804030c522dc7059cb0 Author: Eugene Yasman Date: Thu Dec 29 18:36:56 2011 +0200 video: msm: Add FB_MSM_HDMI_MHL to Kconfig Add FB_MSM_HDMI_MHL config to enable/disable the HDMI to MHL conversion support Change-Id: I51b58e9ca687e244c5b818a3aefb211e605c8e2a Signed-off-by: Eugene Yasman commit 74236ece951d44e17e906433bd4877be0169741d Author: Ashray Kulkarni Date: Fri Nov 11 15:41:06 2011 -0800 vidc: 1080p: Enable closed gop in MPEG4 encoder Change open gop to close gop encoding for MPEG4 ASP. Change-Id: I2e25b00a28848c3e7d6d971620830065fbd5b50e Signed-off-by: Ashray Kulkarni CRs-fixed: 318148 commit 4587dabfaef0a2cde1b456cda870da68144b9736 Author: Mohan Kumar Gubbihalli Lachma Naik Date: Tue Dec 20 12:16:21 2011 -0800 vidc: remove klocwork warnings Changes made to remove klocwork warnings in vidc. CRs-Fixed: 314450 Change-Id: Ia239c93f078d1f9312092e8672b354bc9f849646 Signed-off-by: Mohan Kumar Gubbihalli Lachma Naik commit 4c7758f294a1d4881623a06bb2cd02c04c174a07 Author: Guruprasad Gaonkar Date: Fri Dec 16 17:30:00 2011 -0800 Camera : Change to retreive system time from Kernel This timestamp is needed in the userspace to flush old video frames. Change-Id: I432e5f5d35581b10857b41930d7751500ea131dc Signed-off-by: Guruprasad Gaonkar commit da525ca7a3adf7566ad5f4f4bb09d093786ba43d Author: Deepak Kotur Date: Mon Dec 12 09:19:07 2011 -0800 vidc: fix for memset crash. Check if the luma size is less that or equal to frame size and then do the memset else return error. Change-Id: I975ece55437499efe8988c06d367a33bdd8ff6b6 Signed-off-by: Deepak Kotur commit 353b8e8393fa572d1f77743f83703415e5d37d58 Author: Deepak Kotur Date: Fri Dec 9 11:34:50 2011 -0800 vidc: Check for return value of ion alloc. Check for the proper retrun value of ion alloc using the macros. Change-Id: I01dec7391807e7811f677c9c475c714135b88749 Signed-off-by: Deepak Kotur commit fc4be3fbbfd53f52fca2609298ea6a307efcdd9e Author: Mohan Kumar Gubbihalli Lachma Naik Date: Wed Dec 14 16:18:49 2011 -0800 vidc: Add video driver support for h264 level 3.2 Add video encoding support for h264 level 3.2 in video encoder. Change-Id: I0d661cceace46e5059538ae348fa3b3e60a9f62f CRs-fixed: 313116 Signed-off-by: Mohan Kumar Gubbihalli Lachma Naik commit 6bc004a29148396bc3974dc6e22864a63fab4448 Author: Rajakumar Govindaram Date: Mon Dec 5 20:58:19 2011 -0800 msm: camera: Support for MT9M114 YUV sensor Initial support for Aptina 720p YUV sensor Change-Id: Idb2eb0c1d98482077cb170f3fc581b1e548dc1ee Signed-off-by: Rajakumar Govindaram commit 9e002a1d9283acc53c0e6e11ae86a41575105fe5 Author: Maheshwar Ajja Date: Wed Dec 14 15:23:19 2011 +0530 vidc: Add metabuffer mode support for 720p encoder driver Added 720p core video encoder driver changes, this change depends-on 93816, which allows clients to register buffers in data path in meta buffer mode. Change-Id: I41f74ceabe348de37763d9728090238d71a786bd Signed-off-by: Maheshwar Ajja commit a5ede607de98907eb9b76486e3734eb823c45408 Author: Deepika Pepakayala Date: Fri Dec 2 11:33:26 2011 -0800 msm: vidc: Driver changes to disable demux in core decoder. Added the following driver changes to support demux disabling in video core. - IOCTLs to check if feature can be enabled. - set/get feature properties - descriptor buffer handling - HAL changes to enable/disable feature in video core - Resource tracker changes Change-Id: I86cf4c959175aba954339fff9f78dae6b5be740c Signed-off-by: Deepika Pepakayala commit 0a34f5ce81e084dfdb0a148106b90c41bae7840d Author: Gopikrishnaiah Anandan Date: Thu Dec 1 12:01:19 2011 -0800 vidc: Add metabuffer mode support for encoder driver. Video encoder driver when configured in meta buffer mode, will allow clients to register buffers in data path. Change-Id: I23e2cb07386461275da5731134d8aad7df1cd060 Signed-off-by: Gopikrishnaiah Anandan commit 39ada7bc05276dc0ab6a4c1ceee74ff25ef0963c Author: Stephen Boyd Date: Mon Dec 12 12:40:45 2011 -0800 vidc: Make more pr_info()s into pr_debug()s The logging messages in the vdec driver are for debug purposes. Replace the info printks with debug printks. If desired they can be turned on individually via # mount -t debugfs none /sys/kernel/debug # echo -n "file vdec.c +p" > /sys/kernel/debug/dynamic_debug/control Finer based prints can be done on a line by line basis as well. Change-Id: I5b6f94e13724036d02c25d1d478d25ca2555dfa2 Signed-off-by: Stephen Boyd commit 34c5f958890c8881e92a05e05ac6f95b5a48eaf1 Author: Huaibin Yang Date: Tue Nov 29 13:56:59 2011 -0800 msm_fb: display: cleanup overlay0 writeback funcs and config flags The writeback blt mode is controlled by assignment of blt_base (NULL or not), only the #ifdef in board file is effective. Those flags and funcs on the driver side is cleaned up. Change-Id: Idc9a7fbb5525071bf3cf68e5182bc7f6a5693932 Signed-off-by: Huaibin Yang commit a86367e34880ba37cabc0a6041300c0e3ae2424b Author: Deepika Pepakayala Date: Mon Nov 28 11:59:58 2011 -0800 msm: vidc: Fix handling EOS with bitstream error. If the EOS frame has codec config flag set and decoder return status is bitstream error, then driver was handling EOS done before the core returned with EOS done. Fixed by adding a check in the driver to not handle EOS done until the core returns with EOS done. CRs-Fixed: 320107 Change-Id: If2c6dc67e5d8e7df54b17443c753f0325b6f5175 Signed-off-by: Deepika Pepakayala commit 8feaa3fe882332192daacd5027386b000667674e Author: Mingcheng Zhu Date: Wed Nov 23 11:33:52 2011 -0800 msm: separating frame divert and post process path. Add a new IOCTL to handle the completion of diverted frame. Change-Id: I3bbfc2bd3bfdfcd5e078713c068f3f6f97f7239a Signed-off-by: Mingcheng Zhu commit b7523cde9399347fa357f0a5d43ccdfeaa30a04a Author: Rajeshwar Kurapaty Date: Fri Nov 18 13:23:14 2011 +0530 vidc: 1080p: Override profile to ASP for XVid/Divx456 Always set profile to ASP for XVid/Divx456 apart from MPEG-4. Core will ignore the profile information from the sequence header and continue to decode with profile set by driver. Change-Id: Ided0fe74ace8c78e28dfc68ba172cce024015e47 CRs-fixed: 319168 Signed-off-by: Rajeshwar Kurapaty commit d973663b4a2086c7fe1bf0264f16d413673c36c3 Author: Liyuan Li Date: Fri Nov 11 13:47:59 2011 -0800 video: msm: Adding support for MDP4 HSIC controls Adding support for users to adjust Hue, Saturation, Intensity and Contrast of the display. Change-Id: I79cb69c871686ccba115798f635f768b9a50affc Signed-off-by: Liyuan Li commit 12301a7e05dd4c94ce1d9bc2e68f31912c792931 Author: Deepak Kotur Date: Wed Nov 9 18:30:29 2011 -0800 vidc: Select board specific memory heap id. Allocates ION memory from the heap id specified in the board file. Change-Id: If701972a632fa336c6447e95b79484739593f1da Signed-off-by: Deepak Kotur commit d7dc26f4487d7945ec17ae50d912699df5ce4afe Author: Mohan Kumar Gubbihalli Lachma Naik Date: Mon Nov 14 16:01:44 2011 -0800 vidc: vdec: Pass alignment flag to mapping api's. Mapping api by default assumes 4K alignment. Video core requires output buffer to be aligned to 8K.This change will pass aligment information to the mapper API. Change-Id: Iea630649476946614dfdbdf5150d97cf46a0ba42 Signed-off-by: Mohan Kumar Gubbihalli Lachma Naik commit 3e90b9f72602f9536bc31270643989a056e1bea3 Author: Ankit Premrajka Date: Tue Nov 1 18:48:45 2011 -0700 msm: camera: add ion support to native driver. This change adds ion support to native (non V4L2) camera driver. It also adds ion structures to the msm_frame structure. Change-Id: I9be720e7d9924074706c93eec52178cb6f130af6 Signed-off-by: Ankit Premrajka commit c18a362bd68407b80e660425c7fa1d2a975fd0b0 Author: Maheshwar Ajja Date: Wed Nov 2 19:13:38 2011 -0700 msm: vidc: enable thumbnail mode with single output buffer Generate thumbnails using 720p core with single video decoder output buffer. Change-Id: I51453f240ab38abd5326df96ea407981c6806f6b Signed-off-by: Maheshwar Ajja commit f6719199aff866be5c77f2ddcfd56539932dc1cf Author: Deepak kotur Date: Fri Oct 21 15:03:11 2011 -0700 vidc: Add ION support for Decoder and Encoder. If ION is enabled in the platform, then use the ION api's to allocate memory, to get the virtual address and physical address for decoder and encoder. Change-Id: I6372d14914de3a8f589fbcf45ffcee211fe563e3 Signed-off-by: Deepak Kotur commit ebd12f62bc7dc8b32e8efc099c4fdfa235226106 Author: Maheshwar Ajja Date: Fri Nov 4 11:56:35 2011 -0700 msm: vidc: print message as kernel info instead of error both decoder and encoder uses same driver structure and 720p/1080p core base addresses, so the below log message is not an error message. hence making it as kernel info meesage intead of error message. Log message: Device config mismatch CRs-fixed: 316470 Change-Id: Ib0f070eb44217961639d8326409f18f8a3600f19 Signed-off-by: Maheshwar Ajja commit 996be18a0a1cc98fbf70d05ab99eb4343dacf9b9 Author: Mingcheng Zhu Date: Sun Oct 16 16:04:23 2011 -0700 msm-camera: allow non-zero Y offset. Change-Id: I73238a6cfac0feb146279516f78f4a51c74bc9e9 Signed-off-by: Mingcheng Zhu commit d292ddd67b5eb550d02520403ea2ad1d72957189 Author: Rajeshwar Kurapaty Date: Tue Nov 8 16:22:49 2011 +0530 vidc: 720p: Set DB line buffers in case of reconfig In the case of multi resolution H263 clip, there is no response from the core. With fixes in video f/w, there is a problem in reconfig. Fixed by setting the DB line buffers to the core again in the case of reconfiguration. Change-Id: Iab3402d76ee904568c684ecdcc36f19b417aaa42 CRs-Fixed: 303874 Signed-off-by: Rajeshwar Kurapaty commit 27020d1b5db194e11b08dc46dd7b89078895b6eb Author: Vinay Kalia Date: Fri Oct 14 17:50:29 2011 -0700 video: msm: Writeback support in mdp for WFD. Adds writeback mode in mdp for wifi-display(WFD). This mode can be used to get the captured frames from mdp. This is added to support wifi-display capture device. Change-Id: Iae30cac65af181d8df4b514a128cd876fe7dda1c Signed-off-by: Vinay Kalia commit 3d40367cac25700f31510af395f58975bec65522 Author: Deepak Kotur Date: Fri Oct 28 16:35:00 2011 -0700 vidc: Map userspace allocated buffers into video smmu. Buffers allocated in userspace are registered with video driver for video core to use them. Video driver uses the msm mapped buffer API's to get the device address for those buffers. This address is then passed on to video core. Change-Id: I33dae3c90feb6c320cf0d422adf17b14eee03625 Signed-off-by: Deepak Kotur commit 4cff94aea759ca85177d8e95bbc5446e6efc742d Author: Kiran Kumar H N Date: Mon Oct 17 11:37:33 2011 -0700 msm: camera: Add support for YV12 image format. If the application uses YV12 or similar image formats which have more than 2 planes, then enable all the 3 channels of VFE output. Change-Id: I31af22a4047a38a12fe09a0b07a68f435506aad1 Signed-off-by: Kiran Kumar H N commit a9bdb01e48798ed256c416c6eefa0964ffd6637c Author: Taniya Das Date: Thu Sep 8 11:21:33 2011 +0530 msm: camera: Add camera driver support for ov5640 and ov7692 Add supprt for ov5640 and ov7692 for QRD devices. Change-Id: I9aa5b5031f0cd05f88fa5958a8dd4dbea18f04ab Signed-off-by: Taniya Das Signed-off-by: Lokesh Kumar Aakulu commit cd7bc3ba9b76cdb5293653121508b56be470d65c Author: Kiran Kumar H N Date: Wed Oct 12 16:14:48 2011 -0700 camera: Add multiplanar support in postprocessing. The current postprocessing framework uses single planar structures. Change the data structures to support multiplanar image formats. Change-Id: I27dc6f4c544a4a628bbf2b073d6abd899450a396 Signed-off-by: Kiran Kumar H N commit d893034f3c7b3bc9435cd0cba78f220349b484ae Author: Taniya Das Date: Tue Aug 23 18:47:05 2011 +0530 msm_fb: display: Add support for MIPI DSI Truly panel Change-Id: I499f050622e72c9f1daafa251b16ac67c35a7991 Signed-off-by: Taniya Das commit 5283716d21af697a88ce5ec20fc2bba7a19a6272 Author: Matt Wagantall Date: Thu Oct 20 11:18:31 2011 -0700 msm: vidc: 7x30: Fix device argument of clk_get() for mem_clk A NULL device pointer will cause clk_get() to fail. Fix it. Change-Id: Iac42c467e1c9ed6ee30996d550ae24b231792a40 Signed-off-by: Matt Wagantall commit 272f660ed75b1c91187cbcbc24f4e6db2389ab04 Author: Kevin Chan Date: Tue Oct 18 14:20:03 2011 -0700 msm: camera: Add binning factor to sensor output info Incoporate binning factor to calculate exposure time Change-Id: I31f6896ae7b36f606b8a407e5662d341f8f8ff1e Signed-off-by: Kevin Chan commit ef93b15891225f596b0e8bed8d2b727560456107 Author: Eduardo Carrasco Date: Tue Oct 18 11:11:56 2011 -0700 msm: vidc: Preventing dereference pointers and array out of bounds Preventing a dereference pointer, and adding logic to prevent array out of bounds Change-Id: I8b21e4cb25a3dbb13c907d84c7ea342a12eed468 Signed-off-by: Eduardo Carrasco commit a2c2767ee7fa7e55d9cb30873739dc42311d60f4 Author: Manoj Rao Date: Tue Aug 30 17:19:39 2011 -0700 msm: display: HDMI: Driver support for CEC feature Driver implementation of HDMI CEC feature. Support includes CEC frame send and frame receive. Support added for sysfs interface for CEC daemon to interact with the driver for reading and writing frames. sysfs interface /sys/class/graphics/fb1/cec Read: CEC block state. Write: Enable/Disable CEC block. /sys/class/graphics/fb1/cec_logical_addr Read: Print CEC logical address Write: Set CEC logical address which is used for addressing CEC messages to and from MSM /sys/class/graphics/fb1/cec_rd_frame Read: Read rcvd CEC message from message queue. If queue is empty -EBUSY. If CEC block is disabled -EPERM. Write: N/A /sys/class/graphics/fb1/cec_wr_frame Read: N/A Write: Write to send CEC message. If CEC line arbitration fault/no ack -EINVAL. If CEC block is disabled -EPERM. Change-Id: I62ce418b7f1e887550319081cc4b78fbd564a6f5 Signed-off-by: Manoj Rao commit e30d3697182ecd07564b547d98abf183cd0a2d55 Author: Kevin Chan Date: Fri Oct 14 16:11:01 2011 -0700 msm: camera: Separate video timing and output pixel clk Camera video timing pixel clk and output pixel clk can be different. Added vt_pixel_clk and op_pixel_clk to address the difference. Change-Id: I8770c9897bc340908776d01a7583fed84398ff33 Signed-off-by: Kevin Chan commit 898f4bd8a9e7027e2fd9e50000e34abb41834e19 Author: Ravishangar Kalyanam Date: Fri Jul 15 18:25:47 2011 -0700 msm_fb: display: Add support for HDMI as primary Add support for using HDMI as primary. Includes changing number of framebuffers to 2, using RGBA format, enabling HPD by default. Change-Id: I7a01ee3cf981b08d05eed13cd0fb7a41983211b5 Signed-off-by: Ravishangar Kalyanam commit 0b51780505f6bf734687533ab37d0f4e5b4ba000 Author: Kiran Kumar H N Date: Wed Oct 5 09:49:51 2011 -0700 camera: Modify the camera event interface. - The current camera event interface is limited to 64 bytes. This restricts the interaction between the driver and the userspace since the current structures used are already using the entire 64 bytes. Hence change the interface to overcome this limitation and accomodate more usecases(eg: postprocessing for multiplanar formats) - Renamed the event structure to a more generic name. Change-Id: Id3c635e2652491da4efd8fe34c32d63464b83755 Signed-off-by: Kiran Kumar H N commit 3f7660ba0f3fdbe3780bee49aaa8ddc3ae3ab6dc Author: Matt Wagantall Date: Wed Aug 17 21:25:13 2011 -0700 msm: vidc: Register device with clock driver and rename clocks Rename the clocks per the new naming convention under which similarly named clocks are distinguish between using their associated device's name and ID. Change-Id: I807b6c46ec78bd4eb54d36e0f8a57a5c314ad46c Signed-off-by: Matt Wagantall commit 7b6e1fa36e1dce1a098995c630307d66d8dc54de Author: Rajeshwar Kurapaty Date: Wed Oct 12 12:29:55 2011 +0530 vidc: 1080p: Recovery point SEI support for ISDB-Tmm Enable Recovery point SEI parsing in the core for H264. Core notifies the Decoded YUV correctness in the output done callback for both decode and display order types. Parse this information and notify the user space with VCD_FRAME_FLAG_DATACORRUPT if the data is corrupt. Change-Id: I58373a2e2e7517431d6b120ea6fcb810d1a463c8 Signed-off-by: Rajeshwar Kurapaty commit 29e31c3659ad0e0bf601026a7f8e1d7eacd97dbf Author: Deepika Pepakayala Date: Wed Sep 21 17:15:47 2011 -0700 msm: vidc: Increase the decoder input buffer size. Increase the decoder input buffer size to 2MB to be able to handle input frames greater than 1 MB. CRs-Fixed: 306909 Signed-off-by: Deepika Pepakayala commit bfe9f472c3e904bd6e18bc5a536a9b315414b3b3 Author: Gopikrishnaiah Anandan Date: Mon Aug 8 11:14:49 2011 -0700 vidc: vdec: Buffer optimization for smooth streaming. Smooth streaming client has the buffer count optimized to lower value than profile and level based counts for H264 decoder. Adding support in driver to take advantage of lower buffer count to optimize memory requirements for smooth streaming. Signed-off-by: Gopikrishnaiah Anandan commit e17a2ddc109e0691a25c69acd3ee16de354f5a82 Author: Ravishangar Kalyanam Date: Fri Sep 30 15:04:39 2011 -0700 msm_fb: display: Fix display driver init calls for auto-detection Fix display driver init calls for auto-detection logic to avoid initialization of panel drivers that are not selected for loading through fastboot Signed-off-by: Ravishangar Kalyanam commit f6d94f2458bdbb02a5cd49a7efa270768fb0bddf Author: Deepak Kotur Date: Mon Oct 3 14:45:15 2011 -0700 vidc: venc: Return the correct error code for IOCTL. When ioctl fails for VEN_IOCTL_CMD_READ_NEXT_MSG send the correct return value to userspace. CRs-fixed: 310431 Signed-off-by: Deepak Kotur commit c719c541d8ec1c9a036002a80725457aab10e54f Author: Ravishangar Kalyanam Date: Thu Jul 28 16:49:25 2011 -0700 msm_fb: display: Add boot param LCDC/MIPI panel detection support Add boot param LCDC/MIPI panel detection support for automatically loading selected panels through fastboot command Signed-off-by: Ravishangar Kalyanam commit c0055a1e92d713993f221d145aef38b4934e7249 Author: Yonggui Mao Date: Thu Sep 29 19:31:47 2011 -0700 Camera: add special effect of emboss, sketch and neon Signed-off-by: Yonggui Mao commit 2c232595feefe3c0edc054cf140b656cb59dc009 Author: Deepika Pepakayala Date: Tue Sep 20 15:49:36 2011 -0700 msm: vidc: Fix to handle VOL header errors. VOL header errors trigger reconfig in the driver. Driver tries to handle the reconfig but the core returns incorrect status causing a hang. Fix will set the flag appropriately for the core to know that the driver is handling reconfig and thereby return the right status. CRs-Fixed: 299978 Signed-off-by: Deepika Pepakayala commit 80eaa6c4e2f9ddd1b4bc4424e7feb9bcb4e14695 Author: Eduardo Carrasco Date: Fri Sep 23 10:37:42 2011 -0700 msm: vidc: Fix GOB Header for H.263 encoding. For H.263, enable the GOB header, when user space selects this option Signed-off-by: Eduardo Carrasco CRs-Fixed: 305978 commit efc36f7734ab4a65bd0058f9ec91a53c16ef40f6 Author: Deepika Pepakayala Date: Thu Sep 22 15:40:49 2011 -0700 msm: vidc: Fix performance level computation The required performance level is rounded off to the incorrect value due to the order of execution of the operations. Fixed the issue by ensuring correct order of execution when computing this value. Signed-off-by: Deepika Pepakayala commit 8e9f99e6223480a453501c07afe6aadaeec2085e Author: Mingcheng Zhu Date: Fri Aug 26 16:33:32 2011 -0700 msm: add video processing engine (VPE) as a V4L2 subdev in 8960. Signed-off-by: Mingcheng Zhu commit 6354a925a1369a1925a040dbf3ede153b1a9f466 Author: Rajeshwar Kurapaty Date: Fri Aug 12 16:49:42 2011 +0530 vidc: vdec: Copy the End of Sequence flag To get End of Sequence flag in the output buffer from the video driver, we need to copy the end of sequence flag from the input buffer to the output buffer in the driver. Added these changes as needed for ISDB-Tmm EoSeq feature. Signed-off-by: Rajeshwar Kurapaty commit 5f4b344ef8050c77eadaff2e6471a0f49f81efa7 Author: Sreesudhan Ramakrish Ramkumar Date: Thu Sep 8 14:56:35 2011 -0700 msm: camera: Get info changes for unified actuator Signed-off-by: Sreesudhan Ramakrish Ramkumar commit a4b5f30e624a97c17df789f442c8dece775f2ad1 Author: Sreesudhan Ramakrish Ramkumar Date: Mon Sep 12 16:23:22 2011 -0700 msm: camera: Actuator changes for 8960 1) Added actuator framework with common functions abstracted out 2) Added actuator as a sub device in media controller 3) coupled sensor with its specific actuator in board file 4) Added new actuator control structure and new enum for communication between user space and kernel space 5) Added common logging module with different logging levels Signed-off-by: Sreesudhan Ramakrish Ramkumar Conflicts: arch/arm/configs/msm8960_defconfig commit 5f31685a1775030f4c071f9b984d300b44467c62 Author: Deepika Pepakayala Date: Thu Aug 18 11:35:17 2011 -0700 msm: vidc: Fix H.263 30fps standard resolution encoding. For H.263, when encoding standard resolutions(CIF/QCIF) at 30fps, the encoded bitstream should not have the Custom PCF flag set in the PlusPType header. This is fixed by enabling the custom PCF for non-30fps encoding only. Signed-off-by: Deepika Pepakayala CRs-Fixed: 300807 commit 07f710c887b0be083da21e36f60a62d2c31e5c9e Author: Kevin Chan Date: Fri Aug 26 19:35:18 2011 -0700 msm: camera: Add camera epprom utility functions New utility file for handling camera eeprom. Added standard functions for reading from eeprom. Signed-off-by: Kevin Chan commit 36e2bdcdf3e325449daa899c08aab3511923415d Author: Kevin Chan Date: Tue Aug 30 17:21:21 2011 -0700 msm: camera: Add camera sensor quarter & full size enum Add quarter and full size as a valid resolution. Both size are always present and used in sensor driver. Signed-off-by: Kevin Chan commit 1bc306ad8db1bd0b5cc55361d905cbc04d75ef62 Author: Ashray Kulkarni Date: Thu Aug 18 11:50:20 2011 -0700 vidc: vdec: Update firmware memory size. Firmware releases dated 07/30/11 and later require 800KB of firmware global context space. Signed-off-by: Ashray Kulkarni commit b84120b47e318d5144604e7249e0e0bc119e1301 Author: Amir Samuelov Date: Sat Sep 3 17:49:43 2011 +0300 msm_fb: display: Add Chimei MIPI-DSI WXGA panel driver. Add Chimei MIPI-DSI WXGA (1366x768) panel driver. Signed-off-by: Amir Samuelov commit ceea762f4b33c244059f674798527902b0e2168e Author: Kiran Kumar H N Date: Tue Aug 23 14:01:03 2011 -0700 msm: camera: Support for Multi planar image formats. Add support for multi-planar image formats. This allows the luma and chroma planes of the image to reside in different memory locations. Signed-off-by: Kiran Kumar H N commit 15b5b3ec2a58cef0bc576ab442f9cb472eb5841b Author: Ashray Kulkarni Date: Thu Aug 11 15:04:08 2011 -0700 vidc: venc: Remove check for allocation of sequence buffer size. Firmware requires non-zero sequence buffer size for H.263. Signed-off-by: Ashray Kulkarni commit 7a6a34fb26f959fcbad55c9450819d79015a6f2e Author: Gopikrishnaiah Anandan Date: Thu May 19 13:27:08 2011 -0700 vidc: 1080p: Override SP profile to ASP for MPEG4 decoding. Always set profile to ASP for MPEG4 decoding. Core will ignore the profile information from the sequence header and continue to decode with profile set by driver. Signed-off-by: Gopikrishnaiah Anandan commit fe7abc088b52d20b47b84737bad0517acfd8a551 Author: Mingcheng Zhu Date: Tue Aug 9 13:27:39 2011 -0700 mm camera: Add pmem vaddr mapping in HAL Signed-off-by: Mingcheng Zhu commit 9559ee42d03855217bd884d814a643f85faa1c6d Author: Mingcheng Zhu Date: Tue Aug 9 11:54:22 2011 -0700 msm camera: separate daemon pmem mapping away from video node Signed-off-by: Mingcheng Zhu commit 0a0fe6a2a6bf9496373d73545b81a1f063399b6c Author: Rajeshwar Kurapaty Date: Tue Aug 23 18:57:58 2011 +0530 vidc: 720p: Handle profile unknown as bitstream error. For corrupted VOL header in the middle of playback core is returning UNKNOWN PROFILE error and is being treated as Fatal error and playback is getting aborted. Now handling it as sequence header fail/recoverable error. CRs-Fixed: 302549 Signed-off-by: Rajeshwar Kurapaty commit 48bc4ee915717166ad735d852bd52491494086ce Author: Rajeshwar Kurapaty Date: Wed Aug 24 18:27:51 2011 +0530 vidc: 720p: Memset MPEG-4 recon buffers to black In the case of MPEG-4 decoding with clips which have initial frames starting with P-VOPs, green macroblocks are seen. This is because of recon buffers used for MPEG-4 have 0 preset values. The default values are changed to 0x10 & 0x80 for luma and chroma to get default color as black. CRs-Fixed: 303298 Signed-off-by: Rajeshwar Kurapaty commit f94bcc6852eae1a1623388b16833569c985e2998 Author: Ankit Premrajka Date: Mon Aug 22 15:23:53 2011 -0700 msm: camera: add config identifier to control command structure. Signed-off-by: Ankit Premrajka commit d880c704a91e2ad56514e5deee20dd194576cc0c Author: Ananda Kishore Date: Thu Jun 23 15:19:31 2011 +0530 vdec: 720p: deblocking filter enabled for Divx and XVID Default deblocking filter is enabled for Divx 4,5,6 and XVID. Signed-off-by: Ananda Kishore commit 3a8b8514533d94af2e9fcb4b215f968f07d14253 Author: Zhang Chang Ken Date: Thu Aug 4 18:41:39 2011 -0400 msm:8060: lcdc nt35582 panel support Signed-off-by: Zhang Chang Ken commit 270813aace6f99b5d6b3515b581a0c40ffee771f Author: Mingcheng Zhu Date: Wed Aug 10 17:23:18 2011 -0700 msm: code clean up of the existing improper event implementation Current implementation has a bug in v4l2 event subscription. Also it is good to make the kernel to be transparent to those notification events from daemon to HAL. Signed-off-by: Mingcheng Zhu commit 4ab97a9943c6eede62a4c62aedeac3ebbcc093d3 Author: Lakshmi Narayana Kalavala Date: Tue Jul 26 15:30:14 2011 -0700 msm: camera: Include Minimum Luma in Stats buffer Include Minimum Luma Pixel value in Stats buffer for AWB stats process. Signed-off-by: Lakshmi Narayana Kalavala commit a980f399e0a4f7e0521449cdaef4766257677867 Author: Kevin Chan Date: Mon Aug 1 20:55:00 2011 -0700 msm: camera: Improve unify sensor apis Added more error checking code Separate dimension specific register settings into separate structure Code flow improvements Signed-off-by: Kevin Chan commit a35a77c817d5dad4d1f915a4fbfea26e9bcbcc60 Author: Ashray Kulkarni Date: Thu Aug 4 12:59:49 2011 -0700 vidc: vdec: Set correct divx codec type. Added support in video driver to configure divx codecs 4/5/6. Signed-off-by: Ashray Kulkarni CRs-fixed: 297558 commit 1d053f856bb08c43006a76ecbfec71f5357df54c Author: Maheshwar Ajja Date: Wed Jul 20 20:45:11 2011 +0530 vidc: 720p: Add IDR Frame type support for H264 format Read IDR frame type from 720p core register set and propagate it to user space using new IDR frame type enumeration added in api header file. The IDR frame type info is used in SYNCFRAME logic for H264 format in userspace. CRs-Fixed: 296738 Signed-off-by: Maheshwar Ajja commit 474f225b5559e57c8df99d0512c1b02861017d44 Author: Nishant Pandit Date: Sat Jul 23 23:17:56 2011 +0530 msm: camera: Initial version of LED Driver on 8960 Initial version of LED driver for Cdp & Mdp comprise - Enable SC628A LED Driver chip for 8960. - Configure SX150X Gpio Expander chip. - Restructure Camera Gpio Mux settings table which will later be used to toggle function select for LED Flash between Mdp & Cdp. Signed-off-by: Nishant Pandit commit 2fe35efa5b3075bc32d00356ad0004162d3df19d Author: Shuzhen Wang Date: Thu Jul 28 10:20:08 2011 -0700 camera: v4l2: Add zoom support in driver. Add implementation of G_CROP and event for zoom completion. Signed-off-by: Shuzhen Wang commit 0d9277c6c15665222a9cdb5d16e45cbb6055d147 Author: Shuzhen Wang Date: Thu Jul 28 10:19:10 2011 -0700 camera: v4l2: Use v4l2_event for event from config to app. This simplies the way event is propagated. Driver only needs to pass on the v4l2_event structure directly. Signed-off-by: Shuzhen Wang commit 5b04d356f55188a7e196a47c570e1cdf6f714c59 Author: Mingcheng Zhu Date: Fri Jul 22 21:18:42 2011 -0700 msm camera: snapshot wavelet denoise support Signed-off-by: Mingcheng Zhu commit 248eac2b1519a94c2587d627fe68a38727b16b58 Author: Gopikrishnaiah Anandan Date: Tue Jul 12 14:24:14 2011 -0700 vidc: vdec: Report dropped field for interlace clips. For field based interlace clips, video core will generate an error when one of field is missing in bitstream. Driver will report this to upper layer, so that it can take appropriate action. CRs-fixed: 290659 Signed-off-by: Gopikrishnaiah Anandan commit c50e30a43b78b54308f7c2681be42b5f110153bb Author: Pradnya Chaphekar Date: Mon Jun 27 13:57:16 2011 -0700 vidc: 1080p: Set chroma address change in smooth streaming mode If resolution change is detected in smooth streaming mode and status indicates that video core can continue decoding, update chroma address for new resolution instead of starting frame realloc. Signed-off-by: Pradnya Chaphekar commit 746d9ab0dabf7165b88906860ed3b52b351bcfe8 Author: Gopikrishnaiah Anandan Date: Thu Jul 7 11:55:13 2011 -0700 vidc: vdec: Report bitstream errors to driver client. When video core generates recoverable bitstream errors, driver will report them to upper layer. CRs-fixed: 290659 Signed-off-by: Gopikrishnaiah Anandan commit 5d41837ac192f0545416b7c0510f4769fc5c04ed Author: Mansoor Aftab Date: Tue Jul 26 17:01:26 2011 -0700 msm: camera: Changes to enable events and Auto Focus Added event notify message support added entries for autofocus event types Signed-off-by: Mansoor Aftab commit 60f8007df48104b7b067de307704abb830ef901a Author: Gopikrishnaiah Anandan Date: Wed Jul 20 12:10:07 2011 -0700 vidc: vdec: Pass alignment flag to mapping api's. Mapping api by default assumes 4K alignment. Video core requires output buffer to be aligned to 8K.This change will pass aligment information to the mapper API. Signed-off-by: Gopikrishnaiah Anandan Conflicts: drivers/video/msm/vidc/common/init/vidc_init.c commit 4288de3af5711a81e86eb33d29f06996a95eb94f Author: Deepika Pepakayala Date: Fri Jul 15 17:40:12 2011 -0700 msm: vidc: Set Y and C size registers to allocated size. Currently the Y and C sizes are set based on the size of video being decoded. In case of smooth streaming, decoded sizes are not the same as allocated sizes. This change will set the Y and C sizes to allocated sizes. Signed-off-by: Deepika Pepakayala commit c63847bcddab79bbd5850322843bf0b4ae098745 Author: Ananda Kishore Date: Mon Jul 18 19:02:15 2011 +0530 vidc: add change to print MFC firmware version CRs-Fixed: 296531 Signed-off-by: Ananda Kishore commit 4950550ed4974d3f971892777bab9bc074cecc2c Author: Mingcheng Zhu Date: Tue Jul 19 20:44:36 2011 -0700 msm: Add new msm_buffer and event structs and event defines Signed-off-by: Mingcheng Zhu commit 0fb9dcfbc652ed617ceb244bd8a9201d00a124fe Author: Kiran Kumar H N Date: Sun Jul 17 12:31:53 2011 -0700 msm-camera: configure preview and recording buffers seperately. decouple preview and recording path configuration by configuring the buffers during preview start and recording start respectively. Signed-off-by: Kiran Kumar H N Signed-off-by: Mingcheng Zhu commit 5a19c68d63da33710ed52a974a996f03a706b84f Author: Kiran Kumar H N Date: Sat Jul 23 11:34:34 2011 -0700 Revert "msm: camera: YV12 video support" This reverts commit 66882a5046143601429632a0b589d9ffeeb3c668. This change will be submitted later. Signed-off-by: Kiran Kumar H N commit 7ff0cf49995d22fddaa90cea95dac8850abcac89 Author: Azam Sadiq Pasha Kapatrala Syed Date: Fri Jul 15 15:56:40 2011 -0700 msm: camera: YV12 video support Support for color format YV12. Signed-off-by: Azam Sadiq Pasha Kapatrala Syed commit d81678207da7c9bb936e98c4f7f917eff81f710a Author: Matt Wagantall Date: Thu Jul 14 12:38:07 2011 -0700 vidc: Stop using vcodec_axi_a_clk and vcodec_axi_b_clk directly These two clock are now implicityly enabled and disabled as dependencies of vcodec_clk (as was already the case for vcodec_axi_clk). Signed-off-by: Matt Wagantall commit a411f7e5195777253d4c3c94430787b4f19ea068 Author: Stepan Moskovchenko Date: Wed Jul 20 13:21:08 2011 -0700 video: Kconfig: Remove extraneous dots from help text Clean up the help text by removing extraneous punctuation. Signed-off-by: Stepan Moskovchenko commit 653c0f9b74db91425f7cda4f13cb2bde638282eb Author: Rajeshwar Kurapaty Date: Fri Jul 15 18:14:30 2011 +0530 vidc: 1080p: Removed check for comparing DPB Size For best effort decoding we don't need to compare the available DPB size with the decoded size and throw error. So, removed the check that compares them. CRs-Fixed: 296211 Signed-off-by: Rajeshwar Kurapaty commit bdc7bbba1cc1202166a45b479b1cb7b0e54eec8f Author: Matt Wagantall Date: Fri Jul 15 12:26:19 2011 -0700 msm: Remove last references to NPA-related code for AXI rate management The NPA driver was removed some time ago, but wrapper code and some of its driver hooks persisted in the tree, despite not being compiled (or even compilable). Remove these now. Signed-off-by: Matt Wagantall commit 814e6171ab7a99fdcb2207b5c0c96dab4b3a3f2b Author: Gopikrishnaiah Anandan Date: Wed Jun 29 13:10:58 2011 -0700 vidc: 1080p: Allocate firmware buffer in driver init. Video core has requirement that firmware buffer address should be a lesser value than the all other video buffers. Hence moving allocation to driver init function to satisfy this requirement. Signed-off-by: Gopikrishnaiah Anandan commit abfb35634e1a165f194208834db1aab9fa7007a9 Author: Gopikrishnaiah Anandan Date: Wed Jun 22 12:53:00 2011 -0700 vidc: Map video driver allocated buffers to video smmu video driver will use the new msm mapped buffer api's to get kernel virtual and device virtual address.This change will replace ioremap calls with new api's. Signed-off-by: Gopikrishnaiah Anandan commit 3f2bc4d6eb5a4fada842462ba22bb6bbb41d00c7 Author: Bryan Huntsman Date: Tue Aug 16 17:27:22 2011 -0700 Initial Contribution msm-2.6.38: tag AU_LINUX_ANDROID_GINGERBREAD.02.03.04.00.142 Signed-off-by: Bryan Huntsman commit 9743b69d29eb846eca3425a647ef9d290925d441 Author: Deepika Pepakayala Date: Wed Sep 21 17:15:47 2011 -0700 msm: vidc: Increase the decoder input buffer size. Increase the decoder input buffer size to 2MB to be able to handle input frames greater than 1 MB. CRs-Fixed: 306909 Change-Id: I0b426e505326e1c1825faf481f77f46369c09154 Signed-off-by: Deepika Pepakayala commit 3b9047132b38c211d4d8a26896ceb4e151bf618a Author: Ravishangar Kalyanam Date: Fri Sep 30 15:04:39 2011 -0700 msm_fb: display: Fix display driver init calls for auto-detection Fix display driver init calls for auto-detection logic to avoid initialization of panel drivers that are not selected for loading through fastboot Change-Id: I32a7c220efd33f748a7b46fb1006e5f0a59dc4dd Signed-off-by: Ravishangar Kalyanam commit 91be717084e45121fc1232e8309343c605603928 Author: Ravishangar Kalyanam Date: Thu Jul 28 16:49:25 2011 -0700 msm_fb: display: Add boot param LCDC/MIPI panel detection support Add boot param LCDC/MIPI panel detection support for automatically loading selected panels through fastboot command Change-Id: I5f5167411ac2e5bbc4287148d22608a7e1f2af35 Signed-off-by: Ravishangar Kalyanam commit f871a5629dd82a60309610bf8d3f82fbf0c8d0d1 Author: Deepak Kotur Date: Mon Oct 3 14:45:15 2011 -0700 vidc: venc: Return the correct error code for IOCTL. When ioctl fails for VEN_IOCTL_CMD_READ_NEXT_MSG send the correct return value to userspace. CRs-fixed: 310431 Change-Id: I9afa3f9afcd718c31d5de99964030fe73eb7be57 Signed-off-by: Deepak Kotur commit 6f6a85717fdc5e82cc0b993840e6efe006d57040 Author: Gopikrishnaiah Anandan Date: Mon Aug 8 11:14:49 2011 -0700 vidc: vdec: Buffer optimization for smooth streaming. Smooth streaming client has the buffer count optimized to lower value than profile and level based counts for H264 decoder. Adding support in driver to take advantage of lower buffer count to optimize memory requirements for smooth streaming. Change-Id: I26a726df8357a5b8ab5de6263b16e842887cac3f Signed-off-by: Gopikrishnaiah Anandan commit f209909baab78b37409249530ca1e840720a4a31 Author: Yonggui Mao Date: Thu Sep 29 19:31:47 2011 -0700 Camera: add special effect of emboss, sketch and neon Change-Id: Iac4c7127745b55e2569ca1976e41ce9dbfd60f5a Signed-off-by: Yonggui Mao commit 65f8ca24b292d4af84955620ee4061b078e5e582 Author: Deepika Pepakayala Date: Tue Sep 20 15:49:36 2011 -0700 msm: vidc: Fix to handle VOL header errors. VOL header errors trigger reconfig in the driver. Driver tries to handle the reconfig but the core returns incorrect status causing a hang. Fix will set the flag appropriately for the core to know that the driver is handling reconfig and thereby return the right status. Change-Id: Ic3ea0f57d886abc5597b7ac0d85f9ae5597aa5d1 CRs-Fixed: 299978 Signed-off-by: Deepika Pepakayala commit e92f9695de49c179e60172b4e625a94bf0ff6dc0 Author: Eduardo Carrasco Date: Fri Sep 23 10:37:42 2011 -0700 msm: vidc: Fix GOB Header for H.263 encoding. For H.263, enable the GOB header, when user space selects this option Change-Id: I03690a7755c48f540fe359cd31ff4257992b9680 Signed-off-by: Eduardo Carrasco CRs-Fixed: 305978 commit c9fc55be6efdd5518618f64f9a658619e86d5139 Author: Deepika Pepakayala Date: Thu Sep 22 15:40:49 2011 -0700 msm: vidc: Fix performance level computation The required performance level is rounded off to the incorrect value due to the order of execution of the operations. Fixed the issue by ensuring correct order of execution when computing this value. Change-Id: Ic0b18fac50ca7bd0094f147b36ee3c2050305445 Signed-off-by: Deepika Pepakayala commit 8763c92c756a1dcd82f3309de42f1961c2e1853b Author: Mingcheng Zhu Date: Fri Aug 26 16:33:32 2011 -0700 msm: add video processing engine (VPE) as a V4L2 subdev in 8960. Change-Id: I635bfc6f484ca727df2144a0ae59f0af1a180091 Signed-off-by: Mingcheng Zhu commit 1a16d5244a27781dad10838c93f11ec58758ee49 Author: Rajeshwar Kurapaty Date: Fri Aug 12 16:49:42 2011 +0530 vidc: vdec: Copy the End of Sequence flag To get End of Sequence flag in the output buffer from the video driver, we need to copy the end of sequence flag from the input buffer to the output buffer in the driver. Added these changes as needed for ISDB-Tmm EoSeq feature. Change-Id: I15c33f1457bdeda978973f74eb2f91c809f530ba Signed-off-by: Rajeshwar Kurapaty commit ba5cc67740ee3c5a62a000f097cf08147a234193 Author: Sreesudhan Ramakrish Ramkumar Date: Thu Sep 8 14:56:35 2011 -0700 msm: camera: Get info changes for unified actuator Change-Id: I3dcce410edf9ce8daaecc94ef231e26832f105dc Signed-off-by: Sreesudhan Ramakrish Ramkumar commit 900d17d8855fd42f0245178824a85012d8af6aaf Author: Sreesudhan Ramakrish Ramkumar Date: Mon Sep 12 16:23:22 2011 -0700 msm: camera: Actuator changes for 8960 1) Added actuator framework with common functions abstracted out 2) Added actuator as a sub device in media controller 3) coupled sensor with its specific actuator in board file 4) Added new actuator control structure and new enum for communication between user space and kernel space 5) Added common logging module with different logging levels Change-Id: Ic32e19dc35092e31e972b77e2f48362a956ae175 Signed-off-by: Sreesudhan Ramakrish Ramkumar commit 184e6cc62fdb2a15da3ea267799a3c1a04ae4808 Author: Kevin Chan Date: Fri Aug 26 19:35:18 2011 -0700 msm: camera: Add camera epprom utility functions New utility file for handling camera eeprom. Added standard functions for reading from eeprom. Change-Id: Ia08c2bfe2e6c37ed2c679822d1a2b1ae94f5e6eb Signed-off-by: Kevin Chan commit 8142983e23840b115a968704be81fa2cb42df246 Author: Deepika Pepakayala Date: Thu Aug 18 11:35:17 2011 -0700 msm: vidc: Fix H.263 30fps standard resolution encoding. For H.263, when encoding standard resolutions(CIF/QCIF) at 30fps, the encoded bitstream should not have the Custom PCF flag set in the PlusPType header. This is fixed by enabling the custom PCF for non-30fps encoding only. Change-Id: I2cd896e5d78cef6160413d792a8be57ce1368bcd Signed-off-by: Deepika Pepakayala CRs-Fixed: 300807 commit 6948f366310cc43779ef7d4f13bb0855aee6a098 Author: Kevin Chan Date: Tue Aug 30 17:21:21 2011 -0700 msm: camera: Add camera sensor quarter & full size enum Add quarter and full size as a valid resolution. Both size are always present and used in sensor driver. Change-Id: I347aac21175f3d15e7fa50f885c83e58f3f741f0 Signed-off-by: Kevin Chan commit 4f7e10164fc8f8477a0929cb910a849772620bc9 Author: Amir Samuelov Date: Sat Sep 3 17:49:43 2011 +0300 msm_fb: display: Add Chimei MIPI-DSI WXGA panel driver. Add Chimei MIPI-DSI WXGA (1366x768) panel driver. Change-Id: I0409909ea6f24db3da6ebf4d92233e45da93c2a4 Signed-off-by: Amir Samuelov commit ba77ebe9cf446942cb0b2851a881425b6caab5d5 Author: Gopikrishnaiah Anandan Date: Thu May 19 13:27:08 2011 -0700 vidc: 1080p: Override SP profile to ASP for MPEG4 decoding. Always set profile to ASP for MPEG4 decoding. Core will ignore the profile information from the sequence header and continue to decode with profile set by driver. Change-Id: I8800ea0e97c0966c243210bb9fd86eb6178575fe Signed-off-by: Gopikrishnaiah Anandan commit debb66baacf7db342891436d01b94a3afde0d905 Author: Ashray Kulkarni Date: Thu Aug 18 11:50:20 2011 -0700 vidc: vdec: Update firmware memory size. Firmware releases dated 07/30/11 and later require 800KB of firmware global context space. Change-Id: Ice7410dcdcef262dd3737b2d63e0f2ff91a5de46 Signed-off-by: Ashray Kulkarni commit 93d42d4357772a178c7729d20f1a4353a5d9b08d Author: Kiran Kumar H N Date: Tue Aug 23 14:01:03 2011 -0700 msm: camera: Support for Multi planar image formats. Add support for multi-planar image formats. This allows the luma and chroma planes of the image to reside in different memory locations. Change-Id: Ibd85b89d752d17d6f840e6959d9b3692e0f2aa98 Signed-off-by: Kiran Kumar H N commit 93f518e6dfac090e4caaf5b6bb7d2cddd057e377 Author: Mingcheng Zhu Date: Tue Aug 9 13:27:39 2011 -0700 mm camera: Add pmem vaddr mapping in HAL Change-Id: I2f5768eeeee42f5df527a85980f3eab24d773451 Signed-off-by: Mingcheng Zhu commit 8ca74aecd2072d2aec9a7d0167198180a6c2386c Author: Mingcheng Zhu Date: Tue Aug 9 11:54:22 2011 -0700 msm camera: separate daemon pmem mapping away from video node Change-Id: Ie4731ea5cea5c51142093fcc2671942a1297644a Signed-off-by: Mingcheng Zhu commit 301cbf57a42e99ef403b38793431046fd0d1bc19 Author: Rajeshwar Kurapaty Date: Tue Aug 23 18:57:58 2011 +0530 vidc: 720p: Handle profile unknown as bitstream error. For corrupted VOL header in the middle of playback core is returning UNKNOWN PROFILE error and is being treated as Fatal error and playback is getting aborted. Now handling it as sequence header fail/recoverable error. Change-Id: I28f79cec1946d3430f90087920f93ef74cf4c101 CRs-Fixed: 302549 Signed-off-by: Rajeshwar Kurapaty commit 207df7f89bf731c456bf6d5c905bde1aa014a8af Author: Rajeshwar Kurapaty Date: Wed Aug 24 18:27:51 2011 +0530 vidc: 720p: Memset MPEG-4 recon buffers to black In the case of MPEG-4 decoding with clips which have initial frames starting with P-VOPs, green macroblocks are seen. This is because of recon buffers used for MPEG-4 have 0 preset values. The default values are changed to 0x10 & 0x80 for luma and chroma to get default color as black. CRs-Fixed: 303298 Change-Id: I526605ff5bf08256f01bebed4a6ba1bfed0c7803 Signed-off-by: Rajeshwar Kurapaty commit ede104a0244a04ca6fa6ce8fe9fc98008462df9e Author: Zhang Chang Ken Date: Thu Aug 4 18:41:39 2011 -0400 msm:8060: lcdc nt35582 panel support Change-Id: Ic5714dad929cf56505569cba14722a20dee12c15 Signed-off-by: Zhang Chang Ken commit 4f65a96f9c198458cb8c237bddf68551f1c5a6ec Author: Ankit Premrajka Date: Mon Aug 22 15:23:53 2011 -0700 msm: camera: add config identifier to control command structure. Change-Id: I5db0e3efe3aea783e969c612463f93b5c31824b9 Signed-off-by: Ankit Premrajka commit 2b20a4b52083d8f054b27daf6f23ec5e3603bc13 Author: Ananda Kishore Date: Thu Jun 23 15:19:31 2011 +0530 vdec: 720p: deblocking filter enabled for Divx and XVID Default deblocking filter is enabled for Divx 4,5,6 and XVID. Change-Id: I7fe9d4194c30bb9effdc8a24e4f5549eb64b42a9 Signed-off-by: Ananda Kishore commit d7c755ef190523324dace3b46431ae5d89e3bb1c Author: Mingcheng Zhu Date: Wed Aug 10 17:23:18 2011 -0700 msm: code clean up of the existing improper event implementation Current implementation has a bug in v4l2 event subscription. Also it is good to make the kernel to be transparent to those notification events from daemon to HAL. Change-Id: If09a7721c43bde513611c67bd2c13470620bcef9 Signed-off-by: Mingcheng Zhu commit b1a3ca7e81ef3336818945e834ac6b19101e1490 Author: Lakshmi Narayana Kalavala Date: Tue Jul 26 15:30:14 2011 -0700 msm: camera: Include Minimum Luma in Stats buffer Include Minimum Luma Pixel value in Stats buffer for AWB stats process. Change-Id: I7ca6121dd8b250588a21634af956685c0f0f4525 Signed-off-by: Lakshmi Narayana Kalavala commit 1afa3df4f6ec987a4adee2ab912926932d2f6590 Author: Kevin Chan Date: Mon Aug 1 20:55:00 2011 -0700 msm: camera: Improve unify sensor apis Added more error checking code Separate dimension specific register settings into separate structure Code flow improvements Change-Id: Ib54f2ac5fd69da9b9b9cd48a96a7f521715c637c Signed-off-by: Kevin Chan commit 28bf67bfebafe573525e73b9c2ad6dad3f588ecb Author: Ashray Kulkarni Date: Thu Aug 11 15:04:08 2011 -0700 vidc: venc: Remove check for allocation of sequence buffer size. Firmware requires non-zero sequence buffer size for H.263. Change-Id: I49da2db9ca90afe7c981b300e0cd526cf7ca50c9 Signed-off-by: Ashray Kulkarni commit 893d5e34665abafade791c0308de09edf55b2c82 Author: Ashray Kulkarni Date: Thu Aug 4 12:59:49 2011 -0700 vidc: vdec: Set correct divx codec type. Added support in video driver to configure divx codecs 4/5/6. Change-Id: I0ee1353e1398207eec7df2d194fdf67e098e4dca Signed-off-by: Ashray Kulkarni CRs-fixed: 297558 commit 94c88008c3f291c17ad3abd992df88681f1e6aa0 Author: Nishant Pandit Date: Sat Jul 23 23:17:56 2011 +0530 msm: camera: Initial version of LED Driver on 8960 Initial version of LED driver for Cdp & Mdp comprise - Enable SC628A LED Driver chip for 8960. - Configure SX150X Gpio Expander chip. - Restructure Camera Gpio Mux settings table which will later be used to toggle function select for LED Flash between Mdp & Cdp. Change-Id: Ieed8b066128d29958d83351152b0611a1cd3c1f0 Signed-off-by: Nishant Pandit commit 99aca45235226074dca943b5099eb26f9eca9c1c Author: Shuzhen Wang Date: Thu Jul 28 10:20:08 2011 -0700 camera: v4l2: Add zoom support in driver. Add implementation of G_CROP and event for zoom completion. Change-Id: I258af6801d235ea47b0b643eb415d995596625b7 Signed-off-by: Shuzhen Wang commit 3b1e09c3011b504da77f5670221b6d169a325b2a Author: Shuzhen Wang Date: Thu Jul 28 10:19:10 2011 -0700 camera: v4l2: Use v4l2_event for event from config to app. This simplies the way event is propagated. Driver only needs to pass on the v4l2_event structure directly. Change-Id: Ic6bc06e0c26989fbf22a8c3b294f5d677ac79d90 Signed-off-by: Shuzhen Wang commit f6af73ecdbab8b493acc5a3815f474a2f9cca865 Author: Maheshwar Ajja Date: Wed Jul 20 20:45:11 2011 +0530 vidc: 720p: Add IDR Frame type support for H264 format Read IDR frame type from 720p core register set and propagate it to user space using new IDR frame type enumeration added in api header file. The IDR frame type info is used in SYNCFRAME logic for H264 format in userspace. Change-Id: Ibf925967464bcdfa73dbe471ddb8c5336e14233f CRs-Fixed: 296738 Signed-off-by: Maheshwar Ajja commit e2bc8ebfbb47c71d0cd862eacc4767b9bee04745 Author: Mingcheng Zhu Date: Fri Jul 22 21:18:42 2011 -0700 msm camera: snapshot wavelet denoise support Change-Id: I9d29083f0c4e386e25da05fb8fcdb3c61f424e78 Signed-off-by: Mingcheng Zhu commit 9897903fd8db48b47a0c0fb20b00d0492938497b Author: Gopikrishnaiah Anandan Date: Tue Jul 12 14:24:14 2011 -0700 vidc: vdec: Report dropped field for interlace clips. For field based interlace clips, video core will generate an error when one of field is missing in bitstream. Driver will report this to upper layer, so that it can take appropriate action. CRs-fixed: 290659 Change-Id: I4e208e533b556c74088171e4b44f28f07116d511 Signed-off-by: Gopikrishnaiah Anandan commit bcfc24b9152d0e4a8624074b8d787cf8e2cef6a9 Author: Mansoor Aftab Date: Tue Jul 26 17:01:26 2011 -0700 msm: camera: Changes to enable events and Auto Focus Added event notify message support added entries for autofocus event types Change-Id: Ieb4cc38df89b04b15c673d12e8cf9e09dbe56aa1 Signed-off-by: Mansoor Aftab commit be6b9a6592940fb0eda12ae3722d4f6e8cf2846a Author: Mingcheng Zhu Date: Tue Jul 19 20:44:36 2011 -0700 msm: Add new msm_buffer and event structs and event defines Change-Id: Ic0a82e13c4a80d7896d53321f0c48db4d71bc978 Signed-off-by: Mingcheng Zhu commit 6e2b2c568fbbd95762b777e7e6e0107e6bdb0c84 Author: Kiran Kumar H N Date: Sun Jul 17 12:31:53 2011 -0700 msm-camera: configure preview and recording buffers seperately. decouple preview and recording path configuration by configuring the buffers during preview start and recording start respectively. Change-Id: I4ea157db4e84add285191dc5702dc1276b2bb2c2 Signed-off-by: Kiran Kumar H N Signed-off-by: Mingcheng Zhu commit 9b10b255cf789b4cb06ba554515b001ec5f8ad16 Author: Deepika Pepakayala Date: Fri Jul 15 17:40:12 2011 -0700 msm: vidc: Set Y and C size registers to allocated size. Currently the Y and C sizes are set based on the size of video being decoded. In case of smooth streaming, decoded sizes are not the same as allocated sizes. This change will set the Y and C sizes to allocated sizes. Change-Id: Iad03498953477934b9a9b8b49b7d8d11586dcc6b Signed-off-by: Deepika Pepakayala commit 6465d940156fa4d05a27772eb64d7fbeee343445 Author: Pradnya Chaphekar Date: Mon Jun 27 13:57:16 2011 -0700 vidc: 1080p: Set chroma address change in smooth streaming mode If resolution change is detected in smooth streaming mode and status indicates that video core can continue decoding, update chroma address for new resolution instead of starting frame realloc. Change-Id: Ib3abae9be955eae525dfade37a6376ddd786a712 Signed-off-by: Pradnya Chaphekar commit 5cbaea9e412af13dd0b0e2d0dbcf461f1c7457b2 Author: Gopikrishnaiah Anandan Date: Wed Jul 20 12:10:07 2011 -0700 vidc: vdec: Pass alignment flag to mapping api's. Mapping api by default assumes 4K alignment. Video core requires output buffer to be aligned to 8K.This change will pass aligment information to the mapper API. Change-Id: If064d5ff09855c395aa5ca9d3d7e6ef48af32adc Signed-off-by: Gopikrishnaiah Anandan commit 01a5bde2b58c6968994480d9738c0defd8149b1a Author: Kiran Kumar H N Date: Sat Jul 23 11:34:34 2011 -0700 Revert "msm: camera: YV12 video support" This reverts commit 66882a5046143601429632a0b589d9ffeeb3c668. This change will be submitted later. Change-Id: I9ac60ad2dadbc330a0b010a706bbefe344d706e7 Signed-off-by: Kiran Kumar H N commit a6782181ebd3600967e269efd176c8e2454bee56 Author: Ananda Kishore Date: Mon Jul 18 19:02:15 2011 +0530 vidc: add change to print MFC firmware version Change-Id: Ia93a09115b8ae212a0ea24cff0e962ec1a947873 CRs-Fixed: 296531 Signed-off-by: Ananda Kishore commit 66882a5046143601429632a0b589d9ffeeb3c668 Author: Azam Sadiq Pasha Kapatrala Syed Date: Fri Jul 15 15:56:40 2011 -0700 msm: camera: YV12 video support Support for color format YV12. Change-Id: I89c139c6c7a4d3ec6555cadcb8afe9eef0023de2 Signed-off-by: Azam Sadiq Pasha Kapatrala Syed commit f830dce45e3493c750b57eff550b8df9da3af796 Author: Gopikrishnaiah Anandan Date: Thu Jul 7 11:55:13 2011 -0700 vidc: vdec: Report bitstream errors to driver client. When video core generates recoverable bitstream errors, driver will report them to upper layer. CRs-fixed: 290659 Change-Id: I5b1187a6784c99ab987cbc7369ba140274a21ff7 Signed-off-by: Gopikrishnaiah Anandan commit ff1c35bd257e0cf42051ae365dd40ae879cc628d Author: Matt Wagantall Date: Thu Jul 14 12:38:07 2011 -0700 vidc: Stop using vcodec_axi_a_clk and vcodec_axi_b_clk directly These two clock are now implicityly enabled and disabled as dependencies of vcodec_clk (as was already the case for vcodec_axi_clk). Change-Id: I640e2b618760b0dfc216301fe1be2e8587a46ca5 Signed-off-by: Matt Wagantall commit a34b0bc9e1e66f9e9c6ef6063bf3c858bca2e2f4 Author: Stepan Moskovchenko Date: Wed Jul 20 13:21:08 2011 -0700 video: Kconfig: Remove extraneous dots from help text Clean up the help text by removing extraneous punctuation. Change-Id: I043abaf33ce6a5f926a3b27551a517e829b30af9 Signed-off-by: Stepan Moskovchenko commit 3eaa215567715925b93e5d5d60f679de6028d0c1 Author: Matt Wagantall Date: Fri Jul 15 12:26:19 2011 -0700 msm: Remove last references to NPA-related code for AXI rate management The NPA driver was removed some time ago, but wrapper code and some of its driver hooks persisted in the tree, despite not being compiled (or even compilable). Remove these now. Change-Id: I34148433f8fd946a9aa664df6ca7782cb02bba2b Signed-off-by: Matt Wagantall commit 0df6ccfc7ac0cf0e34e8fd4bd1ca86565b9f0b3a Author: Rajeshwar Kurapaty Date: Fri Jul 15 18:14:30 2011 +0530 vidc: 1080p: Removed check for comparing DPB Size For best effort decoding we don't need to compare the available DPB size with the decoded size and throw error. So, removed the check that compares them. Change-Id: Ifcc597a164618ddb5bc9fbba29336ec1a45646c1 CRs-Fixed: 296211 Signed-off-by: Rajeshwar Kurapaty commit 3eca044c87d55176025410d729d8ee61fbf2dab0 Author: Gopikrishnaiah Anandan Date: Wed Jun 29 13:10:58 2011 -0700 vidc: 1080p: Allocate firmware buffer in driver init. Video core has requirement that firmware buffer address should be a lesser value than the all other video buffers. Hence moving allocation to driver init function to satisfy this requirement. Change-Id: Idc24c25ce4a8a174704d0ed2a016f7bb652f69d1 Signed-off-by: Gopikrishnaiah Anandan commit f39923cb3a786a13dda46782f550ec66bbdd3953 Author: Gopikrishnaiah Anandan Date: Wed Jun 22 12:53:00 2011 -0700 vidc: Map video driver allocated buffers to video smmu video driver will use the new msm mapped buffer api's to get kernel virtual and device virtual address.This change will replace ioremap calls with new api's. Change-Id: I61df32ae239d3acbf52be78e897765fca01550d4 Signed-off-by: Gopikrishnaiah Anandan commit e762e7006e0f5e199d14cc7bf52daab7f74324ff Author: Gopikrishnaiah Anandan Date: Thu Jun 16 19:04:32 2011 -0700 vidc: Map userspace allocated buffers into video smmu. When video driver client allocates the buffers in userspace, it has to register with driver for video core to use it. Driver will use the msm mapped buffer api's to get the device address. Device address will be passed onto the video core. Change-Id: I73e0ff769c2ef3daf03dd56289e65f256632e991 Signed-off-by: Gopikrishnaiah Anandan commit a1f3f0704761e961df64f7b466c30122d3d1fce3 Author: Ashray Kulkarni Date: Mon Jun 27 12:37:00 2011 -0700 vidc: venc: add Check for infinite intraperiod configuration. Max value allowed is 0xFFFF, any higher value is configured as infinite intra period to the video core. CRs-fixed: 292859 Change-Id: Ieda8e0880b2b9b687e41d8fac87c055e6025dfe1 Signed-off-by: Ashray Kulkarni commit 413398e81521f677418d1de9681dbcd06ed90deb Author: Kevin Chan Date: Thu Jul 7 19:30:44 2011 -0700 msm: camera: Add v4l2 strobe flash ctrl command Adding v4l2 strobe flash ctrl command used in userspace driver Change-Id: If9c7bbc6631a3ad08d75acee7e93756ab7f9f571 Signed-off-by: Kevin Chan commit 08fd174f02cc8001d1da38b5db2386cca542a2ee Author: Ananda Kishore Date: Wed Jul 6 14:42:59 2011 +0530 vidc: 720p:Increased the default input buffer size Increased the default input buffer size from half-frame size to three fourth of frame size. CRs-Fixed: 294663 Change-Id: I16779b04032221a24c3a3e33f2583d1da54dc7ad Signed-off-by: Ananda Kishore commit b191c0f83532e1f1238dca2f6965389f87e88a39 Author: Mingcheng Zhu Date: Thu Jun 30 19:59:10 2011 -0700 Camera V4L2: Adding native camera control command support Change-Id: Idc7f8831eea0b2c2ad0988aafd5cbc3f48ce27d0 Signed-off-by: Mingcheng Zhu commit da7283c54090a0597d0ae4127f9214ab4f338c83 Author: Shuzhen Wang Date: Sat Jun 18 22:59:45 2011 -0700 camera: v4l2: Implement raw snapshot. Enhance videobuf-msm-mem, msm_mctl, and msm_vfe32 to support CAMIF raw snapshot. Change-Id: Id93b9e76c461f12fedddd9ac8b7e8c3c571759a4 Signed-off-by: Shuzhen Wang commit c26269f2d539f2b72ef9a24d1435e5e86744cafa Author: Matt Wagantall Date: Thu Jun 23 19:21:17 2011 -0700 msm: vidc: Move from internal_power_rail APIs to regulator APIs for 7x30 Remove use of the msm-specific internal_power_rail driver in favor of the new footswitch-pcom driver, which uses the regulator framework's APIs. Change-Id: I70462d028622b44bafb4745fe10efd33085d9ff1 Signed-off-by: Matt Wagantall commit 791278e730c6ebce77aea7c16e256eb4ae161aca Author: Ujwal Patel Date: Mon Jun 6 14:18:36 2011 -0700 msm: camera: Support for manual convergence in stereo camera. Adding support for manual convergence in stereo camera and changing the delivery method of stereo quality indicator. Change-Id: Ic614b198c59458797a3f7830621c9556790ece35 Signed-off-by: Ujwal Patel commit 941c6bf893e856837e91be76ccac6664de30d921 Author: Ashray Kulkarni Date: Wed Jun 8 13:01:20 2011 -0700 vidc: venc: configure slicing for every frame. Slicing support was there only during init time, firmware support is now added to configure dynamically. Change-Id: Ife5ce4e23a86d8b8fc66c5a34c5cd40711774a80 Signed-off-by: Ashray Kulkarni commit 9c4382b6cd117160559a1c4d812332e83c2aa8ee Author: Ashray Kulkarni Date: Wed Apr 27 12:18:25 2011 -0700 vidc: 1080p: Reject unsupported profile clips. HIGH10 profile clips are not supported by video core. so added check in driver to reject playback of those clips. Change-Id: I84ba584e1dac0f5932db82f86308e2afeb510a71 Signed-off-by: Ashray Kulkarni CRs-fixed: 273798 commit b345af06153ff47c428858912c348338875dd68e Author: Ankit Premrajka Date: Thu Jun 23 10:08:30 2011 -0700 msm: v4l2: add private CID for backlight and snow detection. Change-Id: Ia990c92d2cd2cf0c14fc9af9f1e34f09f95ce7b8 Signed-off-by: Ankit Premrajka commit 1397bd786a0b96d9728c15f9b7898a074c326102 Author: Gopikrishnaiah Anandan Date: Tue Jun 21 17:17:03 2011 -0700 vidc: Use acm api's for firmware buffer allocation. To ensure address range consistency for video, moving to acm allocaiton api's. Change-Id: I0b2a0f94b9855772cce13d92a71970c8f7e93c2c Signed-off-by: Gopikrishnaiah Anandan commit 0ae7f99864cb402e886486477f2eba79296006ed Author: Ankit Premrajka Date: Tue Jun 21 15:08:37 2011 -0700 msm: v4l2: add private CID for auto focus mode Change-Id: I60a1520c6182a1a517f3f39a03bff17577a94062 Signed-off-by: Ankit Premrajka commit 17ab2187ccf5c82ec2ff6017f85f4a104df736e8 Author: Deepika Pepakayala Date: Mon Jun 20 11:27:20 2011 -0700 msm: vidc: Fix not coded vop handling in decode order. When decoding not coded vops in decode order, the output buffer address was incorrect. Fix will read the correct buffer address from the decode order address register. Change-Id: I1cd0e46af71bfa730e2e794f583b97ae3c3650e4 Signed-off-by: Deepika Pepakayala CRs-fixed: 291342 commit e60198edb29f74b55ee1f4d8bfabddf078444d99 Author: Ankit Premrajka Date: Mon Jun 20 21:00:25 2011 -0700 msm: v4l2: add private CID for Best Shot mode. Change-Id: Ibea4dcbc657ad074df244ed81385ad4825320c70 Signed-off-by: Ankit Premrajka commit 3be1fe39bd035ef2a3008c0a4e585f46543651bb Author: Ankit Premrajka Date: Thu Jun 16 18:49:38 2011 -0700 msm: v4l2: Add private CID for Luma Adaptation. Change-Id: I1403b445e25ed1a618d96a603ceef94a14c12def Signed-off-by: Ankit Premrajka commit f2a6f6f3959f5ab0a79fad769317d50039a20f2c Author: Vinay Kalia Date: Fri May 20 11:35:42 2011 -0700 vidc: 1080p: Startup latency optimization. Startup latency optimization for video playback: 1. Bumped up bus and video core clock at startup. 2. memsetting output buffers in kernel rather than in userspace. Change-Id: I9f0caa05a0a7133795c78d763a23561566461508 Signed-off-by: Vinay Kalia commit fc299bb8066e0325db239bb356c546e57c7ef347 Author: kuogee hsieh Date: Mon Jun 6 10:29:28 2011 -0700 msm_fb: display: add mdp writeback mode support dsi video mode MDP writeback mode has been worked for both lcdc and dsi comamnd mode. This patch add dsi video mode writeback mode support and unify interface to enable/disable writeback mode. CRs-fixed: 287700 Change-Id: I4ced3fa8927fb94e5457957aab274e7d07acdd79 Signed-off-by: KUogee Hsieh commit 81bb021aa870c9649d0b3157e1273e8b1639fa44 Author: Ashray Kulkarni Date: Tue Jun 7 13:30:24 2011 -0700 vidc: vidc: Replace pmem calls with new API pmem_kalloc() pmem_free() are being deprecated, hence replacing them with new API's. Change-Id: Iebe4a73d7834fe5301d101552487f1268eaf87d7 Signed-off-by: Ashray Kulkarni commit 638485841a6243c5bf4fd7291e436516bc6b82a1 Author: Gopikrishnaiah Anandan Date: Mon Jun 6 18:28:55 2011 -0700 vidc: Remove memory type #defines from video driver. Memory type for the driver will be obtained from the board file. Removing the #defines from driver. Change-Id: Id4578cfe777f19f69a3791203335c4efd87cebf4 Signed-off-by: Gopikrishnaiah Anandan commit 0141c1bb3831768724c1a4621859e73040ee4564 Author: Gopikrishnaiah Anandan Date: Mon Jun 6 12:19:15 2011 -0700 vidc: Move platform specific configuration into board file. 7x30,8660 and 8960 support different memory configurations. This information will be obtained by video driver using platform_data. Change-Id: Ice7faac7121547c3d432f12dcface523d030a8ff Signed-off-by: Gopikrishnaiah Anandan commit d8a1c720541845e513bce5a37731ee77b3c7c504 Author: Deepika Pepakayala Date: Wed Jun 8 14:48:37 2011 -0700 msm: vidc: Increase firmware memory size to 500KB. Latest firmware size is greater than 400KB. Change-Id: Ic2101e6ff1f93c88b9499eb8c160414f7db82b1e Signed-off-by: Deepika Pepakayala commit 898afe35de8add2401c15299095805e1a2fc8723 Author: Gopikrishnaiah Anandan Date: Fri Jun 3 10:30:23 2011 -0700 vidc: 1080p: Handle b-frame not supported error. MPEG4 simple profile doesn't support b-frames. There could be erroneous clips in which we can have bframes in simple profile clip. Video core will report an error in this usecase and driver should consider this as warning. Change-Id: I0685ae0839f9a21df41846cc81ec551d2128b242 Signed-off-by: Gopikrishnaiah Anandan commit e9ae0f93eafec0f16207c777daabde7f29189580 Author: Shuzhen Wang Date: Wed Jun 1 17:30:44 2011 -0700 camera: Use msm_cam_evt_msg to pass VFE events/messages. v4l2_event structure isn't big enough to hold all possible VFE events/messages. The solution is to store the events/ messages in a separate buffer, and maintain a pointer in msm_cam_evt_msg. Change-Id: I620bf4f4cad34654336928ee06514bfe4ede15ff Signed-off-by: Shuzhen Wang commit 0ef7cd7e5f0510c937171c931f00583484741910 Author: Pradnya Chaphekar Date: Wed May 11 14:02:19 2011 -0700 vidc: 1080p: Update buffer count calculation for smooth streaming Calculate worst case buffer requirement in smooth streaming mode to avoid unecessary port reconfiguration. Change-Id: If87466ff77823ff87e5915b39f5b7a4c2c174ef6 Signed-off-by: Pradnya Chaphekar commit 2936befa32f998589a4b33ab262e296017134a4e Author: Pradnya Chaphekar Date: Fri May 13 14:28:54 2011 -0700 vidc: 1080p: Send smooth streaming event in output done callback In smooth streaming mode, if a change in frame size is detected, send info event in output done callback instead of sequence done callback. This ensures that the openmax compoenent appends extradata corersponding to updated width and height to the output buffer with updated frame size. Change-Id: Ib42ad1bd9a5f744d8824722d7a55aa46530ae015 Signed-off-by: Pradnya Chaphekar commit 7c395a949da6a08bb3a86a5faf760f26cbbd91db Author: Deepika Pepakayala Date: Tue May 3 14:13:41 2011 -0700 msm: vidc: Support dynamic change of interlaced format. The interlaced format can change dynamically with in a sequence/clip. This change ensures that the interlaced format is updated and passed to the client appropriately. Change-Id: If067d8b2bea6060d1103596bc145a93484db2145 Signed-off-by: Deepika Pepakayala commit 604dc5ee98802356b5a7563ed62f632ad5bba5dc Author: Deepika Pepakayala Date: Tue Apr 19 13:55:44 2011 -0700 msm: vidc: Fix recoverable error log message. Change to log core recoverable errors as recoverable errors to be able to distinguish them from other errors when triaging issues. Change-Id: I9a5404c3257a14a748713188bfc32ae9f2d9ad78 Signed-off-by: Deepika Pepakayala commit 3c11dee0fdd6cc31f28e052a93d1b5d27e47792e Author: Ankit Premrajka Date: Thu Mar 31 15:32:00 2011 -0700 msm: v4l2: V4L2 multi buffer for video and snapshot. Enable multi buffer queues and pcam instances for snapshot and video integration. Change-Id: Ifa16c17df414bbd204243bf80e95f32c002fcbd0 Signed-off-by: Ankit Premrajka commit 866779d5deb7ad68e4625739c33e03c6163e06b4 Author: Gopikrishnaiah Anandan Date: Thu May 19 12:47:37 2011 -0700 vidc: 1080p: Move firmware buffer allocation to driver init. Video core has requirement that firmware base address should be less than input, output and scratch buffer addresses. Hence we allocate the memory during driver initialization. This change will be reverted once SMMU driver is integrated and verified in 8960 target. Change-Id: Ie3c43663f237b89d922af3b7e533df810fffa1d5 Signed-off-by: Gopikrishnaiah Anandan commit 6d7f475e8e4d40c0a787c7e1f2fe7e57a4d84929 Author: Nagesh Subba Reddy Date: Wed May 18 16:19:40 2011 -0700 msm: camera: Consolidate VFE messages for performance improvement Change-Id: I7c8afa619824bbbb188e60b2b78d5ccd13f9b12f Signed-off-by: Nagesh Subba Reddy commit 8a1df7e451ceb7c74ed7d0745dfeefb44628cb40 Author: Gopikrishnaiah Anandan Date: Wed May 18 18:16:45 2011 -0700 vidc: 1080p: Enable AXI clock gating for video core. Add support for gating AXI clocks for porta and portb of video core. Change-Id: I34f4b7d73c59d7172dcf9e00be007bc1214d36ce Signed-off-by: Gopikrishnaiah Anandan commit 0bc71c3ce0852d717720fa81fc90a2c24e40a41c Author: Gopikrishnaiah Anandan Date: Wed May 18 18:57:04 2011 -0700 vidc: 1080p: Pass correct memtype to alloc function. SMI memory type was used wrongly passed to allocation api. 1080p video core work with SMI/EBI memory. Change-Id: I4ce256ffa48a38bcb5c2262fd45d9e243e571535 Signed-off-by: Gopikrishnaiah Anandan commit f4d7806fbccb201a45d12cff1f64aa6fb363952f Author: Gopikrishnaiah Anandan Date: Wed May 18 17:37:31 2011 -0700 Revert "vidc: Disable AXI and pixel cache for 8960 virtio." This reverts commit 7f710b28cf71f08b30d657afca7650487eb0f615. Target supports Axi bus and pixel cache. Reverting change made sepcific to simulator. Change-Id: I09ca785b5111f6d40b43ec1987d0b7705caabd4a Signed-off-by: Gopikrishnaiah Anandan commit c7163d9a33d86d1001aa4083423c68c07743861c Author: Ravishangar Kalyanam Date: Mon May 16 14:07:15 2011 -0700 msm_fb: display: Reorganize DSI clock and PHY settings code Reorganize DSI clock and PHY layer settings by moving code to different file from base driver Change-Id: I7d02a4cd0f5322b80462e3721d5c8fb4f83d002f Signed-off-by: Ravishangar Kalyanam commit 757e2ea8064b379ecfd02a6fdd36f6f2894066c8 Author: Ravishangar Kalyanam Date: Wed Apr 6 11:15:36 2011 -0700 msm_fb: Display: Enable WSVGA Toshiba MIPI DSI video mode panel. Add code to configure and enable MDT61 Toshiba MIPI DSI video mode panel. Add new command set to initialize and configure the new panel. Change-Id: I8c543677f75ade967a77100a7878b9e487dc991b Signed-off-by: Ravishangar Kalyanam commit f6f653c41b41d6c77fcfe1c50be3fe5044dc496a Author: Pradnya Chaphekar Date: Fri May 13 14:07:06 2011 -0700 vdec: 1080p: Align stride and scan lines for tile format Update decoder output buffer stride and scan lines as per tile format specificaton. Change-Id: I2192b7f6f81d867b8f7cefe870184c2c70134b6a Signed-off-by: Pradnya Chaphekar commit 261ac91e537884441aebc8c7a2dffba67f77b496 Author: Pradnya Chaphekar Date: Wed May 11 18:44:56 2011 -0700 vidc: 1080p: Fix compilation error in debug message Change-Id: Ib7c9eccaf8eec9945df02745ab087f7a4835c4eb Signed-off-by: Pradnya Chaphekar commit 5bc5a8c6c58a60d0a3d2032c3398b254a081cb75 Author: Gopikrishnaiah Anandan Date: Fri Apr 29 17:27:07 2011 -0700 vidc: 1080p: Move target specific changes into devices file. Bus architecture is different in 8660 and 8960 for video core. This change updates devices file with target specific info. Change-Id: I87aed6d88143b78600f4cceb8519302031e5b8e7 Signed-off-by: Gopikrishnaiah Anandan commit 1fda5c33b03ae5ff6d2e1fb15e50d23f10b5f08e Author: Deepika Pepakayala Date: Thu May 5 17:17:00 2011 -0700 msm: vidc: Fix to handle non-fatal sequence header errors. Non-fatal sequence header errors thrown by the core in frame run state are being handled as fatal errors. Fix will handle non-fatal errors as recoverable bit-stream errors. CRs-fixed: 286257 Change-Id: Id4c8949248e00655ad11b86b3de71b8c69a0ddbd Signed-off-by: Deepika Pepakayala commit ddd599efc860c6d60018c3c2e4696e23317ff9f5 Author: Gopikrishnaiah Anandan Date: Fri May 6 11:48:42 2011 -0700 vidc: vdec: Generate reconfig when minimum count changes. Generate output port reconfig when minimum buffer count that the video core requests after the sequnce header parsing doesn't match clients count. Change-Id: Ief927c6e104bb105c4b5d60eaf671a49c09e2e0f CRs-fixed: 278839 Signed-off-by: Gopikrishnaiah Anandan commit 946be5687a15c87a43a786cb9f51244bc1133b56 Author: Pradnya Chaphekar Date: Mon Apr 18 17:27:48 2011 -0700 vidc: 1080p: Add smooth streaming support for video decode Avoid port reconfiguration for dynamic frame size changes, if client allocates sufficient number of buffers of required size. If not, fallback to port reconfiguration. Change-Id: Ic020a83f714f921c5cc3586f8b2a83e044066460 Signed-off-by: Pradnya Chaphekar commit 4913bb029b869fcc66661d83304f3a4a50b156ee Author: Deepika Pepakayala Date: Fri Apr 15 11:30:18 2011 -0700 msm:vidc: Interlaced content error handling. Fix NPF and bitstream error handling for interlaced clips. When a paired field is missing or bitstream error occurs for one of the fields, release the previous field, if it is present. Change-Id: I4f18a5948c2a2f27fc18ffdd52087471f513fafe Signed-off-by: Deepika Pepakayala commit 56e2543e6541f95f60b29d33804ce4805ee46985 Author: Gopikrishnaiah Anandan Date: Tue Apr 26 19:50:39 2011 -0700 vdec: 720p: Update video dimensions based on color format. Change updates the stride and scan line values based on color format. CRs-fixed: 284790 Change-Id: Ief87f95344857218ba18b8c89527965ef74dcf0d Signed-off-by: Gopikrishnaiah Anandan commit f14e9201e64dd73ea1b11f8e42090c6b4d510919 Author: Gopikrishnaiah Anandan Date: Wed Apr 27 11:12:39 2011 -0700 vdec: 1080p: Align stride and scan lines for TILE format. For tile format buffer size is calculated by aligning width to 128 pixels and height to 32 pixels for decoding. This change updates the stride and scanline values as per TILE format specification. CRs-fixed: 284571 Change-Id: I0363292cce7e5a9c9c49fe10a6e187001b141d5c Signed-off-by: Gopikrishnaiah Anandan commit 551c692934c576d7105a0d65b39aca126652ec3a Author: Pradeep Jilagam Date: Wed Apr 20 12:37:54 2011 +0530 msm_fb: mdp: Add support for DSI Interface in MDP 3.03 Add new interface support (DSI) support for MDP v3.03 Change-Id: Ifc85b8d1f84a91e97ac11c8e62480568096f1845 Signed-off-by: Pradeep Jilagam commit b90405524409bcad8f825169690c34171d26f395 Author: Gopikrishnaiah Anandan Date: Tue Apr 26 16:37:37 2011 -0700 vidc: 720p: Report unsupported resolution as fatal error. After parsing sequence header if core reports unsupported resolution error, driver will raise a client fatal error to the upper layer for session to be cleaned up. CRs-fixed: 275983 Change-Id: I1a6ccdaaf7eb8afd1681f884495879c3e9043d36 Signed-off-by: Gopikrishnaiah Anandan commit a05374e7a851b02ed9c43d5b68dee17b8d5b1b49 Author: Gopikrishnaiah Anandan Date: Wed Apr 27 14:35:55 2011 -0700 vidc: 1080p: Reject unsupported resolution clips. Reject clips for which video core reports unsupported resolution error. Change-Id: I039027f1b021c86f7d4fa3f09cc5f68f4972e393 CRs-fixed: 275983 Signed-off-by: Gopikrishnaiah Anandan commit 0038bf513bbc101cb975f36bd6d45f0bb4d8b1fe Author: Ashray Kulkarni Date: Tue Apr 26 15:00:57 2011 -0700 vidc: 1080p: Set concealed MB to black color. When MB's are concealed, it was displayed as green frames. Now changing concealed MB's to black. Change-Id: I0ebbbeabe601aad4525ff38118753505db2006c2 Signed-off-by: Ashray Kulkarni CRs-fixed: 284571 commit b3715620d09f0166c2b88c549adae64b34395c44 Author: Deepika Pepakayala Date: Mon Apr 25 10:32:48 2011 -0700 msm: vidc: Disable debug logs. Some debug logs are being logged as error messages. This change disables these debug logs. CRs-fixed: 275926, 275927, 275928 Change-Id: I6c97036c61474bb594c48838522aed924496be6c Signed-off-by: Deepika Pepakayala commit 7a35826ae448f47d871d6a38cf8cc99f196fc990 Author: Ujwal Patel Date: Wed Apr 20 19:21:10 2011 -0700 msm: camera: Support for more 3D camera features. support for following new 3D camera features have been added. 1. 3D Digital Zoom for snapshot and video recording. 2. 3D Quality Indicator for preview and video recording. 3. Framework changes to support 3D 1080p video recording. Change-Id: I17996756ad5f27a3b12cb356ba01f1e493fa3056 Signed-off-by: Ujwal Patel commit 4fcad1c781dd427195c79a4519908f997c5583cf Author: Nishant Pandit Date: Wed Apr 27 03:17:41 2011 +0530 msm: Disable Vfe Rolloff for 3D Sensor Update camera sensor info structure with support_3d variable which is passed to user space to determine whether to enable or disable VFE RollOff. Change-Id: Ic74aec61bca64b5380ed4cefdb4401b563e9948a Signed-off-by: Nishant Pandit commit 5a698c0f9e55742641bdd7724451d418fb426b0c Author: Gopikrishnaiah Anandan Date: Tue Apr 19 17:25:35 2011 -0700 vidc: vdec: Fix 720p driver memory alloc failure handling. When memory allocation fails, driver should gracefully close the session. Change-Id: I98ff304cc08c30a85003a4e1b1e315d389b5b3d8 Signed-off-by: Gopikrishnaiah Anandan commit a6a1618edcdfa45b8a03dceb768e873ac5cec731 Author: Nagamalleswararao Ganji Date: Thu Apr 21 00:12:44 2011 -0700 msm_fb: display: Mipi driver for 8960 simulator Mipi display panel driver support is added for 8960 simulator. It will control the data flow between dsi controller and the mipi dsi panel. Right now it supports only video mode. Change-Id: I3712907a0e0c07b9ebd7e9fb2678f37a3058d5f3 Signed-off-by: Nagamalleswararao Ganji commit 708f3b8c4c8115e9a6543b6cef50288dc94aedfd Author: Pradeep Jilagam Date: Thu Feb 17 01:13:07 2011 -0800 msm_fb: display: Add support for MIPI DSI Renesas panel Adds basic support for renesas mipi dsi panel driver. It will control the data flow between msm dsi controller and the renesas mipi dsi panel. Change-Id: Ib92a342bfb3d596d99dbcf564c86a684c2d2f8c4 Signed-off-by: Nagamalleswararao Ganji commit 7f710b28cf71f08b30d657afca7650487eb0f615 Author: Gopikrishnaiah Anandan Date: Wed Apr 20 20:27:49 2011 -0700 vidc: Disable AXI and pixel cache for 8960 virtio. Pixel cache and Axi bus is not supported in virtio, for video core hence disabling them. Change-Id: Ib911461c0753ed5a65ca57a14518ac8a76e41191 Signed-off-by: Gopikrishnaiah Anandan commit c545195f2e4d2c1a964d34206991e17d6a47d362 Author: Gopikrishnaiah Anandan Date: Wed Apr 20 20:10:18 2011 -0700 vidc: 1080p: Add video driver support for 8960. Change-Id: I2c4daf1301a57d2b7bfef260955d31e6d8f56227 Signed-off-by: Gopikrishnaiah Anandan commit fedc6ec9550713de753d288a32539f5964c7388c Author: Vinay Kalia Date: Mon Apr 18 15:08:47 2011 -0700 Revert "msm: vcd: Update bistream error handling in EOS" This reverts commit ed060bcc936f1a05a6e17e60505dd8f247c328c1. This commit was causing issues with flash playback so reverting it. CRs-fixed: 280822 Change-Id: I3429743ec4b58c9c20f676b7401f739af48cece2 Signed-off-by: Vinay Kalia commit 39a431b383ee8eb54fe358b4fed1881295942096 Author: Ankit Premrajka Date: Fri Apr 15 16:15:00 2011 -0700 msm: v4l2: 8960 V4L2 kernel re-architecture Change-Id: I144053e1a9a30c360a21b5dd1da4e3ca4b7241b3 Signed-off-by: Ankit Premrajka commit 910fd2b7cbd05a21040546e0bd1fd6656835d5a3 Author: Gopikrishnaiah Anandan Date: Thu Apr 14 14:50:37 2011 -0700 vidc: vdec: Generate output done in reconfig. In reconfig, if output buffers are queued then driver will generate output buffer done with filled length as zero. Change-Id: Ib1a8ffc37aa8b5c6ed9d986bc621341e617367a9 CRs-fixed: 283868 Signed-off-by: Gopikrishnaiah Anandan commit 04a6f98fb77c9749cfa50fa9e5cbfda132fdd28e Author: Pradeep Jilagam Date: Sun Apr 17 03:42:22 2011 +0530 msm_fb: display: Add support for LCDC Toshiba FWVGA panel. Add driver file to support Toshiba FWVGA panel with LCDC interface Change-Id: I15dd2abcfe474ec7737e7915884ea33ea78da689 Signed-off-by: Pradeep Jilagam commit c23977d023044c77e6c8c92fa3a28c2eb5b41eef Author: Kevin Chan Date: Thu Mar 24 03:35:38 2011 -0700 camera: Support for 60 & 120 fps in MT9E013 Sensor Added HFR support in MT9E013 Sensor Added HFR structure in msm_camera.h Change-Id: I7782992f95511598f7ea01790b4751f7d5a376bc Signed-off-by: Kevin Chan commit 95470cb9230c1dd31172e410683c402dc52787b3 Author: Gopikrishnaiah Anandan Date: Thu Apr 7 17:23:13 2011 -0700 vidc: vdec: Generate input done for codec config buffer. When video core consumes more than bitstream buffer payload length during sequence header parsing, generate a inputdone. Change-Id: I395696e3ab3f5c5a81b485c7b7bdde659ebcb993 CRs-fixed: 282370 Signed-off-by: Gopikrishnaiah Anandan commit d153b2cfa8ea220b042b02e8c37ef4e7c80c74d5 Author: Deepika Pepakayala Date: Wed Apr 6 13:46:35 2011 -0700 msm: vidc: Improve the decoding times for interlaced clips. Increasing the performance level to 720p for all interlaced clips with VGA resolution to improve the decoding times. Change-Id: I5cf8afe10b51c4fb7e70c156261b16318944c685 Signed-off-by: Deepika Pepakayala commit 77c13428ea3b78dd674771332a2dd95c80452441 Author: Nishant Pandit Date: Tue Apr 5 18:26:41 2011 +0530 msm: Fixes in the 3D Camera Sensor Enable the 3D Calibration and Lens shading. Fix the i2c configuration for eeprom. Add new settings for the 3D View Finder Change-Id: Ia4e3b68bfe0549f6f9aa77ba95698d438e3c84a8 Signed-off-by: Nishant Pandit commit 744d4918e393f8e4466a86e8a716598dbeaf0d94 Author: Deepika Pepakayala Date: Fri Apr 15 10:31:38 2011 -0700 msm: vidc: msm: vidc: Decode order interlaced decoding fix. Fix to handle the top and bottom frame tags appropriately for interlaced clips when decode order display is enabled. Change-Id: Ib48312549c1dd4337e7e1affc8d3f302958299a7 Signed-off-by: Deepika Pepakayala CRs-fixed: 274264 commit 28570c3c979b6906ba76850225b48a8deec0dc96 Author: Deepika Pepakayala Date: Thu Apr 7 13:43:53 2011 -0700 Revert "msm: vidc: Release first field transaction for interlace frames" This reverts commit 53c267d871521c0ac7c0d1a9e43a02654761067f. Change-Id: Id44708bd3d980ea1412e6277a2e3d3a761aa305b Signed-off-by: Deepika Pepakayala CRs-fixed: 280620,280692 commit 81ffc9580ff39248634e2cac2153fc6688cdb2c7 Author: Ashray Kulkarni Date: Tue Apr 5 14:49:08 2011 -0700 vidc: 1080p: Add support for non-multiple of 16 input width in driver. Change-Id: I9eeff5f9b258bc220be8322bc987cead9f96abcc Signed-off-by: Ashray Kulkarni CRs-fixed: 280280 commit 8e393f6c4d77b37e5a7a8fb9e7e495cd55e2fb47 Author: Michael Bohan Date: Thu Feb 24 12:10:11 2011 -0800 Initial contribution This commit takes the MSM and driver changes from git://codeaurora.org/quic/la/kernel/msm.git:android-msm-2.6.35 and applies them on top of git://android.git.kernel.org/kernel/common.git:android-2.6.38. Change-Id: I3e80240311c76c05d4177a4958a660fba80d5d14 Signed-off-by: Michael Bohan commit 2e0515a0d01c3d8b77ec39960d9c2f4af255acbe Author: Maheshwar Ajja Date: Mon Jan 30 15:24:22 2012 +0530 msm: vidc: insert break in switch-case statement Insert break statement at appropriate case statement in a switch condition. If no break statement resulting in corruption for next case statement. CRs-fixed: 333684 Signed-off-by: Maheshwar Ajja (cherry picked from commit 8eecbbe64be9bda61624d5d23cde9615b5ccb588) Change-Id: Ie842ca7f784f31a456696a30bc2ad76dec4c2d47 Signed-off-by: Swetha Basineni commit 0d636e968954539c87cd777d839111e3498ddbb2 Author: Deepika Pepakayala Date: Wed Jan 25 11:40:11 2012 +0530 msm: vidc: Remove endianness change for 1080p firmware. Endianness change is no longer required for 1080p firmware starting with Nov 30th 2011 firmware version. CRs-Fixed: 317041 Signed-off-by: Deepika Pepakayala (cherry picked from commit e0e9e92051e2170b79713f3455c481e8defd2e47) Conflicts: drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c Change-Id: I848b4c5000e8a81d50d25be333b1666fa172182b Signed-off-by: Swetha Basineni commit d3b8ce23c9adc7d1d32f7e6a80975af7cd547abf Author: Rajeshwar Kurapaty Date: Wed Jan 11 04:54:51 2012 +0530 vidc: 1080p: Increase context memory size of the H.264 encoder. Increasing the context memory size of H264 encoder to 20KB as it is a requirement from 11302011 firmware. CRs-Fixed: 317041 Signed-off-by: Rajeshwar Kurapaty (cherry picked from commit 6fb6e94208d7eacebf159127b558515ac77ea164) Change-Id: I1ac38b430261bae5fe13a94523457568e9b8d1d9 Signed-off-by: Swetha Basineni commit 6a966397517d2df84c61ba3e53d4f41723a23b65 Author: Deepika Pepakayala Date: Mon Nov 28 11:59:58 2011 -0800 msm: vidc: Fix handling EOS with bitstream error. If the EOS frame has codec config flag set and decoder return status is bitstream error, then driver was handling EOS done before the core returned with EOS done. Fixed by adding a check in the driver to not handle EOS done until the core returns with EOS done. CRs-Fixed: 320107 Signed-off-by: Deepika Pepakayala (cherry picked from commit a86367e34880ba37cabc0a6041300c0e3ae2424b) Change-Id: I67d891d38cf746245fb26600b15d05f38c679b02 Signed-off-by: Swetha Basineni commit 7dac58fcb9d5a70373f015271e3df7f3b4d1c790 Author: Rajeshwar Kurapaty Date: Fri Nov 18 13:23:14 2011 +0530 vidc: 1080p: Override profile to ASP for XVid/Divx456 Always set profile to ASP for XVid/Divx456 apart from MPEG-4. Core will ignore the profile information from the sequence header and continue to decode with profile set by driver. CRs-fixed: 319168 Signed-off-by: Rajeshwar Kurapaty (cherry picked from commit b7523cde9399347fa357f0a5d43ccdfeaa30a04a) Change-Id: I3672f172460ec56afc4d22c435af59612b6669bc Signed-off-by: Swetha Basineni commit 10b798f6f82d275f9f4360ca71c9a317549366b5 Author: Maheshwar Ajja Date: Fri Nov 4 11:56:35 2011 -0700 msm: vidc: print message as kernel info instead of error both decoder and encoder uses same driver structure and 720p/1080p core base addresses, so the below log message is not an error message. hence making it as kernel info meesage intead of error message. Log message: Device config mismatch CRs-fixed: 316470 Signed-off-by: Maheshwar Ajja (cherry picked from commit ebd12f62bc7dc8b32e8efc099c4fdfa235226106) Change-Id: I5a5c29423e0b79201b75d912d79c662071a55833 Signed-off-by: Swetha Basineni commit 0a693110809d2a782a137f242f6438cb0e32218b Author: Manoj Rao Date: Wed Nov 16 22:00:05 2011 -0800 msm: display: HDMI: Driver support for CEC feature Driver implementation of HDMI CEC feature. Support includes CEC frame send and frame receive. Support added for sysfs interface for CEC daemon to interact with the driver for reading and writing frames. sysfs interface /sys/class/graphics/fb1/cec Read: CEC block state. Write: Enable/Disable CEC block. /sys/class/graphics/fb1/cec_logical_addr Read: Print CEC logical address Write: Set CEC logical address which is used for addressing CEC messages to and from MSM /sys/class/graphics/fb1/cec_rd_frame Read: Read rcvd CEC message from message queue. If queue is empty -EBUSY. If CEC block is disabled -EPERM. Write: N/A /sys/class/graphics/fb1/cec_wr_frame Read: N/A Write: Write to send CEC message. If CEC line arbitration fault/no ack -EINVAL. If CEC block is disabled -EPERM. Change-Id: I00ccf91c022d6b9962ec0231eb3c8f159a200e40 Signed-off-by: Manoj Rao commit adec2759e9289d184762f0c535068f2deaee3820 Author: Rajeshwar Kurapaty Date: Tue Nov 8 16:22:49 2011 +0530 vidc: 720p: Set DB line buffers in case of reconfig In the case of multi resolution H263 clip, there is no response from the core. With fixes in video f/w, there is a problem in reconfig. Fixed by setting the DB line buffers to the core again in the case of reconfiguration. CRs-Fixed: 303874 Signed-off-by: Rajeshwar Kurapaty (cherry picked from commit d292ddd67b5eb550d02520403ea2ad1d72957189) Change-Id: I5c794bb016636780cf0f37426d91c4ed9935a80c Signed-off-by: swetha commit 7cf99d3aada509d17ade5c413e6c415aa7629dec Author: Gopikrishnaiah Anandan Date: Mon Aug 8 11:14:49 2011 -0700 vidc: vdec: Buffer optimization for smooth streaming. Smooth streaming client has the buffer count optimized to lower value than profile and level based counts for H264 decoder. Adding support in driver to take advantage of lower buffer count to optimize memory requirements for smooth streaming. Signed-off-by: Gopikrishnaiah Anandan (cherry picked from commit 6f6a85717fdc5e82cc0b993840e6efe006d57040) Change-Id: Id073af9e68b2558a6d8aabaff8e0d97200fc2d96 Signed-off-by: swetha commit ae1e361e1a81c132b40f3569229a0af9775ccbfb Author: Deepika Pepakayala Date: Wed Sep 21 17:15:47 2011 -0700 msm: vidc: Increase the decoder input buffer size. Increase the decoder input buffer size to 2MB to be able to handle input frames greater than 1 MB. CRs-Fixed: 306909 Signed-off-by: Deepika Pepakayala (cherry picked from commit 9743b69d29eb846eca3425a647ef9d290925d441) Change-Id: I229985fb1cc90e96d36d0b065dec57e5144d28ee Signed-off-by: Shruthi Krishna commit a32bcdf8975a5367d454b8b713a2a9e36b924a19 Author: Deepak Kotur Date: Mon Oct 3 14:45:15 2011 -0700 vidc: venc: Return the correct error code for IOCTL. When ioctl fails for VEN_IOCTL_CMD_READ_NEXT_MSG send the correct return value to userspace. CRs-fixed: 310431 Signed-off-by: Deepak Kotur (cherry picked from commit f871a5629dd82a60309610bf8d3f82fbf0c8d0d1) Change-Id: I5e6e41f0389608ac0a38d2d4bc2b3d3264bc133d Signed-off-by: Shruthi Krishna commit ad90a0e360d4c4cefca3fd5f0405c4754cb40984 Author: Rajeshwar Kurapaty Date: Wed Oct 12 12:29:55 2011 +0530 vidc: 1080p: Recovery point SEI support for ISDB-Tmm Enable Recovery point SEI parsing in the core for H264. Core notifies the Decoded YUV correctness in the output done callback for both decode and display order types. Parse this information and notify the user space with VCD_FRAME_FLAG_DATACORRUPT if the data is corrupt. CRs-Fixed: 313004 Signed-off-by: Rajeshwar Kurapaty (cherry picked from commit 7b6e1fa36e1dce1a098995c630307d66d8dc54de) Change-Id: I9638253a857409a49d28344cb4107a9956fcce8b Signed-off-by: swetha commit 145a91a210719b13ce82cf331a75b479894db962 Author: Rajeshwar Kurapaty Date: Fri Aug 12 16:49:42 2011 +0530 vidc: vdec: Copy the End of Sequence flag To get End of Sequence flag in the output buffer from the video driver, we need to copy the end of sequence flag from the input buffer to the output buffer in the driver. Added these changes as needed for ISDB-Tmm EoSeq feature. CRs-Fixed: 313005 Signed-off-by: Rajeshwar Kurapaty (cherry picked from commit 1a16d5244a27781dad10838c93f11ec58758ee49) Change-Id: Ieac43a71edb5c2f64096016716be748e1c334695 Signed-off-by: swetha commit 726c854342a1684291581f83807bcd57e7d0c8e6 Author: Eduardo Carrasco Date: Fri Sep 23 10:37:42 2011 -0700 msm: vidc: Fix GOB Header for H.263 encoding. For H.263, enable the GOB header, when user space selects this option Signed-off-by: Eduardo Carrasco CRs-Fixed: 305978 (cherry picked from commit e92f9695de49c179e60172b4e625a94bf0ff6dc0) Change-Id: Idc3e93fa087f4e8168795ef9e4c48bf94b2f9b74 Signed-off-by: Shruthi Krishna commit fcbf7a9a41c51e0df5ca1c69785d3db42d22bcbc Author: Deepika Pepakayala Date: Thu Sep 22 15:40:49 2011 -0700 msm: vidc: Fix performance level computation The required performance level is rounded off to the incorrect value due to the order of execution of the operations. Fixed the issue by ensuring correct order of execution when computing this value. Signed-off-by: Deepika Pepakayala (cherry picked from commit c9fc55be6efdd5518618f64f9a658619e86d5139) Change-Id: I46350ef37d4549e882d90a9063841f4e39292ed2 Signed-off-by: Shruthi Krishna commit 708a271386b2238fff1df20eb44ff51af14bd786 Author: Deepika Pepakayala Date: Tue Sep 20 15:49:36 2011 -0700 msm: vidc: Fix to handle VOL header errors. VOL header errors trigger reconfig in the driver. Driver tries to handle the reconfig but the core returns incorrect status causing a hang. Fix will set the flag appropriately for the core to know that the driver is handling reconfig and thereby return the right status. CRs-Fixed: 299978 Signed-off-by: Deepika Pepakayala (cherry picked from commit 65f8ca24b292d4af84955620ee4061b078e5e582) Change-Id: Ie4060c96e7766f9a752c6989d404e96a6cb61664 Signed-off-by: Shruthi Krishna commit 51b100549accd6e0ac79a4f8fe6db0c76f74a3a7 Author: Deepika Pepakayala Date: Thu Aug 18 11:35:17 2011 -0700 msm: vidc: Fix H.263 30fps standard resolution encoding. For H.263, when encoding standard resolutions(CIF/QCIF) at 30fps, the encoded bitstream should not have the Custom PCF flag set in the PlusPType header. This is fixed by enabling the custom PCF for non-30fps encoding only. Signed-off-by: Deepika Pepakayala CRs-Fixed: 300807 (cherry picked from commit a19b9ad00c0ae9d93c358a24595cbca463074526) Change-Id: I94d37cd218c0a1876768a22d1281f168db64f1f1 Signed-off-by: Raj Kushwaha commit f741b6181d29f5482a679977c9065f32bda66bdd Author: Ashray Kulkarni Date: Thu Aug 18 11:50:20 2011 -0700 vidc: vdec: Update firmware memory size. Increase firmware global context space from 500kb to 800kb as per the updated firmware requirements. Signed-off-by: Ashray Kulkarni (cherry picked from commit dc435924798f7a80e2136e88330e89505766bf63) Change-Id: Iad5b14f6830a487e22a2def9167d85bf063dcec9 Signed-off-by: Shruthi Krishna commit ff76156be8e17b1e927c724c80e949c8c39de33f Author: Ashray Kulkarni Date: Thu Aug 11 15:04:08 2011 -0700 vidc: venc: Remove check for allocation of sequence buffer size. Firmware requires non-zero sequence buffer size for H.263. Signed-off-by: Ashray Kulkarni (cherry picked from commit 28bf67bfebafe573525e73b9c2ad6dad3f588ecb) Change-Id: Iddecdd8051bcb065a8ab17315f0f1e8697a73899 Signed-off-by: Shruthi Krishna commit 3b452d3580630ad80cb1cf5610327d5aeb89c870 Author: Gopikrishnaiah Anandan Date: Thu May 19 13:27:08 2011 -0700 vidc: 1080p: Override SP profile to ASP for MPEG4 decoding. Always set profile to ASP for MPEG4 decoding. Core will ignore the profile information from the sequence header and continue to decode with profile set by driver. Signed-off-by: Gopikrishnaiah Anandan (cherry picked from commit 343eda5d60c084abcb53e4713eb45ee2be50e7a8) Change-Id: Iadbff386ad6ba6a92ee5275c0fa2314e76caa2fc Signed-off-by: Shruthi Krishna commit 6dd953ba1536ebc951edbc64a3f1fa00bf3153c2 Author: Rajeshwar Kurapaty Date: Wed Aug 24 18:27:51 2011 +0530 vidc: 720p: Memset MPEG-4 recon buffers to black In the case of MPEG-4 decoding with clips which have initial frames starting with P-VOPs, green macroblocks are seen. This is because of recon buffers used for MPEG-4 have 0 preset values. The default values are changed to 0x10 & 0x80 for luma and chroma to get default color as black. CRs-Fixed: 303298 Signed-off-by: Rajeshwar Kurapaty (cherry picked from commit 207df7f89bf731c456bf6d5c905bde1aa014a8af) Change-Id: I45b0c241dd5f75b25e15ae9d211fd51d701d3c83 Signed-off-by: Raj Kushwaha commit 48ae59ca8a48e62c3bac361ad430e166a75a4819 Author: Rajeshwar Kurapaty Date: Tue Aug 23 18:57:58 2011 +0530 vidc: 720p: Handle profile unknown as bitstream error. For corrupted VOL header in the middle of playback core is returning UNKNOWN PROFILE error and is being treated as Fatal error and playback is getting aborted. Now handling it as sequence header fail/recoverable error. CRs-Fixed: 302549 Signed-off-by: Rajeshwar Kurapaty (cherry picked from commit 301cbf57a42e99ef403b38793431046fd0d1bc19) Change-Id: I1aaa99ef6bf8e5096d30d644f434792fba4b1981 Signed-off-by: Raj Kushwaha commit 79563d6a95103435f9b303f8acb95febfd260c40 Author: Ashray Kulkarni Date: Thu Aug 4 12:59:49 2011 -0700 vidc: vdec: Set correct divx codec type. Added support in video driver to configure divx codecs 4/5/6. Signed-off-by: Ashray Kulkarni CRs-fixed: 297558 (cherry picked from commit 893d5e34665abafade791c0308de09edf55b2c82) Change-Id: I8dd9275a7047c4ca6969801b4b469948528da7fc Signed-off-by: Raj Kushwaha commit f06d93da8a290927cf3be14ce07a85148e50d530 Author: Ashray Kulkarni Date: Wed Jun 8 13:01:20 2011 -0700 vidc: venc: configure slicing for every frame. Slicing support was there only during init time, firmware support is now added to configure dynamically. Signed-off-by: Ashray Kulkarni (cherry picked from commit 941c6bf893e856837e91be76ccac6664de30d921) CRs-fixed: 297685 Change-Id: I1db1e9679b6a5f14f28927602587f19276839224 Signed-off-by: Raj Kushwaha commit 3c3dacdb73d76aacab9368a325d5c914a6f3a75f Author: Gopikrishnaiah Anandan Date: Fri Jun 3 10:30:23 2011 -0700 vidc: 1080p: Handle b-frame not supported error. MPEG4 simple profile doesn't support b-frames. There could be erroneous clips in which we can have bframes in simple profile clip. Video core will report an error in this usecase and driver should consider this as warning. Signed-off-by: Gopikrishnaiah Anandan (cherry picked from commit 898afe35de8add2401c15299095805e1a2fc8723) CRs-fixed: 300633 Change-Id: I911e85d03b90780dcc082f1c2e937cccaa53f880 Signed-off-by: Shruthi Krishna commit dddae4afb8809a2d6f4d27ac903e79466964b54e Author: Gopikrishnaiah Anandan Date: Tue Jul 12 14:24:14 2011 -0700 vidc: vdec: Report dropped field for interlace clips. For field based interlace clips, video core will generate an error when one of field is missing in bitstream. Driver will report this to upper layer, so that it can take appropriate action. CRs-fixed: 290659 Change-Id: I4e208e533b556c74088171e4b44f28f07116d511 Signed-off-by: Gopikrishnaiah Anandan commit e468071478237e5d157613bc26548b3bc7dc80df Author: Gopikrishnaiah Anandan Date: Thu Jul 7 11:55:13 2011 -0700 vidc: vdec: Report bitstream errors to driver client. When video core generates recoverable bitstream errors, driver will report them to upper layer. CRs-fixed: 290659 Change-Id: I5b1187a6784c99ab987cbc7369ba140274a21ff7 Signed-off-by: Gopikrishnaiah Anandan commit d26a61df194f503bec6289899029fe04c9050320 Author: Deepika Pepakayala Date: Fri Jul 15 17:40:12 2011 -0700 msm: vidc: Set Y and C size registers to allocated size. Currently the Y and C sizes are set based on the size of video being decoded. In case of smooth streaming, decoded sizes are not the same as allocated sizes. This change will set the Y and C sizes to allocated sizes. Signed-off-by: Deepika Pepakayala (cherry picked from commit 9b10b255cf789b4cb06ba554515b001ec5f8ad16) Change-Id: I7f2f7448e81893bd2a6dec6f23dfcbdb21da4694 Signed-off-by: Shruthi Krishna commit f6ee43e1c97241b65aeacb33e33abce43c301c58 Author: Pradnya Chaphekar Date: Mon Jun 27 13:57:16 2011 -0700 vidc: 1080p: Set chroma address change in smooth streaming mode If resolution change is detected in smooth streaming mode and status indicates that video core can continue decoding, update chroma address for new resolution instead of starting frame realloc. Signed-off-by: Pradnya Chaphekar (cherry picked from commit 6465d940156fa4d05a27772eb64d7fbeee343445) Change-Id: Ie4c1c0970bd79fab3094178e9dd265e8c69c409b Signed-off-by: Shruthi Krishna commit cf11804b78c6257f5f23bf56a309e787b5d60079 Author: Ananda Kishore Date: Mon Jul 18 19:02:15 2011 +0530 vidc: add change to print MFC firmware version CRs-Fixed: 296531 Signed-off-by: Ananda Kishore (cherry picked from commit a6782181ebd3600967e269efd176c8e2454bee56) Change-Id: Ibbd8bb6f818ecec3a6b1457e4af3ecdb25d3ef17 Signed-off-by: Raj Kushwaha commit 56ac84551cdcfc3f76ee86a8eda1af3f22e1c494 Author: Rajeshwar Kurapaty Date: Fri Jul 15 18:14:30 2011 +0530 vidc: 1080p: Removed check for comparing DPB Size For best effort decoding we don't need to compare the available DPB size with the decoded size and throw error. So, removed the check that compares them. CRs-Fixed: 296211 Signed-off-by: Rajeshwar Kurapaty (cherry picked from commit 0df6ccfc7ac0cf0e34e8fd4bd1ca86565b9f0b3a) Change-Id: Icfabb4cf2fba6b04964edf5294e53aab326f2dc7 Signed-off-by: Shruthi Krishna commit e28b9efb04371ded7bfe2ee7c56636ac9f2e72fa Author: Ashray Kulkarni Date: Mon Jun 27 12:37:00 2011 -0700 vidc: venc: add Check for infinite intraperiod configuration. Max value allowed is 0xFFFF, any higher value is configured as infinite intra period to the video core. CRs-fixed: 292859 Signed-off-by: Ashray Kulkarni (cherry picked from commit a1f3f0704761e961df64f7b466c30122d3d1fce3) Change-Id: I1c4c3a1a0277eff88c8cd44db9c7c7c613d09876 Signed-off-by: Sunil Joseph commit a6677cef8954109c3e99047e2c21482dbe46008e Author: Ujwal Patel Date: Mon Jun 6 14:18:36 2011 -0700 msm: camera: Support for manual convergence in stereo camera. Adding support for manual convergence in stereo camera and changing the delivery method of stereo quality indicator. Signed-off-by: Ujwal Patel (cherry picked from commit 791278e730c6ebce77aea7c16e256eb4ae161aca) Change-Id: I4f9073309c11e326150623edc19dfb7453428631 Signed-off-by: Raj Kushwaha commit 6a50674d696213efebb93a5d9d109723aa69d758 Author: Chandan Uddaraju Date: Wed Jun 22 23:38:16 2011 -0700 msm: Display: Fix IOCTL ID for 3D ioctl. Add code to have unique ID for 3D Ioctl call. Move Novatek specific changes for 3D to novatek panel file and remove the usage of featurization macro "CONFIG_FB_MSM_MIPI_NOVATEK_3D_PANEL". Change-Id: I01e2ec5cd85d2778fc800fd452ee3b1e6d0602f3 Signed-off-by: Chandan Uddaraju commit ef65cd2dba8cd82fbea61e8be6560c8092a5d441 Author: Ashray Kulkarni Date: Wed Apr 27 12:18:25 2011 -0700 vidc: 1080p: Reject unsupported profile clips. HIGH10 profile clips are not supported by video core. so added check in driver to reject playback of those clips. Signed-off-by: Ashray Kulkarni CRs-fixed: 273798 (cherry picked from commit 9c4382b6cd117160559a1c4d812332e83c2aa8ee) Change-Id: I58626968d5f8c1e5704d6d14ae4de62df939f477 Signed-off-by: Sunil Joseph Signed-off-by: Raj Kushwaha commit a91286f049791f2dc605270b6423a1b07595e999 Author: Deepika Pepakayala Date: Thu May 5 17:17:00 2011 -0700 msm: vidc: Fix to handle non-fatal sequence header errors. Non-fatal sequence header errors thrown by the core in frame run state are being handled as fatal errors. Fix will handle non-fatal errors as recoverable bit-stream errors. CRs-fixed: 286257 Signed-off-by: Deepika Pepakayala (cherry picked from commit 1fda5c33b03ae5ff6d2e1fb15e50d23f10b5f08e) Change-Id: Iddbc8091d8839c58af74fddad5554cad4e66a5e6 Signed-off-by: Shruthi Krishna commit 6a5a125bf8fca8b9dfe3b4cb10a536c148e81c77 Author: Raj Kushwaha Date: Wed Jun 22 11:49:45 2011 -0700 msm: Display: Add code to provide 3D panel information to UI. Add code to provide information to the user interface about wheather the panel supports 3D display or not. Change-Id: I1086b8deb2980ffcacae153ba5ac80c680e04eb8 Signed-off-by: Chandan Uddaraju Signed-off-by: Raj Kushwaha commit 515353fd67a55051febe8c32c4c6e3c874a684a9 Author: Deepika Pepakayala Date: Mon Jun 20 11:27:20 2011 -0700 msm: vidc: Fix not coded vop handling in decode order. When decoding not coded vops in decode order, the output buffer address was incorrect. Fix will read the correct buffer address from the decode order address register. Signed-off-by: Deepika Pepakayala CRs-fixed: 291342 (cherry picked from commit 17ab2187ccf5c82ec2ff6017f85f4a104df736e8) Change-Id: Id4bf53813df71147305d77e6aff4dac4f650b3a6 Signed-off-by: Shruthi Krishna commit 779f7bd1701f03df11030c420b59a2034cf13554 Author: Deepika Pepakayala Date: Wed Jun 8 14:48:37 2011 -0700 msm: vidc: Increase firmware memory size to 500KB. Latest firmware size is greater than 400KB. Signed-off-by: Deepika Pepakayala (cherry picked from commit d8a1c720541845e513bce5a37731ee77b3c7c504) Change-Id: Ie9f0188a74bdbc439fb26cfdbe012fb533e61916 Signed-off-by: Shruthi Krishna commit ef56408ab473612c4102f1e816b5076abd9b19f6 Author: Vinay Kalia Date: Fri May 20 11:35:42 2011 -0700 vidc: 1080p: Startup latency optimization. Startup latency optimization for video playback: 1. Bumped up bus and video core clock at startup. 2. memsetting output buffers in kernel rather than in userspace. Signed-off-by: Vinay Kalia (cherry picked from commit f2a6f6f3959f5ab0a79fad769317d50039a20f2c) Change-Id: I56085e61bec65bc78de6a159f92548589c6688e1 Signed-off-by: Shruthi Krishna commit 3b6b2347a2b87e96c566d8460c6e697622a759a5 Author: kuogee hsieh Date: Mon Jun 6 10:29:28 2011 -0700 msm_fb: display: add mdp writeback mode support dsi video mode MDP writeback mode has been worked for both lcdc and dsi comamnd mode. This patch add dsi video mode writeback mode support and unify interface to enable/disable writeback mode. Change-Id: I74898d7d80e9b4727eb417b0f1d831845d229c73 CRs-fixed: 287700 Signed-off-by: KUogee Hsieh commit fedcafa7b4e53b325a14561512dbcdb21749b959 Author: Deepika Pepakayala Date: Tue May 3 14:13:41 2011 -0700 msm: vidc: Support dynamic change of interlaced format. The interlaced format can change dynamically with in a sequence/clip. This change ensures that the interlaced format is updated and passed to the client appropriately. Signed-off-by: Deepika Pepakayala (cherry picked from commit 7c395a949da6a08bb3a86a5faf760f26cbbd91db) Change-Id: I1bf81748245e34d33bc2a2f8746551f397ea0ed1 Signed-off-by: Shruthi Krishna commit efe458de5146143a03d73310d66fadd50e64bdb6 Author: Ujwal Patel Date: Wed Jun 8 11:59:59 2011 -0700 msm: camera: Consolidate VFE messages for performance improvement (cherry picked from commit 6d7f475e8e4d40c0a787c7e1f2fe7e57a4d84929) Change-Id: Id378388f3d1219cb8e69f48acac79dbf4ebbbc32 Signed-off-by: Nagesh Subba Reddy Signed-off-by: Ujwal Patel commit a017c3a92b28096b789577a2e2d0c01b47efd569 Author: Gopikrishnaiah Anandan Date: Fri May 6 11:48:42 2011 -0700 vidc: vdec: Generate reconfig when minimum count changes. Generate output port reconfig when minimum buffer count that the video core requests after the sequnce header parsing doesn't match clients count. CRs-fixed: 278839 Signed-off-by: Gopikrishnaiah Anandan (cherry picked from commit ddd599efc860c6d60018c3c2e4696e23317ff9f5) Change-Id: I284b4d35c94e151ca899dbc1202bd2e29ab8eaf4 Signed-off-by: Shruthi Krishna commit dc3ac7e8f22d5482ad28597763f34b40ef84201a Author: Pradnya Chaphekar Date: Wed May 11 14:02:19 2011 -0700 vidc: 1080p: Update buffer count calculation for smooth streaming Calculate worst case buffer requirement in smooth streaming mode to avoid unecessary port reconfiguration. (cherry picked from commit 0ef7cd7e5f0510c937171c931f00583484741910) Change-Id: I0384bbc896ec3ab242b31f7cda01872754a059aa Signed-off-by: Raj Kushwaha commit b227bf53b1ddf87b0f7603fb49431100e92b3111 Author: Pradnya Chaphekar Date: Fri May 13 14:28:54 2011 -0700 vidc: 1080p: Send smooth streaming event in output done callback In smooth streaming mode, if a change in frame size is detected, send info event in output done callback instead of sequence done callback. This ensures that the openmax compoenent appends extradata corersponding to updated width and height to the output buffer with updated frame size. (cherry picked from commit 2936befa32f998589a4b33ab262e296017134a4e) Change-Id: I3e9cea92e3a4d8bf8456d256435cd0a9c28de08c Signed-off-by: Raj Kushwaha commit 4fc46c5440383aa7897cafc906d347951ab9e43a Author: Pradnya Chaphekar Date: Fri May 13 14:07:06 2011 -0700 vdec: 1080p: Align stride and scan lines for tile format Update decoder output buffer stride and scan lines as per tile format specificaton. (cherry picked from commit f6f653c41b41d6c77fcfe1c50be3fe5044dc496a) Change-Id: I42ee9eddd5f6ced83a35b03567c6be76072bcc0e Signed-off-by: Raj Kushwaha commit 11f7e4082ffc8d0f357a24a1d8faa4a0b14be20c Author: Pradnya Chaphekar Date: Wed May 11 18:44:56 2011 -0700 vidc: 1080p: Fix compilation error in debug message (cherry picked from commit 261ac91e537884441aebc8c7a2dffba67f77b496) Change-Id: I15631079c1c0fa5f5c5c975d77c34de049c85030 Signed-off-by: Raj Kushwaha commit 18a0862208c1b960b661b849d4b748c72888d256 Author: Raj Kushwaha Date: Tue Jun 7 09:40:36 2011 -0700 vidc: 1080p: Add smooth streaming support for video decode Avoid port reconfiguration for dynamic frame size changes, if client allocates sufficient number of buffers of required size. If not, fallback to port reconfiguration. (cherry picked from commit 946be5687a15c87a43a786cb9f51244bc1133b56) Change-Id: Ife31a748d3df507c1a173ccb47b86f8c904c3e7e Signed-off-by: Raj Kushwaha commit cad97a5b2a19c15c981b5cf534d687db550a969b Author: Ujwal Patel Date: Wed Apr 20 19:21:10 2011 -0700 msm: camera: Support for more 3D camera features. support for following new 3D camera features have been added. 1. 3D Digital Zoom for snapshot and video recording. 2. 3D Quality Indicator for preview and video recording. 3. Framework changes to support 3D 1080p video recording. Signed-off-by: Ujwal Patel (cherry picked from commit 7a35826ae448f47d871d6a38cf8cc99f196fc990) Change-Id: I99f6cb2498328ae09b06dc7a7e5c5567f42f2f46 Signed-off-by: Shruthi Krishna commit 116e0b4800a5794b25fe2be3851b8bf5d0bde4e7 Author: Gopikrishnaiah Anandan Date: Wed Apr 27 14:35:55 2011 -0700 vidc: 1080p: Reject unsupported resolution clips. Reject clips for which video core reports unsupported resolution error. CRs-fixed: 275983 Signed-off-by: Gopikrishnaiah Anandan (cherry picked from commit a05374e7a851b02ed9c43d5b68dee17b8d5b1b49) Change-Id: If319dbf79f86691fdb9cf598588ce695cb59f22c Signed-off-by: Sunil Joseph commit de6c370237bfeb0a5ff78b55593724a894142644 Author: Nishant Pandit Date: Wed Apr 27 03:17:41 2011 +0530 msm: Disable Vfe Rolloff for 3D Sensor Update camera sensor info structure with support_3d variable which is passed to user space to determine whether to enable or disable VFE RollOff. Signed-off-by: Nishant Pandit (cherry picked from commit 4fcad1c781dd427195c79a4519908f997c5583cf) Change-Id: I81abb1e35d3c093083fcc18dc13dad843be54aaa Signed-off-by: Shruthi Krishna commit e9dc3f8bd651b0cd54c6b7d9f359d41d59c9e894 Author: Deepika Pepakayala Date: Fri Apr 15 11:30:18 2011 -0700 msm:vidc: Interlaced content error handling. Fix NPF and bitstream error handling for interlaced clips. When a paired field is missing or bitstream error occurs for one of the fields, release the previous field, if it is present. Signed-off-by: Deepika Pepakayala (cherry picked from commit 4913bb029b869fcc66661d83304f3a4a50b156ee) Change-Id: I98a5e084309aa0b26be4a187552e0bde40dddb54 Signed-off-by: Shruthi Krishna commit 1c22dd35c3e0944038825b0804ce7c3b62cc941d Author: Vinay Kalia Date: Mon Apr 18 15:08:47 2011 -0700 Revert "msm: vcd: Update bistream error handling in EOS" This reverts commit ed060bcc936f1a05a6e17e60505dd8f247c328c1. This commit was causing issues with flash playback so reverting it. CRs-fixed: 280822 Signed-off-by: Vinay Kalia (cherry picked from commit fedc6ec9550713de753d288a32539f5964c7388c) Change-Id: I5bfa248e831d3c02e755afa0d8078d5698feadb4 Signed-off-by: Shruthi Krishna commit 1f3f7d05fdb83d49b34e6bb55b955bb6ae4a514d Author: Gopikrishnaiah Anandan Date: Tue Apr 26 16:37:37 2011 -0700 vidc: 720p: Report unsupported resolution as fatal error. After parsing sequence header if core reports unsupported resolution error, driver will raise a client fatal error to the upper layer for session to be cleaned up. CRs-fixed: 275983 Signed-off-by: Gopikrishnaiah Anandan (cherry picked from commit b90405524409bcad8f825169690c34171d26f395) Change-Id: Iba53e8f794f098d1b864a35ac76f90f0c5754f1c Signed-off-by: Sunil Joseph commit 7877d69ed85126d66d04c40eb7bf16e3b900234e Author: Gopikrishnaiah Anandan Date: Tue Apr 19 17:25:35 2011 -0700 vidc: vdec: Fix 720p driver memory alloc failure handling. When memory allocation fails, driver should gracefully close the session. CRs-Fixed: 282400 Signed-off-by: Gopikrishnaiah Anandan (cherry picked from commit 5a698c0f9e55742641bdd7724451d418fb426b0c) Change-Id: I5ac672a7903656b0e695f7d971d9dc5fcb00de27 Signed-off-by: Sunil Joseph commit 71b3a7c5c8ff11bded3f98d2842c184e9eeccaab Author: Kevin Chan Date: Thu Mar 24 03:35:38 2011 -0700 camera: Support for 60 & 120 fps in MT9E013 Sensor Added HFR support in MT9E013 Sensor Added HFR structure in msm_camera.h Signed-off-by: Kevin Chan (cherry picked from commit c23977d023044c77e6c8c92fa3a28c2eb5b41eef) Change-Id: I4b2307a4b9e289df96338ea06e17cb590bd85a2f Signed-off-by: Shruthi Krishna commit b008122b1e86f137e8b328eec86ffd22ec1c3150 Author: Gopikrishnaiah Anandan Date: Tue Apr 26 19:50:39 2011 -0700 vdec: 720p: Update video dimensions based on color format. Change updates the stride and scan line values based on color format. CRs-fixed: 284790 Signed-off-by: Gopikrishnaiah Anandan (cherry picked from commit 56e2543e6541f95f60b29d33804ce4805ee46985) Change-Id: Iff082c3313a12ef6269d2029f89d34be6735de8f Signed-off-by: Shruthi Krishna commit b74f08bf7cbcf518620cee3e002c72afbcfa0cc7 Author: Gopikrishnaiah Anandan Date: Wed Apr 27 11:12:39 2011 -0700 vdec: 1080p: Align stride and scan lines for TILE format. For tile format buffer size is calculated by aligning width to 128 pixels and height to 32 pixels for decoding. This change updates the stride and scanline values as per TILE format specification. CRs-fixed: 284571 Signed-off-by: Gopikrishnaiah Anandan (cherry picked from commit f14e9201e64dd73ea1b11f8e42090c6b4d510919) Change-Id: I48ae5fdd6ed3e9bbd4e59d87d2e887719a67a0bf Signed-off-by: Shruthi Krishna commit ffcc9ef7fb5c82a335cf03f67f10f0dd39821fe4 Author: Deepika Pepakayala Date: Mon Apr 25 10:32:48 2011 -0700 msm: vidc: Disable debug logs. Some debug logs are being logged as error messages. This change disables these debug logs. CRs-fixed: 275926, 275927, 275928 Signed-off-by: Deepika Pepakayala (cherry picked from commit b3715620d09f0166c2b88c549adae64b34395c44) Change-Id: Idc81995f6fc3bc4a3848e3a8e8cf4cb77e5df4c6 Signed-off-by: Shruthi Krishna commit 9bc2d7e8e19572317877e9967818d9c4c6ac252d Author: Deepika Pepakayala Date: Fri Apr 15 10:31:38 2011 -0700 msm: vidc: msm: vidc: Decode order interlaced decoding fix. Fix to handle the top and bottom frame tags appropriately for interlaced clips when decode order display is enabled. Signed-off-by: Deepika Pepakayala CRs-fixed: 274264 (cherry picked from commit 744d4918e393f8e4466a86e8a716598dbeaf0d94) Change-Id: I08e25003de82e1472f17500e115fe08c46ee51b6 Signed-off-by: Shruthi Krishna commit f9e61145cd1dd027d00db3bf588fed1d80d7721f Author: Gopikrishnaiah Anandan Date: Thu Apr 14 14:50:37 2011 -0700 vidc: vdec: Generate output done in reconfig. In reconfig, if output buffers are queued then driver will generate output buffer done with filled length as zero. CRs-fixed: 283868 Signed-off-by: Gopikrishnaiah Anandan (cherry picked from commit 910fd2b7cbd05a21040546e0bd1fd6656835d5a3) Change-Id: I73632acadc0ae6454ff58931d22f3f34437da828 Signed-off-by: Shruthi Krishna commit 0baf9b524bf6863fa0f263d3c813e4ca5e56407f Author: Nishant Pandit Date: Tue Apr 5 18:26:41 2011 +0530 msm: Fixes in the 3D Camera Sensor Enable the 3D Calibration and Lens shading. Fix the i2c configuration for eeprom. Add new settings for the 3D View Finder Signed-off-by: Nishant Pandit (cherry picked from commit 77c13428ea3b78dd674771332a2dd95c80452441) Change-Id: I476e4e268c2a23e5aeb29f7e4409d3c45b58b955 Signed-off-by: Shruthi Krishna commit 8a505d574a92fec20889f3134aa2dac02073f9b1 Author: Deepika Pepakayala Date: Wed Apr 6 13:46:35 2011 -0700 msm: vidc: Improve the decoding times for interlaced clips. Increasing the performance level to 720p for all interlaced clips with VGA resolution to improve the decoding times. Change-Id: I5cf8afe10b51c4fb7e70c156261b16318944c685 Signed-off-by: Deepika Pepakayala commit 82f440a89565bac0bc1371fbf733e45d81680800 Author: Deepika Pepakayala Date: Thu Apr 7 13:43:53 2011 -0700 Revert "msm: vidc: Release first field transaction for interlace frames" This reverts commit 53c267d871521c0ac7c0d1a9e43a02654761067f. Change-Id: Id44708bd3d980ea1412e6277a2e3d3a761aa305b Signed-off-by: Deepika Pepakayala CRs-fixed: 280620,280692 commit 4ddcddbc417702d9f809182c38ff6f1c2b36e979 Author: Ashray Kulkarni Date: Tue Apr 5 14:49:08 2011 -0700 vidc: 1080p: Add support for non-multiple of 16 input width in driver. Change-Id: I9eeff5f9b258bc220be8322bc987cead9f96abcc Signed-off-by: Ashray Kulkarni CRs-fixed: 280280 commit 1b7d16d196656c9c22f625c624cb59d1d32481f6 Author: Ashray Kulkarni Date: Mon Apr 4 19:11:18 2011 -0700 vidc: vdec: Fix VC1 failure in driver Configure Width, height for the core in case of VC1 and VC1_RCV codecs. Change-Id: I90a6f9fdfe000575e954894451f2c68a724d69f5 Signed-off-by: Ashray Kulkarni CRs-fixed: 279645 commit 388867a3bb6d72b3da409962380ebf876c735622 Author: Deepika Pepakayala Date: Tue Mar 29 11:24:52 2011 -0700 msm: vidc: Fix video core clock power up/down sequence Change to ensure that the clock is enabled before enabling or disabling the power rail. Change-Id: If182550752e8f89a2756d61953d79f1a4814c533 Signed-off-by: Deepika Pepakayala CRs-fixed: 281686 commit 4b0a040d6b2eb420c36abbb6ef505b46b0021617 Author: Vinay Kalia Date: Tue Mar 22 18:03:34 2011 -0700 msm: vidc: Adding ioctl for IDR only decoding Adding ioctl for only sync frame decoding. This will configure hardware in IDR only decoding mode. Change-Id: I1e218bdf9705fdadbf51cfc5d0542eb7fc970c40 Signed-off-by: Vinay Kalia commit f09a67fa9d158783da17e0bb7d480f0970ab3ed0 Author: Rajakumar Govindaram Date: Fri Mar 25 15:58:19 2011 -0700 msm: camera: Add IMX074 Calibration data usage support The IMX074 camera sensor has calibration data available in eeprom to adjust the variation of color and focus parameters. This data is used to adjust the tuned parameters. Change-Id: I5b998b26ef748e341bce1c0f892d73897538f52b Signed-off-by: Rajakumar Govindaram commit 1559eab74c563cb60a22048997337db5af423d0d Author: Nishant Pandit Date: Fri Feb 25 09:26:54 2011 +0530 msm: camera: 8x60: Initial support for qs_s5k4e1 camera sensor Change-Id: I10b4c7eee463da8f5ea21676ad2706cbad4dc614 Signed-off-by: Nishant Pandit commit f6de814765ccb615c173dccdd588c6f5cb97b66b Author: Ashray Kulkarni Date: Wed Mar 23 15:07:40 2011 -0700 vidc: Enable Messages when Hardware timeout happens. Change-Id: I0cd90006096571e885bee260da1decd2dcf428bd Signed-off-by: Ashray Kulkarni commit f4a2361bbaad07a9e7eade0e42a1a0d20bd81914 Author: Zhang Chang Ken Date: Fri Mar 11 15:41:04 2011 -0500 msm_fb: display: AUO WVGA LCDC Panel Adding driver for AUO wvga(480x800) 3.61" lcdc panel. Activated for msm8660 Fluid platform revision 3 and up Change-Id: I528894540ed1990b7d0e8ea763fd9c54c70cf276 Signed-off-by: Zhang Chang Ken commit 7e4217db2504593e2c8c962dd32c896cb7fe2129 Author: Ujwal Patel Date: Sat Mar 19 13:32:35 2011 -0700 msm: camera: Stereoscopic 3D Camera feature. This is the base change for S3D camera feature. Change-Id: I4dd5a4fac4fde73defc34b2f08aade8ca373cf6f Signed-off-by: Ujwal Patel commit 964e19b741decbd2189a407b09f2918a70b3ead1 Author: Gopikrishnaiah Anandan Date: Fri Mar 11 17:30:20 2011 -0800 vidc: 720p: Align stride and scanlines to Tile format. If color format is tile, decoder will align the stride and scan lines to 128 & 32 pixels. CRs-fixed: 276530 Change-Id: If467fcd51b3ef543bf9e234dbcc4d113680fbd59 Signed-off-by: Gopikrishnaiah Anandan commit fec11dfdf2db7026bf63eeaff81bea4ae5c12da3 Author: Ajay Dudani Date: Thu Jan 13 15:16:19 2011 -0800 msm: vdec: Cleanup info level logs Change-Id: Ice71d404e510529dcad40e7a8afba87cca06ef59 Signed-off-by: Ajay Dudani commit e5b0e25fd8a4ad347cad6db874e6930aadfa8ac2 Author: Gopikrishnaiah Anandan Date: Wed Mar 9 12:00:38 2011 -0800 vidc: 1080p: Align stride and scanline values to yuv tile Render is expecting stride and scaline values as per tile format.This change will align sride to 128 and scan line to 32 pixels. CRs-fixed: 276530 Change-Id: I228a98f0d6b60e42fbd24f4b96c53e922ef6d6df Signed-off-by: Gopikrishnaiah Anandan commit 4d6ea04a7e9bd0350e5fe3822ac1c0f6bd3afe80 Author: Gopikrishnaiah Anandan Date: Wed Mar 2 18:20:08 2011 -0800 vidc: vdec: Reject unsupported data partition clips. Video core supports data partition clips upto SD dimension. This change rejects data partitioned clips that has dimension greater than SD resolution. CRs-fixed: 277123 Change-Id: I5b958107f352e77603b66c5aae8b1df61d039755 Signed-off-by: Gopikrishnaiah Anandan commit 8ae66ceb26dd7baecc85d2b334029903cb7a1bb8 Author: Urs Muff Date: Wed Sep 8 12:42:21 2010 -0600 msm_fb: display: Samsung AMOLED PenTile panel Adding driver for the Samsung AMS367PE02 3.7" PenTile 480 x 800 16.7M AMOLED panel. Enable LCDC auto detect when MIPI detect is enabled Clear regulator handles after they are released to avoid crashing Change-Id: I6abf705fd19d5baa429fb2a7c47e4299f73c6b67 Signed-off-by: Urs Muff Signed-off-by: Wentao Xu commit 5092bd17c84279fe44d6ae0f9e2dcc39bd919068 Author: Marco A Vital Yep Date: Wed Feb 16 13:05:28 2011 -0800 msm: vidc: Add dynamic enabling for pmem messages Add support to enable the pmem messages at runtime for memory allocation and de-allocation to detect memory leaks. Change-Id: I515cbcafeee5a5dfc83dc42838b7bef8a7c0ab02 Signed-off-by: Marco A Vital Yep commit 410d84a28f6019f9ee6d8e065ea86c0c2ef4147a Author: Sunid Wilson Date: Thu Feb 24 12:30:33 2011 -0800 msm: camera: Zero Shutter Lag feature support Changes include - VFE 3 output configuration - ZSL streaming mode support - Handling of raw snapshot, regular snapshot and zsl streaming in IRQ1. Change-Id: If94135d4d6a6ed0a8344413725ded2e45f5f7a5a Signed-off-by: Sunid Wilson commit c500a60e670c44f217369d98145013bce46002b1 Author: Shuzhen Wang Date: Fri Jan 21 16:27:48 2011 -0800 v4l2: msm: Add back chained copy for msm_ctrl_cmd. v4l2_event structure is not enough to hold all control commands. Instead, we use pre-allocated buffers in the driver and daemon so that no run-time allocation is required. Change-Id: I37f0512b5de33bb4cd43ed5f535c1ac76de397e6 Signed-off-by: Shuzhen Wang commit 6ae4ecafedef28e15fac051fcb2cad61c592f922 Author: Marco A Vital Yep Date: Wed Feb 16 18:29:48 2011 -0800 vidc: 1080p: Add time metrics for decoder initialization Add logic to provide the decoder initialization times. Change-Id: I39bbf85b292428cc7e5f61cba8138b5e2e1ae58e Signed-off-by: Marco A Vital Yep commit 477d8d33411c2a4298cd259f3e918e45aa4e02f5 Author: Marco A Vital Yep Date: Thu Feb 24 17:26:25 2011 -0800 msm: 720p: Set resolution to core for VC1 and VC1_RCV Set resolution to core for VC1 and VC1_RCV codec enumerations in HAL. Change-Id: Idc2be9312546f24ef29fd7ab82216b900ca629b1 Signed-off-by: Marco A Vital Yep commit 53c267d871521c0ac7c0d1a9e43a02654761067f Author: Marco A Vital Yep Date: Thu Feb 24 08:16:33 2011 -0800 msm: vidc: Release first field transaction for interlace frames Release the transaction corresponding to the first field of interlace frames since no output done callback is expected for this field. Change-Id: I621738424b1f8fe6b4d998a5f7e152dc29da17f6 Signed-off-by: Marco A Vital Yep CRs-fixed: 274264 commit c315489fbe1a75c52b968c4a237d9f7f4334336f Author: kuogee hsieh Date: Mon Feb 7 16:58:43 2011 -0800 msm_fb: display: add chimei panel driver Add Chimei LCDC panel driver. This patch also incorporate backlight control through PWM of gpio-24 (channel 0) of pm8058. Change-Id: I2e00d6ce0f6a9858a56d929c660776fcbfc54732 Signed-off-by: Kuogee Hsieh commit d1e94baf4e6fdacc87c619f40c3abca2a88fb593 Author: Marco A Vital Yep Date: Wed Feb 16 16:52:19 2011 -0800 msm: vidc: Add time metrics for decoder initialization Add logic to provide the decoder initialization times. Change-Id: Iff66fc8d7ff0f43ccb8fb16ab6310c56567e0589 Signed-off-by: Marco A Vital Yep commit bac3c0d10476b3d2023a1569e3520f3e90fe0a33 Author: Sunid Wilson Date: Tue Feb 8 17:48:20 2011 -0800 msm: camera: snapshot interface redesign Created pic node and associated snapshot functionality to the new node. Fixed pmem lookup error for raw snapshot. Change-Id: I3fe532d9818f9dfb2ad8157b6e1ff98dfce8dfff Signed-off-by: Sunid Wilson commit b9a23083f5bb8ceaa5325f6feefbbba5f1b2a94a Author: Marco A Vital Yep Date: Mon Feb 14 11:55:38 2011 -0800 msm: vidc: Remove not requested flush done callback Remove flush done callback when the driver is stopped while handling an error in invalid state. Change-Id: I6cbdee961f6caa8172be7c2ac829ae258547213b Signed-off-by: Marco A Vital Yep commit d034fc1101365fd5593b8dc1da66da63d8a5f61f Author: Harshad Bhutada Date: Fri Jan 21 19:42:49 2011 +0530 msm_fb: display: add 3 frame buffers support Add triple framebuffer to improve display performance Change-Id: I132c74f11f5ddcee62d12599c85dd615e14235d4 Signed-off-by: Harshad Bhutada commit 76ad97c210e10d57584e8d8a1eb90723c22bbd8f Author: Marco A Vital Yep Date: Mon Jan 31 18:57:53 2011 -0800 msm: 1080p: Support output decode order Add support for output in decode order. Change-Id: I9af33604a7ec879210b09a00c399fec4216c0300 Signed-off-by: Marco A Vital Yep CRs-fixed: 273581 commit 62f6148fd162d51f900d10b16bdd421528fc2b38 Author: Gagan Mac Date: Mon Jan 10 23:11:23 2011 -0700 msm: msm_bus: Decouple nodes from fabrics for scalability Node ids need to be independent of the fabrics. For this external ids and internal ids need to be maintained separately. This is required to avoid misleading enums in case a node is switched from one fabric to other. Change-Id: I3ef56eba3a8cb504d7dedeeab4b47468c87fe729 Signed-off-by: Gagan Mac commit 3f7a7060fc6b4d14f90354f9ccefe787531becbd Author: Ashray Kulkarni Date: Tue Jan 25 17:26:37 2011 -0800 vidc: venc: bframe cleanup during flush In bframe encoding when flush command is issued last buffer does not get released.This changes releases the remaining buffer. Change-Id: I3a85c447106e462a673dc8e70698c0c8551e55ce Signed-off-by: Ashray Kulkarni commit 364d619844ec836388c7022bf4ab1155d6d48f01 Author: Gopikrishnaiah Anandan Date: Tue Feb 1 12:53:25 2011 -0800 vidc: vdec: Handle clips with corrupted sequence header. When sequence header is corrupt video firmware can return data consumed length greater than supplied.Added support to handle this usecase Change-Id: Idd8df3b50aee5b44ed543f05adb2e53f3a28f636 CRs-fixed: 273148 Signed-off-by: Gopikrishnaiah Anandan commit cb64336b06207f55b38bf808d0b71e94ed02c9cd Author: Gopikrishnaiah Anandan Date: Tue Feb 1 16:52:37 2011 -0800 vidc: vdec: Handle Eos with corrupted sequence header. Driver was not passing transaction pointer when an error occured with sequence header parsing and eos flag set Change-Id: I2b00d5c650545ae1bacd98650ede2bb13031b397 CRs-fixed: 273137 Signed-off-by: Gopikrishnaiah Anandan commit 91e6e6dfd6cd17b0bf701bbe4a950097aba0ecb9 Author: Gopikrishnaiah Anandan Date: Mon Jan 31 12:16:28 2011 -0800 vidc: vdec: Support to reject YUV422 clips. For h264 decoding once sequence header is parsed, core will return yuv format. YUV422 clips will be rejected based on the idc format CRs-fixed: 253750 Change-Id: If073ca355427fb0f107e6c1ad89237ec7a2e16ce Signed-off-by: Gopikrishnaiah Anandan commit 68ce6a52d8017dd4cad4f5aba024bb9d0a0fcaf7 Author: Ashray Kulkarni Date: Thu Feb 3 12:45:56 2011 -0800 vidc: venc: Enable OOO support in MGEN2AXI register Enable Out of Order instruction execution in MGEN2AXI. Change-Id: I38f9009bf1dbdb41fd18bb39c4f25f1118ee75b3 Signed-off-by: Ashray Kulkarni commit 8e879b7af034784a850cc76f17a9af5dc8f63e8e Author: Ashray Kulkarni Date: Wed Feb 2 11:13:49 2011 -0800 vidc: venc: Initialize the vop_timing to high value for H.264 Change-Id: I105978a86d57f4e20d3246e2e2f1c41fac0f3078 Signed-off-by: Ashray Kulkarni commit ed060bcc936f1a05a6e17e60505dd8f247c328c1 Author: Marco A Vital Yep Date: Fri Jan 21 18:04:27 2011 -0800 msm: vcd: Update bistream error handling in EOS Update the logic to don't report the EOS done event to client until this event is received from core for completely corrupted bistreams. Change-Id: I914d7044f2349c449c8d7cee6f93174dddb83251 Signed-off-by: Marco A Vital Yep CRs-fixed: 271520 commit b727d2ede2075c99ff82891012687bffcbf9104b Author: Marco A Vital Yep Date: Fri Jan 21 18:23:58 2011 -0800 msm: vdec: Fix memory leak for video decoder message Free memory allocated for video decoder message when message is not required. Change-Id: Ia64bebdaff903dd22deed31084ff869825fc4f44 Signed-off-by: Marco A Vital Yep CRs-fixed: 271497 commit 6497dfb946781d3f9ae5f27910869b2739876ba6 Author: Marco A Vital Yep Date: Thu Jan 20 18:45:14 2011 -0800 msm: 1080p: Support dynamic reconfiguration for video decoder Add logic to support reconfiguration at runtime for video decoder. Change-Id: I170d221afd139abfc1f09be7bea95a1261f988c1 Signed-off-by: Marco A Vital Yep commit 5e42eff243e5fbf145fe4f2c6d03a09aba809233 Author: Marco A Vital Yep Date: Wed Dec 29 14:01:27 2010 -0800 msm: vidc: Add logic to handle reconfiguration in error state Add logic to handle the reconfiguration event in invalid state and close the driver instance properly. Change-Id: I7b7fcc565be692b355fb0f2ea963be71fda79b32 Signed-off-by: Marco A Vital Yep CRs-fixed: 269214 commit aa7fb33f8deb4a81b5b68302324f40439256cc23 Author: Marco A Vital Yep Date: Tue Dec 21 17:44:09 2010 -0800 vidc: 720p: Support non-standard resolutions for h264 encoder Add support for resolutions non-multiple of 16 for h.624 encoder. Input YUV still must have multiple of 16 dimensions, buffer size will be calculated rounding the dimension set by the client up to next multiple of 16. Change-Id: Ia5379ca45e4028ec8bfae183be0e9bd634f34dcd Signed-off-by: Marco A Vital Yep CRs-fixed: 268399 commit 74626e6d2e22ce20065f3dd18e04eef5748dae5b Author: Ankit Premrajka Date: Fri Nov 12 09:29:35 2010 -0800 v4l2: Enable passing msm_isp_ctrl_cmd in v4l2_event structure. Create a new control command structure so that it can be packed in v4l2_event. This avoids the deep copy required for msm_ctrl_cmd. Change-Id: I48210062fb6c53c480174186994f26b4aa7e70d8 Signed-off-by: Ankit Premrajka commit 3eb3330418fb87cf756cf3a886c509e51a56c5bf Author: Ankit Premrajka Date: Mon Dec 13 14:47:43 2010 -0800 msm_camera: export certain kernel headers for use from user space. Change-Id: I850d5fc6cb33948b29814757ea3e56adca725fb4 Signed-off-by: Ankit Premrajka commit e19c02de0a3b062d21fe82eee4913e631683e105 Author: Shuzhen Wang Date: Wed Dec 22 11:43:27 2010 -0800 v4l2: msm: Implement preview support for vx6953 sensor. Add v4l2 implementation of msm camera driver. The application interacts with the driver via v4l2 APIs.The configue daemon polls on events from /dev/config0 and sends appropriate control commands to hardware. Change-Id: Ifb07cd2452599106915035daddd862c074088d28 Signed-off-by: Shuzhen Wang commit c57c3cd0ea7a0bc645516df5d96c20fc782849d7 Author: Stephen Boyd Date: Mon Dec 20 17:19:54 2010 -0800 video: vidc: Migrate to clock rate voting Use the clock api, instead of pm_qos, to vote on the EBI1 rate. The transformation is as follows: pm_qos_add_request() -> clk_get() and clk_enable() pm_qos_update_request(*, *) -> clk_set_rate() pm_qos_remove_request() -> clk_disable() and clk_put() Change-Id: I9ecaa8b0b5026958e034910b44a2ea489d0a149d Signed-off-by: Stephen Boyd commit 905d5644635740c0ae1d85a0d1d3707251e66670 Author: Marco A Vital Yep Date: Mon Jan 10 20:12:17 2011 -0800 msm: 1080p: Update handling of SYNC_POINT_NOT_RECEIVED warning Update the handling of the SYNC_POINT_NOT_RECEIVED warning from cor to issue the input done callback but don't report this as an error. Change-Id: I90fb9ce44386e333b504688774cbe197288bf5d4 CRs-fixed: 269494 Signed-off-by: Marco A Vital Yep commit cb3981db8c84ba6e16516eb2e03d9163cb12c3eb Author: Ashray Kulkarni Date: Mon Jan 10 18:54:13 2011 -0800 vidc: venc: Add support for Dynamic setting changes in encoder. Change-Id: I639119063367d84d9b917a66ea19acd229936026 Signed-off-by: Ashray Kulkarni commit 19bd80a50f313d21ec80cd099cb88f8621a073c4 Author: Gopikrishnaiah Anandan Date: Mon Jan 10 19:13:22 2011 -0800 vidc:1080p: Integrate firmware version 01072011. Driver changes to pick firmware version 01072011 Change-Id: I9244b8854250189dea2104b40f7bb38001b8954e Signed-off-by: Gopikrishnaiah Anandan commit 7194f4369912e0ac56fa5a80ee5e258f3d427cc2 Author: Ashray Kulkarni Date: Fri Jan 14 19:54:43 2011 -0800 vidc: venc: Add constrain baseline support for H.264 Change-Id: I4f6cc2fc315656c0d67185383f0f7c7b59cbfc25 Signed-off-by: Ashray Kulkarni commit f0114c5cf39a0dd3968076e331a11ac70f1a1841 Author: Ashray Kulkarni Date: Wed Jan 5 11:44:00 2011 -0800 vidc: venc: 1080p Encoder RC config changes. Modified the RC setting to reflect the changes for achieving proper bitrate. CRs-fixed: 269181 Change-Id: Ie2b0292a49a93d60828b9aa37bfd5f54a3946458 Signed-off-by: Ashray Kulkarni commit 4908e57928a2c2a7570a4d991561f7c35f6cbb05 Author: Ninad Patgaonkar Date: Fri Jan 7 12:22:28 2011 -0800 msm: camera: Support for providing sensor mount angle to the APP Added support to provide the sensor mount angle. This will enable the camera application to display the camera preview with the correct orientation. Change-Id: I9f3096807f6f99c711a12044f5259dab30555986 Signed-off-by: Ninad Patgaonkar commit a3677e5726482ac28afc6e21c2aa7a8cdc5fde72 Author: Ashray Kulkarni Date: Tue Dec 7 14:37:15 2010 -0800 vidc: venc: Add Bframe support B frame support is necessary for MPEG4 ASP, H264 HIGH and MAIN profiles. Change-Id: I291d10ce9faa12dd12bd15172bfd229eba4925b1 Signed-off-by: Ashray Kulkarni commit 4b795f85a01714849dc159b701ae09c780459b3f Author: Marco A Vital Yep Date: Tue Dec 14 18:26:32 2010 -0800 msm: vidc: Add missing mutex in close function Add missing mutex to fix error in close function when multiple video instances are running concurrently. Change-Id: I569ded1c30565b7bec5beae796d2e5de3a79b624 Signed-off-by: Marco A Vital Yep CRs-fixed: 267339 commit 3dbc778eaeda8b7b0b0e6023a2a826e6f721dbf8 Author: Marco A Vital Yep Date: Tue Nov 16 18:58:10 2010 -0800 msm: vidc: Update stride calculation for mpeg4 Update the stride calculation for mpeg4 to round the value to the next multiple of 16 instead to next multiple of 32, this was causing some color noise at the bottom of the displayed screen. Change-Id: I9747256066ef2226cea477fc914a950f3950a01d CRs-fixed: 267073 Signed-off-by: Marco A Vital Yep commit 6a7d21afce5211a76c15163804642ecd68058371 Author: Ashray Kulkarni Date: Fri Dec 17 18:45:17 2010 -0800 vidc: venc: Free unprocessed messages When stop is called the remaining unprocessed messages were not released. Change-Id: I26d48634733241e9a79ab2d885eca88640a23770 Signed-off-by: Ashray Kulkarni commit 986181e64ef2837c63c3b2d10ad400f6297aeb56 Author: Ashray Kulkarni Date: Wed Dec 15 19:28:41 2010 -0800 vidc: VCD to return error when the event is corrupted. Encoder and Decoder to return error when the callback event is corrupted in vcd. Change-Id: I0929fdfec6293a0c3dfdffc3d2d3e17feb80c8f8 Signed-off-by: Ashray Kulkarni commit 33ddab182878e9c0f48f49ad299a25760bf0e8e6 Author: Gopikrishnaiah Anandan Date: Wed Dec 15 10:50:14 2010 -0800 vidc: vdec: Report error for H264 FMO clips. Video core doesn't support FMO clips.Core will respond with unsupported feature in profile error once sequence header is parsed.In case of H264 driver will raise a client fatal error. Change-Id: Idd1e4112b18f87fd3bce99b944a31bd3e1cc15fd CRs-fixed: 263176 Signed-off-by: Gopikrishnaiah Anandan commit 9232895c67d0eefbf7af3fa356b27ba200430ec8 Author: Gagan Mac Date: Mon Dec 13 14:58:55 2010 -0700 msm: 8x60: Add name for video and camera clients This patch adds the name to camera and video platform data to view requests using debugfs Change-Id: I53d25548cb59b4a19675f0a556f571c63e4b32ae Signed-off-by: Gagan Mac commit f47b11552ba9705722b79d6cb40dd4ff938e57c9 Author: Ashray Kulkarni Date: Mon Dec 6 12:40:32 2010 -0800 vidc: 1080p: Port flipping for IPP sequence encoder Enable the port flipping for 1080p core in line with new firmware. Change-Id: I09fc6151dced68e7873a895a504c8fc8fea4d719 Signed-off-by: Ashray Kulkarni commit ba72eb905c3a1c1b92daf5c8ba99e1e3681a631c Author: Nagamalleswararao Ganji Date: Tue Dec 7 14:38:08 2010 -0800 video: vidc: Removing the CONFIG_ARCH from the video driver Removed the CONFIG_ARCH_MSM7X30 from the video driver as it should not be used outside of the machine architecture code Change-Id: Iad54c2dc124f3d226b9b70d15eeee2e6e135e950 Signed-off-by: Nagamalleswararao Ganji CRs-fixed: 260771 commit 3cd5438f2b13286566c6eb0e2ec6fe22d3711652 Author: Gopikrishnaiah Anandan Date: Tue Nov 30 17:28:31 2010 -0800 vidc: 1080p: Update bus bandwidth for video driver Based on dimension video driver requests the bus bandwidth Change-Id: I55f5cdbd8c7dfe1046bae792c894bae3229f90e8 Signed-off-by: Gopikrishnaiah Anandan commit b1723b7f02cbfabd99b61473e7681223d08ff0ab Author: Gopikrishnaiah Anandan Date: Wed Nov 3 17:42:52 2010 -0700 vidc: 1080p: Change trigger for reconfig event. Decoder should raise reconfig event if output buffer count reduces after sequence header parsing. Change-Id: I1a48acba812e893188f552843e4a03c34c849034 CRs-fixed: 261451 Signed-off-by: Gopikrishnaiah Anandan commit 83996fbd86254e0eda667734c07fb5f298660fea Author: Gopikrishnaiah Anandan Date: Mon Dec 6 12:24:54 2010 -0800 vidc: 1080p: Memory optimization for videoplayback Video decoder estimates buffer requirements based on profile and level which is worst case requirements. Actual clip memory requirements will be lesser than worst case. This change will reduce the intial estimate to a lower value, so that clips with low memory requirements can be supported when multiple instances are played. Change-Id: Ie9e8a7c07d45d269608bfe315979084cca872e2b CRs-fixed: 261451 Signed-off-by: Gopikrishnaiah Anandan commit 5567d544d44a3440973e537327558da406741a46 Author: Marco A Vital Yep Date: Fri Dec 3 10:05:38 2010 -0800 msm: vdec: Update to return error code in get message Return the error code in the get next message ioctl to handle properly errors in user space based on this code. Change-Id: I2248d9db1e0752fe0321f69cc3264b311e35c205 Signed-off-by: Marco A Vital Yep CRs-fixed: 266516 commit c6927fa95ca2ba9e86ff50a69c5079633ec6c8b2 Author: Gopikrishnaiah Anandan Date: Fri Dec 3 10:31:08 2010 -0800 vidc: 1080p: Handle display status for decoder. Video core can generate frames with display_only status. Added support to handle display_only status and generate frame done to client. Change-Id: I80c035295ec5861fa82662ddd8bce2b480254815 CRs-fixed: 265494 Signed-off-by: Gopikrishnaiah Anandan commit 3ac59c5be790c9ce6d38d03dfa24c71b7ca93d1f Author: Sunid Wilson Date: Mon Nov 15 15:30:15 2010 -0800 msm: camera: Support for querying the camera info Added ioctl for querying the camera info such as 1) num of camera nodes created 2) check the position of camera (front/back) 3) check whether 3D mode is supported Change-Id: I4492c3cc8b32b8d6a607775f6987d1520b26274c Signed-off-by: Sunid Wilson commit fcf8eac2ff452e9343b7304b207766766bb0694d Author: Ashray Kulkarni Date: Mon Nov 15 19:57:05 2010 -0800 vidc: Kernel memory optimizations - Changes for encoder and decoder header files - Moved reconstruction buffer allocation to userspace - Moved h264_mv buffer allocation to userspace Change-Id: I2f5511c4513252f84cf0f0d44ab88ee166d1dfbd Signed-off-by: Ashray Kulkarni commit f00a2e9a6ed9e80597ebbc70c83d8849da5cdaff Author: Deepika Pepakayala Date: Fri Dec 3 10:47:11 2010 -0800 msm: vidc: Fix to handle EOS in clips where all frames are corrupted. The 7x30 and 8660 cores behave differently in this scenario. Driver needs to handle the usecase differently for each core. Fixed by adding a api to identify the core. CRs-fixed: 261861 Change-Id: I4e9e9ad79395a43198bdff0d82564a6eafb64b42 Signed-off-by: Deepika Pepakayala commit d69992c27c7ff358089b3b4f7511f7c01d7560f2 Author: Deepika Pepakayala Date: Fri Nov 19 15:22:19 2010 -0800 msm: vidc: Fix for Reconfig in EOS. When core returns with SeqDone when EOS flag is set, the driver is raising a Reconfig event on a transaction that has already been invalidated. Fixed the issue by not raising a reconfig event when EOS flag is already set. CRs-fixed: 263178 Change-Id: Id7df1e2c7b4903756317addb63929a68e3b9b220 Signed-off-by: Deepika Pepakayala commit ea6f85c39749cdf419292e9918b3419a02a72884 Author: Deepika Pepakayala Date: Tue Nov 30 15:26:33 2010 -0800 msm: vidc: Fix un-initialized variable. The ddl_context was un-initialized in metadata parser. Fixed by initializing the ddl_context. Change-Id: Ic6888cb78bae8a5d5e1b8d2bd292bcc1f4b39996 Signed-off-by: Deepika Pepakayala commit 40b7baee14bfb8d33f7f0c3082b4707bccb3900c Author: Laura Abbott Date: Wed Nov 17 17:55:24 2010 -0800 video: vidc: Fix section mismatch The function vidc_720p_probe is referenced outside of the __init section. This is fixed by placing the probe function in the section which is for driver initialization code. Change-Id: Ib552280c8ea2b8e35149290b5778937122d4bfce Signed-off-by: Laura Abbott commit b9151f12c369ea1bcfed0cb63bd8c204bd43cf51 Author: Ashray Kulkarni Date: Thu Nov 18 17:08:46 2010 -0800 vidc: 1080p: Video optimizations - Enable Pixel cache - Use burst size of 9 for reads/writes in MGEN2MAXI instead of 4 - Enable core timing message Change-Id: Ie2fd2d34317cdfd0fd2136e83863c1914db76b75 Signed-off-by: Ashray Kulkarni CRs-fixed: 257534 commit 03a342909deec930eb52fc947bbb60b2198fb011 Author: Gopikrishnaiah Anandan Date: Wed Nov 24 15:40:17 2010 -0800 vidc: 1080p: Video footswitch regulator support. With this change video driver will - enable video core foot switch at start of session. - disable video core foot switch at end of session. Change-Id: Ib23e4164abd48ad7c1447bdafb8f734e5c01cc24 Signed-off-by: Gopikrishnaiah Anandan commit d0735aca94d969e653da4f62c02200607231dfa4 Author: Nagamalleswararao Ganji Date: Tue Sep 14 19:47:32 2010 -0700 vidc: 1080p: Clock gating for 8660 video driver Enable clock gating feature for video driver Change-Id: Ic265222e4c1350e8f0fb574e86af696e1a88522a Signed-off-by: Gopikrishnaiah Anandan commit e69f641acbe060badb10a354bfbf46076f8ad7e7 Author: Philip Elcan Date: Thu Oct 14 15:20:01 2010 -0400 msm_fb: Add VGA resolution to 8660 FFA panel On 8660, the LCDC panel and VGA display are on the same bus, so specify the maximum VGA mode as the secondary mode in the panel definition and the Samsung WSGA panel settings for the primary. This will allow userspace to change the resolution when using VGA mode. Change-Id: Ia805ce6477cf9b300a1f969679f2012980d14a61 Signed-off-by: Philip Elcan commit be482dd056b5ff02c8a3f98d60875e7f80fe0aec Author: Chandan Uddaraju Date: Tue Nov 9 16:57:21 2010 -0800 defconfig: Add configuration macros for MIPI DSI display Interface. Add configuration macros for Toshiba and Novatek MIPI panels. Add macros for both command and video mode. Disable MIPI panels and enable SAMSUNG display by default. Change-Id: Id2a9dca3a2467e588ffdad1ec9d149ca6a4d4d76 Signed-off-by: Chandan Uddaraju commit 3661713ece532d5b50fd0fa1ab415058736fd0ce Author: kuogee hsieh Date: Wed Nov 3 09:19:57 2010 -0700 msm_fb: display Add Novatek video/cmd panel support Incorporated both video/command mode panel configuation to mipi_host_init to support both video/command. Change-Id: I51555e9065038607765de54e98c36128aa611d8f Signed-off-by: Kuogee Hsieh commit 7ebd338046d3fa07df2dad394bc824ae271a30d4 Author: Ashray Kulkarni Date: Wed Nov 17 20:21:19 2010 -0800 vidc: 1080p: Remove check for byte based slicing Remove the check for minimum of 1920 bytes for byte based slicing. The hardware now supports smaller byte size slices. Change-Id: I404b91ae1ce859690b93e4221c27a1d5f982ca4c Signed-off-by: Ashray Kulkarni commit d9e6339a4fafcfdc0689ae55eec571d3ded4fcbf Author: Marco A Vital Yep Date: Tue Nov 16 17:30:07 2010 -0800 msm: vidc: Add IOCTL to get number of encoder instances Add IOCTL to read the number of current encoder instances and allow create new instances based on client requirements to support single or multiple instances. Change-Id: Id0ad7e296f87122ef434fb29e7bdbd9ec3a68b9b Signed-off-by: Marco A Vital Yep CRs-fixed: 263431 commit 83a16cc81ef55165de4f89b2a9419d733d41d4c4 Author: Nagamalleswararao Ganji Date: Thu Sep 16 16:31:11 2010 -0700 video: vidc: Metadata support is added SEI, VUI, ConcealMB, QPArray metadata support is added to the 8660 video driver. This metadata support is needed for features like 3D video compression and playback. Change-Id: I945215cb74c687b0c6e4ad84373faa7914bb9c62 Signed-off-by: Nagamalleswararao Ganji commit 09b822088791f8b0be37d4aa7cf998ca482b07e9 Author: Neil Leeder Date: Tue Oct 26 16:41:13 2010 -0400 msm_fb: qrdc: add backlight support Make the driver a platform driver to add the backlight callback. Add the EC driver used to control the backlight as a Kconfig dependency. Change-Id: Id66f3d371917d8721c3bfe9af761080171f206a1 Signed-off-by: Neil Leeder commit 8a0f8c6e3e7b78c2fb4cf62394548e43c8049a7e Author: Deepika Pepakayala Date: Mon Nov 1 11:37:42 2010 -0700 msm: vidc: Fix for video codec HW reset with fatal error. When fatal error occurs, the video core reset was failing thereby blocking any further video playback. Fixing this by changing the reset sequence as per the new video firmware interface. CRs-fixed: 260074,257708 Change-Id: I24d8a4b45acadf1e15d61602797c56cd983838c1 Signed-off-by: Deepika Pepakayala commit 6aa7b7900119027b60fd8afc1861bec99b8e13d1 Author: Gopikrishnaiah Anandan Date: Tue Nov 9 20:32:24 2010 -0800 Revert "msm: vidc: Increase hardware timeout to 10 secs." This reverts commit 34d4c6c773d16b1065de9e2a357620c372b4dcb2. Firmware fixes the H264 decoding issue,reverting timeout value to 1 sec. Change-Id: I6b262837e1e9919a8a659be2c6d1c0d20f3feab1 Signed-off-by: Gopikrishnaiah Anandan commit 0bd1ab16c20a675495d167c7a46b673daac0ab4f Author: Marco A Vital Yep Date: Wed Oct 27 17:19:58 2010 -0700 msm: vidc: Fix frame channel tracking for reconfiguration Remove frame channel release from the client state machine when a reconfiguration event is received in stopping state, frame channel is released inside the function in charge to handle the reconfiguration event. Change-Id: Icfddaa3256e465e7ff0a0013f547466300fef836 Signed-off-by: Marco A Vital Yep commit 539c8fae724e2c05bc4ba7414dfd454d64660c9e Author: Marco A Vital Yep Date: Thu Nov 4 16:22:56 2010 -0700 msm: 720p: Fix to recover from header parse errors Fix to report header parse errors as recoverable. Change-Id: I3630811946ec07ecb81e877971c8d3a686c8653b CRs-fixed: 262904 Signed-off-by: Marco A Vital Yep commit eaa86835c64178fa3c4028779eeabb0c28548c73 Author: Marco A Vital Yep Date: Mon Oct 25 12:51:17 2010 -0700 msm: vidc: Fix logic for extradata processing Fix the logic to enable extradata by client request only Change-Id: Ie013263222c9857c2a53e4a4957c23f74b77102c CRs-fixed: 258603 Signed-off-by: Marco A Vital Yep commit 0485614603ab2ca87285295feb666b675370ed12 Author: Marco A Vital Yep Date: Thu Oct 21 16:11:28 2010 -0700 msm: vidc: Fix EOS done callback for bit stream errors Fix to send EOS done callback when the input bit stream is corrupted only if no other input frame has been processed, otherwise EOS done must be received from core. Change-Id: I79f15337a0ead3a94f7dc6f5c2d3456e4b3a5147 CRs-fixed: 260370 Signed-off-by: Marco A Vital Yep commit 035bcbcb0facfc6ccfe207e986830b3cdbb466f2 Author: Gopikrishnaiah Anandan Date: Sun Nov 7 18:26:35 2010 -0800 vidc: 1080p: Add bus scaling support for video. Bus scaling support for video playback and recording. Change-Id: I4648d828467a66b6d6255845c961382d868f4acb Signed-off-by: Gopikrishnaiah Anandan commit be2ca92457ca00d30e01ce9687c5971871bd8450 Author: Jignesh Mehta Date: Wed Oct 20 12:13:04 2010 -0700 camera: Add the support of facial framework feature attach face-detection region-of-interested information to frame Change-Id: I6a127163dad740f452d67a439cddae0306ea49e2 Signed-off-by: Jignesh Mehta commit 324d255ee45b6bd6f412aa9efc5c3e95d829a799 Author: Ninad Patgaonkar Date: Thu Oct 14 16:53:15 2010 -0700 msm: camera: Support for common IOCTL call for LED & Strobe Flash Added a single IOCT interface for LED & Strobe Flash control operations. Change-Id: I206076dd82ad99588c74e2776cf8a2875ddc35e5 Signed-off-by: Ninad Patgaonkar commit b583d437533ceba0efecd85bbd7d58e2a0582187 Author: Ashray kulkarni Date: Thu Oct 21 16:50:27 2010 -0700 vidc: 1080p: Fix Level check in MPEG4 Change-Id: I92f8d977b62d4e5939629f4e02c746b1253b5572 Signed-off-by: Ashray kulkarni commit 0e2aea52cea7488889ca8c591d774da7642c3a9c Author: Marco A Vital Yep Date: Wed Oct 13 12:48:08 2010 -0700 vidc: 720p: Fix memory leak for reconfiguration Fix to release the memory allocated for comv (h264) and reference (mpeg4) buffers when reconfiguration happens at the middle of the playback. Change-Id: I6e4f91e193bd77a9ef089de9d9b4f08a8fa883d9 Signed-off-by: Marco A Vital Yep commit fffb24688cfd3560ecca5b8d162427c21467ecd1 Author: Ravishangar Kalyanam Date: Tue Oct 19 15:49:07 2010 -0700 msm_fb: display: Correct Initlogo filename Correct Initlogo filename accessed from display driver CRs-fixed: 257109 Signed-off-by: Ravishangar Kalyanam Change-Id: I95e5ff1f473e3c0a73a7a693c1965ad6e7653ee5 commit 761df5db2b9852c290364e0e26cce767e40d4950 Author: Marco A Vital Yep Date: Tue Oct 19 13:33:26 2010 -0700 msm: 720p: Add constrained baseline profile for h264 Add enumeration to support constrained baseline profile for h264 encoder. Change-Id: Ib6c0acaec7a6c06c3fb0bdf0cada2a77f5780018 Signed-off-by: Marco A Vital Yep CRs-fixed: 252192 commit e7cc19c8991a41767322f25cc2129c5e52f62e5d Author: Sunid Wilson Date: Tue Oct 19 00:34:46 2010 -0700 media: camera: Fix for freeze in msm_get_pic while aborting capture Changes are made to woke up the userspace thread executing msm_get_pic when abort is called during capture. Also made the abort flag thread safe and reset the flag during msm_get_pic to avoid race condition which can cause capture failure CRs-fixed: 260328 Change-Id: I5be1153494a5680079788e994b417ad2136260bb Signed-off-by: Sunid Wilson commit 9e6464530b9600897ae25af594967c4acc521fbe Author: Ashray kulkarni Date: Mon Oct 18 14:57:06 2010 -0700 vidc: 1080p: Add H264 Level 4 support Change-Id: Idcd89305efd024f945fa7b83e5ec6a6b3398325f Signed-off-by: Ashray kulkarni commit 50c6e660d401c083233946d8aff0bc375a9dea62 Author: Ashray kulkarni Date: Mon Oct 18 15:27:31 2010 -0700 venc: 720p: Add missing mutex unlock. Change-Id: I2cff29ea58dca53b531df91519f25fe3536b7781 Signed-off-by: Ashray kulkarni commit c8a5ba53effdfb7e28b56f8c43baad43d1a6f948 Author: Deepika Pepakayala Date: Mon Oct 18 11:42:39 2010 -0700 msm: vidc: Fix to handle Reconfig in EOS case Suspending client from scheduler until Reconfig is complete. CRs-fixed: 257273 Change-Id: I073e0149cb25220bad4f23e92bc723e86148f018 Signed-off-by: Deepika Pepakayala commit c607332a3c77fceaa44d41a8b83f1db766d5642c Author: Gopikrishnaiah Anandan Date: Fri Oct 15 11:53:50 2010 -0700 vidc: 1080p: Fix for interlace playback. Read interlace flag from decode status instead of display_status. Change-Id: I788317c8713069fc74f1176a007f2bf728cc7de8 CRs-fixed: 257731 Signed-off-by: Gopikrishnaiah Anandan commit 1d5c84793f2e6bb5513b8441034d4b9b8b871009 Author: Gopikrishnaiah Anandan Date: Wed Oct 13 16:52:32 2010 -0700 Revert "msm: vidc: Handle eos & flush for decoder." This reverts commit 0b23433851716783cda50d93e7e6097d853a21b8. Reverting work around since video firmware fixes issues. Change-Id: I214d8aa93bbfff4882bebbcb745d5b2de782d44a Signed-off-by: Gopikrishnaiah Anandan commit 97967b0cfe8aba9230233f11785c65ada912acd2 Author: Marco A Vital Yep Date: Mon Oct 11 11:08:47 2010 -0700 vidc: 720p: Remove sequence header after it's parsed Remove the sequence header from the input buffer in the header done callback for all codecs except for H263, this codec requires short header along with each frame. Change-Id: Ia842f14934f17bb3db05b48430bedaa75efc3647 Signed-off-by: Marco A Vital Yep CRs-Fixed: 257552 commit 0b91c7ceee8bd00d4ad45a08841e892ff7a4040d Author: Marco A Vital Yep Date: Tue Oct 12 09:39:24 2010 -0700 vidc: 720p: Reset ARM endianness register Reset the ARM endianness register in reset core function. Change-Id: I8b1474a3d986cdac01a9dd63d226c1a33847573f Signed-off-by: Marco A Vital Yep commit 302e36a9907723d9b48d37297072b64ac078cd76 Author: Ravishangar Kalyanam Date: Tue Oct 12 19:59:42 2010 -0700 msm_fb: display: Add dynamic MIPI panel detection support Change-Id: Ie1281a353c15c7d7575eb1b591d325382d61c303 Signed-off-by: Ravishangar Kalyanam commit ac62b3d02df6c4146a27f9d869c9f07dd4c03733 Author: Gopikrishnaiah Anandan Date: Tue Oct 5 12:41:26 2010 -0700 vidc: 720p: Enable mb level rc for h264 encoder - Enable Macro Block level RC for H264 encoder. - Allow setting dynamic properties for encoder in frame_done state. - Change reaction co-efficient for CBR_VFR mode. Change-Id: I55a0820d2a86fd233a16f76ba18139a1f9d6f66f CRs-fixed: 257652 Signed-off-by: Gopikrishnaiah Anandan commit 21cad0ff89284f24df708c2085007721a1e788c7 Author: Deepika Pepakayala Date: Tue Oct 5 14:23:02 2010 -0700 mm-video: venc: Fix for chroma corruption in 1080p clips. This fix uses the un-aligned width and height to compute the input yuv buffer size for the encoder. CRs-fixed: 258138 Change-Id: Ic26025764db2100558c131698ac9da946f5a8351 Signed-off-by: Deepika Pepakayala commit b47c1eb0bf3da41572af1abcbdb90f8ccc0466ec Author: Nagamalleswararao Ganji Date: Tue Sep 14 13:39:20 2010 -0700 video: vidc: Runtime PM support for 8660 video driver Runtime PM support is added for the 8660 video driver Change-Id: I8175494b22ae29eca7e1a6853547823558ca7e63 Signed-off-by: Nagamalleswararao Ganji commit 80726b692d586d1d7d10d75db1966128f468f27a Author: David Brown Date: Thu Oct 7 14:56:56 2010 -0700 msm_fb: Warning fixes Eliminite some unused variables. Change-Id: Ia8d6d1edb99eb67bf60cc183a87482d5871a129a Signed-off-by: David Brown commit 27cef4d3f474c834ce0c90a5bb49137a11d2db29 Author: Marco A Vital Yep Date: Thu Oct 7 14:05:31 2010 -0700 msm: vidc: Fix error handling in vcd Fix error handling to release channel and close component properly after some error. Change-Id: I6500210675e2b1a8623fda3514c0420a4478fee4 Signed-off-by: Marco A Vital Yep commit 2b67939aa0169a7078ad17a6480bd0309014cfd7 Author: Marco A Vital Yep Date: Thu Oct 7 14:59:30 2010 -0700 msm: vidc: Update codel level enumeration for vc1 Update codec level enumeration for vc1 simple, advance and main profiles. Change-Id: I26f7132cb0dc264b3ef98f80b80311145cb356cc Signed-off-by: Marco A Vital Yep commit c23c38750bff1b5e0886d4aba9cb7b9b7e027026 Author: Gopikrishnaiah Anandan Date: Mon Oct 4 16:42:11 2010 -0700 vidc: common: Fix device fatal error recovery path Driver should cleanup context only if client is in NULL state.If client is not in NULL state driver should notify that fatal error occured and move the client into invalid state. Change-Id: I041c830c39d46fbaaf9ec12f1a9d77de0f85fa9e CRs-Fixed: 258697 Signed-off-by: Gopikrishnaiah Anandan commit e662af7106510eddc6f6144df0afd54704fff1c2 Author: Ravishangar Kalyanam Date: Wed Sep 1 17:32:16 2010 -0700 msm_fb: display: Add QuickLogic MDDI panel driver Change-Id: I2829ea3c91cbb658544a46fc1de5343a9883637b Signed-off-by: Ravishangar Kalyanam commit 5b3b773b3bd38c2d70c1d97c4008d6424406d923 Author: Ashish Singhal Date: Mon Oct 4 09:45:42 2010 -0600 vidc: 720p: Removing the clock setting before enabling the clock Change-Id: I952e0bd275c9091ff9267f5a629e1323fe910364 Signed-off-by: Ashish Singhal commit ed9d41ff440649c6ad9ee15c572427d0d38b68d2 Author: Kevin Chan Date: Thu Sep 16 11:38:40 2010 -0700 camera: Support for enhanced ESD interface Once CAMIF error is detected, reset the VFE and make Camera state to ERROR. This state will prevent VFE to start again when reset ack is received. Now send a fake frame with error code to camframe which will send an instant error callback to HAL which inturn will shutdown camera preventing 6 seconds timeout. CRs-fixed: 256140 Change-Id: I925bde6d625fd60a7a25aef768baffacdf1784c6 Signed-off-by: Kevin Chan commit aabef1e74db50ce5342171daf0119c2cee77ddb8 Author: Urs Muff Date: Tue Sep 28 16:01:42 2010 -0600 msm_fb: msm_hdmi: support 3D Side-by-side mode Adding support to send 3D mode over HDMI. To turn 3D on write 1 into /sys/class/graphics/fbx/format_3d. This can be done during actual playback, switching in real-time. Change-Id: If933332b84ecbbe6b75fd896b3acf804216a6abf Signed-off-by: Urs Muff commit 7afed7369cc57382a8053cb12fade2f763df2391 Author: Matt Wagantall Date: Tue Aug 17 19:51:14 2010 -0700 msm: vidc: Enable/disable video encoder/decoder power rail as needed On newer SoC like 8x60, power to the rotator hardware must be turned off and on explicity. Introduce use of 'regulator' APIs to turn on and off power with the clocks. Previous SoC that automatically turned power on and off as part of clk_enable() and clk_disable() calls are still supported. The vidc driver assumes that if the call to regulator_get() is unsuccessful, then the rail will be controlled automatically. Change-Id: I8c0186dbd5c739c8ccadc2984684cfb5892c0e1c Signed-off-by: Matt Wagantall commit c6f5c0bd9e55d2c5931e1e44a136b3b175aa9ee0 Author: Deepika Pepakayala Date: Fri Sep 24 14:15:34 2010 -0700 msm: vidc: Support for Rate Control configuration CBR_CFR CRs Fixed: 256119 Change-Id: I8387b390ac7aefdcf34d7b3d888b3e483aef1994 Signed-off-by: Deepika Pepakayala commit 08eea16771990edacb31620aaf9f57e3afd50d8e Author: Gopikrishnaiah Anandan Date: Tue Sep 28 16:04:54 2010 -0700 vidc: 1080p: Fix for multiple decode playback. Instance id is returned by the video core when a channel is opened. Instance id was wrongly assigned by the driver to channel id, which was causing the second instance to fail. Change-Id: I064c969f7e0f9249124b2afee25b99cc7c1f0066 CRs-Fixed: 257267 Signed-off-by: Gopikrishnaiah Anandan commit 2451e66dae8ff6b5797a91209180856b301166ee Author: Gopikrishnaiah Anandan Date: Mon Sep 27 19:58:46 2010 -0700 vidc: 1080p: Output buffer requirements fix. Buffer requirements shouldn't change when start decode is called. Change-Id: Ie18920b289baf65f90f1f586322f8fcfdd5bb36d CRs-Fixed: 257427 Signed-off-by: Gopikrishnaiah Anandan commit 0760a6783ef14e12e7631aa7c000f514ec81cb29 Author: Ashray kulkarni Date: Fri Sep 24 15:16:04 2010 -0700 vidc: 1080p: Added missing error handling cases Added missing H/W error cases Change-Id: Iee24857bb99b025a28385ee1aad20e828e89641c Signed-off-by: Ashray kulkarni commit 6104cf5d17be998dc6784350096d92c71842b138 Author: Marco A Vital Yep Date: Fri Sep 24 16:47:02 2010 -0700 msm: 720p: Enable SEI & VUI metadata Enable SEI & VUI metadata to propagate picture timing and panscan data to client. Change-Id: I5f5b43552a0f8b2984a3c80e817eb3849dfaf17e Signed-off-by: Marco A Vital Yep commit 2d308c56e2fa2ccc3f0b3758970b3242f5dc68a6 Author: Nagamalleswararao Ganji Date: Sun Sep 19 15:01:37 2010 -0700 video: vidc: Fix for the VC1 AP issue VC1 AP clips are failed as the core is getting non frame data. as part of fix we are not updating the consumed bytes while parsing the sequence header for the AP clips. Change-Id: I48960ad3ecfd688a46953409f143c3f323ebea5a CRs-fixed: 256437 Signed-off-by: Nagamalleswararao Ganji commit 92df7eef80e028adfeb30445c6cbf66b1fbe830e Author: Neil Leeder Date: Tue Sep 21 17:54:34 2010 -0400 msm_fb: add qrdc lcd panel support Change-Id: Id8f57b99300075d4b4a0f7a53b222c8f9614b2ef Signed-off-by: Neil Leeder commit 65dd5e92304aa362582c72def459c04141a171c9 Author: Ravishangar Kalyanam Date: Mon Sep 13 18:36:21 2010 -0700 msm_fb: display: Add common Debugfs support for all MDP versions Change-Id: Ifd57e1d9072444678d5d325ebaee1aecbb788a43 Signed-off-by: Ravishangar Kalyanam commit 2f1e48f67af62b078300c178251804c1db8d7839 Author: Ashray kulkarni Date: Mon Sep 20 14:29:05 2010 -0700 vidc:1080p: Decoder input buffer optimizations. Changed Decoder Input buffer count and input buffer size Change-Id: I93ae5295c26d24b54c3ce3722852842df9ff3432 Signed-off-by: Ashray kulkarni commit f2c71ffd6123c48d7991a21fdb47231923819a27 Author: Ashray kulkarni Date: Wed Sep 22 11:19:12 2010 -0700 vidc:720p: Set the clk_rate before enabling the clock Change-Id: Ifd6d99142224c5ef8c9f0ede5ef20e4b3d125094 Signed-off-by: Ashray kulkarni commit 748e97a5b21ec2adf87fb92ed064fec94456e156 Author: Carlos Romanillos Date: Tue Sep 21 21:01:32 2010 -0700 vidc: 1080p: Seek till the end of file fix. Certain cases core returns dpb buffer empty for flush command, in those cases input buffer needs to be requeued. Change-Id: Ib488d6354e556175d1967103fbec9c7dac9ff419 CRs-fixed: 256436 Signed-off-by: Carlos Romanillos commit 26eac4cddb0d9a3d7dbc559c0631ee01f44942b9 Author: Marco A Vital Yep Date: Thu Sep 16 14:13:42 2010 -0700 msm: 720p: Enable comv buffer allocation for h263 decoder Enable comv buffer allocation for h263 decoder Change-Id: I5ef1f7b078c2a0aa6b2d5d48989eb11d9c960096 Signed-off-by: Marco A Vital Yep commit 71459b08e11f1c8c834912c35cb7e5dec1162fd6 Author: Marco A Vital Yep Date: Wed Sep 15 15:34:07 2010 -0700 msm: 720p: Support video portrait recording up to 720p Updates to support video portrait recording up to 720p Change-Id: I24f5e910ca9a8a359afeac40c9c467072c2e1cc2 Signed-off-by: Marco A Vital Yep commit 34a939d02afa388b911070b3b872f6f12cfabbc2 Author: Ajay Krishnaprasad Date: Tue Sep 14 13:08:24 2010 -0600 msm: video: cable detect feature for tv-out Cable detect feature for tv-out. Interrupt-driven when external display is on. Polling-driven when external display is off. Change-Id: I41e9005c61d65657b9db54531306bd664d839cde Signed-off-by: Ajay Krishnaprasad commit e9ce823d0f79b665ccc780281701f4bd92f97375 Author: Marco A Vital Yep Date: Wed Sep 15 14:56:25 2010 -0700 msm: vidc: Add support to set frame rate for decoder Add support to set frame rate for decoder and update scheduler and resource tracker according. CRs-Fixed: 253989 Change-Id: I31a7e2288a943bb440883dcec0a0b31d3ac3ffa4 Signed-off-by: Marco A Vital Yep commit 99e9d919300ab0b552b95271bcb4d52c28bc31e7 Author: Carlos Romanillos Date: Fri Sep 17 12:44:02 2010 -0700 vidc: 1080p: Disabled deblock filter. When post filter is enabled most of the mpeg4 clips are failing and firmware is complaining that buffers are not released by the app properly. Need to triage this issue separately. Change-Id: Iddeb9c68ef507aa7a5c2ba44be0b81c6b2c1deab Signed-off-by: Carlos Romanillos commit 0b23433851716783cda50d93e7e6097d853a21b8 Author: Gopikrishnaiah Anandan Date: Wed Sep 15 14:33:02 2010 -0700 msm: vidc: Handle eos & flush for decoder. When EOS with flush is sent to video core, firmware is ignoring the flush command.As a workaround, driver will generate EOS done, so that session is closed. Change-Id: I04e2e6ff0507e67cc387ec3609a82c0e3f3ab367 Signed-off-by: Gopikrishnaiah Anandan commit 8d0920f77ecbbdb2082a5a67a5cfa929a1e990d7 Author: Marco A Vital Yep Date: Fri Sep 17 15:24:27 2010 -0700 msm: vidc: Fix to update performance level in resource tracker Remove client context pointer check to update the performance level when no client pointer is passed. Change-Id: I36a71a9d9f1de4df32676417c3f370dc89917467 Signed-off-by: Marco A Vital Yep commit 128e65b4dd913d8d8c9af20ca150e1cd7d54b4ca Author: Nagamalleswararao Ganji Date: Tue Sep 14 23:04:53 2010 -0700 video: vidc: Changes to the 8660 video driver property interface. couple of encoder properties moved to dynamic properties Change-Id: Icefdb08681792160b35d9c2ad874d35cfabd9a88 Signed-off-by: Nagamalleswararao Ganji commit e3530ce520cb0622d58a0f9f8958199f16f80cd5 Author: Abhishek Kharbanda Date: Mon Sep 13 11:36:58 2010 -0700 msm_fb: HDCP feature support on 7x30 Read EDID,set HDCP start bit,set internal keys bit, wait for BKSV interrupts,read BKSV keys against revocation list,shut down A/V transmission on HDMI interface on getting HDCP controller error interrupt. Change-Id: I5cf518598f2ccde8327757e5da39f5b8de46b765 CRs-Fixed: 254800 Signed-off-by: Abhishek Kharbanda commit 207a747004c6ead4c7fe7b9d3dca789744eabf19 Author: Ajay Krishnaprasad Date: Thu Sep 16 13:01:33 2010 -0600 msm: video: featurize external interface code for hdmi and tv-out Featurized HDMI specific code to use appropriate methods and sysfs attributes. Change-Id: I9b67ec23a6c3debfc6e65e9776d05e059c3e3cd2 Signed-off-by: Ajay Krishnaprasad commit 84c26603f052a116cca0633dbb6500320a09d1c0 Author: Marco A Vital Yep Date: Thu Sep 16 14:08:07 2010 -0700 msm: vidc: Verify device sm status before pause sessions Add device sm status verification before pause all the sessions. Change-Id: Ie8d5b22841a34a6b59b396462da6e432c66b9083 Signed-off-by: Marco A Vital Yep commit 631773558e5673d9d1b8d6e39a4c46c548b6783e Author: Marco A Vital Yep Date: Thu Sep 16 14:04:53 2010 -0700 msm: vidc: Allow read properties in transition states Enable read properties by client in transition states: starting and flushing. Change-Id: Ib34db8385a780f1361f683fb38295a84c11d5472 Signed-off-by: Marco A Vital Yep commit b4ac0c10f60127dacd56b888e90b2ba9201902d7 Author: Marco A Vital Yep Date: Thu Sep 16 14:01:00 2010 -0700 msm: vidc: Propagate transaction frame type for decoder only Propagate the frame type from the transaction in the frame done callback for decoder only, DDL populates this field for encoder case. Change-Id: Ic065a6682fcb6f94760e4875d7a08e51aa0a4224 Signed-off-by: Marco A Vital Yep commit aed9026d953987b4507a7ee96d643facb52efc0b Author: Marco A Vital Yep Date: Wed Sep 15 14:36:31 2010 -0700 msm: vidc: Update frame delta calculation for encoder Update frame delta calculation for encoder to handle cases where camera sends erratic timestamps with very small delta. Change-Id: I03454066f226ef75c057eff199a1dd55b202b542 Signed-off-by: Marco A Vital Yep commit 3da74428dd36a57d4df6340e87e30cca598b5785 Author: Marco A Vital Yep Date: Wed Sep 15 13:08:47 2010 -0700 msm: 720p: Implement output decode order support Implement support for output in decode order. Change-Id: I73090b856bedb38ebf66bdc73431d7614d9899fe Signed-off-by: Marco A Vital Yep commit a6ce0fa8475b398f7402108916cdbe92c27e74a7 Author: Marco A Vital Yep Date: Wed Sep 15 12:49:53 2010 -0700 msm: 720p: Remove check to allow client read default parameters Remove conditions to allow client read default parameters Change-Id: I81f13b4410ee73cf2863ab12a049748add5cff8f Signed-off-by: Marco A Vital Yep commit b2dca140a5d46df344f52f0402cfea98349279f7 Author: Nagamalleswararao Ganji Date: Tue Sep 14 22:47:27 2010 -0700 video: vidc: Vc1 rcv support to the 8660 video driver rcv is not supported in vc1 and this change adds the support for rcv Change-Id: I9bc1df4260719c56b6df2c89c4bb3c3707acacdd Signed-off-by: Nagamalleswararao Ganji commit 6820cfcd67258601fd7f9d52d60333e13c62c647 Author: Marco A Vital Yep Date: Thu Sep 16 12:07:14 2010 -0700 msm: 720p: Disable adaptive rc flags for encoder by default Disable adaptive rc flags for encoder by default Change-Id: I3d986ff775fd11ee04f6e5c82b4613248e780d03 Signed-off-by: Marco A Vital Yep commit 546fae156eae496acfe525f00d6ee59249aa50e7 Author: Marco A Vital Yep Date: Thu Sep 16 12:06:16 2010 -0700 msm: 720p: Update vop timing resolution for non-mpeg4 encoder Update vop timing resolution for non-mpeg4 encoder Change-Id: I795b39f62b0cd98cb1e8583d497ec5a80c438fce Signed-off-by: Marco A Vital Yep commit 6806a6d77ed7fcfad06e37d9cc5cc22014ac01af Author: Marco A Vital Yep Date: Thu Sep 16 12:03:02 2010 -0700 msm: 720p: Add bitrate boundaries check for encoder Add bitrate boundaries check for encoder Change-Id: I53d00a0d16c94e6279ce47cce00a2f97ce1baf33 Signed-off-by: Marco A Vital Yep commit c2368ed51e32e78666099cf9e05cf042673f5ecd Author: Marco A Vital Yep Date: Wed Sep 15 10:47:38 2010 -0700 msm: 720p: Add dynamic intra refresh support for encoder Add dynamic intra refresh support for encoder. Change-Id: Ie610d7a483042b4b4426db411aa2fcceb052c953 Signed-off-by: Marco A Vital Yep commit 2dd86c4ce08abfb3674fa0f4448a987e911f17b8 Author: Nagamalleswararao Ganji Date: Tue Sep 14 22:33:02 2010 -0700 video: vidc: 8660 video driver memory optimizations unused buffers are removed to reduce memory Change-Id: Ief0d4891e90baf1c0e44b8e54f1199e72e17afd8 Signed-off-by: Nagamalleswararao Ganji commit 34d4c6c773d16b1065de9e2a357620c372b4dcb2 Author: Gopikrishnaiah Anandan Date: Wed Sep 15 12:45:14 2010 -0700 msm: vidc: Increase hardware timeout to 10 secs. Increased the hardware time out to 10 secs. When command is issued if core is not responding in 10 secs session will be cleaned up with device fatal error. This is required for current firmware version of 1080p core. For some clips 1080p core is taking more time to respond. Change-Id: Ia8c25b77d6f5bd078cc4de1d0b3b5018446faf79 Signed-off-by: Gopikrishnaiah Anandan commit e0d8a781a00c43726baa32864925fa04f373e534 Author: Ajay Krishnaprasad Date: Tue Sep 14 21:57:35 2010 -0600 msm: video: rename hdmi common code for reuse with tv-out Rename hdmi common as external common so that it could be reused with TV out Change-Id: I110fb77df6db097f9f60d1845b692fda5b9a1b42 Signed-off-by: Ajay Krishnaprasad commit 3c471193614eb95c7e43dfba74b1dcf1141b1b7c Author: Marco A Vital Yep Date: Wed Sep 15 10:36:09 2010 -0700 msm: vidc: Fix to handle sequence header buffer with EOS Fix to handle sequence header buffer with EOS and no reconfiguration event raised. Change-Id: I046e10d861282de24e17eceea96b4089938ce953 Signed-off-by: Marco A Vital Yep commit a15b7f6dd6b1cf772f331de06e82877b8d4e6a20 Author: Marco A Vital Yep Date: Wed Sep 15 10:12:49 2010 -0700 msm: 720p: Fix comv buffer size calculation Fix comv buffer size calculation in DDL to use stride and scan lines instead of width and height. CRs-Fixed: 253518 Change-Id: I11560a3d7fbe3b93186f5e017856dcc8d68144b4 Signed-off-by: Marco A Vital Yep commit 41b61d7eed3002dfac9d4c225781b76956a8fc6a Author: Nagamalleswararao Ganji Date: Tue Sep 14 21:17:27 2010 -0700 video: vidc: New error types are added to the video driver. New error types are added to the 8660 video driver Change-Id: I7593bb7f7ac9b663a279efe34da9fff0e6cf4adc Signed-off-by: Nagamalleswararao Ganji commit a62d12543c3f3bea529dfa92fbfcd473ef24c4db Author: Nagamalleswararao Ganji Date: Tue Sep 14 20:35:31 2010 -0700 video: vidc: Crop support is added to video driver. Crop support is added to the 8660 video driver Change-Id: I8c7397231bac3c5010d8b4cc0e9f15824114e882 Signed-off-by: Nagamalleswararao Ganji commit 7b288484a98c0c0a7aeb5e52664f4fa221b56bd7 Author: Ashray kulkarni Date: Mon Sep 13 16:27:14 2010 -0700 vidc: Added support for ConcealMB extradata Change-Id: I6c23f8756a8899a05101fa3551f964fe9d6ba249 Signed-off-by: Ashray kulkarni commit 160d42d529f7a5563bbd7cd117c83b7f434f0c22 Author: Bryan Huntsman Date: Wed Sep 8 18:01:18 2010 -0700 Initial contribution. This commit takes the MSM and driver changes from git://codeaurora.org/quic/la/kernel/msm.git:android-msm-2.6.32 and applies them on top of git://android.git.kernel.org/kernel/common.git:android-2.6.35. Signed-off-by: Bryan Huntsman commit aff28a5412ffa8cb4b87598cb8381bbe7efc8679 Author: Gopikrishnaiah Anandan Date: Tue Sep 7 16:12:31 2010 -0700 msm: vidc: Handle core warnings. Recoverable errors were being reported as fatal by driver, which leading to termination of playback. CRs-fixed: 254621 Change-Id: I9b9c6a3c0e92e36241267e9c3a1aeb43b146eb19 Signed-off-by: Gopikrishnaiah Anandan commit eaaa034ea93b9dea24aeebdda24a6f87d099a491 Author: Gopikrishnaiah Anandan Date: Fri Sep 3 16:55:20 2010 -0700 msm: vidc: Change the default input buffer size. - Input buffer size should be 4K aligned. - We set the default input buffer size to maximum resolution supported(1080p.) CRs-fixed: 254023 Change-Id: Ica6e0216765486b120beb9fc4c2df63bfdcd1101 Signed-off-by: Gopikrishnaiah Anandan commit ce0817fe24ba0dc6c267089c549d1ed1d5ad68a1 Author: Gopikrishnaiah Anandan Date: Wed Sep 1 18:15:12 2010 -0700 msm: vidc: Handle multiple decode stop command. - Handle multiple stop commands from client. - Handle usecase where driver release is called by client without calling stop. - Handle hardware timeout when stop is called in release. Change-Id: I461efe0de1b3b203ae2e736541f92373b0a4edc7 Signed-off-by: Gopikrishnaiah Anandan commit 750c7abed0995878cda089697d8bff2a10aa5c16 Author: Marco A Vital Yep Date: Wed Sep 1 18:21:18 2010 -0700 msm: 720p: Fix for grey fade out issue for h263 codec Fix grey fade out issue for h263 when reconfig is not happening. Change-Id: I9ac455c450f5f7eec52e2ceb4ab1b626ef222ff5 Signed-off-by: Marco A Vital Yep commit 8b41367efcee71aaf25c69f5e22f7969b7190d57 Author: Carlos Romanillos Date: Tue Aug 31 13:18:30 2010 -0700 vidc: dec: 1080p clock scaling work around. As a workaround for clock scaling the 1080p core clocks are always set. Change-Id: Iad50ba1b650e4414d12f9ba8c7cde7bf944b1d3f CRs-Fixed: 253533 Signed-off-by: Carlos Romanillos commit 9aa17462f1d3d201c32a7b942919d974c1ebb943 Author: Kalyani Oruganti Date: Wed Aug 25 20:28:52 2010 -0700 camera: To add support for strobe and LED flash. This change adds the functionality for LED and Xenon strobe flash. Change-Id: I9cd1d4e696cd1971e8c3c3c7e4c6cdd0a3d7d5bc Signed-off-by: Kalyani Oruganti commit a92c2dee2d51acbcdaece820500ee2815528a15e Author: Marco A Vital Yep Date: Tue Aug 31 16:59:45 2010 -0700 msm: vidc: Fix first output received flag for reconfig Fix first output received flag for reconfig scenario. Change-Id: Ia2443455ee685d1f26352facf7d70f48fd762592 CRs-Fixed: 253623 Signed-off-by: Marco A Vital Yep commit 5a6964716f3bb6e3c9274162622b5dfcfaf9a667 Author: Carlos Romanillos Date: Mon Aug 30 20:27:50 2010 -0700 vidc: vcd: Free buffer pool fix. Free buffer pool without iterating over already blank items, only reset list head. Change-Id: I177293f4a18e12a1cf02374bde31607b4d3e393e Signed-off-by: Carlos Romanillos commit 34eefcb285e0ed232b86c165aa8de2ea8d397bb9 Author: Deepika Pepakayala Date: Fri Aug 27 16:24:18 2010 -0700 msm: vidc: Support for VC1 simple and main profiles (RCV) Add codec index for VC1 RCV. Change-Id: I964c7ce02fc304220a3c52bc084d3b8365a2f8a6 Signed-off-by: Deepika Pepakayala commit 444aa5a8324427cc42f7d757ad8eef42b22838c2 Author: Ajay Krishnaprasad Date: Thu Aug 26 11:37:40 2010 -0600 msm: video: sysfs support for TV out driver and replace old files TV out driver with sysfs support for switching video modes. Merged files for better management of sysfs attributes for TV out Change-Id: I3f71e8f92a3e420762190824265ad4209bd3f42d Signed-off-by: Ajay Krishnaprasad commit ccddd0db8976f06bdfa813fc6b4e1fc402fe85d5 Author: Marco A Vital Yep Date: Thu Aug 26 14:53:16 2010 -0700 msm: vdec: Add DivX 3 codec index Add DivX 3 codec index to support 3.11 content in 8660 Change-Id: I08008109a5ae73aecae8bafecac6df8635d76d10 Signed-off-by: Marco A Vital Yep commit 307aed551ec3f2c08c4445a2c77a915f98278c3a Author: Gopikrishnaiah Anandan Date: Thu Aug 26 16:02:12 2010 -0700 vidc: 1080p: Reconfig fixes for 1080p decoder. Raise the reconfig event if any of frame size,stride,scan lines are modified. Change-Id: Ib951b70f2c5c48302a9ca9c33774def78e9bb6d9 Signed-off-by: Gopikrishnaiah Anandan commit 690317ef813b9ad5bc9cd303283924da4b53beff Author: Nagamalleswararao Ganji Date: Tue Aug 24 20:58:09 2010 -0700 msm: vidc: Videco core clock scaling changes for 8660 Added video core clock scaling for 8660 video driver Change-Id: I1e34d8ec5bee5b244452d7ac98ce7e79aa52912d Signed-off-by: Nagamalleswararao Ganji commit 56e744c769b9f76f25542ff3763a8f5b553c53c8 Author: Nagamalleswararao Ganji Date: Tue Aug 24 13:59:16 2010 -0700 msm: vidc: Input Format type Fix for 8660 encoder. NV12_16M2KA format is added for KAD layer to support input format type for 8660 encoder Change-Id: I13dedc9789f673b2f0c93c546f7397adf8c3f4d0 Signed-off-by: Nagamalleswararao Ganji commit dec207bf6bd3c32c1965b07bd53ab7143c058741 Author: Mansi Patel Date: Thu Jul 22 13:22:44 2010 -0600 msm: video: 8660 HDMI TX / PHY kernel driver: HDCP Adding HDCP support Change-Id: I6f6f9a6cd3f3b0ed62973095a5abb91c9fb69583 Signed-off-by: Mansi Patel commit e28154c9723ee7d232e7a9aab42a4d24b3390c3d Author: Urs Muff Date: Tue Aug 10 10:01:42 2010 -0600 msm: video: HDMI common code Move common HDMI code into hdmi_common.c so that it can be reused by 7x30 and other HDMI drivers. Change-Id: I41ecc78f9e68e8f80b3ce8da41eb27244e5b101d Signed-off-by: Urs Muff commit 6a2e3fc2cc64ae4e1b8ad30614271bd0f4e840bf Author: kuogee hsieh Date: Wed Jul 7 15:09:53 2010 -0700 msm_fb: display: Add mipi dsi display panel support Add mipi dsi both video and command mode display support by adding mipi dsi host, mipi dsi client and display panel drivers. Change-Id: I67d6d6881993c021706f07d96b02902c9393f7d9 Signed-off-by: Kuogee Hsieh commit b9a7552d34c82d411018b77c21d5cffe3be6886b Author: Marco A Vital Yep Date: Mon Aug 23 19:51:59 2010 -0700 msm: vidc: Add interlace format support - Add code in DDL to report a reconfiguration event when the format detected is not progressive (interlace detected). - Add code in KAD to support interlace/progressive query from the client. Change-Id: Ibf43d17f13a6f44550ba93b8d4d87ea4bde153cf Signed-off-by: Marco A Vital Yep commit 6939c313498e53d7b8810d10cf646bf75da3e1dd Author: Marco A Vital Yep Date: Mon Aug 23 19:02:00 2010 -0700 msm: vidc: Implement logic to handle reconfiguration in EOS Implement logic to handle properly a reconfiguration event when the eos has been received. Change-Id: Idcda8dbb225c717a55dd6a5cdb59b19708a9516b Signed-off-by: Marco A Vital Yep commit a0aad1ddc08f8490e8a7d722c5c638bca40e83da Author: Marco A Vital Yep Date: Thu Aug 19 17:27:38 2010 -0700 msm: vdec: Free remaining client messages in driver release. Free remaining client messages in video driver release to fix memory leak. Change-Id: Ief264501ceb9860c50f792ae0a5967a9b7866bb1 Signed-off-by: Marco A Vital Yep commit 5893e2088d9e7d5931648b8424672452c54b14bc Author: Sunid Wilson Date: Fri Aug 20 01:43:59 2010 -0700 msm: camera: Live snapshot feature support Added output type for live snapshot frame to distinguish it from video frame and code for propagating the frame to userspace. Change-Id: Ic7530fa2b143293ae663f91e618953b5c04d384f Signed-off-by: Sunid Wilson commit ef6af7d7b2fdc2e3770238f010a01551a8507a16 Author: Marco A Vital Yep Date: Fri Aug 13 10:45:12 2010 -0700 vidc: 1080p: Update default decoder input buffer requirements Update the default actual count and buffer size for the decoder input buffer requirements. This fixes the scenario when the client set the frame size and the buffer requirements are recalculated. Change-Id: Idc701fd1ae2b80c5924ccb816eec11496b10beae Signed-off-by: Marco A Vital Yep commit 9d252b35b2d392369bae3eff71dc64f451fbeb50 Author: Marco A Vital Yep Date: Fri Aug 13 10:19:09 2010 -0700 vidc: 720p: Update default decoder input buffer requirements Update the default actual count and buffer size for the decoder input buffer requirements. This fixes the scenario when the client set the frame size and the buffer requirements are recalculated. Change-Id: I7ef8cd61c9af256869e4224e1116518c09dd4454 Signed-off-by: Marco A Vital Yep commit 58b1152d7d51363d74c96ec3bbeaef018c87b27a Author: Marco A Vital Yep Date: Fri Aug 13 15:32:20 2010 -0700 vidc: 720p: Update default encoder input buffer requirements Update the default number of buffers for encoder to 8 input and 5 output buffers. Change-Id: I36e0c656a68c19db6c99ca67abdb06e211886227 Signed-off-by: Marco A Vital Yep commit 5c28aa36bf36b5a5f2f19e3932fe9dde43f97a73 Author: Marco A Vital Yep Date: Tue Aug 10 17:08:11 2010 -0700 vidc: 720p: Fix to update the output tokens in ftb. - Fix to update the output tokens before try to submit a frame when an output buffer is received. Change-Id: I964bbdb0be7d6b4ad8ecb31d3c9585755acb3de0 Signed-off-by: Marco A Vital Yep commit 0703df21832ee8a1da621228e30f9fe838a23bbf Author: Marco A Vital Yep Date: Thu Aug 5 15:56:54 2010 -0700 msm: vidc: Fixes to handle errors and commands at EOS Fixes to handle pause-resume sequence, recoverable errors in eos state and propagate the eos done event to client when not output buffer is available. Change-Id: Ibc0042779d51da474bd3330235cf2a834ee7a22e Signed-off-by: Marco A Vital Yep commit 9a0a181271c96220f24cc2fab49fee3593b3a0d0 Author: Marco A Vital Yep Date: Thu Aug 12 16:32:11 2010 -0700 vidc: 720p: Add error concealment register Add error concealment register. Change-Id: Ibf3c44293b9428a74d316ace0def7cbdf72d4cca Signed-off-by: Marco A Vital Yep commit d3fd017fc21087f098ba7714b5a92064f1b93efa Author: Marco A Vital Yep Date: Thu Aug 12 16:07:01 2010 -0700 msm: vidc: Add processing mask and updates for reconfiguration - Add mask to remove multiple boolean flags - Add flag to handle ftb while reconfiguration is in progress - Handle the case when the scheduler structure already exists when the client is added - Remove old scheduler macros Change-Id: Idd65dfdf0e304c704977d6c9981105847172f941 Signed-off-by: Marco A Vital Yep commit bda3be1685fb70052f8827c56fb81c420af6d2a0 Author: Marco A Vital Yep Date: Thu Aug 12 15:28:52 2010 -0700 vidc: 720p: Add support for reconfiguration at any time The changes to add support for reconfiguartion at any time are: - Move DDL cmd to EOS to flush remaining buffers with hw - Read resolution change register when FW is done to identify if process is complete because of a real EOS or a reconfiguration is in progress. - Increase H264 VSP buffer size and moved to init codec Change-Id: I79686d422d4905d083f70b18973ea6bd9c446ac5 Signed-off-by: Marco A Vital Yep commit 0af975339191d66dbffd55707e5828ad5d375e57 Author: Marco A Vital Yep Date: Thu Aug 12 14:55:01 2010 -0700 msm: vidc: Update transaction, error and input buffers handling - Add logic to verify the received transaction exists in the transactions table - Replace assignments with the function to release transactions - Release transaction & command channel when stop is done for invalid state - Add error handling for eos functions - Add logic to handle separately the cases when an empty buffer or one with null virtual address is received - Move logic to handle frame with VCD_FRAME_FLAG_CODECCONFIG flag to decoder specific condition and reset this flag Change-Id: I0fdac229ea41bcbe019132efa11c015a66e4fc86 Signed-off-by: Marco A Vital Yep commit 685d33b75877e12e0c6318a9d3e6442f2804ad4b Author: Marco A Vital Yep Date: Thu Aug 12 14:25:57 2010 -0700 vidc: 720p: Updates parameters and calculations in DDL. - Set recommended parameters for high quality H264 encoding - Set multislice default size as 0 (multislice OFF) - Update DDL_I_FRAME_PROC_UNITS and yuv buffer size calculation Change-Id: I37d8cebbbac070361b3ae41ead1462f0fdb53796 Signed-off-by: Marco A Vital Yep commit 96a030255f62913472edcdd1d074030a86781619 Author: Marco A Vital Yep Date: Tue Jul 27 17:03:44 2010 -0700 vidc: 720p: Remove invalid interrupt and assert messages. Remove invalid interrupt status and assert messages. Change-Id: Iee3aae462227ebf2900d2dd64c34727dbf5f0583 Signed-off-by: Marco A Vital Yep commit 08a4c2ca97a85a15a40441b17a328a252d930e01 Author: Marco A Vital Yep Date: Fri Jul 23 19:31:02 2010 -0700 vidc: 720p: Fix green line on top of video for stage fright. Fix green line on top of video for stage fright when the width and height set by the client doesn't match with the stride and scan-line parsed from the header. Change-Id: I8c96aad5692e0845bcb22e76978153d7f8af62da Signed-off-by: Marco A Vital Yep commit 782f0632da67164210d7edbadc43e8c28d143553 Author: Gopikrishnaiah Anandan Date: Tue Aug 10 17:52:22 2010 -0700 msm: vidc: Video driver cleanup Remove type hint from variable names. Change-Id: I9ef779fd82635bbcd7886444943af0d302b358d0 Signed-off-by: Gopikrishnaiah Anandan commit 5455b12c4d410da95dd8a90f9934d494c122bd2c Author: Gopikrishnaiah Anandan Date: Mon Aug 9 18:52:09 2010 -0700 msm: vidc: Move 720p video driver into msm folder. Moved the 720p driver files from drivers/misc/vidc to drivers/video/msm/vidc Change-Id: I27cfd2e9258a95e9190ce0fec37fad2265fba8eb Signed-off-by: Gopikrishnaiah Anandan commit 9a04b5201fe5af031ef0f91f40ff620fab39aaa7 Author: Jignesh Mehta Date: Tue Aug 10 22:23:35 2010 -0700 camera: Add support for video preprocessing engine for VFE 3.1 Include support for video preprocessing engine for VFE 3.1. Change-Id: I82101ccf2fa26aab21c7a95a342d247b0c334a06 Signed-off-by: Jignesh Mehta commit 9724e0deb88d0961c630d6fcb6e9a7d76702716e Author: Gopikrishnaiah Anandan Date: Fri Aug 6 14:17:17 2010 -0700 msm: vidc: Converge 1080p & 720p driver common code. As part of converging to a common driver base for 720p and 1080p core,these changes were pulled from 720p to 1080p common folder. Change-Id: I2aef25b8927a8802935cceac7c886c060664050a Signed-off-by: Gopikrishnaiah Anandan commit 6e8a672946e445d7e278b9524c0c9b4a1b2b160c Author: Gopikrishnaiah Anandan Date: Wed Aug 4 11:40:02 2010 -0700 msm: vidc: Reduce Max clock freq of video core. Bumping down max clock frequency to 200Mhz. Change-Id: I2d6352aa8d80d2a8bf712a0c0538c6a8f0b08168 Signed-off-by: Gopikrishnaiah Anandan commit 10280429cb8a5709cfe2d1e75a6be93eaf3fa576 Author: Nagamalleswararao Ganji Date: Fri Jul 30 18:37:43 2010 -0700 msm: vidc: disabling the clock gating for 8660 video core. disabled the clock gating at frame level for 8660 video core Change-Id: Iaf660df1f55748eaea683d5bc35dfdc413ad7630 Signed-off-by: Nagamalleswararao Ganji commit c5cdaaa58e7b1bd6da45f4ab14caf749a9dc21cf Author: kuogee hsieh Date: Fri Jul 30 16:04:45 2010 -0700 msm_fb: display: make TV_OUT is not set by default Make TV_OUT configure is not set at default configure setting to avoid confliction with DTV. Change-Id: I95b51f38ea9fcb3178639a161822880fe370059f Signed-off-by: Kuogee Hsieh commit 1a9a814f18cdee2ff2b07b18222d5b6f6a0438ef Author: Urs Muff Date: Wed Jun 9 11:32:37 2010 -0600 msm: video: 8660 HDMI TX / PHY kernel driver. Setup PHY and TX Core, and adding FB_MSM device. Handle Power on/off events by the controlling panel. HDMI Audio support (2 channel, 48kHz) HDMI SWI debug support (enabled by default until feature complete) MDP-DTV debug support (needs to be enabled) Change-Id: I74cdfe1489f8a981efa7b415f6f7ee0507643fe1 Signed-off-by: Urs Muff commit 86b810f046b0d76146d46ae720dbbdc18fee4d5c Author: Ravi Bandi Date: Mon Jul 12 15:16:38 2010 -0700 msm_fb: MDP4 Analog TV support Add an RGB pipe as base layer to blend with a VG pipe to carry Analog TV YUV format and put it to tv encoder through dma_e dma engine. CRs-fixed: 241816 Change-Id: I847a7eeafe6f4b1b9977e144374eb3c1a6a2498a Signed-off-by: Kuogee Hsieh commit 8834d94ad6a82fc4c668a9197792b64a487e4894 Author: Gopikrishnaiah Anandan Date: Fri Jul 9 18:13:18 2010 -0700 vidc: 1080p: Update resource tracker Change-Id: I6fbe36ec33c50c48ce57102efec761f6404e4c25 Signed-off-by: Gopikrishnaiah Anandan commit 2a228e7612135c700d75917a69668942d8910d43 Author: Nagamalleswararao Ganji Date: Wed Jun 16 09:59:15 2010 -0700 msm: vidc: 1080p video driver support for 8660 1080p video driver support is added for 8660 Change-Id: I0e2a491dd32d2a8eeee5d65cd70a7fe4fa719678 Signed-off-by: Nagamalleswararao Ganji commit 6e171f11960234827f335fb0be0ff777cfa752f8 Author: Nagamalleswararao Ganji Date: Wed Jul 7 23:21:19 2010 -0700 include: linux: Level4 support for H264 encoder Interface Level4 support is added for the H264 encoder Interface Change-Id: Ib8d2c9bc664db5d3414cc68f81b10bebd5090a8d Signed-off-by: Nagamalleswararao Ganji commit afca0b48329ef4d35de4fc8dc9b87aaf4ec14f55 Author: Yen-Pin Hsiao Date: Fri Apr 9 15:46:15 2010 -0700 msm7x30: camera: Sony 12MP Bayer sensor support. Addition of new files for supporting Sony 12 MP Bayer sensor. Change-Id: I45133ff8140b040cc1974ba7e636fb2470c0cf62 Signed-off-by: Yen-Pin Hsiao commit b8edd675c91c8f6f92a6067356cacf01dff95393 Author: Jordan Crouse Date: Mon Jun 28 11:08:34 2010 -0600 msm_fb: Set the default color depth from the kernel config Make the default color depth for the framebuffer configurable via the kernel config. Default is RGB565, but ARGB8888 and RGBA8888 are available. Signed-off-by: Jordan Crouse commit 91277807c75b4ed9844441da31d9a49c990c1334 Author: kuogee hsieh Date: Fri Jun 4 08:19:58 2010 -0700 msm_fb: display: Add FB_MSM_OVERLAY dependency Add FB_MSM_OVERLAY dependency to FB_MSM_HDMI_ADV7520_PANEL to fix compiler error when FB_MSM_OVERLAY is not defined. CRs-fixed: 240734 Change-Id: I948b2b198f69ada3dfb2eb4903363230a48935aa Signed-off-by: Kuogee Hsieh commit a54aac47e202993920fae8e9297e6bf59221b765 Author: Ajay Dudani Date: Wed Jun 2 18:40:14 2010 -0700 msm_fb: Add ST1.5 LCDC driver Change-Id: Ia592bed81e316118f4c301ad59931fb9502ce49e Signed-off-by: Ajay Dudani commit f95c6bd8c07d38466c51d2c245aeaac3aac189d8 Author: Abhijeet Dharmapurikar Date: Fri Apr 2 13:11:55 2010 -0700 msm_fb: display: Add panel driver for wsvga display Add code for the Samsung's wsvga panel (part number LTS480WS-C01). It has a resolution of 1024 x 600 pixels, runs over an LVDS interface and accepts RGB666 pixel data. Change-Id: I399a0c08257a645fe205d5f3cb766e7dfbf20121 Signed-off-by: Abhijeet Dharmapurikar commit b239b82c8efa23759c5ab320cb2cb648b133e2fd Author: Jeremy Gebben Date: Wed May 12 12:05:15 2010 -0600 msm: kgsl: move to drivers/gpu/msm This location was recommended by google and matches where other chipset vendors are putting their gpu drivers for android. Change-Id: I1a1620871e5121363c8a080b80ec25d725065e4c Signed-off-by: Jeremy Gebben --- drivers/video/Kconfig | 8 +- drivers/video/msm/Kconfig | 3 + drivers/video/msm/Makefile | 3 + drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c | 718 +++ drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h | 493 ++ .../video/msm/vidc/1080p/ddl/vcd_ddl_api.h | 120 + .../video/msm/vidc/1080p/ddl/vcd_ddl_core.h | 156 + .../video/msm/vidc/1080p/ddl/vcd_ddl_errors.c | 771 +++ .../video/msm/vidc/1080p/ddl/vcd_ddl_helper.c | 1074 ++++ .../1080p/ddl/vcd_ddl_interrupt_handler.c | 2042 ++++++++ .../msm/vidc/1080p/ddl/vcd_ddl_metadata.c | 508 ++ .../msm/vidc/1080p/ddl/vcd_ddl_metadata.h | 66 + .../msm/vidc/1080p/ddl/vcd_ddl_properties.c | 2113 ++++++++ .../msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c | 876 ++++ .../msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h | 196 + .../video/msm/vidc/1080p/ddl/vcd_ddl_utils.c | 518 ++ .../video/msm/vidc/1080p/ddl/vcd_ddl_utils.h | 78 + .../video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c | 1182 +++++ drivers/video/msm/vidc/1080p/ddl/vidc.c | 1108 ++++ drivers/video/msm/vidc/1080p/ddl/vidc.h | 586 +++ drivers/video/msm/vidc/1080p/ddl/vidc_hwio.h | 115 + .../video/msm/vidc/1080p/ddl/vidc_hwio_reg.h | 4544 +++++++++++++++++ .../video/msm/vidc/1080p/ddl/vidc_pix_cache.c | 349 ++ .../video/msm/vidc/1080p/ddl/vidc_pix_cache.h | 87 + .../1080p/resource_tracker/vcd_res_tracker.c | 1023 ++++ .../1080p/resource_tracker/vcd_res_tracker.h | 78 + .../resource_tracker/vcd_res_tracker_api.h | 53 + drivers/video/msm/vidc/720p/ddl/vcd_ddl.c | 628 +++ drivers/video/msm/vidc/720p/ddl/vcd_ddl.h | 292 ++ drivers/video/msm/vidc/720p/ddl/vcd_ddl_api.h | 53 + .../video/msm/vidc/720p/ddl/vcd_ddl_core.h | 99 + .../video/msm/vidc/720p/ddl/vcd_ddl_errors.c | 609 +++ .../msm/vidc/720p/ddl/vcd_ddl_firmware.c | 352 ++ .../msm/vidc/720p/ddl/vcd_ddl_firmware.h | 53 + drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c | 971 ++++ .../video/msm/vidc/720p/ddl/vcd_ddl_helper.c | 297 ++ .../vidc/720p/ddl/vcd_ddl_internal_property.h | 81 + .../vidc/720p/ddl/vcd_ddl_interrupt_handler.c | 1130 ++++ .../msm/vidc/720p/ddl/vcd_ddl_metadata.c | 580 +++ .../msm/vidc/720p/ddl/vcd_ddl_metadata.h | 79 + .../msm/vidc/720p/ddl/vcd_ddl_properties.c | 1943 +++++++ .../video/msm/vidc/720p/ddl/vcd_ddl_utils.c | 242 + .../video/msm/vidc/720p/ddl/vcd_ddl_utils.h | 60 + drivers/video/msm/vidc/720p/ddl/vidc.c | 804 +++ drivers/video/msm/vidc/720p/ddl/vidc.h | 2705 ++++++++++ .../720p/resource_tracker/vcd_res_tracker.c | 771 +++ .../720p/resource_tracker/vcd_res_tracker.h | 57 + .../resource_tracker/vcd_res_tracker_api.h | 43 + drivers/video/msm/vidc/Kconfig | 39 + drivers/video/msm/vidc/Makefile | 62 + drivers/video/msm/vidc/common/dec/vdec.c | 2380 +++++++++ .../video/msm/vidc/common/dec/vdec_internal.h | 45 + drivers/video/msm/vidc/common/enc/venc.c | 1650 ++++++ .../video/msm/vidc/common/enc/venc_internal.c | 1995 ++++++++ .../video/msm/vidc/common/enc/venc_internal.h | 154 + .../video/msm/vidc/common/init/vidc_init.c | 929 ++++ .../msm/vidc/common/init/vidc_init_internal.h | 41 + drivers/video/msm/vidc/common/vcd/vcd.h | 400 ++ drivers/video/msm/vidc/common/vcd/vcd_api.c | 986 ++++ .../video/msm/vidc/common/vcd/vcd_client_sm.c | 1884 +++++++ .../video/msm/vidc/common/vcd/vcd_client_sm.h | 110 + drivers/video/msm/vidc/common/vcd/vcd_core.h | 228 + .../video/msm/vidc/common/vcd/vcd_device_sm.c | 1218 +++++ .../video/msm/vidc/common/vcd/vcd_device_sm.h | 96 + .../video/msm/vidc/common/vcd/vcd_power_sm.c | 366 ++ .../video/msm/vidc/common/vcd/vcd_power_sm.h | 43 + .../video/msm/vidc/common/vcd/vcd_scheduler.c | 287 ++ drivers/video/msm/vidc/common/vcd/vcd_sub.c | 3433 +++++++++++++ drivers/video/msm/vidc/common/vcd/vcd_util.c | 106 + drivers/video/msm/vidc/common/vcd/vcd_util.h | 52 + include/linux/msm_mdp.h | 80 +- include/linux/msm_vidc_dec.h | 568 +++ include/linux/msm_vidc_enc.h | 617 +++ include/media/msm/vcd_api.h | 158 + include/media/msm/vcd_property.h | 372 ++ include/media/msm/vcd_status.h | 61 + include/media/msm/vidc_init.h | 100 + include/media/msm/vidc_type.h | 30 + include/media/msm_camera.h | 19 + include/media/msm_v4l2_overlay.h | 9 + include/uapi/Kbuild | 1 + include/uapi/linux/Kbuild | 1 + include/uapi/linux/msm_mdp.h | 480 ++ include/uapi/media/Kbuild | 1 + include/uapi/media/msm_camera.h | 2266 ++++++++ 85 files changed, 51914 insertions(+), 70 deletions(-) create mode 100644 drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c create mode 100644 drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h create mode 100644 drivers/video/msm/vidc/1080p/ddl/vcd_ddl_api.h create mode 100644 drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h create mode 100644 drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c create mode 100644 drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c create mode 100644 drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c create mode 100644 drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c create mode 100644 drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.h create mode 100644 drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c create mode 100644 drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c create mode 100644 drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h create mode 100644 drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c create mode 100644 drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h create mode 100644 drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c create mode 100644 drivers/video/msm/vidc/1080p/ddl/vidc.c create mode 100644 drivers/video/msm/vidc/1080p/ddl/vidc.h create mode 100644 drivers/video/msm/vidc/1080p/ddl/vidc_hwio.h create mode 100644 drivers/video/msm/vidc/1080p/ddl/vidc_hwio_reg.h create mode 100644 drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.c create mode 100644 drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.h create mode 100644 drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c create mode 100644 drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h create mode 100644 drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h create mode 100644 drivers/video/msm/vidc/720p/ddl/vcd_ddl.c create mode 100644 drivers/video/msm/vidc/720p/ddl/vcd_ddl.h create mode 100644 drivers/video/msm/vidc/720p/ddl/vcd_ddl_api.h create mode 100644 drivers/video/msm/vidc/720p/ddl/vcd_ddl_core.h create mode 100644 drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c create mode 100644 drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.c create mode 100644 drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.h create mode 100644 drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c create mode 100644 drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c create mode 100644 drivers/video/msm/vidc/720p/ddl/vcd_ddl_internal_property.h create mode 100644 drivers/video/msm/vidc/720p/ddl/vcd_ddl_interrupt_handler.c create mode 100644 drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.c create mode 100644 drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.h create mode 100644 drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c create mode 100644 drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c create mode 100644 drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.h create mode 100644 drivers/video/msm/vidc/720p/ddl/vidc.c create mode 100644 drivers/video/msm/vidc/720p/ddl/vidc.h create mode 100644 drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c create mode 100644 drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h create mode 100644 drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h create mode 100644 drivers/video/msm/vidc/Kconfig create mode 100644 drivers/video/msm/vidc/Makefile create mode 100644 drivers/video/msm/vidc/common/dec/vdec.c create mode 100644 drivers/video/msm/vidc/common/dec/vdec_internal.h create mode 100644 drivers/video/msm/vidc/common/enc/venc.c create mode 100644 drivers/video/msm/vidc/common/enc/venc_internal.c create mode 100644 drivers/video/msm/vidc/common/enc/venc_internal.h create mode 100644 drivers/video/msm/vidc/common/init/vidc_init.c create mode 100644 drivers/video/msm/vidc/common/init/vidc_init_internal.h create mode 100644 drivers/video/msm/vidc/common/vcd/vcd.h create mode 100644 drivers/video/msm/vidc/common/vcd/vcd_api.c create mode 100644 drivers/video/msm/vidc/common/vcd/vcd_client_sm.c create mode 100644 drivers/video/msm/vidc/common/vcd/vcd_client_sm.h create mode 100644 drivers/video/msm/vidc/common/vcd/vcd_core.h create mode 100644 drivers/video/msm/vidc/common/vcd/vcd_device_sm.c create mode 100644 drivers/video/msm/vidc/common/vcd/vcd_device_sm.h create mode 100644 drivers/video/msm/vidc/common/vcd/vcd_power_sm.c create mode 100644 drivers/video/msm/vidc/common/vcd/vcd_power_sm.h create mode 100644 drivers/video/msm/vidc/common/vcd/vcd_scheduler.c create mode 100644 drivers/video/msm/vidc/common/vcd/vcd_sub.c create mode 100644 drivers/video/msm/vidc/common/vcd/vcd_util.c create mode 100644 drivers/video/msm/vidc/common/vcd/vcd_util.h create mode 100644 include/linux/msm_vidc_dec.h create mode 100644 include/linux/msm_vidc_enc.h create mode 100644 include/media/msm/vcd_api.h create mode 100644 include/media/msm/vcd_property.h create mode 100644 include/media/msm/vcd_status.h create mode 100644 include/media/msm/vidc_init.h create mode 100644 include/media/msm/vidc_type.h create mode 100644 include/media/msm_camera.h create mode 100644 include/media/msm_v4l2_overlay.h create mode 100644 include/uapi/linux/msm_mdp.h create mode 100644 include/uapi/media/Kbuild create mode 100644 include/uapi/media/msm_camera.h diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index da4766b456f0..a0afc6ebb059 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -2349,13 +2349,6 @@ config FB_PRE_INIT_FB Select this option if display contents should be inherited as set by the bootloader. -config FB_MSM - tristate "MSM Framebuffer support" - depends on FB && ARCH_MSM - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - config FB_MX3 tristate "MX3 Framebuffer support" depends on FB && MX3_IPU @@ -2472,6 +2465,7 @@ config FB_SIMPLE through device tree, or potentially plain old platform data in the future. +source "drivers/video/msm/Kconfig" source "drivers/video/omap/Kconfig" source "drivers/video/omap2/Kconfig" source "drivers/video/exynos/Kconfig" diff --git a/drivers/video/msm/Kconfig b/drivers/video/msm/Kconfig index f5e3093ffeb1..b8d1df8d29bf 100644 --- a/drivers/video/msm/Kconfig +++ b/drivers/video/msm/Kconfig @@ -1,3 +1,6 @@ + +source "drivers/video/msm/vidc/Kconfig" + config FB_MSM tristate "MSM Framebuffer support" depends on FB && ARCH_MSM diff --git a/drivers/video/msm/Makefile b/drivers/video/msm/Makefile index 0a37cf3a78ae..b2ecb083b9f2 100644 --- a/drivers/video/msm/Makefile +++ b/drivers/video/msm/Makefile @@ -181,6 +181,9 @@ obj-$(CONFIG_FB_MSM_EXTMDDI_SVGA) += mddi_ext_lcd.o obj-$(CONFIG_FB_MSM_WRITEBACK_MSM_PANEL) += mdp4_wfd_writeback_panel.o obj-$(CONFIG_FB_MSM_WRITEBACK_MSM_PANEL) += mdp4_wfd_writeback.o obj-$(CONFIG_FB_MSM_WRITEBACK_MSM_PANEL) += mdp4_overlay_writeback.o + +obj-$(CONFIG_MSM_VIDC_1080P) += vidc/ +obj-$(CONFIG_MSM_VIDC_720P) += vidc/ else obj-$(CONFIG_FB_MSM_EBI2) += ebi2_host.o obj-$(CONFIG_FB_MSM_EBI2) += ebi2_lcd.o diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c new file mode 100644 index 000000000000..ac002e12685c --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.c @@ -0,0 +1,718 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#include +#include "vcd_ddl.h" +#include "vcd_ddl_metadata.h" +#include "vcd_res_tracker_api.h" + +static unsigned int first_time; + +u32 ddl_device_init(struct ddl_init_config *ddl_init_config, + void *client_data) +{ + struct ddl_context *ddl_context; + u32 status = VCD_S_SUCCESS; + void *ptr = NULL; + DDL_MSG_HIGH("ddl_device_init"); + + if ((!ddl_init_config) || (!ddl_init_config->ddl_callback) || + (!ddl_init_config->core_virtual_base_addr)) { + DDL_MSG_ERROR("ddl_dev_init:Bad_argument"); + return VCD_ERR_ILLEGAL_PARM; + } + ddl_context = ddl_get_context(); + if (DDL_IS_INITIALIZED(ddl_context)) { + DDL_MSG_ERROR("ddl_dev_init:Multiple_init"); + return VCD_ERR_ILLEGAL_OP; + } + if (!DDL_IS_IDLE(ddl_context)) { + DDL_MSG_ERROR("ddl_dev_init:Ddl_busy"); + return VCD_ERR_BUSY; + } + memset(ddl_context, 0, sizeof(struct ddl_context)); + DDL_BUSY(ddl_context); + if (res_trk_get_enable_ion()) { + DDL_MSG_LOW("ddl_dev_init:ION framework enabled"); + ddl_context->video_ion_client = + res_trk_get_ion_client(); + if (!ddl_context->video_ion_client) { + DDL_MSG_ERROR("ION client create failed"); + return VCD_ERR_ILLEGAL_OP; + } + } + ddl_context->ddl_callback = ddl_init_config->ddl_callback; + if (ddl_init_config->interrupt_clr) + ddl_context->interrupt_clr = + ddl_init_config->interrupt_clr; + ddl_context->core_virtual_base_addr = + ddl_init_config->core_virtual_base_addr; + ddl_context->client_data = client_data; + ddl_context->ddl_hw_response.arg1 = DDL_INVALID_INTR_STATUS; + + ddl_context->frame_channel_depth = VCD_FRAME_COMMAND_DEPTH; + + DDL_MSG_LOW("%s() : virtual address of core(%x)\n", __func__, + (u32) ddl_init_config->core_virtual_base_addr); + vidc_1080p_set_device_base_addr( + ddl_context->core_virtual_base_addr); + ddl_context->cmd_state = DDL_CMD_INVALID; + ddl_client_transact(DDL_INIT_CLIENTS, NULL); + ddl_context->fw_memory_size = + DDL_FW_INST_GLOBAL_CONTEXT_SPACE_SIZE; + if (res_trk_get_firmware_addr(&ddl_context->dram_base_a)) { + DDL_MSG_ERROR("firmware allocation failed"); + ptr = NULL; + } else { + ptr = (void *)ddl_context->dram_base_a.virtual_base_addr; + } + if (!ptr) { + DDL_MSG_ERROR("Memory Aocation Failed for FW Base"); + status = VCD_ERR_ALLOC_FAIL; + } else { + DDL_MSG_LOW("%s() : physical address of base(%x)\n", + __func__, (u32) ddl_context->dram_base_a.\ + align_physical_addr); + ddl_context->dram_base_b.align_physical_addr = + ddl_context->dram_base_a.align_physical_addr; + ddl_context->dram_base_b.align_virtual_addr = + ddl_context->dram_base_a.align_virtual_addr; + } + if (!status) { + ddl_context->metadata_shared_input.mem_type = DDL_FW_MEM; + ptr = ddl_pmem_alloc(&ddl_context->metadata_shared_input, + DDL_METADATA_TOTAL_INPUTBUFSIZE, + DDL_LINEAR_BUFFER_ALIGN_BYTES); + if (!ptr) { + DDL_MSG_ERROR("ddl_device_init: metadata alloc fail"); + status = VCD_ERR_ALLOC_FAIL; + } + } + if (!status && !ddl_fw_init(&ddl_context->dram_base_a)) { + DDL_MSG_ERROR("ddl_dev_init:fw_init_failed"); + status = VCD_ERR_ALLOC_FAIL; + } + if (!status) { + ddl_context->cmd_state = DDL_CMD_DMA_INIT; + ddl_vidc_core_init(ddl_context); + } else { + ddl_release_context_buffers(ddl_context); + DDL_IDLE(ddl_context); + } + return status; +} + +u32 ddl_device_release(void *client_data) +{ + struct ddl_context *ddl_context; + + DDL_MSG_HIGH("ddl_device_release"); + ddl_context = ddl_get_context(); + if (!DDL_IS_IDLE(ddl_context)) { + DDL_MSG_ERROR("ddl_dev_rel:Ddl_busy"); + return VCD_ERR_BUSY; + } + if (!DDL_IS_INITIALIZED(ddl_context)) { + DDL_MSG_ERROR("ddl_dev_rel:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (!ddl_client_transact(DDL_ACTIVE_CLIENT, NULL)) { + DDL_MSG_ERROR("ddl_dev_rel:Client_present_err"); + return VCD_ERR_CLIENT_PRESENT; + } + DDL_BUSY(ddl_context); + ddl_context->device_state = DDL_DEVICE_NOTINIT; + ddl_context->client_data = client_data; + ddl_context->cmd_state = DDL_CMD_INVALID; + ddl_vidc_core_term(ddl_context); + DDL_MSG_LOW("FW_ENDDONE"); + ddl_context->core_virtual_base_addr = NULL; + ddl_release_context_buffers(ddl_context); + ddl_context->video_ion_client = NULL; + DDL_IDLE(ddl_context); + return VCD_S_SUCCESS; +} + +u32 ddl_open(u32 **ddl_handle, u32 decoding) +{ + struct ddl_context *ddl_context; + struct ddl_client_context *ddl; + void *ptr; + u32 status; + + DDL_MSG_HIGH("ddl_open"); + if (!ddl_handle) { + DDL_MSG_ERROR("ddl_open:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + ddl_context = ddl_get_context(); + if (!DDL_IS_INITIALIZED(ddl_context)) { + DDL_MSG_ERROR("ddl_open:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + status = ddl_client_transact(DDL_GET_CLIENT, &ddl); + if (status) { + DDL_MSG_ERROR("ddl_open:Client_trasac_failed"); + return status; + } + if (res_trk_check_for_sec_session()) + ddl->shared_mem[0].mem_type = DDL_CMD_MEM; + else + ddl->shared_mem[0].mem_type = DDL_FW_MEM; + ptr = ddl_pmem_alloc(&ddl->shared_mem[0], + DDL_FW_AUX_HOST_CMD_SPACE_SIZE, 0); + if (!ptr) + status = VCD_ERR_ALLOC_FAIL; + if (!status && ddl_context->frame_channel_depth + == VCD_DUAL_FRAME_COMMAND_CHANNEL) { + if (res_trk_check_for_sec_session()) + ddl->shared_mem[1].mem_type = DDL_CMD_MEM; + else + ddl->shared_mem[1].mem_type = DDL_FW_MEM; + ptr = ddl_pmem_alloc(&ddl->shared_mem[1], + DDL_FW_AUX_HOST_CMD_SPACE_SIZE, 0); + if (!ptr) { + ddl_pmem_free(&ddl->shared_mem[0]); + status = VCD_ERR_ALLOC_FAIL; + } + } + if (!status) { + memset(ddl->shared_mem[0].align_virtual_addr, 0, + DDL_FW_AUX_HOST_CMD_SPACE_SIZE); + if (ddl_context->frame_channel_depth == + VCD_DUAL_FRAME_COMMAND_CHANNEL) { + memset(ddl->shared_mem[1].align_virtual_addr, 0, + DDL_FW_AUX_HOST_CMD_SPACE_SIZE); + } + DDL_MSG_LOW("ddl_state_transition: %s ~~> DDL_CLIENT_OPEN", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_OPEN; + ddl->codec_data.hdr.decoding = decoding; + ddl->decoding = decoding; + ddl_set_default_meta_data_hdr(ddl); + ddl_set_initial_default_values(ddl); + *ddl_handle = (u32 *) ddl; + } else { + ddl_pmem_free(&ddl->shared_mem[0]); + if (ddl_context->frame_channel_depth + == VCD_DUAL_FRAME_COMMAND_CHANNEL) + ddl_pmem_free(&ddl->shared_mem[1]); + ddl_client_transact(DDL_FREE_CLIENT, &ddl); + } + return status; +} + +u32 ddl_close(u32 **ddl_handle) +{ + struct ddl_context *ddl_context; + struct ddl_client_context **pp_ddl = + (struct ddl_client_context **)ddl_handle; + + DDL_MSG_HIGH("ddl_close"); + if (!pp_ddl || !*pp_ddl) { + DDL_MSG_ERROR("ddl_close:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + ddl_context = ddl_get_context(); + if (!DDL_IS_INITIALIZED(ddl_context)) { + DDL_MSG_ERROR("ddl_close:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (!DDLCLIENT_STATE_IS(*pp_ddl, DDL_CLIENT_OPEN)) { + DDL_MSG_ERROR("ddl_close:Not_in_open_state"); + return VCD_ERR_ILLEGAL_OP; + } + ddl_pmem_free(&(*pp_ddl)->shared_mem[0]); + if (ddl_context->frame_channel_depth == + VCD_DUAL_FRAME_COMMAND_CHANNEL) + ddl_pmem_free(&(*pp_ddl)->shared_mem[1]); + DDL_MSG_LOW("ddl_state_transition: %s ~~> DDL_CLIENT_INVALID", + ddl_get_state_string((*pp_ddl)->client_state)); + (*pp_ddl)->client_state = DDL_CLIENT_INVALID; + ddl_codec_type_transact(*pp_ddl, true, (enum vcd_codec)0); + ddl_client_transact(DDL_FREE_CLIENT, pp_ddl); + return VCD_S_SUCCESS; +} + +u32 ddl_encode_start(u32 *ddl_handle, void *client_data) +{ + struct ddl_client_context *ddl = + (struct ddl_client_context *) ddl_handle; + struct ddl_context *ddl_context; + struct ddl_encoder_data *encoder; + void *ptr; + u32 status = VCD_S_SUCCESS; + DDL_MSG_HIGH("ddl_encode_start"); + if (first_time < 2) { + ddl_reset_core_time_variables(ENC_OP_TIME); + first_time++; + } + ddl_set_core_start_time(__func__, ENC_OP_TIME); + ddl_context = ddl_get_context(); + if (!DDL_IS_INITIALIZED(ddl_context)) { + DDL_MSG_ERROR("ddl_enc_start:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (DDL_IS_BUSY(ddl_context)) { + DDL_MSG_ERROR("ddl_enc_start:Ddl_busy"); + return VCD_ERR_BUSY; + } + if (!ddl || ddl->decoding) { + DDL_MSG_ERROR("ddl_enc_start:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) { + DDL_MSG_ERROR("ddl_enc_start:Not_opened"); + return VCD_ERR_ILLEGAL_OP; + } + if (!ddl_encoder_ready_to_start(ddl)) { + DDL_MSG_ERROR("ddl_enc_start:Err_param_settings"); + return VCD_ERR_ILLEGAL_OP; + } + encoder = &ddl->codec_data.encoder; + status = ddl_allocate_enc_hw_buffers(ddl); + if (status) + return status; +#ifdef DDL_BUF_LOG + ddl_list_buffers(ddl); +#endif + encoder->seq_header.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&encoder->seq_header, + DDL_ENC_SEQHEADER_SIZE, DDL_LINEAR_BUFFER_ALIGN_BYTES); + if (!ptr) { + ddl_free_enc_hw_buffers(ddl); + DDL_MSG_ERROR("ddl_enc_start:Seq_hdr_alloc_failed"); + return VCD_ERR_ALLOC_FAIL; + } + msm_ion_do_cache_op(ddl_context->video_ion_client, + encoder->seq_header.alloc_handle, + encoder->seq_header.virtual_base_addr, + encoder->seq_header.buffer_size, + ION_IOC_CLEAN_INV_CACHES); + if (encoder->slice_delivery_info.enable) { + DDL_MSG_LOW("%s: slice mode allocate memory for struct\n", + __func__); + ptr = ddl_pmem_alloc(&encoder->batch_frame.slice_batch_in, + DDL_ENC_SLICE_BATCH_INPSTRUCT_SIZE, + DDL_LINEAR_BUFFER_ALIGN_BYTES); + if (ptr) { + ptr = ddl_pmem_alloc( + &encoder->batch_frame.slice_batch_out, + DDL_ENC_SLICE_BATCH_OUTSTRUCT_SIZE, + DDL_LINEAR_BUFFER_ALIGN_BYTES); + } + if (!ptr) { + ddl_pmem_free(&encoder->batch_frame.slice_batch_in); + ddl_pmem_free(&encoder->batch_frame.slice_batch_out); + ddl_free_enc_hw_buffers(ddl); + ddl_pmem_free(&encoder->seq_header); + DDL_MSG_ERROR("ddlEncStart:SeqHdrAllocFailed"); + return VCD_ERR_ALLOC_FAIL; + } + } + if (!ddl_take_command_channel(ddl_context, ddl, client_data)) + return VCD_ERR_BUSY; + ddl_vidc_channel_set(ddl); + return status; +} + +u32 ddl_decode_start(u32 *ddl_handle, struct vcd_sequence_hdr *header, + void *client_data) +{ + struct ddl_client_context *ddl = + (struct ddl_client_context *) ddl_handle; + struct ddl_context *ddl_context; + struct ddl_decoder_data *decoder; + u32 status = VCD_S_SUCCESS; + + DDL_MSG_HIGH("ddl_decode_start"); + ddl_reset_core_time_variables(DEC_OP_TIME); + ddl_reset_core_time_variables(DEC_IP_TIME); + ddl_context = ddl_get_context(); + if (!DDL_IS_INITIALIZED(ddl_context)) { + DDL_MSG_ERROR("ddl_dec_start:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (DDL_IS_BUSY(ddl_context)) { + DDL_MSG_ERROR("ddl_dec_start:Ddl_busy"); + return VCD_ERR_BUSY; + } + if (!ddl || !ddl->decoding) { + DDL_MSG_ERROR("ddl_dec_start:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) { + DDL_MSG_ERROR("ddl_dec_start:Not_in_opened_state"); + return VCD_ERR_ILLEGAL_OP; + } + + if ((header) && ((!header->sequence_header_len) || + (!header->sequence_header))) { + DDL_MSG_ERROR("ddl_dec_start:Bad_param_seq_header"); + return VCD_ERR_ILLEGAL_PARM; + } + if (!ddl_decoder_ready_to_start(ddl, header)) { + DDL_MSG_ERROR("ddl_dec_start:Err_param_settings"); + return VCD_ERR_ILLEGAL_OP; + } + decoder = &ddl->codec_data.decoder; + status = ddl_allocate_dec_hw_buffers(ddl); + if (status) + return status; +#ifdef DDL_BUF_LOG + ddl_list_buffers(ddl); +#endif + if (!ddl_take_command_channel(ddl_context, ddl, client_data)) + return VCD_ERR_BUSY; + if (header) { + decoder->header_in_start = true; + decoder->decode_config = *header; + } else { + decoder->header_in_start = false; + decoder->decode_config.sequence_header_len = 0; + } + ddl_vidc_channel_set(ddl); + return status; +} + +u32 ddl_decode_frame(u32 *ddl_handle, + struct ddl_frame_data_tag *input_bits, void *client_data) +{ + u32 vcd_status = VCD_S_SUCCESS; + struct ddl_client_context *ddl = + (struct ddl_client_context *) ddl_handle; + struct ddl_context *ddl_context; + struct ddl_decoder_data *decoder; + DDL_MSG_HIGH("ddl_decode_frame"); + ddl_context = ddl_get_context(); + if (!DDL_IS_INITIALIZED(ddl_context)) { + DDL_MSG_ERROR("ddl_dec_frame:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (DDL_IS_BUSY(ddl_context)) { + DDL_MSG_ERROR("ddl_dec_frame:Ddl_busy"); + return VCD_ERR_BUSY; + } + if (!ddl || !ddl->decoding) { + DDL_MSG_ERROR("ddl_dec_frame:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + if (!input_bits || ((!input_bits->vcd_frm.physical || + !input_bits->vcd_frm.data_len) && + (!(VCD_FRAME_FLAG_EOS & input_bits->vcd_frm.flags)))) { + DDL_MSG_ERROR("ddl_dec_frame:Bad_input_param"); + return VCD_ERR_ILLEGAL_PARM; + } + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME) && + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODEC) && + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB)) { + DDL_MSG_ERROR("Dec_frame:Wrong_state"); + return VCD_ERR_ILLEGAL_OP; + } + decoder = &(ddl->codec_data.decoder); + if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODEC) && + !ddl->codec_data.decoder.dp_buf.no_of_dec_pic_buf) { + DDL_MSG_ERROR("ddl_dec_frame:Dpbs_requied"); + return VCD_ERR_ILLEGAL_OP; + } + if (!ddl_take_command_channel(ddl_context, ddl, client_data)) + return VCD_ERR_BUSY; + + ddl->input_frame = *input_bits; + if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME)) + ddl_vidc_decode_frame_run(ddl); + else { + if (!ddl->codec_data.decoder.dp_buf.no_of_dec_pic_buf) { + DDL_MSG_ERROR("ddl_dec_frame:Dpbs_requied"); + vcd_status = VCD_ERR_ILLEGAL_OP; + } else if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB)) { + vcd_status = ddl_vidc_decode_set_buffers(ddl); + if (vcd_status) + ddl_release_command_channel(ddl_context, + ddl->command_channel); + } else if (DDLCLIENT_STATE_IS(ddl, + DDL_CLIENT_WAIT_FOR_INITCODEC)) { + if (decoder->codec.codec == VCD_CODEC_DIVX_3) { + if ((!decoder->client_frame_size.width) || + (!decoder->client_frame_size.height)) + return VCD_ERR_ILLEGAL_OP; + } + ddl->codec_data.decoder.decode_config.sequence_header = + ddl->input_frame.vcd_frm.physical; + ddl->codec_data.decoder.decode_config.sequence_header_len = + ddl->input_frame.vcd_frm.data_len; + ddl_vidc_decode_init_codec(ddl); + } else { + DDL_MSG_ERROR("Dec_frame:Wrong_state"); + vcd_status = VCD_ERR_ILLEGAL_OP; + } + if (vcd_status) + DDL_IDLE(ddl_context); + } + return vcd_status; +} + +u32 ddl_encode_frame(u32 *ddl_handle, + struct ddl_frame_data_tag *input_frame, + struct ddl_frame_data_tag *output_bit, void *client_data) +{ + struct ddl_client_context *ddl = + (struct ddl_client_context *) ddl_handle; + struct ddl_context *ddl_context; + struct ddl_encoder_data *encoder = + &ddl->codec_data.encoder; + u32 vcd_status = VCD_S_SUCCESS; + struct vcd_transc *transc; + transc = (struct vcd_transc *)(ddl->client_data); + DDL_MSG_LOW("%s: transc = 0x%x", __func__, (u32)ddl->client_data); + if (encoder->slice_delivery_info.enable) { + return ddl_encode_frame_batch(ddl_handle, + input_frame, + output_bit, + 1, + encoder->slice_delivery_info.num_slices, + client_data); + } + + ddl_set_core_start_time(__func__, ENC_OP_TIME); + ddl_context = ddl_get_context(); + if (!DDL_IS_INITIALIZED(ddl_context)) { + DDL_MSG_ERROR("ddl_enc_frame:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (DDL_IS_BUSY(ddl_context)) { + DDL_MSG_ERROR("ddl_enc_frame:Ddl_busy"); + return VCD_ERR_BUSY; + } + if (!ddl || ddl->decoding) { + DDL_MSG_ERROR("ddl_enc_frame:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + if (!input_frame || !input_frame->vcd_frm.physical || + !input_frame->vcd_frm.data_len) { + DDL_MSG_ERROR("ddl_enc_frame:Bad_input_params"); + return VCD_ERR_ILLEGAL_PARM; + } + if ((((u32) input_frame->vcd_frm.physical + + input_frame->vcd_frm.offset) & + (DDL_STREAMBUF_ALIGN_GUARD_BYTES))) { + DDL_MSG_ERROR("ddl_enc_frame:Un_aligned_yuv_start_address"); + return VCD_ERR_ILLEGAL_PARM; + } + if (!output_bit || !output_bit->vcd_frm.physical || + !output_bit->vcd_frm.alloc_len) { + DDL_MSG_ERROR("ddl_enc_frame:Bad_output_params"); + return VCD_ERR_ILLEGAL_PARM; + } + if ((ddl->codec_data.encoder.output_buf_req.sz + + output_bit->vcd_frm.offset) > + output_bit->vcd_frm.alloc_len) + DDL_MSG_ERROR("ddl_enc_frame:offset_large," + "Exceeds_min_buf_size"); + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME)) { + DDL_MSG_ERROR("ddl_enc_frame:Wrong_state"); + return VCD_ERR_ILLEGAL_OP; + } + if (!ddl_take_command_channel(ddl_context, ddl, client_data)) + return VCD_ERR_BUSY; + + ddl->input_frame = *input_frame; + ddl->output_frame = *output_bit; + if (ddl->codec_data.encoder.i_period.b_frames > 0) { + if (!ddl->b_count) { + ddl->first_output_frame = *output_bit; + ddl->b_count++; + } else if (ddl->codec_data.encoder.i_period.b_frames >= + ddl->b_count) { + ddl->extra_output_frame[ddl->b_count-1] = + *output_bit; + ddl->output_frame = ddl->first_output_frame; + ddl->b_count++; + } + } + ddl_insert_input_frame_to_pool(ddl, input_frame); + if (!vcd_status) + ddl_vidc_encode_frame_run(ddl); + else + DDL_MSG_ERROR("insert to frame pool failed %u", vcd_status); + return vcd_status; +} + +u32 ddl_encode_frame_batch(u32 *ddl_handle, + struct ddl_frame_data_tag *input_frame, + struct ddl_frame_data_tag *output_bit, + u32 num_in_frames, u32 num_out_frames, + void *client_data) +{ + struct ddl_client_context *ddl = + (struct ddl_client_context *) ddl_handle; + struct ddl_context *ddl_context; + u32 vcd_status = VCD_S_SUCCESS; + struct ddl_encoder_data *encoder; + + DDL_MSG_LOW("ddl_encode_frame_batch"); + ddl_context = ddl_get_context(); + if (!DDL_IS_INITIALIZED(ddl_context)) { + DDL_MSG_ERROR("ddl_enc_frame:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (DDL_IS_BUSY(ddl_context)) { + DDL_MSG_ERROR("ddl_enc_frame:Ddl_busy"); + return VCD_ERR_BUSY; + } + if (!ddl || ddl->decoding) { + DDL_MSG_ERROR("ddl_enc_frame:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + if (!input_frame || !input_frame->vcd_frm.physical || + !input_frame->vcd_frm.data_len) { + DDL_MSG_ERROR("ddl_enc_frame:Bad_input_params"); + return VCD_ERR_ILLEGAL_PARM; + } + if ((((u32) input_frame->vcd_frm.physical + + input_frame->vcd_frm.offset) & + (DDL_STREAMBUF_ALIGN_GUARD_BYTES))) { + DDL_MSG_ERROR("ddl_enc_frame:Un_aligned_yuv_start_address"); + return VCD_ERR_ILLEGAL_PARM; + } + if (!output_bit || !output_bit->vcd_frm.physical || + !output_bit->vcd_frm.alloc_len) { + DDL_MSG_ERROR("ddl_enc_frame:Bad_output_params"); + return VCD_ERR_ILLEGAL_PARM; + } + if ((ddl->codec_data.encoder.output_buf_req.sz + + output_bit->vcd_frm.offset) > + output_bit->vcd_frm.alloc_len) + DDL_MSG_ERROR("ddl_enc_frame:offset_large," + "Exceeds_min_buf_size"); + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME)) { + DDL_MSG_ERROR("ddl_enc_frame:Wrong_state"); + return VCD_ERR_ILLEGAL_OP; + } + if (!ddl_take_command_channel(ddl_context, ddl, client_data)) + return VCD_ERR_BUSY; + encoder = &ddl->codec_data.encoder; + if (encoder->slice_delivery_info.enable) { + DDL_MEMCPY((void *)&(encoder->batch_frame.output_frame[0]), + (void *)output_bit, + sizeof(struct ddl_frame_data_tag) * num_out_frames); + encoder->batch_frame.num_output_frames = num_out_frames; + ddl->input_frame = *input_frame; + vcd_status = ddl_insert_input_frame_to_pool(ddl, input_frame); + if (!vcd_status) + ddl_vidc_encode_slice_batch_run(ddl); + else + DDL_MSG_ERROR("insert to frame pool failed %u", + vcd_status); + } + return vcd_status; +} + +u32 ddl_decode_end(u32 *ddl_handle, void *client_data) +{ + struct ddl_client_context *ddl = + (struct ddl_client_context *) ddl_handle; + struct ddl_context *ddl_context; + + DDL_MSG_HIGH("ddl_decode_end"); + ddl_reset_core_time_variables(DEC_OP_TIME); + ddl_reset_core_time_variables(DEC_IP_TIME); + ddl_context = ddl_get_context(); + if (!DDL_IS_INITIALIZED(ddl_context)) { + DDL_MSG_ERROR("ddl_dec_end:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (DDL_IS_BUSY(ddl_context)) { + DDL_MSG_ERROR("ddl_dec_end:Ddl_busy"); + return VCD_ERR_BUSY; + } + if (!ddl || !ddl->decoding) { + DDL_MSG_ERROR("ddl_dec_end:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME) && + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODEC) && + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB) && + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_FAVIDC_ERROR)) { + DDL_MSG_ERROR("ddl_dec_end:Wrong_state"); + return VCD_ERR_ILLEGAL_OP; + } + if (!ddl_take_command_channel(ddl_context, ddl, client_data)) + return VCD_ERR_BUSY; + ddl_vidc_channel_end(ddl); + return VCD_S_SUCCESS; +} + +u32 ddl_encode_end(u32 *ddl_handle, void *client_data) +{ + struct ddl_client_context *ddl = + (struct ddl_client_context *) ddl_handle; + struct ddl_context *ddl_context; + + DDL_MSG_HIGH("ddl_encode_end"); + ddl_reset_core_time_variables(ENC_OP_TIME); + ddl_context = ddl_get_context(); + if (!DDL_IS_INITIALIZED(ddl_context)) { + DDL_MSG_ERROR("ddl_enc_end:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (DDL_IS_BUSY(ddl_context)) { + DDL_MSG_ERROR("ddl_enc_end:Ddl_busy"); + return VCD_ERR_BUSY; + } + if (!ddl || ddl->decoding) { + DDL_MSG_ERROR("ddl_enc_end:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME) && + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODEC) && + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_FAVIDC_ERROR)) { + DDL_MSG_ERROR("ddl_enc_end:Wrong_state"); + return VCD_ERR_ILLEGAL_OP; + } + if (!ddl_take_command_channel(ddl_context, ddl, client_data)) + return VCD_ERR_BUSY; + ddl_vidc_channel_end(ddl); + return VCD_S_SUCCESS; +} + +u32 ddl_reset_hw(u32 mode) +{ + struct ddl_context *ddl_context; + struct ddl_client_context *ddl; + u32 i; + + DDL_MSG_HIGH("ddl_reset_hw"); + DDL_MSG_LOW("ddl_reset_hw:called"); + ddl_context = ddl_get_context(); + ddl_context->cmd_state = DDL_CMD_INVALID; + DDL_BUSY(ddl_context); + if (ddl_context->core_virtual_base_addr) { + vidc_1080p_do_sw_reset(VIDC_1080P_RESET_IN_SEQ_FIRST_STAGE); + msleep(DDL_SW_RESET_SLEEP); + vidc_1080p_do_sw_reset(VIDC_1080P_RESET_IN_SEQ_SECOND_STAGE); + msleep(DDL_SW_RESET_SLEEP); + ddl_context->core_virtual_base_addr = NULL; + } + ddl_context->device_state = DDL_DEVICE_NOTINIT; + for (i = 0; i < VCD_MAX_NO_CLIENT; i++) { + ddl = ddl_context->ddl_clients[i]; + ddl_context->ddl_clients[i] = NULL; + if (ddl) { + ddl_release_client_internal_buffers(ddl); + ddl_client_transact(DDL_FREE_CLIENT, &ddl); + } + } + ddl_release_context_buffers(ddl_context); + memset(ddl_context, 0, sizeof(struct ddl_context)); + return true; +} diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h new file mode 100644 index 000000000000..a7b19f9a812d --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl.h @@ -0,0 +1,493 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#ifndef _VCD_DDL_H_ +#define _VCD_DDL_H_ + +#include +#include "vcd_ddl_api.h" +#include "vcd_ddl_core.h" +#include "vcd_ddl_utils.h" +#include "vidc.h" +#include "vidc_hwio.h" +#include "vidc_pix_cache.h" +#include "vidc.h" + +#define DDL_IDLE_STATE 0 +#define DDL_BUSY_STATE 1 +#define DDL_ERROR_STATE 2 +#define DDL_RUN_STATE 3 + +#define DDL_IS_BUSY(ddl_context) \ + ((ddl_context)->ddl_busy == DDL_BUSY_STATE) +#define DDL_IS_IDLE(ddl_context) \ + ((ddl_context)->ddl_busy == DDL_IDLE_STATE) +#define DDL_BUSY(ddl_context) \ + ((ddl_context)->ddl_busy = DDL_BUSY_STATE) +#define DDL_IDLE(ddl_context) \ + ((ddl_context)->ddl_busy = DDL_IDLE_STATE) +#define DDL_ERROR(ddl_context) \ + ((ddl_context)->ddl_busy = DDL_ERROR_STATE) +#define DDL_RUN(ddl_context) \ + ((ddl_context)->ddl_busy = DDL_RUN_STATE) + +#define DDL_DEVICE_NOTINIT 0 +#define DDL_DEVICE_INITED 1 +#define DDL_DEVICE_HWFATAL 2 + +#define DDL_IS_INITIALIZED(ddl_context) \ + (ddl_context->device_state == DDL_DEVICE_INITED) +#define DDLCOMMAND_STATE_IS(ddl_context, command_state) \ + (command_state == (ddl_context)->cmd_state) +#define DDLCLIENT_STATE_IS(ddl, state) \ + (state == (ddl)->client_state) + +#define DDL_DPB_OP_INIT 1 +#define DDL_DPB_OP_MARK_FREE 2 +#define DDL_DPB_OP_MARK_BUSY 3 +#define DDL_DPB_OP_SET_MASK 4 +#define DDL_DPB_OP_RETRIEVE 5 + +#define DDL_INIT_CLIENTS 0 +#define DDL_GET_CLIENT 1 +#define DDL_FREE_CLIENT 2 +#define DDL_ACTIVE_CLIENT 3 + +#define DDL_INVALID_CHANNEL_ID ((u32)~0) +#define DDL_INVALID_CODEC_TYPE ((u32)~0) +#define DDL_INVALID_INTR_STATUS ((u32)~0) + +#define DDL_ENC_REQ_IFRAME 0x01 +#define DDL_ENC_CHANGE_IPERIOD 0x02 +#define DDL_ENC_CHANGE_BITRATE 0x04 +#define DDL_ENC_CHANGE_FRAMERATE 0x08 +#define DDL_ENC_CHANGE_CIR 0x10 + +#define DDL_DEC_REQ_OUTPUT_FLUSH 0x1 + +#define DDL_MIN_NUM_OF_B_FRAME 0 +#define DDL_MAX_NUM_OF_B_FRAME 1 +#define DDL_DEFAULT_NUM_OF_B_FRAME DDL_MIN_NUM_OF_B_FRAME + +#define DDL_MIN_NUM_REF_FOR_P_FRAME 1 +#define DDL_MAX_NUM_REF_FOR_P_FRAME 2 + +#define DDL_MAX_NUM_IN_INPUTFRAME_POOL (DDL_MAX_NUM_OF_B_FRAME + 1) + +#define MDP_MIN_TILE_HEIGHT 96 + +enum ddl_mem_area { + DDL_FW_MEM = 0x0, + DDL_MM_MEM = 0x1, + DDL_CMD_MEM = 0x2 +}; + +struct ddl_buf_addr{ + u8 *virtual_base_addr; + u8 *physical_base_addr; + u8 *align_physical_addr; + u8 *align_virtual_addr; + phys_addr_t alloced_phys_addr; + struct msm_mapped_buffer *mapped_buffer; + struct ion_handle *alloc_handle; + u32 buffer_size; + enum ddl_mem_area mem_type; + void *pil_cookie; +}; +enum ddl_cmd_state{ + DDL_CMD_INVALID = 0x0, + DDL_CMD_DMA_INIT = 0x1, + DDL_CMD_CPU_RESET = 0x2, + DDL_CMD_CHANNEL_SET = 0x3, + DDL_CMD_INIT_CODEC = 0x4, + DDL_CMD_HEADER_PARSE = 0x5, + DDL_CMD_DECODE_SET_DPB = 0x6, + DDL_CMD_DECODE_FRAME = 0x7, + DDL_CMD_ENCODE_FRAME = 0x8, + DDL_CMD_EOS = 0x9, + DDL_CMD_CHANNEL_END = 0xA, + DDL_CMD_ENCODE_CONTINUE = 0xB, + DDL_CMD_32BIT = 0x7FFFFFFF +}; +enum ddl_client_state{ + DDL_CLIENT_INVALID = 0x0, + DDL_CLIENT_OPEN = 0x1, + DDL_CLIENT_WAIT_FOR_CHDONE = 0x2, + DDL_CLIENT_WAIT_FOR_INITCODEC = 0x3, + DDL_CLIENT_WAIT_FOR_INITCODECDONE = 0x4, + DDL_CLIENT_WAIT_FOR_DPB = 0x5, + DDL_CLIENT_WAIT_FOR_DPBDONE = 0x6, + DDL_CLIENT_WAIT_FOR_FRAME = 0x7, + DDL_CLIENT_WAIT_FOR_FRAME_DONE = 0x8, + DDL_CLIENT_WAIT_FOR_EOS_DONE = 0x9, + DDL_CLIENT_WAIT_FOR_CHEND = 0xA, + DDL_CLIENT_FATAL_ERROR = 0xB, + DDL_CLIENT_FAVIDC_ERROR = 0xC, + DDL_CLIENT_WAIT_FOR_CONTINUE = 0xD, + DDL_CLIENT_32BIT = 0x7FFFFFFF +}; +struct ddl_hw_interface{ + u32 cmd; + u32 arg1; + u32 arg2; + u32 arg3; + u32 arg4; +}; +struct ddl_mask{ + u32 client_mask; + u32 hw_mask; +}; +struct ddl_yuv_buffer_size{ + u32 size_yuv; + u32 size_y; + u32 size_c; +}; +struct ddl_dec_buffer_size{ + u32 sz_dpb0; + u32 sz_dpb1; + u32 sz_mv; + u32 sz_vert_nb_mv; + u32 sz_nb_ip; + u32 sz_luma; + u32 sz_chroma; + u32 sz_nb_dcac; + u32 sz_upnb_mv; + u32 sz_sub_anchor_mv; + u32 sz_overlap_xform; + u32 sz_bit_plane3; + u32 sz_bit_plane2; + u32 sz_bit_plane1; + u32 sz_stx_parser; + u32 sz_desc; + u32 sz_cpb; + u32 sz_context; +}; +struct ddl_dec_buffers{ + struct ddl_buf_addr desc; + struct ddl_buf_addr nb_dcac; + struct ddl_buf_addr upnb_mv; + struct ddl_buf_addr sub_anchor_mv; + struct ddl_buf_addr overlay_xform; + struct ddl_buf_addr bit_plane3; + struct ddl_buf_addr bit_plane2; + struct ddl_buf_addr bit_plane1; + struct ddl_buf_addr stx_parser; + struct ddl_buf_addr h264_mv[DDL_MAX_BUFFER_COUNT]; + struct ddl_buf_addr h264_vert_nb_mv; + struct ddl_buf_addr h264_nb_ip; + struct ddl_buf_addr context; +}; +struct ddl_enc_buffer_size{ + u32 sz_cur_y; + u32 sz_cur_c; + u32 sz_dpb_y; + u32 sz_dpb_c; + u32 sz_strm; + u32 sz_mv; + u32 sz_col_zero; + u32 sz_md; + u32 sz_pred; + u32 sz_nbor_info; + u32 sz_acdc_coef; + u32 sz_mb_info; + u32 sz_context; +}; +struct ddl_enc_buffers{ + struct ddl_buf_addr dpb_y[4]; + struct ddl_buf_addr dpb_c[4]; + struct ddl_buf_addr mv; + struct ddl_buf_addr col_zero; + struct ddl_buf_addr md; + struct ddl_buf_addr pred; + struct ddl_buf_addr nbor_info; + struct ddl_buf_addr acdc_coef; + struct ddl_buf_addr mb_info; + struct ddl_buf_addr context; + u32 dpb_count; + u32 sz_dpb_y; + u32 sz_dpb_c; +}; +struct ddl_codec_data_hdr{ + u32 decoding; +}; +struct ddl_batch_frame_data { + struct ddl_buf_addr slice_batch_in; + struct ddl_buf_addr slice_batch_out; + struct ddl_frame_data_tag input_frame; + struct ddl_frame_data_tag output_frame + [DDL_MAX_NUM_BFRS_FOR_SLICE_BATCH]; + u32 num_output_frames; + u32 out_frm_next_frmindex; + u32 first_output_frame_tag; +}; +struct ddl_encoder_data{ + struct ddl_codec_data_hdr hdr; + struct vcd_property_codec codec; + struct vcd_property_frame_size frame_size; + struct vcd_property_frame_rate frame_rate; + struct vcd_property_target_bitrate target_bit_rate; + struct vcd_property_profile profile; + struct vcd_property_level level; + struct vcd_property_rate_control rc; + struct vcd_property_multi_slice multi_slice; + struct ddl_buf_addr meta_data_input; + struct vcd_property_short_header short_header; + struct vcd_property_vop_timing vop_timing; + struct vcd_property_db_config db_control; + struct vcd_property_entropy_control entropy_control; + struct vcd_property_i_period i_period; + struct vcd_property_session_qp session_qp; + struct vcd_property_qp_range qp_range; + struct vcd_property_rc_level rc_level; + struct vcd_property_frame_level_rc_params frame_level_rc; + struct vcd_property_adaptive_rc_params adaptive_rc; + struct vcd_property_intra_refresh_mb_number intra_refresh; + struct vcd_property_buffer_format buf_format; + struct vcd_property_buffer_format recon_buf_format; + struct vcd_property_sps_pps_for_idr_enable sps_pps; + struct ddl_buf_addr seq_header; + struct vcd_buffer_requirement input_buf_req; + struct vcd_buffer_requirement output_buf_req; + struct vcd_buffer_requirement client_input_buf_req; + struct vcd_buffer_requirement client_output_buf_req; + struct ddl_enc_buffers hw_bufs; + struct ddl_yuv_buffer_size input_buf_size; + struct vidc_1080p_enc_frame_info enc_frame_info; + u32 meta_data_enable_flag; + u32 suffix; + u32 meta_data_offset; + u32 hdr_ext_control; + u32 r_cframe_skip; + u32 vb_vbuffer_size; + u32 dynamic_prop_change; + u32 dynmic_prop_change_req; + u32 seq_header_length; + u32 intra_frame_insertion; + u32 mb_info_enable; + u32 ext_enc_control_val; + u32 num_references_for_p_frame; + u32 closed_gop; + struct vcd_property_slice_delivery_info slice_delivery_info; + struct ddl_batch_frame_data batch_frame; +}; +struct ddl_decoder_data { + struct ddl_codec_data_hdr hdr; + struct vcd_property_codec codec; + struct vcd_property_buffer_format buf_format; + struct vcd_property_frame_size frame_size; + struct vcd_property_frame_size client_frame_size; + struct vcd_property_profile profile; + struct vcd_property_level level; + struct ddl_buf_addr meta_data_input; + struct vcd_property_post_filter post_filter; + struct vcd_sequence_hdr decode_config; + struct ddl_property_dec_pic_buffers dp_buf; + struct ddl_mask dpb_mask; + struct vcd_buffer_requirement actual_input_buf_req; + struct vcd_buffer_requirement min_input_buf_req; + struct vcd_buffer_requirement client_input_buf_req; + struct vcd_buffer_requirement actual_output_buf_req; + struct vcd_buffer_requirement min_output_buf_req; + struct vcd_buffer_requirement client_output_buf_req; + struct ddl_dec_buffers hw_bufs; + struct ddl_yuv_buffer_size dpb_buf_size; + struct vidc_1080p_dec_disp_info dec_disp_info; + u32 progressive_only; + u32 output_order; + u32 meta_data_enable_flag; + u32 suffix; + u32 meta_data_offset; + u32 header_in_start; + u32 min_dpb_num; + u32 y_cb_cr_size; + u32 dynamic_prop_change; + u32 dynmic_prop_change_req; + u32 flush_pending; + u32 meta_data_exists; + u32 idr_only_decoding; + u32 field_needed_for_prev_ip; + u32 prev_ip_frm_tag; + u32 cont_mode; + u32 reconfig_detected; + u32 dmx_disable; + int avg_dec_time; + int dec_time_sum; +}; +union ddl_codec_data{ + struct ddl_codec_data_hdr hdr; + struct ddl_decoder_data decoder; + struct ddl_encoder_data encoder; +}; +struct ddl_context{ + u8 *core_virtual_base_addr; + void *client_data; + u32 device_state; + u32 ddl_busy; + u32 cmd_err_status; + u32 disp_pic_err_status; + u32 pix_cache_enable; + u32 fw_version; + u32 fw_memory_size; + u32 cmd_seq_num; + u32 response_cmd_ch_id; + enum ddl_cmd_state cmd_state; + struct ddl_client_context *current_ddl[2]; + struct ddl_buf_addr metadata_shared_input; + struct ddl_client_context *ddl_clients[VCD_MAX_NO_CLIENT]; + struct ddl_buf_addr dram_base_a; + struct ddl_buf_addr dram_base_b; + struct ddl_hw_interface ddl_hw_response; + struct ion_client *video_ion_client; + void (*ddl_callback) (u32 event, u32 status, void *payload, + size_t sz, u32 *ddl_handle, void *const client_data); + void (*interrupt_clr) (void); + void (*vidc_decode_seq_start[2]) + (struct vidc_1080p_dec_seq_start_param *param); + void (*vidc_set_dec_resolution[2]) + (u32 width, u32 height); + void(*vidc_decode_init_buffers[2]) + (struct vidc_1080p_dec_init_buffers_param *param); + void(*vidc_decode_frame_start[2]) + (struct vidc_1080p_dec_frame_start_param *param); + void(*vidc_encode_seq_start[2]) + (struct vidc_1080p_enc_seq_start_param *param); + void(*vidc_encode_frame_start[2]) + (struct vidc_1080p_enc_frame_start_param *param); + void(*vidc_encode_slice_batch_start[2]) + (struct vidc_1080p_enc_frame_start_param *param); + u32 frame_channel_depth; +}; +struct ddl_client_context{ + struct ddl_context *ddl_context; + enum ddl_client_state client_state; + struct ddl_frame_data_tag first_output_frame; + struct ddl_frame_data_tag + extra_output_frame[DDL_MAX_NUM_OF_B_FRAME]; + struct ddl_frame_data_tag input_frame; + struct ddl_frame_data_tag output_frame; + struct ddl_frame_data_tag + input_frame_pool[DDL_MAX_NUM_IN_INPUTFRAME_POOL]; + union ddl_codec_data codec_data; + enum ddl_cmd_state cmd_state; + struct ddl_buf_addr shared_mem[2]; + void *client_data; + u32 decoding; + u32 channel_id; + u32 command_channel; + u32 b_count; + s32 extra_output_buf_count; + u32 instance_id; +}; + +struct ddl_context *ddl_get_context(void); +void ddl_vidc_core_init(struct ddl_context *); +void ddl_vidc_core_term(struct ddl_context *); +void ddl_vidc_channel_set(struct ddl_client_context *); +void ddl_vidc_channel_end(struct ddl_client_context *); +void ddl_vidc_encode_init_codec(struct ddl_client_context *); +void ddl_vidc_decode_init_codec(struct ddl_client_context *); +void ddl_vidc_encode_frame_continue(struct ddl_client_context *); +void ddl_vidc_encode_frame_run(struct ddl_client_context *); +void ddl_vidc_encode_slice_batch_run(struct ddl_client_context *); +void ddl_vidc_decode_frame_run(struct ddl_client_context *); +void ddl_vidc_decode_eos_run(struct ddl_client_context *ddl); +void ddl_vidc_encode_eos_run(struct ddl_client_context *ddl); +void ddl_release_context_buffers(struct ddl_context *); +void ddl_release_client_internal_buffers(struct ddl_client_context *ddl); +u32 ddl_vidc_decode_set_buffers(struct ddl_client_context *); +u32 ddl_decoder_dpb_transact(struct ddl_decoder_data *decoder, + struct ddl_frame_data_tag *in_out_frame, u32 operation); +u32 ddl_decoder_dpb_init(struct ddl_client_context *ddl); +u32 ddl_client_transact(u32 , struct ddl_client_context **); +u32 ddl_set_default_decoder_buffer_req(struct ddl_decoder_data *decoder, + u32 estimate); +void ddl_set_default_encoder_buffer_req(struct ddl_encoder_data + *encoder); +void ddl_set_default_dec_property(struct ddl_client_context *); +u32 ddl_encoder_ready_to_start(struct ddl_client_context *); +u32 ddl_decoder_ready_to_start(struct ddl_client_context *, + struct vcd_sequence_hdr *); +u32 ddl_get_yuv_buffer_size(struct vcd_property_frame_size *frame_size, + struct vcd_property_buffer_format *buf_format, u32 interlace, + u32 decoding, u32 *pn_c_offset); +void ddl_calculate_stride(struct vcd_property_frame_size *frame_size, + u32 interlace); +u32 ddl_codec_type_transact(struct ddl_client_context *ddl, + u32 remove, enum vcd_codec requested_codec); +void ddl_vidc_encode_dynamic_property(struct ddl_client_context *ddl, + u32 enable); +void ddl_vidc_decode_dynamic_property(struct ddl_client_context *ddl, + u32 enable); +void ddl_set_initial_default_values(struct ddl_client_context *ddl); + +u32 ddl_take_command_channel(struct ddl_context *ddl_context, + struct ddl_client_context *ddl, void *client_data); +void ddl_release_command_channel(struct ddl_context *ddl_context, + u32 command_channel); +struct ddl_client_context *ddl_get_current_ddl_client_for_channel_id( + struct ddl_context *ddl_context, u32 channel_id); +struct ddl_client_context *ddl_get_current_ddl_client_for_command( + struct ddl_context *ddl_context, + enum ddl_cmd_state cmd_state); + +u32 ddl_get_yuv_buf_size(u32 width, u32 height, u32 format); +void ddl_free_dec_hw_buffers(struct ddl_client_context *ddl); +void ddl_free_enc_hw_buffers(struct ddl_client_context *ddl); +void ddl_calc_dec_hw_buffers_size(enum vcd_codec codec, u32 width, + u32 height, u32 h264_dpb, + struct ddl_dec_buffer_size *buf_size); +u32 ddl_allocate_dec_hw_buffers(struct ddl_client_context *ddl); +u32 ddl_calc_enc_hw_buffers_size(enum vcd_codec codec, u32 width, + u32 height, enum vcd_yuv_buffer_format input_format, + struct ddl_client_context *ddl, + struct ddl_enc_buffer_size *buf_size); +u32 ddl_allocate_enc_hw_buffers(struct ddl_client_context *ddl); + +u32 ddl_handle_core_errors(struct ddl_context *ddl_context); +void ddl_client_fatal_cb(struct ddl_client_context *ddl); +void ddl_hw_fatal_cb(struct ddl_client_context *ddl); + +void *ddl_pmem_alloc(struct ddl_buf_addr *addr, size_t sz, u32 alignment); +void ddl_pmem_free(struct ddl_buf_addr *addr); + +u32 ddl_get_input_frame_from_pool(struct ddl_client_context *ddl, + u8 *input_buffer_address); +u32 ddl_get_stream_buf_from_batch_pool(struct ddl_client_context *ddl, + struct ddl_frame_data_tag *stream_buffer); +u32 ddl_insert_input_frame_to_pool(struct ddl_client_context *ddl, + struct ddl_frame_data_tag *ddl_input_frame); +void ddl_decoder_chroma_dpb_change(struct ddl_client_context *ddl); +u32 ddl_check_reconfig(struct ddl_client_context *ddl); +void ddl_handle_reconfig(u32 res_change, struct ddl_client_context *ddl); +void ddl_fill_dec_desc_buffer(struct ddl_client_context *ddl); +void ddl_set_vidc_timeout(struct ddl_client_context *ddl); + + +#ifdef DDL_BUF_LOG +void ddl_list_buffers(struct ddl_client_context *ddl); +#endif +#ifdef DDL_MSG_LOG +s8 *ddl_get_state_string(enum ddl_client_state client_state); +#endif +extern unsigned char *vidc_video_codec_fw; +extern u32 vidc_video_codec_fw_size; + +u32 ddl_fw_init(struct ddl_buf_addr *dram_base); +void ddl_get_fw_info(const unsigned char **fw_array_addr, + unsigned int *fw_size); +void ddl_fw_release(struct ddl_buf_addr *); +int ddl_vidc_decode_get_avg_time(struct ddl_client_context *ddl); +void ddl_vidc_decode_reset_avg_time(struct ddl_client_context *ddl); +void ddl_calc_core_proc_time(const char *func_name, u32 index, + struct ddl_client_context *ddl); +#endif diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_api.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_api.h new file mode 100644 index 000000000000..3a7e443eb769 --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_api.h @@ -0,0 +1,120 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#ifndef _VCD_DDL_API_H_ +#define _VCD_DDL_API_H_ + +#include +#include "vidc.h" + +#define VCD_EVT_RESP_DDL_BASE 0x3000 +#define VCD_EVT_RESP_DEVICE_INIT (VCD_EVT_RESP_DDL_BASE + 0x1) +#define VCD_EVT_RESP_OUTPUT_REQ (VCD_EVT_RESP_DDL_BASE + 0x2) +#define VCD_EVT_RESP_EOS_DONE (VCD_EVT_RESP_DDL_BASE + 0x3) +#define VCD_EVT_RESP_TRANSACTION_PENDING (VCD_EVT_RESP_DDL_BASE + 0x4) + +#define VCD_S_DDL_ERR_BASE 0x90000000 +#define VCD_ERR_MAX_NO_CODEC (VCD_S_DDL_ERR_BASE + 0x1) +#define VCD_ERR_CLIENT_PRESENT (VCD_S_DDL_ERR_BASE + 0x2) +#define VCD_ERR_CLIENT_FATAL (VCD_S_DDL_ERR_BASE + 0x3) +#define VCD_ERR_NO_SEQ_HDR (VCD_S_DDL_ERR_BASE + 0x4) + +#define VCD_I_CUSTOM_BASE (VCD_I_RESERVED_BASE) +#define VCD_I_RC_LEVEL_CONFIG (VCD_I_CUSTOM_BASE + 0x1) +#define VCD_I_FRAME_LEVEL_RC (VCD_I_CUSTOM_BASE + 0x2) +#define VCD_I_ADAPTIVE_RC (VCD_I_CUSTOM_BASE + 0x3) +#define VCD_I_CUSTOM_DDL_BASE (VCD_I_RESERVED_BASE + 0x100) +#define DDL_I_INPUT_BUF_REQ (VCD_I_CUSTOM_DDL_BASE + 0x1) +#define DDL_I_OUTPUT_BUF_REQ (VCD_I_CUSTOM_DDL_BASE + 0x2) +#define DDL_I_DPB (VCD_I_CUSTOM_DDL_BASE + 0x3) +#define DDL_I_DPB_RELEASE (VCD_I_CUSTOM_DDL_BASE + 0x4) +#define DDL_I_DPB_RETRIEVE (VCD_I_CUSTOM_DDL_BASE + 0x5) +#define DDL_I_REQ_OUTPUT_FLUSH (VCD_I_CUSTOM_DDL_BASE + 0x6) +#define DDL_I_SEQHDR_ALIGN_BYTES (VCD_I_CUSTOM_DDL_BASE + 0x7) +#define DDL_I_CAPABILITY (VCD_I_CUSTOM_DDL_BASE + 0x8) +#define DDL_I_FRAME_PROC_UNITS (VCD_I_CUSTOM_DDL_BASE + 0x9) +#define DDL_I_SEQHDR_PRESENT (VCD_I_CUSTOM_DDL_BASE + 0xA) + +#define DDL_FRAME_VGA_SIZE (640*480) +#define DDL_FRAME_720P_WIDTH 1280 +#define DDL_FRAME_720P_HEIGHT 720 + +struct vcd_property_rc_level{ + u32 frame_level_rc; + u32 mb_level_rc; +}; +struct vcd_property_frame_level_rc_params{ + u32 reaction_coeff; +}; +struct vcd_property_adaptive_rc_params{ + u32 disable_dark_region_as_flag; + u32 disable_smooth_region_as_flag; + u32 disable_static_region_as_flag; + u32 disable_activity_region_flag; +}; +struct vcd_property_slice_delivery_info { + u32 enable; + u32 num_slices; + u32 num_slices_enc; +}; +struct ddl_property_dec_pic_buffers{ + struct ddl_frame_data_tag *dec_pic_buffers; + u32 no_of_dec_pic_buf; +}; +struct ddl_property_capability{ + u32 max_num_client; + u32 general_command_depth; + u32 exclusive; + u32 frame_command_depth; + u32 ddl_time_out_in_ms; +}; +struct ddl_init_config{ + int memtype; + u8 *core_virtual_base_addr; + void (*interrupt_clr) (void); + void (*ddl_callback) (u32 event, u32 status, void *payload, size_t sz, + u32 *ddl_handle, void *const client_data); +}; +struct ddl_frame_data_tag{ + struct vcd_frame_data vcd_frm; + u32 frm_trans_end; + u32 frm_delta; +}; +u32 ddl_device_init(struct ddl_init_config *ddl_init_config, + void *client_data); +u32 ddl_device_release(void *client_data); +u32 ddl_open(u32 **ddl_handle, u32 decoding); +u32 ddl_close(u32 **ddl_handle); +u32 ddl_encode_start(u32 *ddl_handle, void *client_data); +u32 ddl_encode_frame(u32 *ddl_handle, + struct ddl_frame_data_tag *input_frame, + struct ddl_frame_data_tag *output_bit, void *client_data); +u32 ddl_encode_frame_batch(u32 *ddl_handle, + struct ddl_frame_data_tag *input_frame, + struct ddl_frame_data_tag *output_bit, + u32 num_in_frames, u32 num_out_frames, + void *client_data); +u32 ddl_encode_end(u32 *ddl_handle, void *client_data); +u32 ddl_decode_start(u32 *ddl_handle, struct vcd_sequence_hdr *header, + void *client_data); +u32 ddl_decode_frame(u32 *ddl_handle, + struct ddl_frame_data_tag *input_bits, void *client_data); +u32 ddl_decode_end(u32 *ddl_handle, void *client_data); +u32 ddl_set_property(u32 *ddl_handle, + struct vcd_property_hdr *property_hdr, void *property_value); +u32 ddl_get_property(u32 *ddl_handle, + struct vcd_property_hdr *property_hdr, void *property_value); +u32 ddl_process_core_response(void); +u32 ddl_reset_hw(u32 mode); +void ddl_read_and_clear_interrupt(void); +#endif diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h new file mode 100644 index 000000000000..e65a94d78ed8 --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h @@ -0,0 +1,156 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#ifndef _VCD_DDL_CORE_H_ +#define _VCD_DDL_CORE_H_ + +#define DDL_LINEAR_BUF_ALIGN_MASK 0xFFFFF800U +#define DDL_LINEAR_BUF_ALIGN_GUARD_BYTES 0x7FF +#define DDL_LINEAR_BUFFER_ALIGN_BYTES 2048 +#define DDL_TILE_BUF_ALIGN_MASK 0xFFFFE000U +#define DDL_TILE_BUF_ALIGN_GUARD_BYTES 0x1FFF +#define DDL_TILE_BUFFER_ALIGN_BYTES 8192 + +#define DDL_YUV_BUF_TYPE_LINEAR 0 +#define DDL_YUV_BUF_TYPE_TILE 1 + +#define DDL_NO_OF_MB(nWidth, nHeight) \ + ((((nWidth) + 15) >> 4) * (((nHeight) + 15) >> 4)) + +#define DDL_MAX_FRAME_WIDTH 1920 +#define DDL_MAX_FRAME_HEIGHT 1088 + +#define DDL_MAX_VC1_FRAME_WIDTH (DDL_MAX_FRAME_WIDTH) +#define DDL_MAX_VC1_FRAME_HEIGHT (1280) + +#define MAX_DPB_SIZE_L4PT0_MBS DDL_KILO_BYTE(32) +#define MAX_FRAME_SIZE_L4PT0_MBS DDL_KILO_BYTE(8) + +#define DDL_MAX_MB_PER_FRAME (DDL_NO_OF_MB(DDL_MAX_FRAME_WIDTH,\ + DDL_MAX_FRAME_HEIGHT)) + +#define DDL_DB_LINE_BUF_SIZE\ + (((((DDL_MAX_FRAME_WIDTH * 4) - 1) / 256) + 1) * 8 * 1024) + +#define DDL_MAX_FRAME_RATE 120 +#define DDL_INITIAL_FRAME_RATE 30 + +#define DDL_MAX_BIT_RATE (20*1024*1024) +#define DDL_MAX_MB_PER_SEC (DDL_MAX_MB_PER_FRAME * DDL_INITIAL_FRAME_RATE) + +#define DDL_SW_RESET_SLEEP 1 +#define VCD_MAX_NO_CLIENT 4 +#define VCD_SINGLE_FRAME_COMMAND_CHANNEL 1 +#define VCD_DUAL_FRAME_COMMAND_CHANNEL 2 +#define VCD_FRAME_COMMAND_DEPTH VCD_SINGLE_FRAME_COMMAND_CHANNEL +#define VCD_GENEVIDC_COMMAND_DEPTH 1 +#define VCD_COMMAND_EXCLUSIVE true +#define DDL_HW_TIMEOUT_IN_MS 1000 +#define DDL_STREAMBUF_ALIGN_GUARD_BYTES 0x7FF + +#define DDL_VIDC_1080P_48MHZ (48000000) +#define DDL_VIDC_1080P_133MHZ (133330000) +#define DDL_VIDC_1080P_200MHZ (200000000) +#define DDL_VIDC_1080P_48MHZ_TIMEOUT_VALUE (0xCB8) +#define DDL_VIDC_1080P_133MHZ_TIMEOUT_VALUE (0x2355) +#define DDL_VIDC_1080P_200MHZ_TIMEOUT_VALUE (0x3500) + +#define DDL_CONTEXT_MEMORY (1024 * 15 * (VCD_MAX_NO_CLIENT + 1)) + +#define DDL_ENC_MIN_DPB_BUFFERS 2 +#define DDL_ENC_MAX_DPB_BUFFERS 4 + +#define DDL_FW_AUX_HOST_CMD_SPACE_SIZE (DDL_KILO_BYTE(4)) +#define DDL_FW_INST_GLOBAL_CONTEXT_SPACE_SIZE (DDL_KILO_BYTE(800)) +#define DDL_FW_H264DEC_CONTEXT_SPACE_SIZE (DDL_KILO_BYTE(800)) +#define DDL_FW_H264ENC_CONTEXT_SPACE_SIZE (DDL_KILO_BYTE(20)) +#define DDL_FW_OTHER_CONTEXT_SPACE_SIZE (DDL_KILO_BYTE(20)) + +#define VCD_DEC_CPB_SIZE (DDL_KILO_BYTE(512)) +#define DDL_DBG_CORE_DUMP_SIZE (DDL_KILO_BYTE(10)) +#define DDL_VIDC_1080P_BASE_OFFSET_SHIFT 11 + +#define DDL_BUFEND_PAD 256 +#define DDL_ENC_SEQHEADER_SIZE (512+DDL_BUFEND_PAD) +#define DDL_ENC_SLICE_BATCH_FACTOR 5 +#define DDL_MAX_NUM_BFRS_FOR_SLICE_BATCH 8 +#define DDL_ENC_SLICE_BATCH_INPSTRUCT_SIZE (128 + \ + 32 * DDL_MAX_NUM_BFRS_FOR_SLICE_BATCH) +#define DDL_ENC_SLICE_BATCH_OUTSTRUCT_SIZE (64 + \ + 64 * DDL_MAX_NUM_BFRS_FOR_SLICE_BATCH) +#define DDL_MAX_BUFFER_COUNT 32 +#define DDL_MIN_BUFFER_COUNT 1 + +#define DDL_MPEG_REFBUF_COUNT 2 +#define DDL_MPEG_COMV_BUF_NO 2 +#define DDL_H263_COMV_BUF_NO 0 +#define DDL_COMV_BUFLINE_NO 128 +#define DDL_VC1_COMV_BUFLINE_NO 32 + +#define DDL_MAX_H264_QP 51 +#define DDL_MAX_MPEG4_QP 31 + +#define DDL_CONCEALMENT_Y_COLOR 16 +#define DDL_CONCEALMENT_C_COLOR 128 + +#define DDL_ALLOW_DEC_FRAMESIZE(width, height) \ + ((DDL_NO_OF_MB(width, height) <= \ + MAX_FRAME_SIZE_L4PT0_MBS) && \ + (width <= DDL_MAX_FRAME_WIDTH) && \ + (height <= DDL_MAX_FRAME_WIDTH) && \ + ((width >= 32 && height >= 16) || \ + (width >= 16 && height >= 32))) + +#define DDL_ALLOW_ENC_FRAMESIZE(width, height) \ + ((DDL_NO_OF_MB(width, height) <= \ + MAX_FRAME_SIZE_L4PT0_MBS) && \ + (width <= DDL_MAX_FRAME_WIDTH) && \ + (height <= DDL_MAX_FRAME_WIDTH) && \ + ((width >= 32 && height >= 32))) + +#define DDL_LINEAR_ALIGN_WIDTH 16 +#define DDL_LINEAR_ALIGN_HEIGHT 16 +#define DDL_LINEAR_MULTIPLY_FACTOR 2048 +#define DDL_TILE_ALIGN_WIDTH 128 +#define DDL_TILE_ALIGN_HEIGHT 32 +#define DDL_TILE_MULTIPLY_FACTOR 8192 +#define DDL_TILE_ALIGN(val, grid) \ + (((val) + (grid) - 1) / (grid) * (grid)) + +#define VCD_DDL_720P_YUV_BUF_SIZE ((1280*720*3) >> 1) +#define VCD_DDL_WVGA_BUF_SIZE (800*480) + +#define VCD_DDL_TEST_MAX_WIDTH (DDL_MAX_FRAME_WIDTH) +#define VCD_DDL_TEST_MAX_HEIGHT (DDL_MAX_FRAME_HEIGHT) + +#define VCD_DDL_TEST_MAX_NUM_H264_DPB 8 + +#define VCD_DDL_TEST_NUM_ENC_INPUT_BUFS 6 +#define VCD_DDL_TEST_NUM_ENC_OUTPUT_BUFS 4 + +#define VCD_DDL_TEST_DEFAULT_WIDTH 176 +#define VCD_DDL_TEST_DEFAULT_HEIGHT 144 + +#define DDL_PIXEL_CACHE_NOT_IDLE 0x4000 +#define DDL_PIXEL_CACHE_STATUS_READ_RETRY 10 +#define DDL_PIXEL_CACHE_STATUS_READ_SLEEP 200 + +#define DDL_RESL_CHANGE_NO_CHANGE 0 +#define DDL_RESL_CHANGE_INCREASED 1 +#define DDL_RESL_CHANGE_DECREASED 2 + +#define VIDC_SM_ERR_CONCEALMENT_ENABLE 1 +#define VIDC_SM_ERR_CONCEALMENT_INTER_SLICE_MB_COPY 2 +#define VIDC_SM_ERR_CONCEALMENT_INTRA_SLICE_COLOR_CONCEALMENT 1 + +#endif diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c new file mode 100644 index 000000000000..d9e73fb8b128 --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c @@ -0,0 +1,771 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#include "vcd_ddl.h" +#include "vcd_ddl_shared_mem.h" +#include "vidc.h" + +static u32 ddl_handle_hw_fatal_errors(struct ddl_client_context *ddl); +static u32 ddl_handle_client_fatal_errors( + struct ddl_client_context *ddl); +static void ddl_input_failed_cb(struct ddl_client_context *ddl, + u32 vcd_event, u32 vcd_status); +static u32 ddl_handle_core_recoverable_errors( + struct ddl_client_context *ddl); +static u32 ddl_handle_core_warnings(u32 error_code); +static void ddl_release_prev_field( + struct ddl_client_context *ddl); +static u32 ddl_handle_dec_seq_hdr_fail_error(struct ddl_client_context *ddl); +static void print_core_errors(u32 error_code); +static void print_core_recoverable_errors(u32 error_code); + +void ddl_hw_fatal_cb(struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + u32 error_code = ddl_context->cmd_err_status; + + DDL_MSG_FATAL("VIDC_HW_FATAL"); + ddl->cmd_state = DDL_CMD_INVALID; + ddl_context->device_state = DDL_DEVICE_HWFATAL; + + ddl_context->ddl_callback(VCD_EVT_IND_HWERRFATAL, VCD_ERR_HW_FATAL, + &error_code, sizeof(error_code), + (u32 *)ddl, ddl->client_data); + + ddl_release_command_channel(ddl_context, ddl->command_channel); +} + +static u32 ddl_handle_hw_fatal_errors(struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + u32 status = false, error_code = ddl_context->cmd_err_status; + + switch (error_code) { + case VIDC_1080P_ERROR_INVALID_CHANNEL_NUMBER: + case VIDC_1080P_ERROR_INVALID_COMMAND_ID: + case VIDC_1080P_ERROR_CHANNEL_ALREADY_IN_USE: + case VIDC_1080P_ERROR_CHANNEL_NOT_OPEN_BEFORE_CHANNEL_CLOSE: + case VIDC_1080P_ERROR_OPEN_CH_ERROR_SEQ_START: + case VIDC_1080P_ERROR_SEQ_START_ALREADY_CALLED: + case VIDC_1080P_ERROR_OPEN_CH_ERROR_INIT_BUFFERS: + case VIDC_1080P_ERROR_SEQ_START_ERROR_INIT_BUFFERS: + case VIDC_1080P_ERROR_INIT_BUFFER_ALREADY_CALLED: + case VIDC_1080P_ERROR_OPEN_CH_ERROR_FRAME_START: + case VIDC_1080P_ERROR_SEQ_START_ERROR_FRAME_START: + case VIDC_1080P_ERROR_INIT_BUFFERS_ERROR_FRAME_START: + case VIDC_1080P_ERROR_RESOLUTION_CHANGED: + case VIDC_1080P_ERROR_INVALID_COMMAND_LAST_FRAME: + case VIDC_1080P_ERROR_INVALID_COMMAND: + case VIDC_1080P_ERROR_INVALID_CODEC_TYPE: + case VIDC_1080P_ERROR_MEM_ALLOCATION_FAILED: + case VIDC_1080P_ERROR_INSUFFICIENT_CONTEXT_SIZE: + case VIDC_1080P_ERROR_DIVIDE_BY_ZERO: + case VIDC_1080P_ERROR_DESCRIPTOR_BUFFER_EMPTY: + case VIDC_1080P_ERROR_DMA_TX_NOT_COMPLETE: + case VIDC_1080P_ERROR_VSP_NOT_READY: + case VIDC_1080P_ERROR_BUFFER_FULL_STATE: + ddl_hw_fatal_cb(ddl); + status = true; + break; + default: + break; + } + return status; +} + +void ddl_client_fatal_cb(struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + + if (ddl->cmd_state == DDL_CMD_DECODE_FRAME) + ddl_vidc_decode_dynamic_property(ddl, false); + else if (ddl->cmd_state == DDL_CMD_ENCODE_FRAME) + ddl_vidc_encode_dynamic_property(ddl, false); + ddl->cmd_state = DDL_CMD_INVALID; + DDL_MSG_LOW("ddl_state_transition: %s ~~> DDL_CLIENT_FAVIDC_ERROR", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_FAVIDC_ERROR; + ddl_context->ddl_callback(VCD_EVT_IND_HWERRFATAL, + VCD_ERR_CLIENT_FATAL, NULL, 0, (u32 *)ddl, + ddl->client_data); + ddl_release_command_channel(ddl_context, ddl->command_channel); +} + +static u32 ddl_handle_client_fatal_errors( + struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + u32 status = false; + + switch (ddl_context->cmd_err_status) { + case VIDC_1080P_ERROR_UNSUPPORTED_FEATURE_IN_PROFILE: + case VIDC_1080P_ERROR_RESOLUTION_NOT_SUPPORTED: + case VIDC_1080P_ERROR_VOS_END_CODE_RECEIVED: + case VIDC_1080P_ERROR_FRAME_RATE_NOT_SUPPORTED: + case VIDC_1080P_ERROR_INVALID_QP_VALUE: + case VIDC_1080P_ERROR_INVALID_RC_REACTION_COEFFICIENT: + case VIDC_1080P_ERROR_INVALID_CPB_SIZE_AT_GIVEN_LEVEL: + case VIDC_1080P_ERROR_B_FRAME_NOT_SUPPORTED: + case VIDC_1080P_ERROR_ALLOC_DPB_SIZE_NOT_SUFFICIENT: + case VIDC_1080P_ERROR_NUM_DPB_OUT_OF_RANGE: + case VIDC_1080P_ERROR_NULL_METADATA_INPUT_POINTER: + case VIDC_1080P_ERROR_NULL_DPB_POINTER: + case VIDC_1080P_ERROR_NULL_OTH_EXT_BUFADDR: + case VIDC_1080P_ERROR_NULL_MV_POINTER: + status = true; + DDL_MSG_ERROR("VIDC_CLIENT_FATAL!!"); + break; + default: + break; + } + if (!status) + DDL_MSG_ERROR("VIDC_UNKNOWN_OP_FAILED %d", + ddl_context->cmd_err_status); + ddl_client_fatal_cb(ddl); + return true; +} + +static void ddl_input_failed_cb(struct ddl_client_context *ddl, + u32 vcd_event, u32 vcd_status) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + u32 payload_size = sizeof(struct ddl_frame_data_tag); + + ddl->cmd_state = DDL_CMD_INVALID; + if (ddl->decoding) + ddl_vidc_decode_dynamic_property(ddl, false); + else + ddl_vidc_encode_dynamic_property(ddl, false); + if (ddl->client_state == DDL_CLIENT_WAIT_FOR_INITCODECDONE) { + payload_size = 0; + DDL_MSG_LOW("ddl_state_transition: %s ~~> " + "DDL_CLIENT_WAIT_FOR_INITCODEC", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_INITCODEC; + } else { + DDL_MSG_LOW("ddl_state_transition: %s ~~> " + "DDL_CLIENT_WAIT_FOR_FRAME", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME; + } + if (vcd_status == VCD_ERR_IFRAME_EXPECTED) + vcd_status = VCD_S_SUCCESS; + ddl_context->ddl_callback(vcd_event, vcd_status, &ddl->input_frame, + payload_size, (u32 *)ddl, ddl->client_data); +} + +static u32 ddl_handle_core_recoverable_errors( + struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + u32 vcd_status = VCD_S_SUCCESS; + u32 vcd_event = VCD_EVT_RESP_INPUT_DONE; + u32 eos = false, status = false; + + if (ddl->decoding) { + if (ddl_handle_dec_seq_hdr_fail_error(ddl)) + return true; + } + + if ((ddl->cmd_state != DDL_CMD_DECODE_FRAME) && + (ddl->cmd_state != DDL_CMD_ENCODE_FRAME)) + return false; + + if (ddl->decoding && + (ddl->codec_data.decoder.field_needed_for_prev_ip == 1)) { + ddl->codec_data.decoder.field_needed_for_prev_ip = 0; + ddl_release_prev_field(ddl); + if (ddl_context->cmd_err_status == + VIDC_1080P_ERROR_NON_PAIRED_FIELD_NOT_SUPPORTED) { + ddl_vidc_decode_frame_run(ddl); + return true; + } + } + + switch (ddl_context->cmd_err_status) { + case VIDC_1080P_ERROR_SYNC_POINT_NOT_RECEIVED: + vcd_status = VCD_ERR_IFRAME_EXPECTED; + break; + case VIDC_1080P_ERROR_NO_BUFFER_RELEASED_FROM_HOST: + { + u32 pending_display = 0, release_mask; + + release_mask = + ddl->codec_data.decoder.\ + dpb_mask.hw_mask; + while (release_mask > 0) { + if (release_mask & 0x1) + pending_display++; + release_mask >>= 1; + } + if (pending_display >= ddl->codec_data.\ + decoder.min_dpb_num) { + DDL_MSG_ERROR("VIDC_FW_ISSUE_REQ_BUF"); + ddl_client_fatal_cb(ddl); + status = true; + } else { + vcd_event = VCD_EVT_RESP_OUTPUT_REQ; + DDL_MSG_LOW("VIDC_OUTPUT_BUF_REQ!!"); + } + break; + } + case VIDC_1080P_ERROR_BIT_STREAM_BUF_EXHAUST: + case VIDC_1080P_ERROR_DESCRIPTOR_TABLE_ENTRY_INVALID: + case VIDC_1080P_ERROR_MB_COEFF_NOT_DONE: + case VIDC_1080P_ERROR_CODEC_SLICE_NOT_DONE: + case VIDC_1080P_ERROR_VIDC_CORE_TIME_OUT: + case VIDC_1080P_ERROR_VC1_BITPLANE_DECODE_ERR: + case VIDC_1080P_ERROR_RESOLUTION_MISMATCH: + case VIDC_1080P_ERROR_NV_QUANT_ERR: + case VIDC_1080P_ERROR_SYNC_MARKER_ERR: + case VIDC_1080P_ERROR_FEATURE_NOT_SUPPORTED: + case VIDC_1080P_ERROR_MEM_CORRUPTION: + case VIDC_1080P_ERROR_INVALID_REFERENCE_FRAME: + case VIDC_1080P_ERROR_PICTURE_CODING_TYPE_ERR: + case VIDC_1080P_ERROR_MV_RANGE_ERR: + case VIDC_1080P_ERROR_PICTURE_STRUCTURE_ERR: + case VIDC_1080P_ERROR_SLICE_ADDR_INVALID: + case VIDC_1080P_ERROR_NON_FRAME_DATA_RECEIVED: + case VIDC_1080P_ERROR_NALU_HEADER_ERROR: + case VIDC_1080P_ERROR_SPS_PARSE_ERROR: + case VIDC_1080P_ERROR_PPS_PARSE_ERROR: + case VIDC_1080P_ERROR_HEADER_NOT_FOUND: + case VIDC_1080P_ERROR_SLICE_PARSE_ERROR: + case VIDC_1080P_ERROR_NON_PAIRED_FIELD_NOT_SUPPORTED: + vcd_status = VCD_ERR_BITSTREAM_ERR; + DDL_MSG_ERROR("VIDC_BIT_STREAM_ERR"); + break; + case VIDC_1080P_ERROR_B_FRAME_NOT_SUPPORTED: + case VIDC_1080P_ERROR_UNSUPPORTED_FEATURE_IN_PROFILE: + case VIDC_1080P_ERROR_RESOLUTION_NOT_SUPPORTED: + if (ddl->decoding) { + vcd_status = VCD_ERR_BITSTREAM_ERR; + DDL_MSG_ERROR("VIDC_BIT_STREAM_ERR"); + } + break; + default: + break; + } + + if (((vcd_status) || (vcd_event != VCD_EVT_RESP_INPUT_DONE)) && + !status) { + ddl->input_frame.frm_trans_end = true; + eos = ((vcd_event == VCD_EVT_RESP_INPUT_DONE) && + (ddl->input_frame.vcd_frm.flags & VCD_FRAME_FLAG_EOS)); + if (((ddl->decoding) && (eos)) || !ddl->decoding) + ddl->input_frame.frm_trans_end = false; + ddl_input_failed_cb(ddl, vcd_event, vcd_status); + if (!ddl->decoding) { + ddl->output_frame.frm_trans_end = !eos; + ddl->output_frame.vcd_frm.data_len = 0; + ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE, + VCD_ERR_FAIL, &ddl->output_frame, + sizeof(struct ddl_frame_data_tag), (u32 *)ddl, + ddl->client_data); + if (eos) { + DDL_MSG_LOW("VIDC_ENC_EOS_DONE"); + ddl_context->ddl_callback(VCD_EVT_RESP_EOS_DONE, + VCD_S_SUCCESS, NULL, 0, (u32 *)ddl, + ddl->client_data); + } + } + if ((ddl->decoding) && (eos)) + ddl_vidc_decode_eos_run(ddl); + else + ddl_release_command_channel(ddl_context, + ddl->command_channel); + status = true; + } + return status; +} + +static u32 ddl_handle_core_warnings(u32 err_status) +{ + u32 status = false; + + switch (err_status) { + case VIDC_1080P_WARN_COMMAND_FLUSHED: + case VIDC_1080P_WARN_FRAME_RATE_UNKNOWN: + case VIDC_1080P_WARN_ASPECT_RATIO_UNKNOWN: + case VIDC_1080P_WARN_COLOR_PRIMARIES_UNKNOWN: + case VIDC_1080P_WARN_TRANSFER_CHAR_UNKNOWN: + case VIDC_1080P_WARN_MATRIX_COEFF_UNKNOWN: + case VIDC_1080P_WARN_NON_SEQ_SLICE_ADDR: + case VIDC_1080P_WARN_BROKEN_LINK: + case VIDC_1080P_WARN_FRAME_CONCEALED: + case VIDC_1080P_WARN_PROFILE_UNKNOWN: + case VIDC_1080P_WARN_LEVEL_UNKNOWN: + case VIDC_1080P_WARN_BIT_RATE_NOT_SUPPORTED: + case VIDC_1080P_WARN_COLOR_DIFF_FORMAT_NOT_SUPPORTED: + case VIDC_1080P_WARN_NULL_EXTRA_METADATA_POINTER: + case VIDC_1080P_WARN_DEBLOCKING_NOT_DONE: + case VIDC_1080P_WARN_INCOMPLETE_FRAME: + case VIDC_1080P_ERROR_NULL_FW_DEBUG_INFO_POINTER: + case VIDC_1080P_ERROR_ALLOC_DEBUG_INFO_SIZE_INSUFFICIENT: + case VIDC_1080P_WARN_METADATA_NO_SPACE_NUM_CONCEAL_MB: + case VIDC_1080P_WARN_METADATA_NO_SPACE_QP: + case VIDC_1080P_WARN_METADATA_NO_SPACE_CONCEAL_MB: + case VIDC_1080P_WARN_METADATA_NO_SPACE_VC1_PARAM: + case VIDC_1080P_WARN_METADATA_NO_SPACE_SEI: + case VIDC_1080P_WARN_METADATA_NO_SPACE_VUI: + case VIDC_1080P_WARN_METADATA_NO_SPACE_EXTRA: + case VIDC_1080P_WARN_METADATA_NO_SPACE_DATA_NONE: + case VIDC_1080P_WARN_METADATA_NO_SPACE_MB_INFO: + case VIDC_1080P_WARN_METADATA_NO_SPACE_SLICE_SIZE: + case VIDC_1080P_WARN_RESOLUTION_WARNING: + case VIDC_1080P_WARN_NO_LONG_TERM_REFERENCE: + case VIDC_1080P_WARN_NO_SPACE_MPEG2_DATA_DUMP: + case VIDC_1080P_WARN_METADATA_NO_SPACE_MISSING_MB: + status = true; + DDL_MSG_ERROR("VIDC_WARNING_IGNORED"); + break; + default: + break; + } + return status; +} + +u32 ddl_handle_core_errors(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl; + u32 channel_inst_id, status = false; + u32 disp_status; + + if (!ddl_context->cmd_err_status && + !ddl_context->disp_pic_err_status) { + DDL_MSG_ERROR("VIDC_NO_ERROR"); + return false; + } + vidc_1080p_get_returned_channel_inst_id(&channel_inst_id); + vidc_1080p_clear_returned_channel_inst_id(); + ddl = ddl_get_current_ddl_client_for_channel_id(ddl_context, + ddl_context->response_cmd_ch_id); + if (!ddl) { + DDL_MSG_ERROR("VIDC_SPURIOUS_INTERRUPT_ERROR"); + return true; + } + if (ddl_context->cmd_err_status) { + print_core_errors(ddl_context->cmd_err_status); + print_core_recoverable_errors(ddl_context->cmd_err_status); + } + if (ddl_context->disp_pic_err_status) + print_core_errors(ddl_context->disp_pic_err_status); + status = ddl_handle_core_warnings(ddl_context->cmd_err_status); + disp_status = ddl_handle_core_warnings( + ddl_context->disp_pic_err_status); + if (!status && !disp_status) { + DDL_MSG_ERROR("ddl_warning:Unknown"); + status = ddl_handle_hw_fatal_errors(ddl); + if (!status) + status = ddl_handle_core_recoverable_errors(ddl); + if (!status) + status = ddl_handle_client_fatal_errors(ddl); + } + return status; +} + +static void ddl_release_prev_field(struct ddl_client_context *ddl) +{ + ddl->output_frame.vcd_frm.ip_frm_tag = + ddl->codec_data.decoder.prev_ip_frm_tag; + ddl->output_frame.vcd_frm.physical = NULL; + ddl->output_frame.vcd_frm.virtual = NULL; + ddl->output_frame.frm_trans_end = false; + ddl->ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE, + VCD_ERR_INTRLCD_FIELD_DROP, &(ddl->output_frame), + sizeof(struct ddl_frame_data_tag), + (u32 *) ddl, ddl->client_data); +} + +static u32 ddl_handle_dec_seq_hdr_fail_error(struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + u32 status = false; + + if ((ddl->cmd_state != DDL_CMD_HEADER_PARSE) || + (ddl->client_state != DDL_CLIENT_WAIT_FOR_INITCODECDONE)) { + DDL_MSG_ERROR("STATE-CRITICAL-HDDONE"); + return false; + } + + switch (ddl_context->cmd_err_status) { + case VIDC_1080P_ERROR_UNSUPPORTED_FEATURE_IN_PROFILE: + case VIDC_1080P_ERROR_RESOLUTION_NOT_SUPPORTED: + case VIDC_1080P_ERROR_HEADER_NOT_FOUND: + case VIDC_1080P_ERROR_SPS_PARSE_ERROR: + case VIDC_1080P_ERROR_PPS_PARSE_ERROR: + { + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + if (ddl_context->cmd_err_status == + VIDC_1080P_ERROR_UNSUPPORTED_FEATURE_IN_PROFILE + && decoder->codec.codec == VCD_CODEC_H264) { + DDL_MSG_ERROR("Unsupported Feature for H264"); + ddl_client_fatal_cb(ddl); + return true; + } + if ((ddl_context->cmd_err_status == + VIDC_1080P_ERROR_RESOLUTION_NOT_SUPPORTED) + && (decoder->codec.codec == VCD_CODEC_H263 + || decoder->codec.codec == VCD_CODEC_H264 + || decoder->codec.codec == VCD_CODEC_MPEG4 + || decoder->codec.codec == VCD_CODEC_VC1 + || decoder->codec.codec == VCD_CODEC_VC1_RCV)) { + DDL_MSG_ERROR("Unsupported resolution"); + ddl_client_fatal_cb(ddl); + return true; + } + + DDL_MSG_ERROR("SEQHDR-FAILED"); + if (decoder->header_in_start) { + decoder->header_in_start = false; + ddl_context->ddl_callback(VCD_EVT_RESP_START, + VCD_ERR_SEQHDR_PARSE_FAIL, NULL, 0, + (u32 *) ddl, ddl->client_data); + } else { + ddl->input_frame.frm_trans_end = true; + if ((ddl->input_frame.vcd_frm.flags & + VCD_FRAME_FLAG_EOS)) { + ddl->input_frame.frm_trans_end = false; + } + ddl_vidc_decode_dynamic_property(ddl, false); + ddl_context->ddl_callback( + VCD_EVT_RESP_INPUT_DONE, + VCD_ERR_SEQHDR_PARSE_FAIL, &ddl->input_frame, + sizeof(struct ddl_frame_data_tag), (u32 *)ddl, + ddl->client_data); + if ((ddl->input_frame.vcd_frm.flags & + VCD_FRAME_FLAG_EOS)) { + DDL_MSG_HIGH("EOS_DONE-fromDDL"); + ddl_context->ddl_callback(VCD_EVT_RESP_EOS_DONE, + VCD_S_SUCCESS, NULL, 0, (u32 *) ddl, + ddl->client_data); + } + } + DDL_MSG_LOW("ddl_state_transition: %s ~~> " + "DDL_CLIENT_WAIT_FOR_INITCODEC", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_INITCODEC; + ddl_release_command_channel(ddl_context, ddl->command_channel); + status = true; + break; + } + default: + break; + } + return status; +} + +void print_core_errors(u32 error_code) +{ + s8 *string = NULL; + + switch (error_code) { + case VIDC_1080P_ERROR_INVALID_CHANNEL_NUMBER: + string = "VIDC_1080P_ERROR_INVALID_CHANNEL_NUMBER"; + break; + case VIDC_1080P_ERROR_INVALID_COMMAND_ID: + string = "VIDC_1080P_ERROR_INVALID_COMMAND_ID"; + break; + case VIDC_1080P_ERROR_CHANNEL_ALREADY_IN_USE: + string = "VIDC_1080P_ERROR_CHANNEL_ALREADY_IN_USE"; + break; + case VIDC_1080P_ERROR_CHANNEL_NOT_OPEN_BEFORE_CHANNEL_CLOSE: + string = + "VIDC_1080P_ERROR_CHANNEL_NOT_OPEN_BEFORE_CHANNEL_CLOSE"; + break; + case VIDC_1080P_ERROR_OPEN_CH_ERROR_SEQ_START: + string = "VIDC_1080P_ERROR_OPEN_CH_ERROR_SEQ_START"; + break; + case VIDC_1080P_ERROR_SEQ_START_ALREADY_CALLED: + string = "VIDC_1080P_ERROR_SEQ_START_ALREADY_CALLED"; + break; + case VIDC_1080P_ERROR_OPEN_CH_ERROR_INIT_BUFFERS: + string = "VIDC_1080P_ERROR_OPEN_CH_ERROR_INIT_BUFFERS"; + break; + case VIDC_1080P_ERROR_SEQ_START_ERROR_INIT_BUFFERS: + string = "VIDC_1080P_ERROR_SEQ_START_ERROR_INIT_BUFFERS"; + break; + case VIDC_1080P_ERROR_INIT_BUFFER_ALREADY_CALLED: + string = "VIDC_1080P_ERROR_INIT_BUFFER_ALREADY_CALLED"; + break; + case VIDC_1080P_ERROR_OPEN_CH_ERROR_FRAME_START: + string = "VIDC_1080P_ERROR_OPEN_CH_ERROR_FRAME_START"; + break; + case VIDC_1080P_ERROR_SEQ_START_ERROR_FRAME_START: + string = "VIDC_1080P_ERROR_SEQ_START_ERROR_FRAME_START"; + break; + case VIDC_1080P_ERROR_INIT_BUFFERS_ERROR_FRAME_START: + string = "VIDC_1080P_ERROR_INIT_BUFFERS_ERROR_FRAME_START"; + break; + case VIDC_1080P_ERROR_RESOLUTION_CHANGED: + string = "VIDC_1080P_ERROR_RESOLUTION_CHANGED"; + break; + case VIDC_1080P_ERROR_INVALID_COMMAND_LAST_FRAME: + string = "VIDC_1080P_ERROR_INVALID_COMMAND_LAST_FRAME"; + break; + case VIDC_1080P_ERROR_INVALID_COMMAND: + string = "VIDC_1080P_ERROR_INVALID_COMMAND"; + break; + case VIDC_1080P_ERROR_INVALID_CODEC_TYPE: + string = "VIDC_1080P_ERROR_INVALID_CODEC_TYPE"; + break; + case VIDC_1080P_ERROR_MEM_ALLOCATION_FAILED: + string = "VIDC_1080P_ERROR_MEM_ALLOCATION_FAILED"; + break; + case VIDC_1080P_ERROR_INSUFFICIENT_CONTEXT_SIZE: + string = "VIDC_1080P_ERROR_INSUFFICIENT_CONTEXT_SIZE"; + break; + case VIDC_1080P_ERROR_DIVIDE_BY_ZERO: + string = "VIDC_1080P_ERROR_DIVIDE_BY_ZERO"; + break; + case VIDC_1080P_ERROR_DESCRIPTOR_BUFFER_EMPTY: + string = "VIDC_1080P_ERROR_DESCRIPTOR_BUFFER_EMPTY"; + break; + case VIDC_1080P_ERROR_DMA_TX_NOT_COMPLETE: + string = "VIDC_1080P_ERROR_DMA_TX_NOT_COMPLETE"; + break; + case VIDC_1080P_ERROR_VSP_NOT_READY: + string = "VIDC_1080P_ERROR_VSP_NOT_READY"; + break; + case VIDC_1080P_ERROR_BUFFER_FULL_STATE: + string = "VIDC_1080P_ERROR_BUFFER_FULL_STATE"; + break; + case VIDC_1080P_ERROR_UNSUPPORTED_FEATURE_IN_PROFILE: + string = "VIDC_1080P_ERROR_UNSUPPORTED_FEATURE_IN_PROFILE"; + break; + case VIDC_1080P_ERROR_HEADER_NOT_FOUND: + string = "VIDC_1080P_ERROR_HEADER_NOT_FOUND"; + break; + case VIDC_1080P_ERROR_VOS_END_CODE_RECEIVED: + string = "VIDC_1080P_ERROR_VOS_END_CODE_RECEIVED"; + break; + case VIDC_1080P_ERROR_RESOLUTION_NOT_SUPPORTED: + string = "VIDC_1080P_ERROR_RESOLUTION_NOT_SUPPORTED"; + break; + case VIDC_1080P_ERROR_FRAME_RATE_NOT_SUPPORTED: + string = "VIDC_1080P_ERROR_FRAME_RATE_NOT_SUPPORTED"; + break; + case VIDC_1080P_ERROR_INVALID_QP_VALUE: + string = "VIDC_1080P_ERROR_INVALID_QP_VALUE"; + break; + case VIDC_1080P_ERROR_INVALID_RC_REACTION_COEFFICIENT: + string = "VIDC_1080P_ERROR_INVALID_RC_REACTION_COEFFICIENT"; + break; + case VIDC_1080P_ERROR_INVALID_CPB_SIZE_AT_GIVEN_LEVEL: + string = "VIDC_1080P_ERROR_INVALID_CPB_SIZE_AT_GIVEN_LEVEL"; + break; + case VIDC_1080P_ERROR_B_FRAME_NOT_SUPPORTED: + string = "VIDC_1080P_ERROR_B_FRAME_NOT_SUPPORTED"; + break; + case VIDC_1080P_ERROR_ALLOC_DPB_SIZE_NOT_SUFFICIENT: + string = "VIDC_1080P_ERROR_ALLOC_DPB_SIZE_NOT_SUFFICIENT"; + break; + case VIDC_1080P_ERROR_NUM_DPB_OUT_OF_RANGE: + string = "VIDC_1080P_ERROR_NUM_DPB_OUT_OF_RANGE"; + break; + case VIDC_1080P_ERROR_NULL_METADATA_INPUT_POINTER: + string = "VIDC_1080P_ERROR_NULL_METADATA_INPUT_POINTER"; + break; + case VIDC_1080P_ERROR_NULL_DPB_POINTER: + string = "VIDC_1080P_ERROR_NULL_DPB_POINTER"; + break; + case VIDC_1080P_ERROR_NULL_OTH_EXT_BUFADDR: + string = "VIDC_1080P_ERROR_NULL_OTH_EXT_BUFADDR"; + break; + case VIDC_1080P_ERROR_NULL_MV_POINTER: + string = "VIDC_1080P_ERROR_NULL_MV_POINTER"; + break; + case VIDC_1080P_ERROR_NON_PAIRED_FIELD_NOT_SUPPORTED: + string = "VIDC_1080P_ERROR_NON_PAIRED_FIELD_NOT_SUPPORTED"; + break; + case VIDC_1080P_WARN_COMMAND_FLUSHED: + string = "VIDC_1080P_WARN_COMMAND_FLUSHED"; + break; + case VIDC_1080P_WARN_FRAME_RATE_UNKNOWN: + string = "VIDC_1080P_WARN_FRAME_RATE_UNKNOWN"; + break; + case VIDC_1080P_WARN_ASPECT_RATIO_UNKNOWN: + string = "VIDC_1080P_WARN_ASPECT_RATIO_UNKNOWN"; + break; + case VIDC_1080P_WARN_COLOR_PRIMARIES_UNKNOWN: + string = "VIDC_1080P_WARN_COLOR_PRIMARIES_UNKNOWN"; + break; + case VIDC_1080P_WARN_TRANSFER_CHAR_UNKNOWN: + string = "VIDC_1080P_WARN_TRANSFER_CHAR_UNKNOWN"; + break; + case VIDC_1080P_WARN_MATRIX_COEFF_UNKNOWN: + string = "VIDC_1080P_WARN_MATRIX_COEFF_UNKNOWN"; + break; + case VIDC_1080P_WARN_NON_SEQ_SLICE_ADDR: + string = "VIDC_1080P_WARN_NON_SEQ_SLICE_ADDR"; + break; + case VIDC_1080P_WARN_BROKEN_LINK: + string = "VIDC_1080P_WARN_BROKEN_LINK"; + break; + case VIDC_1080P_WARN_FRAME_CONCEALED: + string = "VIDC_1080P_WARN_FRAME_CONCEALED"; + break; + case VIDC_1080P_WARN_PROFILE_UNKNOWN: + string = "VIDC_1080P_WARN_PROFILE_UNKNOWN"; + break; + case VIDC_1080P_WARN_LEVEL_UNKNOWN: + string = "VIDC_1080P_WARN_LEVEL_UNKNOWN"; + break; + case VIDC_1080P_WARN_BIT_RATE_NOT_SUPPORTED: + string = "VIDC_1080P_WARN_BIT_RATE_NOT_SUPPORTED"; + break; + case VIDC_1080P_WARN_COLOR_DIFF_FORMAT_NOT_SUPPORTED: + string = "VIDC_1080P_WARN_COLOR_DIFF_FORMAT_NOT_SUPPORTED"; + break; + case VIDC_1080P_WARN_NULL_EXTRA_METADATA_POINTER: + string = "VIDC_1080P_WARN_NULL_EXTRA_METADATA_POINTER"; + break; + case VIDC_1080P_WARN_DEBLOCKING_NOT_DONE: + string = "VIDC_1080P_WARN_DEBLOCKING_NOT_DONE"; + break; + case VIDC_1080P_WARN_INCOMPLETE_FRAME: + string = "VIDC_1080P_WARN_INCOMPLETE_FRAME"; + break; + case VIDC_1080P_ERROR_NULL_FW_DEBUG_INFO_POINTER: + string = "VIDC_1080P_ERROR_NULL_FW_DEBUG_INFO_POINTER"; + break; + case VIDC_1080P_ERROR_ALLOC_DEBUG_INFO_SIZE_INSUFFICIENT: + string = + "VIDC_1080P_ERROR_ALLOC_DEBUG_INFO_SIZE_INSUFFICIENT"; + break; + case VIDC_1080P_WARN_METADATA_NO_SPACE_NUM_CONCEAL_MB: + string = "VIDC_1080P_WARN_METADATA_NO_SPACE_NUM_CONCEAL_MB"; + break; + case VIDC_1080P_WARN_METADATA_NO_SPACE_QP: + string = "VIDC_1080P_WARN_METADATA_NO_SPACE_QP"; + break; + case VIDC_1080P_WARN_METADATA_NO_SPACE_CONCEAL_MB: + string = "VIDC_1080P_WARN_METADATA_NO_SPACE_CONCEAL_MB"; + break; + case VIDC_1080P_WARN_METADATA_NO_SPACE_VC1_PARAM: + string = "VIDC_1080P_WARN_METADATA_NO_SPACE_VC1_PARAM"; + break; + case VIDC_1080P_WARN_METADATA_NO_SPACE_SEI: + string = "VIDC_1080P_WARN_METADATA_NO_SPACE_SEI"; + break; + case VIDC_1080P_WARN_METADATA_NO_SPACE_VUI: + string = "VIDC_1080P_WARN_METADATA_NO_SPACE_VUI"; + break; + case VIDC_1080P_WARN_METADATA_NO_SPACE_EXTRA: + string = "VIDC_1080P_WARN_METADATA_NO_SPACE_EXTRA"; + break; + case VIDC_1080P_WARN_METADATA_NO_SPACE_DATA_NONE: + string = "VIDC_1080P_WARN_METADATA_NO_SPACE_DATA_NONE"; + break; + case VIDC_1080P_WARN_METADATA_NO_SPACE_MB_INFO: + string = "VIDC_1080P_WARN_METADATA_NO_SPACE_MB_INFO"; + break; + case VIDC_1080P_WARN_METADATA_NO_SPACE_SLICE_SIZE: + string = "VIDC_1080P_WARN_METADATA_NO_SPACE_SLICE_SIZE"; + break; + case VIDC_1080P_WARN_RESOLUTION_WARNING: + string = "VIDC_1080P_WARN_RESOLUTION_WARNING"; + break; + case VIDC_1080P_WARN_NO_LONG_TERM_REFERENCE: + string = "VIDC_1080P_WARN_NO_LONG_TERM_REFERENCE"; + break; + case VIDC_1080P_WARN_NO_SPACE_MPEG2_DATA_DUMP: + string = "VIDC_1080P_WARN_NO_SPACE_MPEG2_DATA_DUMP"; + break; + case VIDC_1080P_WARN_METADATA_NO_SPACE_MISSING_MB: + string = "VIDC_1080P_WARN_METADATA_NO_SPACE_MISSING_MB"; + break; + } + if (string) + DDL_MSG_ERROR("Error code = 0x%x : %s", error_code, string); +} + +void print_core_recoverable_errors(u32 error_code) +{ + s8 *string = NULL; + + switch (error_code) { + case VIDC_1080P_ERROR_SYNC_POINT_NOT_RECEIVED: + string = "VIDC_1080P_ERROR_SYNC_POINT_NOT_RECEIVED"; + break; + case VIDC_1080P_ERROR_NO_BUFFER_RELEASED_FROM_HOST: + string = "VIDC_1080P_ERROR_NO_BUFFER_RELEASED_FROM_HOST"; + break; + case VIDC_1080P_ERROR_BIT_STREAM_BUF_EXHAUST: + string = "VIDC_1080P_ERROR_BIT_STREAM_BUF_EXHAUST"; + break; + case VIDC_1080P_ERROR_DESCRIPTOR_TABLE_ENTRY_INVALID: + string = "VIDC_1080P_ERROR_DESCRIPTOR_TABLE_ENTRY_INVALID"; + break; + case VIDC_1080P_ERROR_MB_COEFF_NOT_DONE: + string = "VIDC_1080P_ERROR_MB_COEFF_NOT_DONE"; + break; + case VIDC_1080P_ERROR_CODEC_SLICE_NOT_DONE: + string = "VIDC_1080P_ERROR_CODEC_SLICE_NOT_DONE"; + break; + case VIDC_1080P_ERROR_VIDC_CORE_TIME_OUT: + string = "VIDC_1080P_ERROR_VIDC_CORE_TIME_OUT"; + break; + case VIDC_1080P_ERROR_VC1_BITPLANE_DECODE_ERR: + string = "VIDC_1080P_ERROR_VC1_BITPLANE_DECODE_ERR"; + break; + case VIDC_1080P_ERROR_RESOLUTION_MISMATCH: + string = "VIDC_1080P_ERROR_RESOLUTION_MISMATCH"; + break; + case VIDC_1080P_ERROR_NV_QUANT_ERR: + string = "VIDC_1080P_ERROR_NV_QUANT_ERR"; + break; + case VIDC_1080P_ERROR_SYNC_MARKER_ERR: + string = "VIDC_1080P_ERROR_SYNC_MARKER_ERR"; + break; + case VIDC_1080P_ERROR_FEATURE_NOT_SUPPORTED: + string = "VIDC_1080P_ERROR_FEATURE_NOT_SUPPORTED"; + break; + case VIDC_1080P_ERROR_MEM_CORRUPTION: + string = "VIDC_1080P_ERROR_MEM_CORRUPTION"; + break; + case VIDC_1080P_ERROR_INVALID_REFERENCE_FRAME: + string = "VIDC_1080P_ERROR_INVALID_REFERENCE_FRAME"; + break; + case VIDC_1080P_ERROR_PICTURE_CODING_TYPE_ERR: + string = "VIDC_1080P_ERROR_PICTURE_CODING_TYPE_ERR"; + break; + case VIDC_1080P_ERROR_MV_RANGE_ERR: + string = "VIDC_1080P_ERROR_MV_RANGE_ERR"; + break; + case VIDC_1080P_ERROR_PICTURE_STRUCTURE_ERR: + string = "VIDC_1080P_ERROR_PICTURE_STRUCTURE_ERR"; + break; + case VIDC_1080P_ERROR_SLICE_ADDR_INVALID: + string = "VIDC_1080P_ERROR_SLICE_ADDR_INVALID"; + break; + case VIDC_1080P_ERROR_NON_FRAME_DATA_RECEIVED: + string = "VIDC_1080P_ERROR_NON_FRAME_DATA_RECEIVED"; + break; + case VIDC_1080P_ERROR_NALU_HEADER_ERROR: + string = "VIDC_1080P_ERROR_NALU_HEADER_ERROR"; + break; + case VIDC_1080P_ERROR_SPS_PARSE_ERROR: + string = "VIDC_1080P_ERROR_SPS_PARSE_ERROR"; + break; + case VIDC_1080P_ERROR_PPS_PARSE_ERROR: + string = "VIDC_1080P_ERROR_PPS_PARSE_ERROR"; + break; + case VIDC_1080P_ERROR_SLICE_PARSE_ERROR: + string = "VIDC_1080P_ERROR_SLICE_PARSE_ERROR"; + break; + } + if (string) + DDL_MSG_ERROR("Recoverable Error code = 0x%x : %s", + error_code, string); +} diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c new file mode 100644 index 000000000000..aaa6edc629d1 --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c @@ -0,0 +1,1074 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#include +#include +#include "vcd_ddl.h" +#include "vcd_ddl_shared_mem.h" +#include "vcd_res_tracker_api.h" + +struct ddl_context *ddl_get_context(void) +{ + static struct ddl_context ddl_context; + return &ddl_context; +} + +#ifdef DDL_MSG_LOG +s8 *ddl_get_state_string(enum ddl_client_state client_state) +{ + s8 *ptr; + + switch (client_state) { + case DDL_CLIENT_INVALID: + ptr = "INVALID "; + break; + case DDL_CLIENT_OPEN: + ptr = "OPEN "; + break; + case DDL_CLIENT_WAIT_FOR_CHDONE: + ptr = "WAIT_FOR_CHDONE "; + break; + case DDL_CLIENT_WAIT_FOR_INITCODEC: + ptr = "WAIT_FOR_INITCODEC "; + break; + case DDL_CLIENT_WAIT_FOR_INITCODECDONE: + ptr = "WAIT_FOR_INITCODECDONE"; + break; + case DDL_CLIENT_WAIT_FOR_DPB: + ptr = "WAIT_FOR_DPB "; + break; + case DDL_CLIENT_WAIT_FOR_DPBDONE: + ptr = "WAIT_FOR_DPBDONE"; + break; + case DDL_CLIENT_WAIT_FOR_FRAME: + ptr = "WAIT_FOR_FRAME "; + break; + case DDL_CLIENT_WAIT_FOR_FRAME_DONE: + ptr = "WAIT_FOR_FRAME_DONE "; + break; + case DDL_CLIENT_WAIT_FOR_EOS_DONE: + ptr = "WAIT_FOR_EOS_DONE "; + break; + case DDL_CLIENT_WAIT_FOR_CHEND: + ptr = "WAIT_FOR_CHEND "; + break; + case DDL_CLIENT_FATAL_ERROR: + ptr = "FATAL_ERROR"; + break; + default: + ptr = "UNKNOWN "; + break; + } + return ptr; +} +#endif + +u32 ddl_client_transact(u32 operation, + struct ddl_client_context **pddl_client) +{ + struct ddl_context *ddl_context; + u32 ret_status = VCD_ERR_FAIL; + s32 counter; + + ddl_context = ddl_get_context(); + switch (operation) { + case DDL_FREE_CLIENT: + ret_status = VCD_ERR_MAX_CLIENT; + for (counter = 0; (counter < VCD_MAX_NO_CLIENT) && + (ret_status == VCD_ERR_MAX_CLIENT); ++counter) { + if (*pddl_client == ddl_context->ddl_clients + [counter]) { + kfree(*pddl_client); + *pddl_client = NULL; + ddl_context->ddl_clients[counter] + = NULL; + ret_status = VCD_S_SUCCESS; + } + } + break; + case DDL_GET_CLIENT: + ret_status = VCD_ERR_MAX_CLIENT; + for (counter = (VCD_MAX_NO_CLIENT - 1); (counter >= 0) && + (ret_status == VCD_ERR_MAX_CLIENT); --counter) { + if (!ddl_context->ddl_clients[counter]) { + *pddl_client = + (struct ddl_client_context *) + kmalloc(sizeof(struct + ddl_client_context), GFP_KERNEL); + if (!*pddl_client) + ret_status = VCD_ERR_ALLOC_FAIL; + else { + memset(*pddl_client, 0, + sizeof(struct + ddl_client_context)); + ddl_context->ddl_clients + [counter] = *pddl_client; + (*pddl_client)->ddl_context = + ddl_context; + ret_status = VCD_S_SUCCESS; + } + } + } + break; + case DDL_INIT_CLIENTS: + for (counter = 0; counter < VCD_MAX_NO_CLIENT; ++counter) + ddl_context->ddl_clients[counter] = NULL; + ret_status = VCD_S_SUCCESS; + break; + case DDL_ACTIVE_CLIENT: + for (counter = 0; counter < VCD_MAX_NO_CLIENT; + ++counter) { + if (ddl_context->ddl_clients[counter]) { + ret_status = VCD_S_SUCCESS; + break; + } + } + break; + default: + ret_status = VCD_ERR_ILLEGAL_PARM; + break; + } + return ret_status; +} + +u32 ddl_decoder_dpb_transact(struct ddl_decoder_data *decoder, + struct ddl_frame_data_tag *in_out_frame, u32 operation) +{ + struct ddl_frame_data_tag *found_frame = NULL; + struct ddl_mask *dpb_mask = &decoder->dpb_mask; + u32 vcd_status = VCD_S_SUCCESS, loopc; + + switch (operation) { + case DDL_DPB_OP_MARK_BUSY: + case DDL_DPB_OP_MARK_FREE: + for (loopc = 0; !found_frame && loopc < + decoder->dp_buf.no_of_dec_pic_buf; ++loopc) { + if (in_out_frame->vcd_frm.physical == + decoder->dp_buf.dec_pic_buffers[loopc]. + vcd_frm.physical) { + found_frame = &(decoder->dp_buf. + dec_pic_buffers[loopc]); + break; + } + } + if (found_frame) { + if (operation == DDL_DPB_OP_MARK_BUSY) { + dpb_mask->hw_mask &= + (~(u32)(0x1 << loopc)); + *in_out_frame = *found_frame; + } else if (operation == DDL_DPB_OP_MARK_FREE) { + dpb_mask->client_mask |= (0x1 << loopc); + *found_frame = *in_out_frame; + } + } else { + in_out_frame->vcd_frm.physical = NULL; + in_out_frame->vcd_frm.virtual = NULL; + vcd_status = VCD_ERR_BAD_POINTER; + DDL_MSG_ERROR("BUF_NOT_FOUND"); + } + break; + case DDL_DPB_OP_SET_MASK: + dpb_mask->hw_mask |= dpb_mask->client_mask; + dpb_mask->client_mask = 0; + break; + case DDL_DPB_OP_INIT: + { + u32 dpb_size; + dpb_size = (!decoder->meta_data_offset) ? + decoder->dp_buf.dec_pic_buffers[0].vcd_frm.alloc_len : + decoder->meta_data_offset; + } + break; + case DDL_DPB_OP_RETRIEVE: + { + u32 position; + if (dpb_mask->client_mask) { + position = 0x1; + for (loopc = 0; loopc < + decoder->dp_buf.no_of_dec_pic_buf && + !found_frame; ++loopc) { + if (dpb_mask->client_mask & position) { + found_frame = &decoder->dp_buf. + dec_pic_buffers[loopc]; + dpb_mask->client_mask &= + ~(position); + } + position <<= 1; + } + } else if (dpb_mask->hw_mask) { + position = 0x1; + for (loopc = 0; loopc < + decoder->dp_buf.no_of_dec_pic_buf && + !found_frame; ++loopc) { + if (dpb_mask->hw_mask & position) { + found_frame = &decoder->dp_buf. + dec_pic_buffers[loopc]; + dpb_mask->hw_mask &= ~(position); + } + position <<= 1; + } + } + if (found_frame) + *in_out_frame = *found_frame; + else { + in_out_frame->vcd_frm.physical = NULL; + in_out_frame->vcd_frm.virtual = NULL; + } + } + break; + default: + break; + } + return vcd_status; +} + +u32 ddl_decoder_dpb_init(struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + struct ddl_dec_buffers *dec_buffers = &decoder->hw_bufs; + struct ddl_frame_data_tag *frame; + u32 luma[DDL_MAX_BUFFER_COUNT], chroma[DDL_MAX_BUFFER_COUNT]; + u32 mv[DDL_MAX_BUFFER_COUNT], luma_size, i, dpb; + frame = &decoder->dp_buf.dec_pic_buffers[0]; + luma_size = ddl_get_yuv_buf_size(decoder->frame_size.width, + decoder->frame_size.height, DDL_YUV_BUF_TYPE_TILE); + dpb = decoder->dp_buf.no_of_dec_pic_buf; + DDL_MSG_LOW("%s Decoder num DPB buffers = %u Luma Size = %u" + __func__, dpb, luma_size); + if (dpb > DDL_MAX_BUFFER_COUNT) + dpb = DDL_MAX_BUFFER_COUNT; + for (i = 0; i < dpb; i++) { + if (!(res_trk_check_for_sec_session()) && + frame[i].vcd_frm.virtual) { + if (luma_size <= frame[i].vcd_frm.alloc_len) { + memset(frame[i].vcd_frm.virtual, + 0x10101010, luma_size); + memset(frame[i].vcd_frm.virtual + luma_size, + 0x80808080, + frame[i].vcd_frm.alloc_len - luma_size); + if (frame[i].vcd_frm.ion_flag == CACHED) { + msm_ion_do_cache_op( + ddl_context->video_ion_client, + frame[i].vcd_frm.buff_ion_handle, + (unsigned long *)frame[i]. + vcd_frm.virtual, + (unsigned long)frame[i]. + vcd_frm.alloc_len, + ION_IOC_CLEAN_INV_CACHES); + } + } else { + DDL_MSG_ERROR("luma size error"); + return VCD_ERR_FAIL; + } + } + + luma[i] = DDL_OFFSET(ddl_context->dram_base_a. + align_physical_addr, frame[i].vcd_frm.physical); + chroma[i] = luma[i] + luma_size; + DDL_MSG_LOW("%s Decoder Luma address = %x Chroma address = %x" + __func__, luma[i], chroma[i]); + } + switch (decoder->codec.codec) { + case VCD_CODEC_MPEG1: + case VCD_CODEC_MPEG2: + vidc_1080p_set_decode_recon_buffers(dpb, luma, chroma); + break; + case VCD_CODEC_DIVX_3: + case VCD_CODEC_DIVX_4: + case VCD_CODEC_DIVX_5: + case VCD_CODEC_DIVX_6: + case VCD_CODEC_XVID: + case VCD_CODEC_MPEG4: + vidc_1080p_set_decode_recon_buffers(dpb, luma, chroma); + vidc_1080p_set_mpeg4_divx_decode_work_buffers( + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->nb_dcac), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->upnb_mv), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->sub_anchor_mv), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->overlay_xform), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->stx_parser)); + break; + case VCD_CODEC_H263: + vidc_1080p_set_decode_recon_buffers(dpb, luma, chroma); + vidc_1080p_set_h263_decode_work_buffers( + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->nb_dcac), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->upnb_mv), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->sub_anchor_mv), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->overlay_xform)); + break; + case VCD_CODEC_VC1: + case VCD_CODEC_VC1_RCV: + vidc_1080p_set_decode_recon_buffers(dpb, luma, chroma); + vidc_1080p_set_vc1_decode_work_buffers( + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->nb_dcac), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->upnb_mv), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->sub_anchor_mv), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->overlay_xform), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->bit_plane1), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->bit_plane2), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->bit_plane3)); + break; + case VCD_CODEC_H264: + for (i = 0; i < dpb; i++) + mv[i] = DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->h264_mv[i]); + vidc_1080p_set_h264_decode_buffers(dpb, + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->h264_vert_nb_mv), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + dec_buffers->h264_nb_ip), + luma, chroma, mv); + break; + default: + break; + } + return VCD_S_SUCCESS; +} + +void ddl_release_context_buffers(struct ddl_context *ddl_context) +{ + ddl_pmem_free(&ddl_context->metadata_shared_input); + ddl_fw_release(&ddl_context->dram_base_a); +} + +void ddl_release_client_internal_buffers(struct ddl_client_context *ddl) +{ + if (ddl->decoding) { + struct ddl_decoder_data *decoder = + &(ddl->codec_data.decoder); + kfree(decoder->dp_buf.dec_pic_buffers); + decoder->dp_buf.dec_pic_buffers = NULL; + ddl_vidc_decode_dynamic_property(ddl, false); + decoder->decode_config.sequence_header_len = 0; + decoder->decode_config.sequence_header = NULL; + decoder->dpb_mask.client_mask = 0; + decoder->dpb_mask.hw_mask = 0; + decoder->dp_buf.no_of_dec_pic_buf = 0; + decoder->dynamic_prop_change = 0; + ddl_free_dec_hw_buffers(ddl); + } else { + struct ddl_encoder_data *encoder = + &(ddl->codec_data.encoder); + ddl_pmem_free(&encoder->seq_header); + ddl_pmem_free(&encoder->batch_frame.slice_batch_in); + ddl_pmem_free(&encoder->batch_frame.slice_batch_out); + ddl_vidc_encode_dynamic_property(ddl, false); + encoder->dynamic_prop_change = 0; + ddl_free_enc_hw_buffers(ddl); + } + ddl_pmem_free(&ddl->shared_mem[0]); + ddl_pmem_free(&ddl->shared_mem[1]); +} + +u32 ddl_codec_type_transact(struct ddl_client_context *ddl, + u32 remove, enum vcd_codec requested_codec) +{ + if (requested_codec > VCD_CODEC_VC1_RCV || + requested_codec < VCD_CODEC_H264) + return false; + if (!ddl->decoding && requested_codec != VCD_CODEC_MPEG4 && + requested_codec != VCD_CODEC_H264 && + requested_codec != VCD_CODEC_H263) + return false; + + return true; +} + +u32 ddl_take_command_channel(struct ddl_context *ddl_context, + struct ddl_client_context *ddl, void *client_data) +{ + u32 status = true; + + if (!ddl_context->current_ddl[0]) { + ddl_context->current_ddl[0] = ddl; + ddl->client_data = client_data; + ddl->command_channel = 0; + } else if (!ddl_context->current_ddl[1]) { + ddl_context->current_ddl[1] = ddl; + ddl->client_data = client_data; + ddl->command_channel = 1; + } else + status = false; + if (status) { + if (ddl_context->current_ddl[0] && + ddl_context->current_ddl[1]) + DDL_BUSY(ddl_context); + else + DDL_RUN(ddl_context); + } + return status; +} + +void ddl_release_command_channel(struct ddl_context *ddl_context, + u32 command_channel) +{ + ddl_context->current_ddl[command_channel]->client_data = NULL; + ddl_context->current_ddl[command_channel] = NULL; + if (!ddl_context->current_ddl[0] && + !ddl_context->current_ddl[1]) + DDL_IDLE(ddl_context); + else + DDL_RUN(ddl_context); +} + +struct ddl_client_context *ddl_get_current_ddl_client_for_channel_id( + struct ddl_context *ddl_context, u32 channel_id) +{ + struct ddl_client_context *ddl; + + if (ddl_context->current_ddl[0] && channel_id == + ddl_context->current_ddl[0]->command_channel) + ddl = ddl_context->current_ddl[0]; + else if (ddl_context->current_ddl[1] && channel_id == + ddl_context->current_ddl[1]->command_channel) + ddl = ddl_context->current_ddl[1]; + else { + DDL_MSG_LOW("STATE-CRITICAL-FRMRUN"); + DDL_MSG_ERROR("Unexpected channel ID = %d", channel_id); + ddl = NULL; + } + return ddl; +} + +struct ddl_client_context *ddl_get_current_ddl_client_for_command( + struct ddl_context *ddl_context, + enum ddl_cmd_state cmd_state) +{ + struct ddl_client_context *ddl; + + if (ddl_context->current_ddl[0] && + cmd_state == ddl_context->current_ddl[0]->cmd_state) + ddl = ddl_context->current_ddl[0]; + else if (ddl_context->current_ddl[1] && + cmd_state == ddl_context->current_ddl[1]->cmd_state) + ddl = ddl_context->current_ddl[1]; + else { + DDL_MSG_LOW("STATE-CRITICAL-FRMRUN"); + DDL_MSG_ERROR("Error: Unexpected cmd_state = %d", + cmd_state); + ddl = NULL; + } + return ddl; +} + +u32 ddl_get_yuv_buf_size(u32 width, u32 height, u32 format) +{ + u32 mem_size, width_round_up, height_round_up, align; + + width_round_up = width; + height_round_up = height; + if (format == DDL_YUV_BUF_TYPE_TILE) { + width_round_up = DDL_ALIGN(width, DDL_TILE_ALIGN_WIDTH); + height_round_up = DDL_ALIGN(height, DDL_TILE_ALIGN_HEIGHT); + align = DDL_TILE_MULTIPLY_FACTOR; + } + if (format == DDL_YUV_BUF_TYPE_LINEAR) { + width_round_up = DDL_ALIGN(width, DDL_LINEAR_ALIGN_WIDTH); + align = DDL_LINEAR_MULTIPLY_FACTOR; + } + mem_size = (width_round_up * height_round_up); + mem_size = DDL_ALIGN(mem_size, align); + return mem_size; +} +void ddl_free_dec_hw_buffers(struct ddl_client_context *ddl) +{ + struct ddl_dec_buffers *dec_bufs = + &ddl->codec_data.decoder.hw_bufs; + ddl_pmem_free(&dec_bufs->h264_nb_ip); + ddl_pmem_free(&dec_bufs->h264_vert_nb_mv); + ddl_pmem_free(&dec_bufs->nb_dcac); + ddl_pmem_free(&dec_bufs->upnb_mv); + ddl_pmem_free(&dec_bufs->sub_anchor_mv); + ddl_pmem_free(&dec_bufs->overlay_xform); + ddl_pmem_free(&dec_bufs->bit_plane3); + ddl_pmem_free(&dec_bufs->bit_plane2); + ddl_pmem_free(&dec_bufs->bit_plane1); + ddl_pmem_free(&dec_bufs->stx_parser); + ddl_pmem_free(&dec_bufs->desc); + ddl_pmem_free(&dec_bufs->context); + memset(dec_bufs, 0, sizeof(struct ddl_dec_buffers)); +} + +void ddl_free_enc_hw_buffers(struct ddl_client_context *ddl) +{ + struct ddl_enc_buffers *enc_bufs = + &ddl->codec_data.encoder.hw_bufs; + u32 i; + + for (i = 0; i < enc_bufs->dpb_count; i++) { + ddl_pmem_free(&enc_bufs->dpb_y[i]); + ddl_pmem_free(&enc_bufs->dpb_c[i]); + } + ddl_pmem_free(&enc_bufs->mv); + ddl_pmem_free(&enc_bufs->col_zero); + ddl_pmem_free(&enc_bufs->md); + ddl_pmem_free(&enc_bufs->pred); + ddl_pmem_free(&enc_bufs->nbor_info); + ddl_pmem_free(&enc_bufs->acdc_coef); + ddl_pmem_free(&enc_bufs->context); + memset(enc_bufs, 0, sizeof(struct ddl_enc_buffers)); +} + +u32 ddl_get_input_frame_from_pool(struct ddl_client_context *ddl, + u8 *input_buffer_address) +{ + u32 vcd_status = VCD_S_SUCCESS, i, found = false; + + for (i = 0; i < DDL_MAX_NUM_IN_INPUTFRAME_POOL && !found; i++) { + if (input_buffer_address == + ddl->input_frame_pool[i].vcd_frm.physical) { + found = true; + ddl->input_frame = ddl->input_frame_pool[i]; + memset(&ddl->input_frame_pool[i], 0, + sizeof(struct ddl_frame_data_tag)); + } + } + if (!found) + vcd_status = VCD_ERR_FAIL; + + return vcd_status; +} + +u32 ddl_insert_input_frame_to_pool(struct ddl_client_context *ddl, + struct ddl_frame_data_tag *ddl_input_frame) +{ + u32 vcd_status = VCD_S_SUCCESS, i, found = false; + + for (i = 0; i < DDL_MAX_NUM_IN_INPUTFRAME_POOL && !found; i++) { + if (!ddl->input_frame_pool[i].vcd_frm.physical) { + found = true; + ddl->input_frame_pool[i] = *ddl_input_frame; + } + } + if (!found) + vcd_status = VCD_ERR_FAIL; + + return vcd_status; +} + +void ddl_calc_dec_hw_buffers_size(enum vcd_codec codec, u32 width, + u32 height, u32 dpb, struct ddl_dec_buffer_size *buf_size) +{ + u32 sz_dpb0 = 0, sz_dpb1 = 0, sz_mv = 0; + u32 sz_luma = 0, sz_chroma = 0, sz_nb_dcac = 0, sz_upnb_mv = 0; + u32 sz_sub_anchor_mv = 0, sz_overlap_xform = 0, sz_bit_plane3 = 0; + u32 sz_bit_plane2 = 0, sz_bit_plane1 = 0, sz_stx_parser = 0; + u32 sz_desc, sz_cpb, sz_context, sz_vert_nb_mv = 0, sz_nb_ip = 0; + + if (codec == VCD_CODEC_H264) { + sz_mv = ddl_get_yuv_buf_size(width, + height>>2, DDL_YUV_BUF_TYPE_TILE); + sz_nb_ip = DDL_KILO_BYTE(32); + sz_vert_nb_mv = DDL_KILO_BYTE(16); + } else { + if ((codec == VCD_CODEC_MPEG4) || + (codec == VCD_CODEC_DIVX_3) || + (codec == VCD_CODEC_DIVX_4) || + (codec == VCD_CODEC_DIVX_5) || + (codec == VCD_CODEC_DIVX_6) || + (codec == VCD_CODEC_XVID) || + (codec == VCD_CODEC_H263)) { + sz_nb_dcac = DDL_KILO_BYTE(16); + sz_upnb_mv = DDL_KILO_BYTE(68); + sz_sub_anchor_mv = DDL_KILO_BYTE(136); + sz_overlap_xform = DDL_KILO_BYTE(32); + if (codec != VCD_CODEC_H263) + sz_stx_parser = DDL_KILO_BYTE(68); + } else if ((codec == VCD_CODEC_VC1) || + (codec == VCD_CODEC_VC1_RCV)) { + sz_nb_dcac = DDL_KILO_BYTE(16); + sz_upnb_mv = DDL_KILO_BYTE(68); + sz_sub_anchor_mv = DDL_KILO_BYTE(136); + sz_overlap_xform = DDL_KILO_BYTE(32); + sz_bit_plane3 = DDL_KILO_BYTE(2); + sz_bit_plane2 = DDL_KILO_BYTE(2); + sz_bit_plane1 = DDL_KILO_BYTE(2); + } + } + sz_desc = DDL_KILO_BYTE(128); + sz_cpb = VCD_DEC_CPB_SIZE; + if (codec == VCD_CODEC_H264) + sz_context = DDL_FW_H264DEC_CONTEXT_SPACE_SIZE; + else + sz_context = DDL_FW_OTHER_CONTEXT_SPACE_SIZE; + if (buf_size) { + buf_size->sz_dpb0 = sz_dpb0; + buf_size->sz_dpb1 = sz_dpb1; + buf_size->sz_mv = sz_mv; + buf_size->sz_vert_nb_mv = sz_vert_nb_mv; + buf_size->sz_nb_ip = sz_nb_ip; + buf_size->sz_luma = sz_luma; + buf_size->sz_chroma = sz_chroma; + buf_size->sz_nb_dcac = sz_nb_dcac; + buf_size->sz_upnb_mv = sz_upnb_mv; + buf_size->sz_sub_anchor_mv = sz_sub_anchor_mv; + buf_size->sz_overlap_xform = sz_overlap_xform; + buf_size->sz_bit_plane3 = sz_bit_plane3; + buf_size->sz_bit_plane2 = sz_bit_plane2; + buf_size->sz_bit_plane1 = sz_bit_plane1; + buf_size->sz_stx_parser = sz_stx_parser; + buf_size->sz_desc = sz_desc; + buf_size->sz_cpb = sz_cpb; + buf_size->sz_context = sz_context; + } +} + +u32 ddl_allocate_dec_hw_buffers(struct ddl_client_context *ddl) +{ + struct ddl_dec_buffers *dec_bufs; + struct ddl_dec_buffer_size buf_size; + u32 status = VCD_S_SUCCESS, dpb = 0; + u32 width = 0, height = 0; + u8 *ptr; + struct ddl_context *ddl_context = ddl->ddl_context; + + dec_bufs = &ddl->codec_data.decoder.hw_bufs; + ddl_calc_dec_hw_buffers_size(ddl->codec_data.decoder. + codec.codec, width, height, dpb, &buf_size); + if (buf_size.sz_context > 0) { + dec_bufs->context.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&dec_bufs->context, buf_size.sz_context, + DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_free_exit; + else + msm_ion_do_cache_op(ddl_context->video_ion_client, + dec_bufs->context.alloc_handle, + dec_bufs->context.virtual_base_addr, + dec_bufs->context.buffer_size, + ION_IOC_CLEAN_INV_CACHES); + } + if (buf_size.sz_nb_ip > 0) { + dec_bufs->h264_nb_ip.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&dec_bufs->h264_nb_ip, buf_size.sz_nb_ip, + DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_free_exit; + } + if (buf_size.sz_vert_nb_mv > 0) { + dec_bufs->h264_vert_nb_mv.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&dec_bufs->h264_vert_nb_mv, + buf_size.sz_vert_nb_mv, DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_free_exit; + } + if (buf_size.sz_nb_dcac > 0) { + dec_bufs->nb_dcac.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&dec_bufs->nb_dcac, buf_size.sz_nb_dcac, + DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_free_exit; + } + if (buf_size.sz_upnb_mv > 0) { + dec_bufs->upnb_mv.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&dec_bufs->upnb_mv, buf_size.sz_upnb_mv, + DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_free_exit; + } + if (buf_size.sz_sub_anchor_mv > 0) { + dec_bufs->sub_anchor_mv.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&dec_bufs->sub_anchor_mv, + buf_size.sz_sub_anchor_mv, DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_free_exit; + } + if (buf_size.sz_overlap_xform > 0) { + dec_bufs->overlay_xform.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&dec_bufs->overlay_xform, + buf_size.sz_overlap_xform, DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_free_exit; + } + if (buf_size.sz_bit_plane3 > 0) { + dec_bufs->bit_plane3.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&dec_bufs->bit_plane3, + buf_size.sz_bit_plane3, DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_free_exit; + } + if (buf_size.sz_bit_plane2 > 0) { + dec_bufs->bit_plane2.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&dec_bufs->bit_plane2, + buf_size.sz_bit_plane2, DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_free_exit; + } + if (buf_size.sz_bit_plane1 > 0) { + dec_bufs->bit_plane1.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&dec_bufs->bit_plane1, + buf_size.sz_bit_plane1, DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_free_exit; + } + if (buf_size.sz_stx_parser > 0) { + dec_bufs->stx_parser.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&dec_bufs->stx_parser, + buf_size.sz_stx_parser, DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_free_exit; + } + if (buf_size.sz_desc > 0) { + dec_bufs->desc.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&dec_bufs->desc, buf_size.sz_desc, + DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_free_exit; + else { + if (!res_trk_check_for_sec_session()) { + memset(dec_bufs->desc.align_virtual_addr, + 0, buf_size.sz_desc); + msm_ion_do_cache_op( + ddl_context->video_ion_client, + dec_bufs->desc.alloc_handle, + dec_bufs->desc.virtual_base_addr, + dec_bufs->desc.buffer_size, + ION_IOC_CLEAN_INV_CACHES); + } + } + } + return status; +fail_free_exit: + status = VCD_ERR_ALLOC_FAIL; + ddl_free_dec_hw_buffers(ddl); + return status; +} + +u32 ddl_calc_enc_hw_buffers_size(enum vcd_codec codec, u32 width, + u32 height, enum vcd_yuv_buffer_format input_format, + struct ddl_client_context *ddl, + struct ddl_enc_buffer_size *buf_size) +{ + u32 status = VCD_S_SUCCESS, mb_x, mb_y; + u32 sz_cur_y, sz_cur_c, sz_dpb_y, sz_dpb_c, sz_strm = 0, sz_mv; + u32 sz_md = 0, sz_pred = 0, sz_nbor_info = 0 , sz_acdc_coef = 0; + u32 sz_mb_info = 0, sz_context, sz_col_zero = 0; + + mb_x = (width + 15) / 16; + mb_y = (height + 15) / 16; + sz_dpb_y = ddl_get_yuv_buf_size(width, + height, DDL_YUV_BUF_TYPE_TILE); + sz_dpb_c = ddl_get_yuv_buf_size(width, height>>1, + DDL_YUV_BUF_TYPE_TILE); + if (input_format == + VCD_BUFFER_FORMAT_NV12_16M2KA) { + sz_cur_y = ddl_get_yuv_buf_size(width, height, + DDL_YUV_BUF_TYPE_LINEAR); + sz_cur_c = ddl_get_yuv_buf_size(width, height>>1, + DDL_YUV_BUF_TYPE_LINEAR); + } else if (VCD_BUFFER_FORMAT_TILE_4x2 == input_format) { + sz_cur_y = sz_dpb_y; + sz_cur_c = sz_dpb_c; + } else + status = VCD_ERR_NOT_SUPPORTED; + sz_context = DDL_FW_OTHER_CONTEXT_SPACE_SIZE; + if (!status) { + sz_strm = DDL_ALIGN(ddl_get_yuv_buf_size(width, height, + DDL_YUV_BUF_TYPE_LINEAR) + ddl_get_yuv_buf_size(width, + height/2, DDL_YUV_BUF_TYPE_LINEAR), DDL_KILO_BYTE(4)); + sz_mv = DDL_ALIGN(2 * mb_x * mb_y * 8, DDL_KILO_BYTE(2)); + if ((codec == VCD_CODEC_MPEG4) || + (codec == VCD_CODEC_H264)) { + sz_col_zero = DDL_ALIGN(((mb_x * mb_y + 7) / 8) * + 8, DDL_KILO_BYTE(2)); + } + if ((codec == VCD_CODEC_MPEG4) || + (codec == VCD_CODEC_H263)) { + sz_acdc_coef = DDL_ALIGN((width / 2) * 8, + DDL_KILO_BYTE(2)); + } else if (codec == VCD_CODEC_H264) { + sz_md = DDL_ALIGN(mb_x * 48, DDL_KILO_BYTE(2)); + sz_pred = DDL_ALIGN(2 * 8 * 1024, DDL_KILO_BYTE(2)); + sz_context = DDL_FW_H264ENC_CONTEXT_SPACE_SIZE; + if (ddl) { + if (ddl->codec_data.encoder. + entropy_control.entropy_sel == + VCD_ENTROPY_SEL_CAVLC) + sz_nbor_info = DDL_ALIGN(8 * 8 * mb_x, + DDL_KILO_BYTE(2)); + else if (ddl->codec_data.encoder. + entropy_control.entropy_sel == + VCD_ENTROPY_SEL_CABAC) + sz_nbor_info = DDL_ALIGN(8 * 24 * + mb_x, DDL_KILO_BYTE(2)); + if ((ddl->codec_data.encoder. + mb_info_enable) && + (codec == VCD_CODEC_H264)) { + sz_mb_info = DDL_ALIGN(mb_x * mb_y * + 6 * 8, DDL_KILO_BYTE(2)); + } + } + } else { + sz_nbor_info = DDL_ALIGN(8 * 24 * mb_x, + DDL_KILO_BYTE(2)); + sz_mb_info = DDL_ALIGN(mb_x * mb_y * 6 * 8, + DDL_KILO_BYTE(2)); + } + if (buf_size) { + buf_size->sz_cur_y = sz_cur_y; + buf_size->sz_cur_c = sz_cur_c; + buf_size->sz_dpb_y = sz_dpb_y; + buf_size->sz_dpb_c = sz_dpb_c; + buf_size->sz_strm = sz_strm; + buf_size->sz_mv = sz_mv; + buf_size->sz_col_zero = sz_col_zero; + buf_size->sz_md = sz_md; + buf_size->sz_pred = sz_pred; + buf_size->sz_nbor_info = sz_nbor_info; + buf_size->sz_acdc_coef = sz_acdc_coef; + buf_size->sz_mb_info = sz_mb_info; + buf_size->sz_context = sz_context; + } + } + return status; +} + +u32 ddl_allocate_enc_hw_buffers(struct ddl_client_context *ddl) +{ + struct ddl_enc_buffers *enc_bufs; + struct ddl_enc_buffer_size buf_size; + void *ptr; + u32 status = VCD_S_SUCCESS; + struct ddl_context *ddl_context = ddl->ddl_context; + + enc_bufs = &ddl->codec_data.encoder.hw_bufs; + enc_bufs->dpb_count = DDL_ENC_MIN_DPB_BUFFERS; + + if ((ddl->codec_data.encoder.i_period.b_frames > + DDL_MIN_NUM_OF_B_FRAME) || + (ddl->codec_data.encoder.num_references_for_p_frame + > DDL_MIN_NUM_REF_FOR_P_FRAME)) + enc_bufs->dpb_count = DDL_ENC_MAX_DPB_BUFFERS; + DDL_MSG_HIGH("Encoder num DPB buffers allocated = %d", + enc_bufs->dpb_count); + + status = ddl_calc_enc_hw_buffers_size( + ddl->codec_data.encoder.codec.codec, + ddl->codec_data.encoder.frame_size.width, + ddl->codec_data.encoder.frame_size.height, + ddl->codec_data.encoder.buf_format.buffer_format, + ddl, &buf_size); + buf_size.sz_strm = ddl->codec_data.encoder. + client_output_buf_req.sz; + if (!status) { + enc_bufs->sz_dpb_y = buf_size.sz_dpb_y; + enc_bufs->sz_dpb_c = buf_size.sz_dpb_c; + if (buf_size.sz_mv > 0) { + enc_bufs->mv.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&enc_bufs->mv, buf_size.sz_mv, + DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_enc_free_exit; + } + if (buf_size.sz_col_zero > 0) { + enc_bufs->col_zero.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&enc_bufs->col_zero, + buf_size.sz_col_zero, DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_enc_free_exit; + } + if (buf_size.sz_md > 0) { + enc_bufs->md.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&enc_bufs->md, buf_size.sz_md, + DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_enc_free_exit; + } + if (buf_size.sz_pred > 0) { + enc_bufs->pred.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&enc_bufs->pred, + buf_size.sz_pred, DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_enc_free_exit; + } + if (buf_size.sz_nbor_info > 0) { + enc_bufs->nbor_info.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&enc_bufs->nbor_info, + buf_size.sz_nbor_info, DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_enc_free_exit; + } + if (buf_size.sz_acdc_coef > 0) { + enc_bufs->acdc_coef.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&enc_bufs->acdc_coef, + buf_size.sz_acdc_coef, DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_enc_free_exit; + } + if (buf_size.sz_mb_info > 0) { + enc_bufs->mb_info.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&enc_bufs->mb_info, + buf_size.sz_mb_info, DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_enc_free_exit; + } + if (buf_size.sz_context > 0) { + enc_bufs->context.mem_type = DDL_MM_MEM; + ptr = ddl_pmem_alloc(&enc_bufs->context, + buf_size.sz_context, DDL_KILO_BYTE(2)); + if (!ptr) + goto fail_enc_free_exit; + else + msm_ion_do_cache_op( + ddl_context->video_ion_client, + enc_bufs->context.alloc_handle, + enc_bufs->context.virtual_base_addr, + enc_bufs->context.buffer_size, + ION_IOC_CLEAN_INV_CACHES); + } + } + return status; +fail_enc_free_exit: + status = VCD_ERR_ALLOC_FAIL; + ddl_free_enc_hw_buffers(ddl); + return status; +} + +void ddl_decoder_chroma_dpb_change(struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + struct ddl_frame_data_tag *frame = + &(decoder->dp_buf.dec_pic_buffers[0]); + u32 luma[DDL_MAX_BUFFER_COUNT]; + u32 chroma[DDL_MAX_BUFFER_COUNT]; + u32 luma_size, i, dpb; + luma_size = decoder->dpb_buf_size.size_y; + dpb = decoder->dp_buf.no_of_dec_pic_buf; + DDL_MSG_HIGH("%s Decoder num DPB buffers = %u Luma Size = %u" + __func__, dpb, luma_size); + if (dpb > DDL_MAX_BUFFER_COUNT) + dpb = DDL_MAX_BUFFER_COUNT; + for (i = 0; i < dpb; i++) { + luma[i] = DDL_OFFSET( + ddl_context->dram_base_a.align_physical_addr, + frame[i].vcd_frm.physical); + chroma[i] = luma[i] + luma_size; + DDL_MSG_LOW("%s Decoder Luma address = %x" + "Chroma address = %x", __func__, luma[i], chroma[i]); + } + vidc_1080p_set_decode_recon_buffers(dpb, luma, chroma); +} + +u32 ddl_check_reconfig(struct ddl_client_context *ddl) +{ + u32 need_reconfig = true; + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + if (decoder->cont_mode) { + if ((decoder->actual_output_buf_req.sz <= + decoder->client_output_buf_req.sz) && + (decoder->actual_output_buf_req.actual_count <= + decoder->client_output_buf_req.actual_count)) { + need_reconfig = false; + if (decoder->min_dpb_num > + decoder->min_output_buf_req.min_count) { + decoder->min_output_buf_req = + decoder->actual_output_buf_req; + } + DDL_MSG_LOW("%s Decoder width = %u height = %u " + "Client width = %u height = %u\n", + __func__, decoder->frame_size.width, + decoder->frame_size.height, + decoder->client_frame_size.width, + decoder->client_frame_size.height); + } + } else { + if ((decoder->frame_size.width == + decoder->client_frame_size.width) && + (decoder->frame_size.height == + decoder->client_frame_size.height) && + (decoder->actual_output_buf_req.sz <= + decoder->client_output_buf_req.sz) && + (decoder->actual_output_buf_req.min_count == + decoder->client_output_buf_req.min_count) && + (decoder->actual_output_buf_req.actual_count == + decoder->client_output_buf_req.actual_count) && + (decoder->frame_size.scan_lines == + decoder->client_frame_size.scan_lines) && + (decoder->frame_size.stride == + decoder->client_frame_size.stride) && + decoder->progressive_only) + need_reconfig = false; + } + return need_reconfig; +} + +void ddl_handle_reconfig(u32 res_change, struct ddl_client_context *ddl) +{ + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + if ((decoder->cont_mode) && + (res_change == DDL_RESL_CHANGE_DECREASED)) { + DDL_MSG_LOW("%s Resolution decreased, continue decoding\n", + __func__); + vidc_sm_get_min_yc_dpb_sizes( + &ddl->shared_mem[ddl->command_channel], + &decoder->dpb_buf_size.size_y, + &decoder->dpb_buf_size.size_c); + DDL_MSG_LOW(" %s Resolution decreased, size_y = %u" + " size_c = %u\n", + __func__, + decoder->dpb_buf_size.size_y, + decoder->dpb_buf_size.size_c); + ddl_decoder_chroma_dpb_change(ddl); + vidc_sm_set_chroma_addr_change( + &ddl->shared_mem[ddl->command_channel], + true); + ddl_vidc_decode_frame_run(ddl); + } else { + DDL_MSG_LOW("%s Resolution change, start realloc\n", + __func__); + decoder->reconfig_detected = true; + ddl->client_state = DDL_CLIENT_WAIT_FOR_EOS_DONE; + ddl->cmd_state = DDL_CMD_EOS; + vidc_1080p_frame_start_realloc(ddl->instance_id); + } +} + +void ddl_fill_dec_desc_buffer(struct ddl_client_context *ddl) +{ + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + struct vcd_frame_data *ip_bitstream = &(ddl->input_frame.vcd_frm); + struct ddl_buf_addr *dec_desc_buf = &(decoder->hw_bufs.desc); + + if (ip_bitstream->desc_buf && + ip_bitstream->desc_size < DDL_KILO_BYTE(128)) + memcpy(dec_desc_buf->align_virtual_addr, + ip_bitstream->desc_buf, + ip_bitstream->desc_size); +} + +void ddl_set_vidc_timeout(struct ddl_client_context *ddl) +{ + u32 vidc_time_out = 0; + if (ddl->codec_data.decoder.idr_only_decoding) + vidc_time_out = 2 * DDL_VIDC_1080P_200MHZ_TIMEOUT_VALUE; + DDL_MSG_HIGH("%s Video core time out value = 0x%x", + __func__, vidc_time_out); + vidc_sm_set_video_core_timeout_value( + &ddl->shared_mem[ddl->command_channel], vidc_time_out); +} diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c new file mode 100644 index 000000000000..f18f8a9ec7fd --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c @@ -0,0 +1,2042 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + + +#include "vcd_ddl.h" +#include "vcd_ddl_shared_mem.h" +#include "vcd_ddl_metadata.h" +#include "vcd_res_tracker_api.h" +#include + +static void ddl_decoder_input_done_callback( + struct ddl_client_context *ddl, u32 frame_transact_end); +static u32 ddl_decoder_output_done_callback( + struct ddl_client_context *ddl, u32 frame_transact_end); +static u32 ddl_get_decoded_frame(struct vcd_frame_data *frame, + enum vidc_1080p_decode_frame frame_type); +static u32 ddl_get_encoded_frame(struct vcd_frame_data *frame, + enum vcd_codec codec, + enum vidc_1080p_encode_frame frame_type); +static void ddl_get_dec_profile_level(struct ddl_decoder_data *decoder, + u32 profile, u32 level); +static void ddl_handle_enc_frame_done(struct ddl_client_context *ddl, + u32 eos_present); +static void ddl_handle_slice_done_slice_batch(struct ddl_client_context *ddl); +static void ddl_handle_enc_frame_done_slice_mode( + struct ddl_client_context *ddl, u32 eos_present); +static void ddl_handle_enc_skipframe_slice_mode( + struct ddl_client_context *ddl, u32 eos_present); + +static void ddl_fw_status_done_callback(struct ddl_context *ddl_context) +{ + DDL_MSG_MED("ddl_fw_status_done_callback"); + if (!DDLCOMMAND_STATE_IS(ddl_context, DDL_CMD_DMA_INIT)) { + DDL_MSG_ERROR("UNKWN_DMADONE"); + } else { + DDL_MSG_LOW("FW_STATUS_DONE"); + vidc_1080p_set_host2risc_cmd(VIDC_1080P_HOST2RISC_CMD_SYS_INIT, + ddl_context->fw_memory_size, 0, 0, 0); + } +} + +static void ddl_sys_init_done_callback(struct ddl_context *ddl_context, + u32 fw_size) +{ + u32 vcd_status = VCD_S_SUCCESS; + u8 *fw_ver; + + DDL_MSG_MED("ddl_sys_init_done_callback"); + if (!DDLCOMMAND_STATE_IS(ddl_context, DDL_CMD_DMA_INIT)) { + DDL_MSG_ERROR("UNKNOWN_SYS_INIT_DONE"); + } else { + ddl_context->cmd_state = DDL_CMD_INVALID; + DDL_MSG_LOW("SYS_INIT_DONE"); + vidc_1080p_get_fw_version(&ddl_context->fw_version); + fw_ver = (u8 *)&ddl_context->fw_version; + DDL_MSG_ERROR("fw_version %x:%x:20%x", + fw_ver[1]&0xFF, fw_ver[0]&0xFF, fw_ver[2]&0xFF); + if (ddl_context->fw_memory_size >= fw_size) { + ddl_context->device_state = DDL_DEVICE_INITED; + vcd_status = VCD_S_SUCCESS; + } else + vcd_status = VCD_ERR_FAIL; + ddl_context->ddl_callback(VCD_EVT_RESP_DEVICE_INIT, + vcd_status, NULL, 0, NULL, + ddl_context->client_data); + DDL_IDLE(ddl_context); + } +} + +static void ddl_decoder_eos_done_callback( + struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + + if (!ddl->decoding) { + DDL_MSG_ERROR("STATE-CRITICAL-EOSDONE"); + ddl_client_fatal_cb(ddl); + } else { + ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME; + DDL_MSG_LOW("EOS_DONE"); + ddl_context->ddl_callback(VCD_EVT_RESP_EOS_DONE, + VCD_S_SUCCESS, NULL, 0, (u32 *)ddl, + ddl->client_data); + ddl_release_command_channel(ddl_context, + ddl->command_channel); + } +} + +static u32 ddl_channel_set_callback(struct ddl_context *ddl_context, + u32 instance_id) +{ + struct ddl_client_context *ddl; + u32 ret = false; + + DDL_MSG_MED("ddl_channel_open_callback"); + ddl = ddl_get_current_ddl_client_for_command(ddl_context, + DDL_CMD_CHANNEL_SET); + if (ddl) { + ddl->cmd_state = DDL_CMD_INVALID; + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_CHDONE)) { + DDL_MSG_ERROR("STATE-CRITICAL-CHSET"); + ddl_release_command_channel(ddl_context, + ddl->command_channel); + } else { + DDL_MSG_LOW("CH_SET_DONE"); + DDL_MSG_LOW("ddl_state_transition: %s ~~>" + "DDL_CLIENT_WAIT_FOR_INITCODEC", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_INITCODEC; + ddl->instance_id = instance_id; + if (ddl->decoding) { + ddl_calc_core_proc_time(__func__, + DEC_OP_TIME, ddl); + if (ddl->codec_data.decoder.header_in_start) + ddl_vidc_decode_init_codec(ddl); + else { + ddl_context->ddl_callback( + VCD_EVT_RESP_START, + VCD_S_SUCCESS, NULL, 0, + (u32 *)ddl, + ddl->client_data); + ddl_release_command_channel( + ddl_context, + ddl->command_channel); + ret = true; + } + } else + ddl_vidc_encode_init_codec(ddl); + } + } + return ret; +} + +static u32 ddl_encoder_seq_done_callback(struct ddl_context *ddl_context, + struct ddl_client_context *ddl) +{ + struct ddl_encoder_data *encoder; + + DDL_MSG_HIGH("ddl_encoder_seq_done_callback"); + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE)) { + DDL_MSG_ERROR("STATE-CRITICAL-INITCODEC"); + ddl_client_fatal_cb(ddl); + return true; + } + ddl_calc_core_proc_time(__func__, ENC_OP_TIME, ddl); + ddl->cmd_state = DDL_CMD_INVALID; + DDL_MSG_LOW("ddl_state_transition: %s ~~> DDL_CLIENT_WAIT_FOR_FRAME", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME; + DDL_MSG_LOW("INIT_CODEC_DONE"); + encoder = &ddl->codec_data.encoder; + vidc_1080p_get_encoder_sequence_header_size( + &encoder->seq_header_length); + if ((encoder->codec.codec == VCD_CODEC_H264) && + (encoder->profile.profile == VCD_PROFILE_H264_BASELINE)) + if ((encoder->seq_header.align_virtual_addr) && + (encoder->seq_header_length > 6)) + encoder->seq_header.align_virtual_addr[6] = 0xC0; + ddl_context->ddl_callback(VCD_EVT_RESP_START, VCD_S_SUCCESS, + NULL, 0, (u32 *) ddl, ddl->client_data); + ddl_release_command_channel(ddl_context, + ddl->command_channel); + return true; +} + +static void parse_hdr_size_data(struct ddl_client_context *ddl, + struct vidc_1080p_seq_hdr_info *seq_hdr_info) +{ + u32 progressive; + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + if (decoder->output_order == VCD_DEC_ORDER_DISPLAY) { + decoder->frame_size.width = seq_hdr_info->img_size_x; + decoder->frame_size.height = seq_hdr_info->img_size_y; + progressive = seq_hdr_info->disp_progressive; + } else { + vidc_sm_get_dec_order_resl( + &ddl->shared_mem[ddl->command_channel], + &decoder->frame_size.width, + &decoder->frame_size.height); + progressive = seq_hdr_info->dec_progressive; + } + decoder->min_dpb_num = seq_hdr_info->min_num_dpb; + vidc_sm_get_min_yc_dpb_sizes( + &ddl->shared_mem[ddl->command_channel], + &seq_hdr_info->min_luma_dpb_size, + &seq_hdr_info->min_chroma_dpb_size); + decoder->y_cb_cr_size = seq_hdr_info->min_luma_dpb_size + + seq_hdr_info->min_chroma_dpb_size; + decoder->dpb_buf_size.size_yuv = decoder->y_cb_cr_size; + decoder->dpb_buf_size.size_y = + seq_hdr_info->min_luma_dpb_size; + decoder->dpb_buf_size.size_c = + seq_hdr_info->min_chroma_dpb_size; + decoder->progressive_only = progressive ? false : true; +} + +static void parse_hdr_crop_data(struct ddl_client_context *ddl, + struct vidc_1080p_seq_hdr_info *seq_hdr_info) +{ + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + u32 crop_exists = (decoder->output_order == VCD_DEC_ORDER_DISPLAY) ? + seq_hdr_info->disp_crop_exists : seq_hdr_info->dec_crop_exists; + if (crop_exists) { + if (decoder->output_order == + VCD_DEC_ORDER_DISPLAY) + vidc_sm_get_crop_info( + &ddl->shared_mem[ddl->command_channel], + &seq_hdr_info->crop_left_offset, + &seq_hdr_info->crop_right_offset, + &seq_hdr_info->crop_top_offset, + &seq_hdr_info->crop_bottom_offset); + else + vidc_sm_get_dec_order_crop_info( + &ddl->shared_mem[ddl->command_channel], + &seq_hdr_info->crop_left_offset, + &seq_hdr_info->crop_right_offset, + &seq_hdr_info->crop_top_offset, + &seq_hdr_info->crop_bottom_offset); + decoder->frame_size.width -= + seq_hdr_info->crop_right_offset + + seq_hdr_info->crop_left_offset; + decoder->frame_size.height -= + seq_hdr_info->crop_top_offset + + seq_hdr_info->crop_bottom_offset; + } +} + +static u32 ddl_decoder_seq_done_callback(struct ddl_context *ddl_context, + struct ddl_client_context *ddl) +{ + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + struct vidc_1080p_seq_hdr_info seq_hdr_info; + u32 process_further = true; + struct ddl_profile_info_type disp_profile_info; + + DDL_MSG_MED("ddl_decoder_seq_done_callback"); + if (!ddl->decoding || + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE)) { + DDL_MSG_ERROR("STATE-CRITICAL-HDDONE"); + ddl_client_fatal_cb(ddl); + } else { + ddl_calc_core_proc_time(__func__, DEC_OP_TIME, ddl); + ddl->cmd_state = DDL_CMD_INVALID; + DDL_MSG_LOW("ddl_state_transition: %s ~~>" + "DDL_CLIENT_WAIT_FOR_DPB", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_DPB; + DDL_MSG_LOW("HEADER_DONE"); + vidc_1080p_get_decode_seq_start_result(&seq_hdr_info); + parse_hdr_size_data(ddl, &seq_hdr_info); + if (res_trk_get_disable_fullhd() && + (seq_hdr_info.img_size_x * seq_hdr_info.img_size_y > + 1280 * 720)) { + DDL_MSG_ERROR("FATAL:Resolution greater than 720P HD"); + ddl_client_fatal_cb(ddl); + return process_further; + } + if (!seq_hdr_info.img_size_x || !seq_hdr_info.img_size_y) { + DDL_MSG_ERROR("FATAL:ZeroImageSize"); + ddl_client_fatal_cb(ddl); + return process_further; + } + vidc_sm_get_profile_info(&ddl->shared_mem + [ddl->command_channel], &disp_profile_info); + disp_profile_info.pic_profile = seq_hdr_info.profile; + disp_profile_info.pic_level = seq_hdr_info.level; + ddl_get_dec_profile_level(decoder, seq_hdr_info.profile, + seq_hdr_info.level); + switch (decoder->codec.codec) { + case VCD_CODEC_H264: + if (decoder->profile.profile == VCD_PROFILE_H264_HIGH || + decoder->profile.profile == + VCD_PROFILE_UNKNOWN) { + if ((disp_profile_info.chroma_format_idc > + VIDC_1080P_IDCFORMAT_420) || + (disp_profile_info.bit_depth_luma_minus8 + || disp_profile_info. + bit_depth_chroma_minus8)) { + DDL_MSG_ERROR("Unsupported H.264 " + "feature: IDC format : %d, Bitdepth: %d", + disp_profile_info. + chroma_format_idc, + (disp_profile_info. + bit_depth_luma_minus8 + || disp_profile_info. + bit_depth_chroma_minus8)); + ddl_client_fatal_cb(ddl); + return process_further; + } + } + break; + case VCD_CODEC_MPEG4: + case VCD_CODEC_DIVX_4: + case VCD_CODEC_DIVX_5: + case VCD_CODEC_DIVX_6: + case VCD_CODEC_XVID: + if (seq_hdr_info.data_partition) + if ((seq_hdr_info.img_size_x * + seq_hdr_info.img_size_y) > (720 * 576)) { + DDL_MSG_ERROR("Unsupported DP clip"); + ddl_client_fatal_cb(ddl); + return process_further; + } + break; + case VCD_CODEC_VC1: + case VCD_CODEC_VC1_RCV: + if ((seq_hdr_info.img_size_x > + DDL_MAX_VC1_FRAME_WIDTH) || + (seq_hdr_info.img_size_y > + DDL_MAX_VC1_FRAME_HEIGHT)) { + DDL_MSG_ERROR("Unsupported VC1 clip: " + "Resolution X=%d and Y=%d", + seq_hdr_info.img_size_x, + seq_hdr_info.img_size_y); + ddl_client_fatal_cb(ddl); + return process_further; + } + break; + default: + break; + } + ddl_calculate_stride(&decoder->frame_size, + !decoder->progressive_only); + decoder->frame_size.scan_lines = + DDL_ALIGN(decoder->frame_size.height, DDL_TILE_ALIGN_HEIGHT); + decoder->frame_size.stride = + DDL_ALIGN(decoder->frame_size.width, DDL_TILE_ALIGN_WIDTH); + parse_hdr_crop_data(ddl, &seq_hdr_info); + if (decoder->codec.codec == VCD_CODEC_H264 && + seq_hdr_info.level > VIDC_1080P_H264_LEVEL4) { + DDL_MSG_ERROR("WARNING: H264MaxLevelExceeded : %d", + seq_hdr_info.level); + } + ddl_set_default_decoder_buffer_req(decoder, false); + if (decoder->header_in_start) { + if (!(decoder->cont_mode) || + (decoder->min_dpb_num > + decoder->client_output_buf_req.min_count) || + (decoder->actual_output_buf_req.sz > + decoder->client_output_buf_req.sz)) { + decoder->client_frame_size = + decoder->frame_size; + decoder->client_output_buf_req = + decoder->actual_output_buf_req; + decoder->client_input_buf_req = + decoder->actual_input_buf_req; + } + ddl_context->ddl_callback(VCD_EVT_RESP_START, + VCD_S_SUCCESS, NULL, 0, (u32 *) ddl, + ddl->client_data); + ddl_release_command_channel(ddl_context, + ddl->command_channel); + } else { + u32 seq_hdr_only_frame = false; + u32 need_reconfig = false; + struct vcd_frame_data *input_vcd_frm = + &ddl->input_frame.vcd_frm; + need_reconfig = ddl_check_reconfig(ddl); + DDL_MSG_HIGH("%s : need_reconfig = %u\n", __func__, + need_reconfig); + if (input_vcd_frm->flags & + VCD_FRAME_FLAG_EOS) { + need_reconfig = false; + } + if (((input_vcd_frm->flags & + VCD_FRAME_FLAG_CODECCONFIG) && + (!(input_vcd_frm->flags & + VCD_FRAME_FLAG_SYNCFRAME))) || + input_vcd_frm->data_len <= + seq_hdr_info.dec_frm_size) { + seq_hdr_only_frame = true; + input_vcd_frm->offset += + seq_hdr_info.dec_frm_size; + input_vcd_frm->data_len = 0; + input_vcd_frm->flags |= + VCD_FRAME_FLAG_CODECCONFIG; + ddl->input_frame.frm_trans_end = + !need_reconfig; + ddl_context->ddl_callback( + VCD_EVT_RESP_INPUT_DONE, + VCD_S_SUCCESS, &ddl->input_frame, + sizeof(struct ddl_frame_data_tag), + (u32 *) ddl, ddl->client_data); + } else { + if (decoder->codec.codec == + VCD_CODEC_VC1_RCV) { + vidc_sm_set_start_byte_number( + &ddl->shared_mem + [ddl->command_channel], + seq_hdr_info.dec_frm_size); + } + } + if (need_reconfig) { + struct ddl_frame_data_tag *payload = + &ddl->input_frame; + u32 payload_size = + sizeof(struct ddl_frame_data_tag); + decoder->client_frame_size = + decoder->frame_size; + decoder->client_output_buf_req = + decoder->actual_output_buf_req; + decoder->client_input_buf_req = + decoder->actual_input_buf_req; + if (seq_hdr_only_frame) { + payload = NULL; + payload_size = 0; + } + DDL_MSG_HIGH("%s : sending port reconfig\n", + __func__); + ddl_context->ddl_callback( + VCD_EVT_IND_OUTPUT_RECONFIG, + VCD_S_SUCCESS, payload, + payload_size, (u32 *) ddl, + ddl->client_data); + } + if (!need_reconfig && !seq_hdr_only_frame) { + if (!ddl_vidc_decode_set_buffers(ddl)) + process_further = false; + else { + DDL_MSG_ERROR("ddl_vidc_decode_set_" + "buffers failed"); + ddl_client_fatal_cb(ddl); + } + } else + ddl_release_command_channel(ddl_context, + ddl->command_channel); + } + } + return process_further; +} + +static u32 ddl_sequence_done_callback(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl; + u32 channel_inst_id, ret; + + vidc_1080p_get_returned_channel_inst_id(&channel_inst_id); + vidc_1080p_clear_returned_channel_inst_id(); + ddl = ddl_get_current_ddl_client_for_channel_id(ddl_context, + ddl_context->response_cmd_ch_id); + if (!ddl) { + DDL_MSG_ERROR("UNKWN_SEQ_DONE"); + ret = true; + } else { + if (ddl->decoding) + ret = ddl_decoder_seq_done_callback(ddl_context, + ddl); + else + ret = ddl_encoder_seq_done_callback(ddl_context, + ddl); + } + return ret; +} + +static u32 ddl_dpb_buffers_set_done_callback( + struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl; + u32 channel_inst_id, ret_status = true; + + DDL_MSG_MED("ddl_dpb_buffers_set_done_callback"); + vidc_1080p_get_returned_channel_inst_id(&channel_inst_id); + vidc_1080p_clear_returned_channel_inst_id(); + ddl = ddl_get_current_ddl_client_for_command(ddl_context, + DDL_CMD_DECODE_SET_DPB); + if (ddl) { + ddl->cmd_state = DDL_CMD_INVALID; + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPBDONE)) { + DDL_MSG_ERROR("STATE-CRITICAL-DPBDONE"); + ddl_client_fatal_cb(ddl); + } else { + DDL_MSG_LOW("INTR_DPBDONE"); + DDL_MSG_LOW("ddl_state_transition: %s ~~>" + "DDL_CLIENT_WAIT_FOR_FRAME", + ddl_get_state_string(ddl->client_state)); + ddl_calc_core_proc_time(__func__, DEC_OP_TIME, ddl); + ddl_reset_core_time_variables(DEC_OP_TIME); + ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME; + ddl_vidc_decode_frame_run(ddl); + ret_status = false; + } + } + return ret_status; +} + +static void ddl_encoder_frame_run_callback( + struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + struct ddl_encoder_data *encoder = + &(ddl->codec_data.encoder); + struct vcd_frame_data *output_frame = + &(ddl->output_frame.vcd_frm); + u32 eos_present = false; + + DDL_MSG_MED("ddl_encoder_frame_run_callback\n"); + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE) && + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE)) { + DDL_MSG_ERROR("STATE-CRITICAL-ENCFRMRUN"); + ddl_client_fatal_cb(ddl); + } else { + ddl_calc_core_proc_time(__func__, ENC_OP_TIME, ddl); + DDL_MSG_LOW("ENC_FRM_RUN_DONE"); + ddl->cmd_state = DDL_CMD_INVALID; + vidc_1080p_get_encode_frame_info(&encoder->enc_frame_info); + + if (encoder->meta_data_enable_flag) + vidc_sm_get_metadata_status(&ddl->shared_mem + [ddl->command_channel], + &encoder->enc_frame_info.meta_data_exists); + + if (VCD_FRAME_FLAG_EOS & ddl->input_frame.vcd_frm.flags) { + DDL_MSG_LOW("%s EOS detected\n", __func__); + eos_present = true; + } + + if (encoder->enc_frame_info.enc_frame_size || + (encoder->enc_frame_info.enc_frame == + VIDC_1080P_ENCODE_FRAMETYPE_SKIPPED) || + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE)) { + if (encoder->slice_delivery_info.enable) { + if (encoder->enc_frame_info.enc_frame == + VIDC_1080P_ENCODE_FRAMETYPE_SKIPPED) + ddl_handle_enc_skipframe_slice_mode( + ddl, eos_present); + else + ddl_handle_enc_frame_done_slice_mode( + ddl, eos_present); + } else { + ddl_handle_enc_frame_done(ddl, eos_present); + } + if (DDLCLIENT_STATE_IS(ddl, + DDL_CLIENT_WAIT_FOR_EOS_DONE) && + encoder->i_period.b_frames) { + if ((ddl->extra_output_buf_count < 0) || + (ddl->extra_output_buf_count > + encoder->i_period.b_frames)) { + DDL_MSG_ERROR("Invalid B frame output" + "buffer index"); + } else { + struct vidc_1080p_enc_frame_start_param + enc_param; + ddl->output_frame = ddl->\ + extra_output_frame[ddl->\ + extra_output_buf_count]; + ddl->\ + extra_output_buf_count--; + output_frame = + &ddl->output_frame.\ + vcd_frm; + memset(&enc_param, 0, + sizeof(enc_param)); + enc_param.cmd_seq_num = + ++ddl_context->cmd_seq_num; + enc_param.inst_id = ddl->instance_id; + enc_param.shared_mem_addr_offset = + DDL_ADDR_OFFSET(ddl_context->\ + dram_base_a, ddl->shared_mem + [ddl->command_channel]); + enc_param.stream_buffer_addr_offset = + DDL_OFFSET(ddl_context->\ + dram_base_a.\ + align_physical_addr, + output_frame->physical); + enc_param.stream_buffer_size = + encoder->client_output_buf_req.sz; + enc_param.encode = + VIDC_1080P_ENC_TYPE_LAST_FRAME_DATA; + ddl->cmd_state = DDL_CMD_ENCODE_FRAME; + ddl_context->vidc_encode_frame_start + [ddl->command_channel] + (&enc_param); + } + } else if (eos_present && + encoder->slice_delivery_info.enable) { + ddl_vidc_encode_eos_run(ddl); + } else { + DDL_MSG_LOW("ddl_state_transition: %s ~~>" + "DDL_CLIENT_WAIT_FOR_FRAME", + ddl_get_state_string( + ddl->client_state)); + ddl->client_state = + DDL_CLIENT_WAIT_FOR_FRAME; + ddl_release_command_channel(ddl_context, + ddl->command_channel); + } + } else { + ddl_context->ddl_callback( + VCD_EVT_RESP_TRANSACTION_PENDING, + VCD_S_SUCCESS, NULL, 0, (u32 *)ddl, + ddl->client_data); + DDL_MSG_LOW("ddl_state_transition: %s ~~>" + "DDL_CLIENT_WAIT_FOR_FRAME", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME; + ddl_release_command_channel(ddl_context, + ddl->command_channel); + } + } +} + +static void get_dec_status(struct ddl_client_context *ddl, + struct vidc_1080p_dec_disp_info *dec_disp_info, + u32 output_order, u32 *status, u32 *rsl_chg) +{ + if (output_order == VCD_DEC_ORDER_DISPLAY) { + vidc_1080p_get_display_frame_result(dec_disp_info); + *status = dec_disp_info->display_status; + *rsl_chg = dec_disp_info->disp_resl_change; + } else { + vidc_1080p_get_decode_frame_result(dec_disp_info); + vidc_sm_get_dec_order_resl( + &ddl->shared_mem[ddl->command_channel], + &dec_disp_info->img_size_x, + &dec_disp_info->img_size_y); + *status = dec_disp_info->decode_status; + *rsl_chg = dec_disp_info->dec_resl_change; + } +} + +static u32 ddl_decoder_frame_run_callback(struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + u32 callback_end = false, ret_status = false; + u32 eos_present = false, rsl_chg; + u32 more_field_needed, extended_rsl_chg; + enum vidc_1080p_display_status disp_status; + DDL_MSG_MED("ddl_decoder_frame_run_callback"); + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE)) { + DDL_MSG_ERROR("STATE-CRITICAL-DECFRMRUN"); + ddl_client_fatal_cb(ddl); + ret_status = true; + } else { + DDL_MSG_LOW("DEC_FRM_RUN_DONE"); + ddl->cmd_state = DDL_CMD_INVALID; + get_dec_status(ddl, &ddl->codec_data.decoder.dec_disp_info, + ddl->codec_data.decoder.output_order, + &disp_status, &rsl_chg); + + vidc_sm_get_extended_decode_status( + &ddl->shared_mem[ddl->command_channel], + &more_field_needed, + &extended_rsl_chg); + decoder->field_needed_for_prev_ip = + more_field_needed; + decoder->prev_ip_frm_tag = + ddl->input_frame.vcd_frm.ip_frm_tag; + + ddl_vidc_decode_dynamic_property(ddl, false); + if (rsl_chg != DDL_RESL_CHANGE_NO_CHANGE) { + ddl_handle_reconfig(rsl_chg, ddl); + ret_status = false; + } else { + if ((VCD_FRAME_FLAG_EOS & + ddl->input_frame.vcd_frm.flags)) { + callback_end = false; + eos_present = true; + } + if (disp_status == + VIDC_1080P_DISPLAY_STATUS_DECODE_ONLY || + disp_status == + VIDC_1080P_DISPLAY_STATUS_DECODE_AND_DISPLAY) { + if (!eos_present) + callback_end = + (disp_status == + VIDC_1080P_DISPLAY_STATUS_DECODE_ONLY); + ddl_decoder_input_done_callback(ddl, + callback_end); + } + if (disp_status == + VIDC_1080P_DISPLAY_STATUS_DECODE_AND_DISPLAY || + disp_status == + VIDC_1080P_DISPLAY_STATUS_DISPLAY_ONLY) { + if (!eos_present) + callback_end = (disp_status == + VIDC_1080P_DISPLAY_STATUS_DECODE_AND_DISPLAY); + if (ddl_decoder_output_done_callback( + ddl, callback_end)) + ret_status = true; + } + if (!ret_status) { + if (disp_status == + VIDC_1080P_DISPLAY_STATUS_DISPLAY_ONLY + || disp_status == + VIDC_1080P_DISPLAY_STATUS_DPB_EMPTY || + disp_status == + VIDC_1080P_DISPLAY_STATUS_NOOP) { + ddl_vidc_decode_frame_run(ddl); + } else if (eos_present) + ddl_vidc_decode_eos_run(ddl); + else { + ddl->client_state = + DDL_CLIENT_WAIT_FOR_FRAME; + ddl_release_command_channel(ddl_context, + ddl->command_channel); + ret_status = true; + } + } + } + } + return ret_status; +} + +static u32 ddl_eos_frame_done_callback( + struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + struct ddl_mask *dpb_mask = &decoder->dpb_mask; + u32 ret_status = true, rsl_chg, more_field_needed; + enum vidc_1080p_display_status disp_status; + + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE)) { + DDL_MSG_ERROR("STATE-CRITICAL-EOSFRMRUN"); + ddl_client_fatal_cb(ddl); + } else { + DDL_MSG_LOW("EOS_FRM_RUN_DONE"); + ddl->cmd_state = DDL_CMD_INVALID; + get_dec_status(ddl, &ddl->codec_data.decoder.dec_disp_info, + ddl->codec_data.decoder.output_order, + &disp_status, &rsl_chg); + vidc_sm_get_extended_decode_status( + &ddl->shared_mem[ddl->command_channel], + &more_field_needed, &rsl_chg); + + decoder->field_needed_for_prev_ip = + more_field_needed; + decoder->prev_ip_frm_tag = + ddl->input_frame.vcd_frm.ip_frm_tag; + ddl_vidc_decode_dynamic_property(ddl, false); + if (disp_status == + VIDC_1080P_DISPLAY_STATUS_DPB_EMPTY) { + if (rsl_chg) { + decoder->header_in_start = false; + decoder->decode_config.sequence_header = + ddl->input_frame.vcd_frm.physical; + decoder->decode_config.sequence_header_len = + ddl->input_frame.vcd_frm.data_len; + decoder->reconfig_detected = false; + ddl_vidc_decode_init_codec(ddl); + ret_status = false; + } else + ddl_decoder_eos_done_callback(ddl); + } else { + struct vidc_1080p_dec_frame_start_param dec_param; + ret_status = false; + if (disp_status == + VIDC_1080P_DISPLAY_STATUS_DISPLAY_ONLY) { + if (ddl_decoder_output_done_callback( + ddl, false)) + ret_status = true; + } else if (disp_status != + VIDC_1080P_DISPLAY_STATUS_NOOP) + DDL_MSG_ERROR("EOS-STATE-CRITICAL-" + "WRONG-DISP-STATUS"); + if (!ret_status) { + ddl_decoder_dpb_transact(decoder, NULL, + DDL_DPB_OP_SET_MASK); + ddl->cmd_state = DDL_CMD_EOS; + + memset(&dec_param, 0, sizeof(dec_param)); + + dec_param.cmd_seq_num = + ++ddl_context->cmd_seq_num; + dec_param.inst_id = ddl->instance_id; + dec_param.shared_mem_addr_offset = + DDL_ADDR_OFFSET( + ddl_context->dram_base_a, + ddl->shared_mem[ddl->command_channel]); + dec_param.release_dpb_bit_mask = + dpb_mask->hw_mask; + dec_param.decode = + (decoder->reconfig_detected) ?\ + VIDC_1080P_DEC_TYPE_FRAME_DATA :\ + VIDC_1080P_DEC_TYPE_LAST_FRAME_DATA; + + ddl_context->vidc_decode_frame_start[ddl->\ + command_channel](&dec_param); + } + } + } + return ret_status; +} + +static u32 ddl_frame_run_callback(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl; + u32 channel_inst_id; + u32 return_status = true; + + vidc_1080p_get_returned_channel_inst_id(&channel_inst_id); + vidc_1080p_clear_returned_channel_inst_id(); + ddl = ddl_get_current_ddl_client_for_channel_id(ddl_context, + ddl_context->response_cmd_ch_id); + if (ddl) { + if (ddl_context->pix_cache_enable) { + struct vidc_1080P_pix_cache_statistics + pixel_cache_stats; + vidc_pix_cache_get_statistics(&pixel_cache_stats); + + DDL_MSG_HIGH(" pixel cache hits = %d," + "miss = %d", pixel_cache_stats.access_hit, + pixel_cache_stats.access_miss); + DDL_MSG_HIGH(" pixel cache core reqs = %d," + "axi reqs = %d", pixel_cache_stats.core_req, + pixel_cache_stats.axi_req); + DDL_MSG_HIGH(" pixel cache core bus stats = %d," + "axi bus stats = %d", pixel_cache_stats.core_bus, + pixel_cache_stats.axi_bus); + } + + if (ddl->cmd_state == DDL_CMD_DECODE_FRAME) + return_status = ddl_decoder_frame_run_callback(ddl); + else if (ddl->cmd_state == DDL_CMD_ENCODE_FRAME) + ddl_encoder_frame_run_callback(ddl); + else if (ddl->cmd_state == DDL_CMD_EOS) + return_status = ddl_eos_frame_done_callback(ddl); + else { + DDL_MSG_ERROR("UNKWN_FRAME_DONE"); + return_status = false; + } + } else + return_status = false; + + return return_status; +} + +static void ddl_channel_end_callback(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl; + + DDL_MSG_MED("ddl_channel_end_callback"); + ddl = ddl_get_current_ddl_client_for_command(ddl_context, + DDL_CMD_CHANNEL_END); + if (ddl) { + ddl->cmd_state = DDL_CMD_INVALID; + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_CHEND)) { + DDL_MSG_LOW("STATE-CRITICAL-CHEND"); + } else { + DDL_MSG_LOW("CH_END_DONE"); + ddl_release_client_internal_buffers(ddl); + ddl_context->ddl_callback(VCD_EVT_RESP_STOP, + VCD_S_SUCCESS, NULL, 0, (u32 *)ddl, + ddl->client_data); + DDL_MSG_LOW("ddl_state_transition: %s ~~>" + "DDL_CLIENT_OPEN", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_OPEN; + } + ddl_release_command_channel(ddl_context, + ddl->command_channel); + } +} + +static void ddl_edfu_callback(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl; + u32 channel_inst_id; + + DDL_MSG_MED("ddl_edfu_callback"); + vidc_1080p_get_returned_channel_inst_id(&channel_inst_id); + vidc_1080p_clear_returned_channel_inst_id(); + ddl = ddl_get_current_ddl_client_for_channel_id(ddl_context, + ddl_context->response_cmd_ch_id); + if (ddl) { + if (ddl->cmd_state != DDL_CMD_ENCODE_FRAME) + DDL_MSG_LOW("UNKWN_EDFU"); + } +} + +static void ddl_encoder_eos_done(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl; + u32 channel_inst_id; + + vidc_1080p_get_returned_channel_inst_id(&channel_inst_id); + vidc_1080p_clear_returned_channel_inst_id(); + ddl = ddl_get_current_ddl_client_for_channel_id(ddl_context, + ddl_context->response_cmd_ch_id); + DDL_MSG_LOW("ddl_encoder_eos_done\n"); + if (ddl == NULL) { + DDL_MSG_ERROR("NO_DDL_CONTEXT"); + } else { + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE)) { + DDL_MSG_ERROR("STATE-CRITICAL-EOSFRMDONE"); + ddl_client_fatal_cb(ddl); + } else { + struct ddl_encoder_data *encoder = + &(ddl->codec_data.encoder); + vidc_1080p_get_encode_frame_info( + &encoder->enc_frame_info); + if (!encoder->slice_delivery_info.enable) { + ddl_handle_enc_frame_done(ddl, true); + ddl->cmd_state = DDL_CMD_INVALID; + } + DDL_MSG_LOW("encoder_eos_done"); + DDL_MSG_LOW("ddl_state_transition: %s ~~>" + "DDL_CLIENT_WAIT_FOR_FRAME", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME; + DDL_MSG_LOW("eos_done"); + ddl_context->ddl_callback(VCD_EVT_RESP_EOS_DONE, + VCD_S_SUCCESS, NULL, 0, + (u32 *)ddl, ddl->client_data); + ddl_release_command_channel(ddl_context, + ddl->command_channel); + } + } +} + +static u32 ddl_slice_done_callback(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl; + u32 channel_inst_id; + u32 return_status = true; + DDL_MSG_LOW("ddl_sliceDoneCallback"); + vidc_1080p_get_returned_channel_inst_id(&channel_inst_id); + vidc_1080p_clear_returned_channel_inst_id(); + ddl = ddl_get_current_ddl_client_for_channel_id(ddl_context, + ddl_context->response_cmd_ch_id); + if (ddl == NULL) { + DDL_MSG_ERROR("NO_DDL_CONTEXT"); + return_status = false; + } else if (ddl->cmd_state == DDL_CMD_ENCODE_FRAME) { + ddl->cmd_state = DDL_CMD_INVALID; + if (DDLCLIENT_STATE_IS(ddl, + DDL_CLIENT_WAIT_FOR_FRAME_DONE)) { + ddl_handle_slice_done_slice_batch(ddl); + } else { + DDL_MSG_ERROR("STATE-CRITICAL-ENCFRMRUN : %s\n", + __func__); + ddl_client_fatal_cb(ddl); + } + } else { + DDL_MSG_ERROR("UNKNOWN_SLICEDONE : %s\n", __func__); + } + return return_status; +} + +static u32 ddl_process_intr_status(struct ddl_context *ddl_context, + u32 intr_status) +{ + u32 return_status = true; + switch (intr_status) { + case VIDC_1080P_RISC2HOST_CMD_OPEN_CH_RET: + return_status = ddl_channel_set_callback(ddl_context, + ddl_context->response_cmd_ch_id); + break; + case VIDC_1080P_RISC2HOST_CMD_CLOSE_CH_RET: + ddl_channel_end_callback(ddl_context); + break; + case VIDC_1080P_RISC2HOST_CMD_SEQ_DONE_RET: + return_status = ddl_sequence_done_callback(ddl_context); + break; + case VIDC_1080P_RISC2HOST_CMD_FRAME_DONE_RET: + return_status = ddl_frame_run_callback(ddl_context); + break; + case VIDC_1080P_RISC2HOST_CMD_SLICE_DONE_RET: + ddl_slice_done_callback(ddl_context); + break; + case VIDC_1080P_RISC2HOST_CMD_SYS_INIT_RET: + ddl_sys_init_done_callback(ddl_context, + ddl_context->response_cmd_ch_id); + break; + case VIDC_1080P_RISC2HOST_CMD_FW_STATUS_RET: + ddl_fw_status_done_callback(ddl_context); + break; + case VIDC_1080P_RISC2HOST_CMD_EDFU_INT_RET: + ddl_edfu_callback(ddl_context); + break; + case VIDC_1080P_RISC2HOST_CMD_ENC_COMPLETE_RET: + ddl_encoder_eos_done(ddl_context); + break; + case VIDC_1080P_RISC2HOST_CMD_ERROR_RET: + DDL_MSG_ERROR("CMD_ERROR_INTR"); + return_status = ddl_handle_core_errors(ddl_context); + break; + case VIDC_1080P_RISC2HOST_CMD_INIT_BUFFERS_RET: + return_status = + ddl_dpb_buffers_set_done_callback(ddl_context); + break; + default: + DDL_MSG_LOW("UNKWN_INTR"); + break; + } + return return_status; +} + +void ddl_read_and_clear_interrupt(void) +{ + struct ddl_context *ddl_context; + struct ddl_hw_interface *ddl_hw_response; + struct ddl_client_context *ddl; + struct ddl_encoder_data *encoder; + + ddl_context = ddl_get_context(); + if (!ddl_context->core_virtual_base_addr) { + DDL_MSG_LOW("SPURIOUS_INTERRUPT"); + } else { + ddl_hw_response = &ddl_context->ddl_hw_response; + vidc_1080p_get_risc2host_cmd(&ddl_hw_response->cmd, + &ddl_hw_response->arg1, &ddl_hw_response->arg2, + &ddl_hw_response->arg3, + &ddl_hw_response->arg4); + DDL_MSG_LOW("%s vidc_1080p_get_risc2host_cmd cmd = %u" + "arg1 = %u arg2 = %u arg3 = %u" + "arg4 = %u\n", + __func__, ddl_hw_response->cmd, + ddl_hw_response->arg1, ddl_hw_response->arg2, + ddl_hw_response->arg3, + ddl_hw_response->arg4); + ddl = ddl_get_current_ddl_client_for_channel_id(ddl_context, + ddl_context->response_cmd_ch_id); + if (ddl) { + encoder = &(ddl->codec_data.encoder); + if (encoder && encoder->slice_delivery_info.enable + && + ((ddl_hw_response->cmd == + VIDC_1080P_RISC2HOST_CMD_SLICE_DONE_RET) + || (ddl_hw_response->cmd == + VIDC_1080P_RISC2HOST_CMD_FRAME_DONE_RET))) { + vidc_sm_set_encoder_slice_batch_int_ctrl( + &ddl->shared_mem[ddl->command_channel], + 1); + } + } + vidc_1080p_clear_risc2host_cmd(); + vidc_1080p_clear_interrupt(); + vidc_1080p_get_risc2host_cmd_status(ddl_hw_response->arg2, + &ddl_context->cmd_err_status, + &ddl_context->disp_pic_err_status); + DDL_MSG_LOW("%s cmd_err_status = %d\n", __func__, + ddl_context->cmd_err_status); + ddl_context->response_cmd_ch_id = ddl_hw_response->arg1; + } +} + +u32 ddl_process_core_response(void) +{ + struct ddl_context *ddl_context; + struct ddl_hw_interface *ddl_hw_response; + u32 status = false; + + ddl_context = ddl_get_context(); + if (!ddl_context->core_virtual_base_addr) { + DDL_MSG_LOW("SPURIOUS_INTERRUPT"); + return status; + } + ddl_hw_response = &ddl_context->ddl_hw_response; + status = ddl_process_intr_status(ddl_context, ddl_hw_response->cmd); + if (ddl_context->interrupt_clr) + (*ddl_context->interrupt_clr)(); + return status; +} + +static void ddl_decoder_input_done_callback( + struct ddl_client_context *ddl, u32 frame_transact_end) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + struct vidc_1080p_dec_disp_info *dec_disp_info = + &decoder->dec_disp_info; + struct vcd_frame_data *input_vcd_frm = &(ddl->input_frame.vcd_frm); + u32 is_interlaced; + vidc_1080p_get_decoded_frame_size( + &dec_disp_info->input_bytes_consumed); + vidc_sm_set_start_byte_number(&ddl->shared_mem + [ddl->command_channel], 0); + vidc_1080p_get_decode_frame(&dec_disp_info->input_frame); + ddl_get_decoded_frame(input_vcd_frm, + dec_disp_info->input_frame); + vidc_1080p_get_decode_frame_result(dec_disp_info); + is_interlaced = (dec_disp_info->decode_coding == + VIDC_1080P_DISPLAY_CODING_INTERLACED); + if (decoder->output_order == VCD_DEC_ORDER_DECODE) { + dec_disp_info->tag_bottom = is_interlaced ? + dec_disp_info->tag_top : + VCD_FRAMETAG_INVALID; + dec_disp_info->tag_top = input_vcd_frm->ip_frm_tag; + } + input_vcd_frm->interlaced = is_interlaced; + input_vcd_frm->offset += dec_disp_info->input_bytes_consumed; + input_vcd_frm->data_len -= dec_disp_info->input_bytes_consumed; + ddl->input_frame.frm_trans_end = frame_transact_end; + ddl_calc_core_proc_time(__func__, DEC_IP_TIME, ddl); + ddl_context->ddl_callback(VCD_EVT_RESP_INPUT_DONE, VCD_S_SUCCESS, + &ddl->input_frame, sizeof(struct ddl_frame_data_tag), + (u32 *)ddl, ddl->client_data); +} + +static void get_dec_op_done_data(struct vidc_1080p_dec_disp_info *dec_disp_info, + u32 output_order, u8 **physical, u32 *is_interlaced) +{ + enum vidc_1080p_display_coding disp_coding; + if (output_order == VCD_DEC_ORDER_DECODE) { + *physical = (u8 *)(dec_disp_info->decode_y_addr << 11); + disp_coding = dec_disp_info->decode_coding; + } else { + *physical = (u8 *)(dec_disp_info->display_y_addr << 11); + disp_coding = dec_disp_info->display_coding; + } + *is_interlaced = (disp_coding == + VIDC_1080P_DISPLAY_CODING_INTERLACED); +} + +static void get_dec_op_done_crop(u32 output_order, + struct vidc_1080p_dec_disp_info *dec_disp_info, + struct vcd_frame_rect *crop_data, + struct vcd_property_frame_size *op_frame_sz, + struct vcd_property_frame_size *frame_sz, + struct ddl_buf_addr *shared_mem) +{ + u32 crop_exists = + (output_order == VCD_DEC_ORDER_DECODE) ? + dec_disp_info->dec_crop_exists : + dec_disp_info->disp_crop_exists; + crop_data->left = 0; + crop_data->top = 0; + crop_data->right = dec_disp_info->img_size_x; + crop_data->bottom = dec_disp_info->img_size_y; + op_frame_sz->width = dec_disp_info->img_size_x; + op_frame_sz->height = dec_disp_info->img_size_y; + ddl_calculate_stride(op_frame_sz, false); + op_frame_sz->stride = DDL_ALIGN(op_frame_sz->width, + DDL_TILE_ALIGN_WIDTH); + op_frame_sz->scan_lines = DDL_ALIGN(op_frame_sz->height, + DDL_TILE_ALIGN_HEIGHT); + DDL_MSG_LOW("%s img_size_x = %u img_size_y = %u\n", + __func__, dec_disp_info->img_size_x, + dec_disp_info->img_size_y); + if (crop_exists) { + if (output_order == VCD_DEC_ORDER_DECODE) + vidc_sm_get_dec_order_crop_info(shared_mem, + &dec_disp_info->crop_left_offset, + &dec_disp_info->crop_right_offset, + &dec_disp_info->crop_top_offset, + &dec_disp_info->crop_bottom_offset); + else + vidc_sm_get_crop_info(shared_mem, + &dec_disp_info->crop_left_offset, + &dec_disp_info->crop_right_offset, + &dec_disp_info->crop_top_offset, + &dec_disp_info->crop_bottom_offset); + crop_data->left = dec_disp_info->crop_left_offset; + crop_data->top = dec_disp_info->crop_top_offset; + crop_data->right -= dec_disp_info->crop_right_offset; + crop_data->bottom -= dec_disp_info->crop_bottom_offset; + op_frame_sz->width = crop_data->right - crop_data->left; + op_frame_sz->height = crop_data->bottom - crop_data->top; + } +} + +static u32 ddl_decoder_output_done_callback( + struct ddl_client_context *ddl, u32 frame_transact_end) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + struct vidc_1080p_dec_disp_info *dec_disp_info = + &(decoder->dec_disp_info); + struct ddl_frame_data_tag *output_frame = &(ddl->output_frame); + struct vcd_frame_data *output_vcd_frm = &(output_frame->vcd_frm); + u32 vcd_status, free_luma_dpb = 0, disp_pict = 0, is_interlaced; + get_dec_op_done_data(dec_disp_info, decoder->output_order, + &output_vcd_frm->physical, &is_interlaced); + decoder->progressive_only = !(is_interlaced); + output_vcd_frm->frame = VCD_FRAME_YUV; + if (decoder->codec.codec == VCD_CODEC_MPEG4 || + decoder->codec.codec == VCD_CODEC_VC1 || + decoder->codec.codec == VCD_CODEC_VC1_RCV || + (decoder->codec.codec >= VCD_CODEC_DIVX_3 && + decoder->codec.codec <= VCD_CODEC_XVID)) { + vidc_sm_get_displayed_picture_frame(&ddl->shared_mem + [ddl->command_channel], &disp_pict); + if (decoder->output_order == VCD_DEC_ORDER_DISPLAY) { + if (!disp_pict) { + output_vcd_frm->frame = VCD_FRAME_NOTCODED; + vidc_sm_get_available_luma_dpb_address( + &ddl->shared_mem[ddl->command_channel], + &free_luma_dpb); + } + } else { + if (dec_disp_info->input_frame == + VIDC_1080P_DECODE_FRAMETYPE_NOT_CODED) { + output_vcd_frm->frame = VCD_FRAME_NOTCODED; + vidc_sm_get_available_luma_dpb_dec_order_address( + &ddl->shared_mem[ddl->command_channel], + &free_luma_dpb); + } + } + if (free_luma_dpb) + output_vcd_frm->physical = + (u8 *)(free_luma_dpb << 11); + } + vcd_status = ddl_decoder_dpb_transact(decoder, output_frame, + DDL_DPB_OP_MARK_BUSY); + if (vcd_status) { + DDL_MSG_ERROR("CORRUPTED_OUTPUT_BUFFER_ADDRESS"); + ddl_hw_fatal_cb(ddl); + } else { + vidc_sm_get_metadata_status(&ddl->shared_mem + [ddl->command_channel], + &decoder->meta_data_exists); + if (decoder->output_order == VCD_DEC_ORDER_DISPLAY) { + vidc_sm_get_frame_tags(&ddl->shared_mem + [ddl->command_channel], + &dec_disp_info->tag_top, + &dec_disp_info->tag_bottom); + if (dec_disp_info->display_correct == + VIDC_1080P_DECODE_NOT_CORRECT || + dec_disp_info->display_correct == + VIDC_1080P_DECODE_APPROX_CORRECT) + output_vcd_frm->flags |= + VCD_FRAME_FLAG_DATACORRUPT; + } else { + if (dec_disp_info->decode_correct == + VIDC_1080P_DECODE_NOT_CORRECT || + dec_disp_info->decode_correct == + VIDC_1080P_DECODE_APPROX_CORRECT) + output_vcd_frm->flags |= + VCD_FRAME_FLAG_DATACORRUPT; + } + output_vcd_frm->ip_frm_tag = dec_disp_info->tag_top; + vidc_sm_get_picture_times(&ddl->shared_mem + [ddl->command_channel], + &dec_disp_info->pic_time_top, + &dec_disp_info->pic_time_bottom); + get_dec_op_done_crop(decoder->output_order, dec_disp_info, + &output_vcd_frm->dec_op_prop.disp_frm, + &output_vcd_frm->dec_op_prop.frm_size, + &decoder->frame_size, + &ddl->shared_mem[ddl_context->response_cmd_ch_id]); + if ((decoder->cont_mode) && + ((output_vcd_frm->dec_op_prop.frm_size.width != + decoder->frame_size.width) || + (output_vcd_frm->dec_op_prop.frm_size.height != + decoder->frame_size.height) || + (decoder->frame_size.width != + decoder->client_frame_size.width) || + (decoder->frame_size.height != + decoder->client_frame_size.height))) { + DDL_MSG_LOW("%s o/p width = %u o/p height = %u" + "decoder width = %u decoder height = %u ", + __func__, + output_vcd_frm->dec_op_prop.frm_size.width, + output_vcd_frm->dec_op_prop.frm_size.height, + decoder->frame_size.width, + decoder->frame_size.height); + DDL_MSG_HIGH("%s Sending INFO_OP_RECONFIG event\n", + __func__); + ddl_context->ddl_callback( + VCD_EVT_IND_INFO_OUTPUT_RECONFIG, + VCD_S_SUCCESS, NULL, 0, + (u32 *)ddl, + ddl->client_data); + decoder->frame_size = + output_vcd_frm->dec_op_prop.frm_size; + decoder->client_frame_size = decoder->frame_size; + decoder->y_cb_cr_size = + ddl_get_yuv_buffer_size(&decoder->frame_size, + &decoder->buf_format, + (!decoder->progressive_only), + decoder->codec.codec, NULL); + decoder->actual_output_buf_req.sz = + decoder->y_cb_cr_size + decoder->suffix; + decoder->min_output_buf_req = + decoder->actual_output_buf_req; + DDL_MSG_LOW("%s y_cb_cr_size = %u " + "actual_output_buf_req.sz = %u" + "min_output_buf_req.sz = %u\n", + decoder->y_cb_cr_size, + decoder->actual_output_buf_req.sz, + decoder->min_output_buf_req.sz); + vidc_sm_set_chroma_addr_change( + &ddl->shared_mem[ddl->command_channel], + false); + } + output_vcd_frm->interlaced = is_interlaced; + output_vcd_frm->intrlcd_ip_frm_tag = + (!is_interlaced || !dec_disp_info->tag_bottom) ? + VCD_FRAMETAG_INVALID : dec_disp_info->tag_bottom; + output_vcd_frm->offset = 0; + output_vcd_frm->data_len = decoder->y_cb_cr_size; + if (free_luma_dpb) { + output_vcd_frm->data_len = 0; + output_vcd_frm->flags |= VCD_FRAME_FLAG_DECODEONLY; + } + output_vcd_frm->flags |= VCD_FRAME_FLAG_ENDOFFRAME; + output_frame->frm_trans_end = frame_transact_end; + ddl_calc_core_proc_time(__func__, DEC_OP_TIME, ddl); + ddl_process_decoder_metadata(ddl); + vidc_sm_get_aspect_ratio_info( + &ddl->shared_mem[ddl->command_channel], + &output_vcd_frm->aspect_ratio_info); + ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE, + vcd_status, output_frame, + sizeof(struct ddl_frame_data_tag), + (u32 *)ddl, ddl->client_data); + } + return vcd_status; +} + +static u32 ddl_get_decoded_frame(struct vcd_frame_data *frame, + enum vidc_1080p_decode_frame frame_type) +{ + u32 status = true; + + switch (frame_type) { + case VIDC_1080P_DECODE_FRAMETYPE_I: + frame->flags |= VCD_FRAME_FLAG_SYNCFRAME; + frame->frame = VCD_FRAME_I; + break; + case VIDC_1080P_DECODE_FRAMETYPE_P: + frame->frame = VCD_FRAME_P; + break; + case VIDC_1080P_DECODE_FRAMETYPE_B: + frame->frame = VCD_FRAME_B; + break; + case VIDC_1080P_DECODE_FRAMETYPE_NOT_CODED: + frame->frame = VCD_FRAME_NOTCODED; + frame->data_len = 0; + DDL_MSG_HIGH("DDL_INFO:Decoder:NotCodedFrame>"); + break; + case VIDC_1080P_DECODE_FRAMETYPE_OTHERS: + frame->frame = VCD_FRAME_YUV; + break; + case VIDC_1080P_DECODE_FRAMETYPE_32BIT: + default: + DDL_MSG_ERROR("UNKNOWN-FRAMETYPE"); + status = false; + break; + } + return status; +} + +static u32 ddl_get_encoded_frame(struct vcd_frame_data *frame, + enum vcd_codec codec, + enum vidc_1080p_encode_frame frame_type) +{ + u32 status = true; + + if (codec == VCD_CODEC_H264) { + switch (frame_type) { + case VIDC_1080P_ENCODE_FRAMETYPE_NOT_CODED: + frame->frame = VCD_FRAME_P; + break; + case VIDC_1080P_ENCODE_FRAMETYPE_I: + frame->flags |= VCD_FRAME_FLAG_SYNCFRAME; + frame->frame = VCD_FRAME_I; + break; + case VIDC_1080P_ENCODE_FRAMETYPE_P: + frame->frame = VCD_FRAME_P; + break; + case VIDC_1080P_ENCODE_FRAMETYPE_B: + frame->frame = VCD_FRAME_B; + frame->flags |= VCD_FRAME_FLAG_BFRAME; + break; + case VIDC_1080P_ENCODE_FRAMETYPE_SKIPPED: + frame->frame = VCD_FRAME_NOTCODED; + frame->data_len = 0; + break; + case VIDC_1080P_ENCODE_FRAMETYPE_OTHERS: + DDL_MSG_LOW("FRAMETYPE-OTHERS"); + break; + case VIDC_1080P_ENCODE_FRAMETYPE_32BIT: + default: + DDL_MSG_LOW("UNKNOWN-FRAMETYPE"); + status = false; + break; + } + } else if (codec == VCD_CODEC_MPEG4) { + switch (frame_type) { + case VIDC_1080P_ENCODE_FRAMETYPE_NOT_CODED: + frame->frame = VCD_FRAME_P; + break; + case VIDC_1080P_ENCODE_FRAMETYPE_I: + frame->flags |= VCD_FRAME_FLAG_SYNCFRAME; + frame->frame = VCD_FRAME_I; + break; + case VIDC_1080P_ENCODE_FRAMETYPE_P: + frame->frame = VCD_FRAME_P; + break; + case VIDC_1080P_ENCODE_FRAMETYPE_B: + frame->frame = VCD_FRAME_B; + frame->flags |= VCD_FRAME_FLAG_BFRAME; + break; + case VIDC_1080P_ENCODE_FRAMETYPE_SKIPPED: + frame->frame = VCD_FRAME_NOTCODED; + frame->data_len = 0; + break; + case VIDC_1080P_ENCODE_FRAMETYPE_OTHERS: + DDL_MSG_LOW("FRAMETYPE-OTHERS"); + break; + case VIDC_1080P_ENCODE_FRAMETYPE_32BIT: + default: + DDL_MSG_LOW("UNKNOWN-FRAMETYPE"); + status = false; + break; + } + } else if (codec == VCD_CODEC_H263) { + switch (frame_type) { + case VIDC_1080P_ENCODE_FRAMETYPE_NOT_CODED: + frame->frame = VCD_FRAME_P; + break; + case VIDC_1080P_ENCODE_FRAMETYPE_I: + frame->flags |= VCD_FRAME_FLAG_SYNCFRAME; + frame->frame = VCD_FRAME_I; + break; + case VIDC_1080P_ENCODE_FRAMETYPE_P: + frame->frame = VCD_FRAME_P; + break; + case VIDC_1080P_ENCODE_FRAMETYPE_SKIPPED: + frame->frame = VCD_FRAME_NOTCODED; + frame->data_len = 0; + break; + case VIDC_1080P_ENCODE_FRAMETYPE_OTHERS: + DDL_MSG_LOW("FRAMETYPE-OTHERS"); + break; + case VIDC_1080P_ENCODE_FRAMETYPE_32BIT: + default: + DDL_MSG_LOW("UNKNOWN-FRAMETYPE"); + status = false; + break; + } + } else + status = false; + DDL_MSG_HIGH("Enc Frame Type %u", (u32)frame->frame); + return status; +} + +static void ddl_get_mpeg4_dec_level(enum vcd_codec_level *level, + u32 level_codec, enum vcd_codec_profile mpeg4_profile) +{ + switch (level_codec) { + case VIDC_1080P_MPEG4_LEVEL0: + *level = VCD_LEVEL_MPEG4_0; + break; + case VIDC_1080P_MPEG4_LEVEL0b: + *level = VCD_LEVEL_MPEG4_0b; + break; + case VIDC_1080P_MPEG4_LEVEL1: + *level = VCD_LEVEL_MPEG4_1; + break; + case VIDC_1080P_MPEG4_LEVEL2: + *level = VCD_LEVEL_MPEG4_2; + break; + case VIDC_1080P_MPEG4_LEVEL3: + *level = VCD_LEVEL_MPEG4_3; + break; + case VIDC_1080P_MPEG4_LEVEL3b: + if (mpeg4_profile == VCD_PROFILE_MPEG4_SP) + *level = VCD_LEVEL_MPEG4_7; + else + *level = VCD_LEVEL_MPEG4_3b; + break; + case VIDC_1080P_MPEG4_LEVEL4a: + *level = VCD_LEVEL_MPEG4_4a; + break; + case VIDC_1080P_MPEG4_LEVEL5: + *level = VCD_LEVEL_MPEG4_5; + break; + case VIDC_1080P_MPEG4_LEVEL6: + *level = VCD_LEVEL_MPEG4_6; + break; + default: + *level = VCD_LEVEL_UNKNOWN; + break; + } +} + +static void ddl_get_h264_dec_level(enum vcd_codec_level *level, + u32 level_codec) +{ + switch (level_codec) { + case VIDC_1080P_H264_LEVEL1: + *level = VCD_LEVEL_H264_1; + break; + case VIDC_1080P_H264_LEVEL1b: + *level = VCD_LEVEL_H264_1b; + break; + case VIDC_1080P_H264_LEVEL1p1: + *level = VCD_LEVEL_H264_1p1; + break; + case VIDC_1080P_H264_LEVEL1p2: + *level = VCD_LEVEL_H264_1p2; + break; + case VIDC_1080P_H264_LEVEL1p3: + *level = VCD_LEVEL_H264_1p3; + break; + case VIDC_1080P_H264_LEVEL2: + *level = VCD_LEVEL_H264_2; + break; + case VIDC_1080P_H264_LEVEL2p1: + *level = VCD_LEVEL_H264_2p1; + break; + case VIDC_1080P_H264_LEVEL2p2: + *level = VCD_LEVEL_H264_2p2; + break; + case VIDC_1080P_H264_LEVEL3: + *level = VCD_LEVEL_H264_3; + break; + case VIDC_1080P_H264_LEVEL3p1: + *level = VCD_LEVEL_H264_3p1; + break; + case VIDC_1080P_H264_LEVEL3p2: + *level = VCD_LEVEL_H264_3p2; + break; + case VIDC_1080P_H264_LEVEL4: + *level = VCD_LEVEL_H264_4; + break; + default: + *level = VCD_LEVEL_UNKNOWN; + break; + } +} + +static void ddl_get_h263_dec_level(enum vcd_codec_level *level, + u32 level_codec) +{ + switch (level_codec) { + case VIDC_1080P_H263_LEVEL10: + *level = VCD_LEVEL_H263_10; + break; + case VIDC_1080P_H263_LEVEL20: + *level = VCD_LEVEL_H263_20; + break; + case VIDC_1080P_H263_LEVEL30: + *level = VCD_LEVEL_H263_30; + break; + case VIDC_1080P_H263_LEVEL40: + *level = VCD_LEVEL_H263_40; + break; + case VIDC_1080P_H263_LEVEL45: + *level = VCD_LEVEL_H263_45; + break; + case VIDC_1080P_H263_LEVEL50: + *level = VCD_LEVEL_H263_50; + break; + case VIDC_1080P_H263_LEVEL60: + *level = VCD_LEVEL_H263_60; + break; + case VIDC_1080P_H263_LEVEL70: + *level = VCD_LEVEL_H263_70; + break; + default: + *level = VCD_LEVEL_UNKNOWN; + break; + } +} + +static void ddl_get_vc1_dec_level(enum vcd_codec_level *level, + u32 level_codec, enum vcd_codec_profile vc1_profile) +{ + if (vc1_profile == VCD_PROFILE_VC1_ADVANCE) { + switch (level_codec) { + case VIDC_SM_LEVEL_VC1_ADV_0: + *level = VCD_LEVEL_VC1_A_0; + break; + case VIDC_SM_LEVEL_VC1_ADV_1: + *level = VCD_LEVEL_VC1_A_1; + break; + case VIDC_SM_LEVEL_VC1_ADV_2: + *level = VCD_LEVEL_VC1_A_2; + break; + case VIDC_SM_LEVEL_VC1_ADV_3: + *level = VCD_LEVEL_VC1_A_3; + break; + case VIDC_SM_LEVEL_VC1_ADV_4: + *level = VCD_LEVEL_VC1_A_4; + break; + default: + *level = VCD_LEVEL_UNKNOWN; + break; + } + } else if (vc1_profile == VCD_PROFILE_VC1_MAIN) { + switch (level_codec) { + case VIDC_SM_LEVEL_VC1_LOW: + *level = VCD_LEVEL_VC1_M_LOW; + break; + case VIDC_SM_LEVEL_VC1_MEDIUM: + *level = VCD_LEVEL_VC1_M_MEDIUM; + break; + case VIDC_SM_LEVEL_VC1_HIGH: + *level = VCD_LEVEL_VC1_M_HIGH; + break; + default: + *level = VCD_LEVEL_UNKNOWN; + break; + } + } else if (vc1_profile == VCD_PROFILE_VC1_SIMPLE) { + switch (level_codec) { + case VIDC_SM_LEVEL_VC1_LOW: + *level = VCD_LEVEL_VC1_S_LOW; + break; + case VIDC_SM_LEVEL_VC1_MEDIUM: + *level = VCD_LEVEL_VC1_S_MEDIUM; + break; + default: + *level = VCD_LEVEL_UNKNOWN; + break; + } + } +} + +static void ddl_get_mpeg2_dec_level(enum vcd_codec_level *level, + u32 level_codec) +{ + switch (level_codec) { + case VIDC_SM_LEVEL_MPEG2_LOW: + *level = VCD_LEVEL_MPEG2_LOW; + break; + case VIDC_SM_LEVEL_MPEG2_MAIN: + *level = VCD_LEVEL_MPEG2_MAIN; + break; + case VIDC_SM_LEVEL_MPEG2_HIGH_1440: + *level = VCD_LEVEL_MPEG2_HIGH_14; + break; + case VIDC_SM_LEVEL_MPEG2_HIGH: + *level = VCD_LEVEL_MPEG2_HIGH; + break; + default: + *level = VCD_LEVEL_UNKNOWN; + break; + } +} + +static void ddl_get_dec_profile_level(struct ddl_decoder_data *decoder, + u32 profile_codec, u32 level_codec) +{ + enum vcd_codec_profile profile = VCD_PROFILE_UNKNOWN; + enum vcd_codec_level level = VCD_LEVEL_UNKNOWN; + + switch (decoder->codec.codec) { + case VCD_CODEC_MPEG4: + case VCD_CODEC_XVID: + if (profile_codec == VIDC_SM_PROFILE_MPEG4_SIMPLE) + profile = VCD_PROFILE_MPEG4_SP; + else if (profile_codec == VIDC_SM_PROFILE_MPEG4_ADV_SIMPLE) + profile = VCD_PROFILE_MPEG4_ASP; + else + profile = VCD_PROFILE_UNKNOWN; + ddl_get_mpeg4_dec_level(&level, level_codec, profile); + break; + case VCD_CODEC_H264: + if (profile_codec == VIDC_SM_PROFILE_H264_BASELINE) + profile = VCD_PROFILE_H264_BASELINE; + else if (profile_codec == VIDC_SM_PROFILE_H264_MAIN) + profile = VCD_PROFILE_H264_MAIN; + else if (profile_codec == VIDC_SM_PROFILE_H264_HIGH) + profile = VCD_PROFILE_H264_HIGH; + else + profile = VCD_PROFILE_UNKNOWN; + ddl_get_h264_dec_level(&level, level_codec); + break; + case VCD_CODEC_H263: + if (profile_codec == VIDC_SM_PROFILE_H263_BASELINE) + profile = VCD_PROFILE_H263_BASELINE; + else + profile = VCD_PROFILE_UNKNOWN; + ddl_get_h263_dec_level(&level, level_codec); + break; + case VCD_CODEC_MPEG2: + if (profile_codec == VIDC_SM_PROFILE_MPEG2_MAIN) + profile = VCD_PROFILE_MPEG2_MAIN; + else if (profile_codec == VIDC_SM_PROFILE_MPEG2_SIMPLE) + profile = VCD_PROFILE_MPEG2_SIMPLE; + else + profile = VCD_PROFILE_UNKNOWN; + ddl_get_mpeg2_dec_level(&level, level_codec); + break; + case VCD_CODEC_VC1: + case VCD_CODEC_VC1_RCV: + if (profile_codec == VIDC_SM_PROFILE_VC1_SIMPLE) + profile = VCD_PROFILE_VC1_SIMPLE; + else if (profile_codec == VIDC_SM_PROFILE_VC1_MAIN) + profile = VCD_PROFILE_VC1_MAIN; + else if (profile_codec == VIDC_SM_PROFILE_VC1_ADVANCED) + profile = VCD_PROFILE_VC1_ADVANCE; + else + profile = VCD_PROFILE_UNKNOWN; + ddl_get_vc1_dec_level(&level, level_codec, profile); + break; + default: + if (!profile_codec) + profile = VCD_PROFILE_UNKNOWN; + if (!level) + level = VCD_LEVEL_UNKNOWN; + break; + } + decoder->profile.profile = profile; + decoder->level.level = level; +} + +static void ddl_handle_enc_frame_done(struct ddl_client_context *ddl, + u32 eos_present) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + struct vcd_frame_data *output_frame = &(ddl->output_frame.vcd_frm); + u32 bottom_frame_tag; + u8 *input_buffer_address = NULL; + + vidc_sm_get_frame_tags(&ddl->shared_mem[ddl->command_channel], + &output_frame->ip_frm_tag, &bottom_frame_tag); + output_frame->data_len = encoder->enc_frame_info.enc_frame_size; + output_frame->flags |= VCD_FRAME_FLAG_ENDOFFRAME; + (void)ddl_get_encoded_frame(output_frame, + encoder->codec.codec, encoder->enc_frame_info.enc_frame + ); + if (!IS_ERR_OR_NULL(output_frame->buff_ion_handle)) { + msm_ion_do_cache_op(ddl_context->video_ion_client, + output_frame->buff_ion_handle, + (unsigned long *) output_frame->virtual, + (unsigned long) output_frame->alloc_len, + ION_IOC_INV_CACHES); + } + ddl_process_encoder_metadata(ddl); + ddl_vidc_encode_dynamic_property(ddl, false); + ddl->input_frame.frm_trans_end = false; + input_buffer_address = ddl_context->dram_base_a.align_physical_addr + + encoder->enc_frame_info.enc_luma_address; + ddl_get_input_frame_from_pool(ddl, input_buffer_address); + ddl_context->ddl_callback(VCD_EVT_RESP_INPUT_DONE, + VCD_S_SUCCESS, &(ddl->input_frame), + sizeof(struct ddl_frame_data_tag), + (u32 *) ddl, ddl->client_data); + ddl->output_frame.frm_trans_end = eos_present ? + false : true; + ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE, + VCD_S_SUCCESS, &(ddl->output_frame), + sizeof(struct ddl_frame_data_tag), + (u32 *) ddl, ddl->client_data); +} + +static void ddl_handle_slice_done_slice_batch(struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + struct vcd_frame_data *output_frame = NULL; + u32 bottom_frame_tag; + struct vidc_1080p_enc_slice_batch_out_param *slice_output = NULL; + u32 num_slices_comp = 0; + u32 index = 0; + u32 start_bfr_idx = 0; + u32 actual_idx = 0; + + DDL_MSG_LOW("%s\n", __func__); + vidc_sm_get_num_slices_comp( + &ddl->shared_mem[ddl->command_channel], + &num_slices_comp); + slice_output = (struct vidc_1080p_enc_slice_batch_out_param *) + (encoder->batch_frame.slice_batch_out.align_virtual_addr); + DDL_MSG_LOW(" after get no of slices = %d\n", num_slices_comp); + if (slice_output == NULL) + DDL_MSG_ERROR(" slice_output is NULL\n"); + encoder->slice_delivery_info.num_slices_enc += num_slices_comp; + if (vidc_msg_timing) { + ddl_calc_core_proc_time_cnt(__func__, ENC_SLICE_OP_TIME, + num_slices_comp); + ddl_set_core_start_time(__func__, ENC_SLICE_OP_TIME); + } + DDL_MSG_LOW("%s : Slices Completed %d Total slices %d OutBfrInfo:" + "Cmd %d Size %d\n", + __func__, + num_slices_comp, + encoder->slice_delivery_info.num_slices_enc, + slice_output->cmd_type, + slice_output->output_size); + start_bfr_idx = encoder->batch_frame.out_frm_next_frmindex; + for (index = 0; index < num_slices_comp; index++) { + actual_idx = + slice_output->slice_info[start_bfr_idx+index].stream_buffer_idx; + DDL_MSG_LOW("Slice Info: OutBfrIndex %d SliceSize %d\n", + actual_idx, + slice_output->slice_info[start_bfr_idx+index]. + stream_buffer_size); + output_frame = &( + encoder->batch_frame.output_frame[actual_idx].vcd_frm); + DDL_MSG_LOW("OutBfr: vcd_frm 0x%x frmbfr(virtual) 0x%x" + "frmbfr(physical) 0x%x\n", + &output_frame, + output_frame.virtual_base_addr, + output_frame.physical_base_addr); + vidc_1080p_get_encode_frame_info(&encoder->enc_frame_info); + vidc_sm_get_frame_tags(&ddl->shared_mem + [ddl->command_channel], + &output_frame->ip_frm_tag, &bottom_frame_tag); + + if (start_bfr_idx == 0) { + encoder->batch_frame.first_output_frame_tag = + output_frame->ip_frm_tag; + DDL_MSG_LOW("%s: first_output_frame_tag[0x%x]", + __func__, output_frame->ip_frm_tag); + if (!output_frame->ip_frm_tag) { + DDL_MSG_ERROR("%s: first_output_frame_tag "\ + "is zero", __func__); + } + } + if (output_frame->ip_frm_tag != + encoder->batch_frame.first_output_frame_tag) { + DDL_MSG_ERROR("%s: output_frame->ip_frm_tag[0x%x] is "\ + "not equal to the first_output_frame_tag[0x%x]\n", + __func__, output_frame->ip_frm_tag, + encoder->batch_frame.first_output_frame_tag); + output_frame->ip_frm_tag = + encoder->batch_frame.first_output_frame_tag; + } + + ddl_get_encoded_frame(output_frame, + encoder->codec.codec, + encoder->enc_frame_info.enc_frame); + output_frame->data_len = + slice_output->slice_info[actual_idx].stream_buffer_size; + ddl->output_frame = + encoder->batch_frame.output_frame[actual_idx]; + ddl->output_frame.frm_trans_end = false; + ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE, + VCD_S_SUCCESS, &(ddl->output_frame), + sizeof(struct ddl_frame_data_tag), + (u32 *) ddl, ddl->client_data); + ddl->input_frame.frm_trans_end = false; + DDL_MSG_LOW("%s Set i/p o/p transactions to false\n", __func__); + } + encoder->batch_frame.out_frm_next_frmindex = start_bfr_idx + index; + ddl->cmd_state = DDL_CMD_ENCODE_FRAME; + vidc_sm_set_encoder_slice_batch_int_ctrl( + &ddl->shared_mem[ddl->command_channel], + 0); +} + +static void ddl_handle_enc_frame_done_slice_mode( + struct ddl_client_context *ddl, u32 eos_present) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + struct vcd_frame_data *output_frame = NULL; + u32 bottom_frame_tag; + u8 *input_buffer_address = NULL; + struct vidc_1080p_enc_slice_batch_out_param *slice_output = NULL; + u32 num_slices_comp = 0; + u32 index = 0; + u32 start_bfr_idx = 0; + u32 actual_idx = 0; + struct vcd_transc *transc; + + DDL_MSG_LOW("%s\n", __func__); + vidc_sm_get_num_slices_comp( + &ddl->shared_mem[ddl->command_channel], + &num_slices_comp); + slice_output = (struct vidc_1080p_enc_slice_batch_out_param *) + encoder->batch_frame.slice_batch_out.align_virtual_addr; + encoder->slice_delivery_info.num_slices_enc += num_slices_comp; + if (vidc_msg_timing) { + ddl_calc_core_proc_time_cnt(__func__, ENC_OP_TIME, + num_slices_comp); + } + DDL_MSG_LOW("%s Slices Completed %d Total slices done = %d" + " OutBfrInfo: Cmd %d Size %d", + __func__, + num_slices_comp, + encoder->slice_delivery_info.num_slices_enc, + slice_output->cmd_type, + slice_output->output_size); + start_bfr_idx = encoder->batch_frame.out_frm_next_frmindex; + if ((encoder->slice_delivery_info.num_slices_enc % + encoder->batch_frame.num_output_frames) != 0) { + DDL_MSG_ERROR("ERROR : %d %d\n", + encoder->slice_delivery_info.num_slices_enc, + encoder->batch_frame.num_output_frames); + } + for (index = 0; index < num_slices_comp; index++) { + actual_idx = + slice_output->slice_info[start_bfr_idx+index]. \ + stream_buffer_idx; + DDL_MSG_LOW("Slice Info: OutBfrIndex %d SliceSize %d", + actual_idx, + slice_output->slice_info[start_bfr_idx+index]. \ + stream_buffer_size, 0); + output_frame = + &(encoder->batch_frame.output_frame[actual_idx].vcd_frm); + DDL_MSG_LOW("OutBfr: vcd_frm 0x%x frmbfr(virtual) 0x%x" + "frmbfr(physical) 0x%x", + &output_frame, + output_frame.virtual_base_addr, + output_frame.physical_base_addr); + vidc_1080p_get_encode_frame_info( + &encoder->enc_frame_info); + vidc_sm_get_frame_tags(&ddl->shared_mem + [ddl->command_channel], + &output_frame->ip_frm_tag, &bottom_frame_tag); + + if (start_bfr_idx == 0) { + encoder->batch_frame.first_output_frame_tag = + output_frame->ip_frm_tag; + DDL_MSG_LOW("%s: first_output_frame_tag[0x%x]", + __func__, output_frame->ip_frm_tag); + if (!output_frame->ip_frm_tag) { + DDL_MSG_ERROR("%s: first_output_frame_tag "\ + "is zero", __func__); + } + } + if (output_frame->ip_frm_tag != + encoder->batch_frame.first_output_frame_tag) { + DDL_MSG_ERROR("%s: output_frame->ip_frm_tag[0x%x] is "\ + "not equal to the first_output_frame_tag[0x%x]\n", + __func__, output_frame->ip_frm_tag, + encoder->batch_frame.first_output_frame_tag); + output_frame->ip_frm_tag = + encoder->batch_frame.first_output_frame_tag; + } + + ddl_get_encoded_frame(output_frame, + encoder->codec.codec, + encoder->enc_frame_info.enc_frame); + output_frame->data_len = + slice_output->slice_info[actual_idx].stream_buffer_size; + ddl->output_frame = + encoder->batch_frame.output_frame[actual_idx]; + DDL_MSG_LOW(" %s actual_idx = %d" + "encoder->batch_frame.num_output_frames = %d\n", __func__, + actual_idx, encoder->batch_frame.num_output_frames); + if (encoder->batch_frame.num_output_frames == (actual_idx+1)) { + output_frame->flags |= VCD_FRAME_FLAG_ENDOFFRAME; + ddl_vidc_encode_dynamic_property(ddl, false); + ddl->input_frame.frm_trans_end = true; + DDL_MSG_LOW("%s End of frame detected\n", __func__); + input_buffer_address = + ddl_context->dram_base_a.align_physical_addr + + encoder->enc_frame_info.enc_luma_address; + ddl_get_input_frame_from_pool(ddl, + input_buffer_address); + transc = (struct vcd_transc *)(ddl->client_data); + if (eos_present) + ddl->output_frame.frm_trans_end = false; + else + ddl->output_frame.frm_trans_end = true; + } + DDL_MSG_LOW("%s Before output done cb\n", __func__); + transc = (struct vcd_transc *)(ddl->client_data); + ddl->output_frame.vcd_frm = *output_frame; + ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE, + VCD_S_SUCCESS, &(ddl->output_frame), + sizeof(struct ddl_frame_data_tag), + (u32 *) ddl, ddl->client_data); + } + if (encoder->batch_frame.num_output_frames == (actual_idx+1)) { + DDL_MSG_LOW("%s sending input done\n", __func__); + ddl_context->ddl_callback(VCD_EVT_RESP_INPUT_DONE, + VCD_S_SUCCESS, &(ddl->input_frame), + sizeof(struct ddl_frame_data_tag), + (u32 *) ddl, ddl->client_data); + } +} + +static void ddl_handle_enc_skipframe_slice_mode( + struct ddl_client_context *ddl, u32 eos_present) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + struct vcd_frame_data *output_frame = NULL; + u32 bottom_frame_tag; + u8 *input_buffer_address = NULL; + u32 index = 0; + DDL_MSG_HIGH("ddl_handle_enc_skipframe_slice_mode: frame skipped"); + vidc_sm_set_encoder_slice_batch_int_ctrl( + &ddl->shared_mem[ddl->command_channel], + 1); + for (index = 0; + index < encoder->batch_frame.num_output_frames; + index++) { + output_frame = + &(encoder->batch_frame.output_frame[index].vcd_frm); + DDL_MSG_MED("output buffer: vcd_frm = 0x%x " + "frmbfr(virtual) = 0x%x frmbfr(physical) = 0x%x", + (u32)output_frame, (u32)output_frame->virtual, + (u32)output_frame->physical); + vidc_sm_get_frame_tags( + &ddl->shared_mem[ddl->command_channel], + &output_frame->ip_frm_tag, + &bottom_frame_tag); + if (!output_frame->ip_frm_tag) { + DDL_MSG_ERROR("%s: output frame tag is zero", + __func__); + } + ddl_get_encoded_frame( + output_frame, + encoder->codec.codec, + encoder->enc_frame_info.enc_frame); + output_frame->data_len = 0; + ddl->output_frame.frm_trans_end = false; + if (encoder->batch_frame.num_output_frames == + (index + 1)) { + DDL_MSG_MED("last output bfr for skip frame, set EOF"); + output_frame->flags |= VCD_FRAME_FLAG_ENDOFFRAME; + ddl_vidc_encode_dynamic_property(ddl, false); + if (eos_present) + ddl->output_frame.frm_trans_end = false; + else + ddl->output_frame.frm_trans_end = true; + } + ddl->output_frame.vcd_frm = *output_frame; + ddl_context->ddl_callback( + VCD_EVT_RESP_OUTPUT_DONE, + VCD_S_SUCCESS, + &(ddl->output_frame), + sizeof(struct ddl_frame_data_tag), + (u32 *)ddl, + ddl->client_data); + + if (encoder->batch_frame.num_output_frames == + (index + 1)) { + ddl->input_frame.frm_trans_end = false; + input_buffer_address = + ddl_context->dram_base_a.physical_base_addr + + (encoder->enc_frame_info.enc_luma_address); + ddl_get_input_frame_from_pool(ddl, + input_buffer_address); + DDL_MSG_MED("InpBfr: vcd_frm 0x%x frmbfr(virtual) 0x%x" + " frmbfr(physical) 0x%x", + (u32)&(ddl->input_frame.vcd_frm), + (u32)ddl->input_frame.vcd_frm.virtual, + (u32)ddl->input_frame.vcd_frm.physical); + ddl_context->ddl_callback( + VCD_EVT_RESP_INPUT_DONE, + VCD_S_SUCCESS, + &(ddl->input_frame), + sizeof(struct ddl_frame_data_tag), + (u32 *)ddl, + ddl->client_data); + } + } +} diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c new file mode 100644 index 000000000000..aa2827616042 --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.c @@ -0,0 +1,508 @@ +/* Copyright (c) 2010, 2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#include "vcd_ddl.h" +#include "vcd_ddl_shared_mem.h" +#include "vcd_ddl_metadata.h" + +static u32 *ddl_metadata_hdr_entry(struct ddl_client_context *ddl, + u32 meta_data) +{ + u32 skip_words = 0; + u32 *buffer; + + if (ddl->decoding) { + buffer = (u32 *) ddl->codec_data.decoder.meta_data_input. + align_virtual_addr; + skip_words = 32 + 1; + buffer += skip_words; + switch (meta_data) { + default: + case VCD_METADATA_DATANONE: + skip_words = 0; + break; + case VCD_METADATA_QPARRAY: + skip_words = 3; + break; + case VCD_METADATA_CONCEALMB: + skip_words = 6; + break; + case VCD_METADATA_VC1: + skip_words = 9; + break; + case VCD_METADATA_SEI: + skip_words = 12; + break; + case VCD_METADATA_VUI: + skip_words = 15; + break; + case VCD_METADATA_PASSTHROUGH: + skip_words = 18; + break; + case VCD_METADATA_QCOMFILLER: + skip_words = 21; + break; + } + } else { + buffer = (u32 *) ddl->codec_data.encoder.meta_data_input. + align_virtual_addr; + skip_words = 2; + buffer += skip_words; + switch (meta_data) { + default: + case VCD_METADATA_DATANONE: + skip_words = 0; + break; + case VCD_METADATA_ENC_SLICE: + skip_words = 3; + break; + case VCD_METADATA_QCOMFILLER: + skip_words = 6; + break; + } + } + buffer += skip_words; + return buffer; +} + +void ddl_set_default_meta_data_hdr(struct ddl_client_context *ddl) +{ + struct ddl_buf_addr *main_buffer = + &ddl->ddl_context->metadata_shared_input; + struct ddl_buf_addr *client_buffer; + u32 *hdr_entry; + + if (ddl->decoding) + client_buffer = &(ddl->codec_data.decoder.meta_data_input); + else + client_buffer = &(ddl->codec_data.encoder.meta_data_input); + DDL_METADATA_CLIENT_INPUTBUF(main_buffer, client_buffer, + ddl->instance_id); + hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_QCOMFILLER); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_QCOMFILLER; + hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_DATANONE); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_DATANONE; + if (ddl->decoding) { + hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_QPARRAY); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_QPARRAY; + hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_CONCEALMB); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_CONCEALMB; + hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_SEI); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_SEI; + hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_VUI); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_VUI; + hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_VC1); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_VC1; + hdr_entry = ddl_metadata_hdr_entry(ddl, + VCD_METADATA_PASSTHROUGH); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = + VCD_METADATA_PASSTHROUGH; + } else { + hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_ENC_SLICE); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_ENC_SLICE; + } +} + +static u32 ddl_supported_metadata_flag(struct ddl_client_context *ddl) +{ + u32 flag = 0; + + if (ddl->decoding) { + enum vcd_codec codec = + ddl->codec_data.decoder.codec.codec; + + flag |= (VCD_METADATA_CONCEALMB | VCD_METADATA_PASSTHROUGH | + VCD_METADATA_QPARRAY); + if (codec == VCD_CODEC_H264) + flag |= (VCD_METADATA_SEI | VCD_METADATA_VUI); + else if (codec == VCD_CODEC_VC1 || + codec == VCD_CODEC_VC1_RCV) + flag |= VCD_METADATA_VC1; + } else + flag |= VCD_METADATA_ENC_SLICE; + return flag; +} + +void ddl_set_default_metadata_flag(struct ddl_client_context *ddl) +{ + if (ddl->decoding) + ddl->codec_data.decoder.meta_data_enable_flag = 0; + else + ddl->codec_data.encoder.meta_data_enable_flag = 0; +} + +void ddl_set_default_decoder_metadata_buffer_size(struct ddl_decoder_data + *decoder, struct vcd_property_frame_size *frame_size, + struct vcd_buffer_requirement *output_buf_req) +{ + u32 flag = decoder->meta_data_enable_flag; + u32 suffix = 0, size = 0; + + if (!flag) { + decoder->suffix = 0; + return; + } + if (flag & VCD_METADATA_QPARRAY) { + u32 num_of_mb = DDL_NO_OF_MB(frame_size->width, + frame_size->height); + + size = DDL_METADATA_HDR_SIZE; + size += num_of_mb; + DDL_METADATA_ALIGNSIZE(size); + suffix += size; + } + if (flag & VCD_METADATA_CONCEALMB) { + u32 num_of_mb = DDL_NO_OF_MB(frame_size->width, + frame_size->height); + size = DDL_METADATA_HDR_SIZE + (num_of_mb >> 3); + DDL_METADATA_ALIGNSIZE(size); + suffix += size; + } + if (flag & VCD_METADATA_VC1) { + size = DDL_METADATA_HDR_SIZE; + size += DDL_METADATA_VC1_PAYLOAD_SIZE; + DDL_METADATA_ALIGNSIZE(size); + suffix += size; + } + if (flag & VCD_METADATA_SEI) { + size = DDL_METADATA_HDR_SIZE; + size += DDL_METADATA_SEI_PAYLOAD_SIZE; + DDL_METADATA_ALIGNSIZE(size); + suffix += (size * DDL_METADATA_SEI_MAX); + } + if (flag & VCD_METADATA_VUI) { + size = DDL_METADATA_HDR_SIZE; + size += DDL_METADATA_VUI_PAYLOAD_SIZE; + DDL_METADATA_ALIGNSIZE(size); + suffix += (size); + } + if (flag & VCD_METADATA_PASSTHROUGH) { + size = DDL_METADATA_HDR_SIZE; + size += DDL_METADATA_PASSTHROUGH_PAYLOAD_SIZE; + DDL_METADATA_ALIGNSIZE(size); + suffix += (size); + } + size = DDL_METADATA_EXTRADATANONE_SIZE; + DDL_METADATA_ALIGNSIZE(size); + suffix += (size); + suffix += DDL_METADATA_EXTRAPAD_SIZE; + DDL_METADATA_ALIGNSIZE(suffix); + decoder->suffix = suffix; + output_buf_req->sz += suffix; + DDL_MSG_LOW("metadata output buf size : %d", suffix); +} + +void ddl_set_default_encoder_metadata_buffer_size(struct ddl_encoder_data + *encoder) +{ + u32 flag = encoder->meta_data_enable_flag; + u32 suffix = 0, size = 0; + + if (!flag) { + encoder->suffix = 0; + return; + } + if (flag & VCD_METADATA_ENC_SLICE) { + u32 num_of_mb = DDL_NO_OF_MB(encoder->frame_size.width, + encoder->frame_size.height); + size = DDL_METADATA_HDR_SIZE; + size += 4; + size += (num_of_mb << 3); + DDL_METADATA_ALIGNSIZE(size); + suffix += size; + } + size = DDL_METADATA_EXTRADATANONE_SIZE; + DDL_METADATA_ALIGNSIZE(size); + suffix += (size); + suffix += DDL_METADATA_EXTRAPAD_SIZE; + DDL_METADATA_ALIGNSIZE(suffix); + encoder->suffix = suffix; + encoder->output_buf_req.sz += suffix; + encoder->output_buf_req.sz = + DDL_ALIGN(encoder->output_buf_req.sz, DDL_KILO_BYTE(4)); +} + +u32 ddl_set_metadata_params(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value) +{ + u32 vcd_status = VCD_ERR_ILLEGAL_PARM; + if (property_hdr->prop_id == VCD_I_METADATA_ENABLE) { + struct vcd_property_meta_data_enable *meta_data_enable = + (struct vcd_property_meta_data_enable *) property_value; + u32 *meta_data_enable_flag; + enum vcd_codec codec; + + if (ddl->decoding) { + meta_data_enable_flag = + &(ddl->codec_data.decoder.meta_data_enable_flag); + codec = ddl->codec_data.decoder.codec.codec; + } else { + meta_data_enable_flag = + &ddl->codec_data.encoder.meta_data_enable_flag; + codec = ddl->codec_data.encoder.codec.codec; + } + if (sizeof(struct vcd_property_meta_data_enable) == + property_hdr->sz && + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) && codec) { + u32 flag = ddl_supported_metadata_flag(ddl); + flag &= (meta_data_enable->meta_data_enable_flag); + if (flag) + flag |= DDL_METADATA_MANDATORY; + if (*meta_data_enable_flag != flag) { + *meta_data_enable_flag = flag; + if (ddl->decoding) + ddl_set_default_decoder_buffer_req( + &ddl->codec_data.decoder, true); + else + ddl_set_default_encoder_buffer_req( + &ddl->codec_data.encoder); + } + vcd_status = VCD_S_SUCCESS; + } + } else if (property_hdr->prop_id == VCD_I_METADATA_HEADER) { + struct vcd_property_metadata_hdr *hdr = + (struct vcd_property_metadata_hdr *) property_value; + + if (sizeof(struct vcd_property_metadata_hdr) == + property_hdr->sz) { + u32 flag = ddl_supported_metadata_flag(ddl); + + flag |= DDL_METADATA_MANDATORY; + flag &= hdr->meta_data_id; + if (!(flag & (flag - 1))) { + u32 *hdr_entry = ddl_metadata_hdr_entry(ddl, + flag); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = + hdr->version; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = + hdr->port_index; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = + hdr->type; + vcd_status = VCD_S_SUCCESS; + } + } + } + return vcd_status; +} + +u32 ddl_get_metadata_params(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value) +{ + u32 vcd_status = VCD_ERR_ILLEGAL_PARM; + if (property_hdr->prop_id == VCD_I_METADATA_ENABLE && + sizeof(struct vcd_property_meta_data_enable) == + property_hdr->sz) { + struct vcd_property_meta_data_enable *meta_data_enable = + (struct vcd_property_meta_data_enable *) property_value; + + meta_data_enable->meta_data_enable_flag = + ((ddl->decoding) ? + (ddl->codec_data.decoder.meta_data_enable_flag) : + (ddl->codec_data.encoder.meta_data_enable_flag)); + vcd_status = VCD_S_SUCCESS; + } else if (property_hdr->prop_id == VCD_I_METADATA_HEADER && + sizeof(struct vcd_property_metadata_hdr) == + property_hdr->sz) { + struct vcd_property_metadata_hdr *hdr = + (struct vcd_property_metadata_hdr *) property_value; + u32 flag = ddl_supported_metadata_flag(ddl); + + flag |= DDL_METADATA_MANDATORY; + flag &= hdr->meta_data_id; + if (!(flag & (flag - 1))) { + u32 *hdr_entry = ddl_metadata_hdr_entry(ddl, flag); + hdr->version = + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX]; + hdr->port_index = + hdr_entry[DDL_METADATA_HDR_PORT_INDEX]; + hdr->type = hdr_entry[DDL_METADATA_HDR_TYPE_INDEX]; + vcd_status = VCD_S_SUCCESS; + } + } + return vcd_status; +} + +void ddl_vidc_metadata_enable(struct ddl_client_context *ddl) +{ + u32 flag, extradata_enable = false; + u32 qp_enable = false, concealed_mb_enable = false; + u32 vc1_param_enable = false, sei_nal_enable = false; + u32 vui_enable = false, enc_slice_size_enable = false; + + if (ddl->decoding) + flag = ddl->codec_data.decoder.meta_data_enable_flag; + else + flag = ddl->codec_data.encoder.meta_data_enable_flag; + if (flag) { + if (flag & VCD_METADATA_QPARRAY) + qp_enable = true; + if (flag & VCD_METADATA_CONCEALMB) + concealed_mb_enable = true; + if (flag & VCD_METADATA_VC1) + vc1_param_enable = true; + if (flag & VCD_METADATA_SEI) + sei_nal_enable = true; + if (flag & VCD_METADATA_VUI) + vui_enable = true; + if (flag & VCD_METADATA_ENC_SLICE) + enc_slice_size_enable = true; + if (flag & VCD_METADATA_PASSTHROUGH) + extradata_enable = true; + } + + DDL_MSG_LOW("metadata enable flag : %d", sei_nal_enable); + vidc_sm_set_metadata_enable(&ddl->shared_mem + [ddl->command_channel], extradata_enable, qp_enable, + concealed_mb_enable, vc1_param_enable, sei_nal_enable, + vui_enable, enc_slice_size_enable); +} + +u32 ddl_vidc_encode_set_metadata_output_buf(struct ddl_client_context *ddl) +{ + struct ddl_encoder_data *encoder = &ddl->codec_data.encoder; + struct vcd_frame_data *stream = &ddl->output_frame.vcd_frm; + struct ddl_context *ddl_context; + u32 ext_buffer_end, hw_metadata_start; + u32 *buffer; + + ddl_context = ddl_get_context(); + ext_buffer_end = (u32) stream->physical + stream->alloc_len; + if (!encoder->meta_data_enable_flag) { + ext_buffer_end &= ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES); + return ext_buffer_end; + } + hw_metadata_start = (ext_buffer_end - encoder->suffix) & + ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES); + ext_buffer_end = (hw_metadata_start - 1) & + ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES); + buffer = (u32 *) encoder->meta_data_input.align_virtual_addr; + *buffer++ = encoder->suffix; + *buffer = DDL_OFFSET(ddl_context->dram_base_a.align_physical_addr, + hw_metadata_start); + encoder->meta_data_offset = hw_metadata_start - (u32) stream->physical; + return ext_buffer_end; +} + +void ddl_vidc_decode_set_metadata_output(struct ddl_decoder_data *decoder) +{ + struct ddl_context *ddl_context; + u32 loopc, yuv_size; + u32 *buffer; + + if (!decoder->meta_data_enable_flag) { + decoder->meta_data_offset = 0; + return; + } + ddl_context = ddl_get_context(); + yuv_size = ddl_get_yuv_buffer_size(&decoder->client_frame_size, + &decoder->buf_format, !decoder->progressive_only, + decoder->hdr.decoding, NULL); + decoder->meta_data_offset = DDL_ALIGN_SIZE(yuv_size, + DDL_LINEAR_BUF_ALIGN_GUARD_BYTES, DDL_LINEAR_BUF_ALIGN_MASK); + buffer = (u32 *) decoder->meta_data_input.align_virtual_addr; + *buffer++ = decoder->suffix; + DDL_MSG_LOW("Metadata offset & size : %d/%d", + decoder->meta_data_offset, decoder->suffix); + for (loopc = 0; loopc < decoder->dp_buf.no_of_dec_pic_buf; + ++loopc) { + *buffer++ = (u32)(decoder->meta_data_offset + (u8 *) + DDL_OFFSET(ddl_context->dram_base_a. + align_physical_addr, decoder->dp_buf. + dec_pic_buffers[loopc].vcd_frm.physical)); + } +} + +void ddl_process_encoder_metadata(struct ddl_client_context *ddl) +{ + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + struct vcd_frame_data *out_frame = + &(ddl->output_frame.vcd_frm); + u32 *qfiller_hdr, *qfiller, start_addr; + u32 qfiller_size; + if (!encoder->meta_data_enable_flag) { + out_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA); + return; + } + if (!encoder->enc_frame_info.meta_data_exists) { + out_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA); + return; + } + out_frame->flags |= VCD_FRAME_FLAG_EXTRADATA; + DDL_MSG_LOW("processing metadata for encoder"); + start_addr = (u32) ((u8 *)out_frame->virtual + out_frame->offset); + qfiller = (u32 *)((out_frame->data_len + + start_addr + 3) & ~3); + qfiller_size = (u32)((encoder->meta_data_offset + + (u8 *) out_frame->virtual) - (u8 *) qfiller); + qfiller_hdr = ddl_metadata_hdr_entry(ddl, VCD_METADATA_QCOMFILLER); + *qfiller++ = qfiller_size; + *qfiller++ = qfiller_hdr[DDL_METADATA_HDR_VERSION_INDEX]; + *qfiller++ = qfiller_hdr[DDL_METADATA_HDR_PORT_INDEX]; + *qfiller++ = qfiller_hdr[DDL_METADATA_HDR_TYPE_INDEX]; + *qfiller = (u32)(qfiller_size - DDL_METADATA_HDR_SIZE); +} + +void ddl_process_decoder_metadata(struct ddl_client_context *ddl) +{ + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + struct vcd_frame_data *output_frame = + &(ddl->output_frame.vcd_frm); + u32 *qfiller_hdr, *qfiller; + u32 qfiller_size; + + if (!decoder->meta_data_enable_flag) { + output_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA); + return; + } + if (!decoder->meta_data_exists) { + output_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA); + return; + } + DDL_MSG_LOW("processing metadata for decoder"); + DDL_MSG_LOW("data_len/metadata_offset : %d/%d", + output_frame->data_len, decoder->meta_data_offset); + output_frame->flags |= VCD_FRAME_FLAG_EXTRADATA; + if (output_frame->data_len != decoder->meta_data_offset) { + qfiller = (u32 *)((u32)((output_frame->data_len + + output_frame->offset + + (u8 *) output_frame->virtual) + 3) & ~3); + qfiller_size = (u32)((decoder->meta_data_offset + + (u8 *) output_frame->virtual) - + (u8 *) qfiller); + qfiller_hdr = ddl_metadata_hdr_entry(ddl, + VCD_METADATA_QCOMFILLER); + *qfiller++ = qfiller_size; + *qfiller++ = qfiller_hdr[DDL_METADATA_HDR_VERSION_INDEX]; + *qfiller++ = qfiller_hdr[DDL_METADATA_HDR_PORT_INDEX]; + *qfiller++ = qfiller_hdr[DDL_METADATA_HDR_TYPE_INDEX]; + *qfiller = (u32)(qfiller_size - DDL_METADATA_HDR_SIZE); + } +} diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.h new file mode 100644 index 000000000000..11283932a78d --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_metadata.h @@ -0,0 +1,66 @@ +/* Copyright (c) 2010, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#ifndef _VCD_DDL_METADATA_H_ +#define _VCD_DDL_METADATA_H_ + +#define DDL_MAX_DEC_METADATATYPE 8 +#define DDL_MAX_ENC_METADATATYPE 3 +#define DDL_METADATA_EXTRAPAD_SIZE 256 +#define DDL_METADATA_HDR_SIZE 20 +#define DDL_METADATA_EXTRADATANONE_SIZE 24 +#define DDL_METADATA_ALIGNSIZE(x) ((x) = (((x) + 0x7) & ~0x7)) +#define DDL_METADATA_MANDATORY \ + (VCD_METADATA_DATANONE | VCD_METADATA_QCOMFILLER) +#define DDL_METADATA_VC1_PAYLOAD_SIZE (38*4) +#define DDL_METADATA_SEI_PAYLOAD_SIZE 100 +#define DDL_METADATA_SEI_MAX 5 +#define DDL_METADATA_VUI_PAYLOAD_SIZE 256 +#define DDL_METADATA_PASSTHROUGH_PAYLOAD_SIZE 68 +#define DDL_METADATA_CLIENT_INPUTBUFSIZE 256 +#define DDL_METADATA_TOTAL_INPUTBUFSIZE \ + (DDL_METADATA_CLIENT_INPUTBUFSIZE * VCD_MAX_NO_CLIENT) + +#define DDL_METADATA_CLIENT_INPUTBUF(main_buffer, client_buffer,\ + channel_id) { \ + (client_buffer)->align_physical_addr = (u8 *) \ + ((u8 *)(main_buffer)->align_physical_addr + \ + (DDL_METADATA_CLIENT_INPUTBUFSIZE * channel_id)); \ + (client_buffer)->align_virtual_addr = (u8 *) \ + ((u8 *)(main_buffer)->align_virtual_addr + \ + (DDL_METADATA_CLIENT_INPUTBUFSIZE * channel_id)); \ + (client_buffer)->virtual_base_addr = 0; \ + } + +#define DDL_METADATA_HDR_VERSION_INDEX 0 +#define DDL_METADATA_HDR_PORT_INDEX 1 +#define DDL_METADATA_HDR_TYPE_INDEX 2 + +void ddl_set_default_meta_data_hdr(struct ddl_client_context *ddl); +u32 ddl_get_metadata_params(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value); +u32 ddl_set_metadata_params(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value); +void ddl_set_default_metadata_flag(struct ddl_client_context *ddl); +void ddl_set_default_decoder_metadata_buffer_size(struct ddl_decoder_data + *decoder, struct vcd_property_frame_size *frame_size, + struct vcd_buffer_requirement *output_buf_req); +void ddl_set_default_encoder_metadata_buffer_size( + struct ddl_encoder_data *encoder); +void ddl_vidc_metadata_enable(struct ddl_client_context *ddl); +u32 ddl_vidc_encode_set_metadata_output_buf(struct ddl_client_context *ddl); +void ddl_vidc_decode_set_metadata_output(struct ddl_decoder_data *decoder); +void ddl_process_encoder_metadata(struct ddl_client_context *ddl); +void ddl_process_decoder_metadata(struct ddl_client_context *ddl); + +#endif diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c new file mode 100644 index 000000000000..e1959a1ba3cb --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c @@ -0,0 +1,2113 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#include "vcd_ddl.h" +#include "vcd_ddl_metadata.h" +#include "vcd_res_tracker_api.h" + +static u32 ddl_set_dec_property(struct ddl_client_context *pddl, + struct vcd_property_hdr *property_hdr, void *property_value); +static u32 ddl_set_enc_property(struct ddl_client_context *pddl, + struct vcd_property_hdr *property_hdr, void *property_value); +static u32 ddl_get_dec_property(struct ddl_client_context *pddl, + struct vcd_property_hdr *property_hdr, void *property_value); +static u32 ddl_get_enc_property(struct ddl_client_context *pddl, + struct vcd_property_hdr *property_hdr, void *property_value); +static u32 ddl_set_enc_dynamic_property(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value); +static void ddl_set_default_enc_property(struct ddl_client_context *ddl); +static void ddl_set_default_enc_profile( + struct ddl_encoder_data *encoder); +static void ddl_set_default_enc_level(struct ddl_encoder_data *encoder); +static void ddl_set_default_enc_vop_timing( + struct ddl_encoder_data *encoder); +static void ddl_set_default_enc_intra_period( + struct ddl_encoder_data *encoder); +static void ddl_set_default_enc_rc_params( + struct ddl_encoder_data *encoder); +static u32 ddl_valid_buffer_requirement( + struct vcd_buffer_requirement *original_buf_req, + struct vcd_buffer_requirement *req_buf_req); +static u32 ddl_decoder_min_num_dpb(struct ddl_decoder_data *decoder); +static u32 ddl_set_dec_buffers(struct ddl_decoder_data *decoder, + struct ddl_property_dec_pic_buffers *dpb); + +u32 ddl_set_property(u32 *ddl_handle, + struct vcd_property_hdr *property_hdr, void *property_value) +{ + struct ddl_context *ddl_context; + struct ddl_client_context *ddl = + (struct ddl_client_context *) ddl_handle; + u32 vcd_status; + + DDL_MSG_HIGH("ddl_set_property"); + if (!property_hdr || !property_value) { + DDL_MSG_ERROR("ddl_set_prop:Bad_argument"); + return VCD_ERR_ILLEGAL_PARM; + } + ddl_context = ddl_get_context(); + if (!DDL_IS_INITIALIZED(ddl_context)) { + DDL_MSG_ERROR("ddl_set_prop:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (!ddl) { + DDL_MSG_ERROR("ddl_set_prop:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + if (ddl->decoding) + vcd_status = ddl_set_dec_property(ddl, property_hdr, + property_value); + else + vcd_status = ddl_set_enc_property(ddl, property_hdr, + property_value); + if (vcd_status) + DDL_MSG_ERROR("ddl_set_prop:FAILED"); + return vcd_status; +} + +u32 ddl_get_property(u32 *ddl_handle, + struct vcd_property_hdr *property_hdr, void *property_value) +{ + struct ddl_context *ddl_context; + struct ddl_client_context *ddl = + (struct ddl_client_context *) ddl_handle; + u32 vcd_status = VCD_ERR_ILLEGAL_PARM; + + DDL_MSG_HIGH("ddl_get_property"); + if (!property_hdr || !property_value) + return VCD_ERR_ILLEGAL_PARM; + if (property_hdr->prop_id == DDL_I_CAPABILITY) { + if (sizeof(struct ddl_property_capability) == + property_hdr->sz) { + struct ddl_property_capability *ddl_capability = + (struct ddl_property_capability *) + property_value; + + ddl_capability->max_num_client = VCD_MAX_NO_CLIENT; + ddl_capability->exclusive = VCD_COMMAND_EXCLUSIVE; + ddl_capability->frame_command_depth = + VCD_FRAME_COMMAND_DEPTH; + ddl_capability->general_command_depth = + VCD_GENEVIDC_COMMAND_DEPTH; + ddl_capability->ddl_time_out_in_ms = + DDL_HW_TIMEOUT_IN_MS; + vcd_status = VCD_S_SUCCESS; + } + return vcd_status; + } + ddl_context = ddl_get_context(); + if (!DDL_IS_INITIALIZED(ddl_context)) + return VCD_ERR_ILLEGAL_OP; + if (!ddl) + return VCD_ERR_BAD_HANDLE; + if (ddl->decoding) + vcd_status = ddl_get_dec_property(ddl, property_hdr, + property_value); + else + vcd_status = ddl_get_enc_property(ddl, property_hdr, + property_value); + if (vcd_status) + DDL_MSG_ERROR("ddl_get_prop:FAILED"); + else + DDL_MSG_MED("ddl_get_prop:SUCCESS"); + return vcd_status; +} + +u32 ddl_decoder_ready_to_start(struct ddl_client_context *ddl, + struct vcd_sequence_hdr *header) +{ + struct ddl_decoder_data *decoder = + &(ddl->codec_data.decoder); + + if (!decoder->codec.codec) { + DDL_MSG_ERROR("ddl_dec_start_check:Codec_not_set"); + return false; + } + if ((!header) && (!decoder->client_frame_size.height || + !decoder->client_frame_size.width)) { + DDL_MSG_ERROR("ddl_dec_start_check:" + "Client_height_width_default"); + return false; + } + return true; +} + +u32 ddl_encoder_ready_to_start(struct ddl_client_context *ddl) +{ + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + + if (!encoder->codec.codec || !encoder->frame_size.height || + !encoder->frame_size.width || + !encoder->frame_rate.fps_denominator || + !encoder->frame_rate.fps_numerator || + !encoder->target_bit_rate.target_bitrate) + return false; + if (encoder->frame_rate.fps_numerator > + (encoder->frame_rate.fps_denominator * + encoder->vop_timing.vop_time_resolution)) { + DDL_MSG_ERROR("ResVsFrameRateFailed!"); + return false; + } + if (encoder->profile.profile == VCD_PROFILE_H264_BASELINE && + encoder->entropy_control.entropy_sel == VCD_ENTROPY_SEL_CABAC) { + DDL_MSG_ERROR("H264BaseLineCABAC!!"); + return false; + } + return true; +} + +static u32 ddl_set_dec_property(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value) +{ + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + u32 vcd_status = VCD_ERR_ILLEGAL_PARM ; + + switch (property_hdr->prop_id) { + case DDL_I_DPB_RELEASE: + if ((sizeof(struct ddl_frame_data_tag) == + property_hdr->sz) && + (decoder->dp_buf.no_of_dec_pic_buf)) + vcd_status = ddl_decoder_dpb_transact(decoder, + (struct ddl_frame_data_tag *) + property_value, DDL_DPB_OP_MARK_FREE); + break; + case DDL_I_DPB: + { + struct ddl_property_dec_pic_buffers *dpb = + (struct ddl_property_dec_pic_buffers *) property_value; + + if ((sizeof(struct ddl_property_dec_pic_buffers) == + property_hdr->sz) && + (DDLCLIENT_STATE_IS(ddl, + DDL_CLIENT_WAIT_FOR_INITCODEC) || + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB)) && + (dpb->no_of_dec_pic_buf == + decoder->client_output_buf_req.actual_count)) + vcd_status = ddl_set_dec_buffers(decoder, dpb); + } + break; + case DDL_I_REQ_OUTPUT_FLUSH: + if (sizeof(u32) == property_hdr->sz) { + decoder->dynamic_prop_change |= + DDL_DEC_REQ_OUTPUT_FLUSH; + decoder->dpb_mask.client_mask = 0; + vcd_status = VCD_S_SUCCESS; + } + break; + case DDL_I_INPUT_BUF_REQ: + { + struct vcd_buffer_requirement *buffer_req = + (struct vcd_buffer_requirement *)property_value; + + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz && + (DDLCLIENT_STATE_IS(ddl, + DDL_CLIENT_WAIT_FOR_INITCODEC) || + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB) || + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) && + (ddl_valid_buffer_requirement( + &decoder->min_input_buf_req, buffer_req))) { + decoder->client_input_buf_req = *buffer_req; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case DDL_I_OUTPUT_BUF_REQ: + { + struct vcd_buffer_requirement *buffer_req = + (struct vcd_buffer_requirement *)property_value; + + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz && + (DDLCLIENT_STATE_IS(ddl, + DDL_CLIENT_WAIT_FOR_INITCODEC) || + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB) || + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) && + (ddl_valid_buffer_requirement( + &decoder->min_output_buf_req, buffer_req))) { + decoder->client_output_buf_req = + *buffer_req; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_CODEC: + { + struct vcd_property_codec *codec = + (struct vcd_property_codec *)property_value; + if (sizeof(struct vcd_property_codec) == + property_hdr->sz && + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) && + ddl_codec_type_transact(ddl, false, + codec->codec)) { + if (decoder->codec.codec != codec->codec) { + decoder->codec = *codec; + ddl_set_default_dec_property(ddl); + } + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_POST_FILTER: + if (sizeof(struct vcd_property_post_filter) == + property_hdr->sz && + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) && ( + decoder->codec.codec == VCD_CODEC_MPEG4 || + decoder->codec.codec == VCD_CODEC_MPEG2)) { + decoder->post_filter = + *(struct vcd_property_post_filter *) + property_value; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_FRAME_SIZE: + { + struct vcd_property_frame_size *frame_size = + (struct vcd_property_frame_size *) property_value; + if ((sizeof(struct vcd_property_frame_size) == + property_hdr->sz) && + (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) && + (DDL_ALLOW_DEC_FRAMESIZE(frame_size->width, + frame_size->height))) { + if (decoder->client_frame_size.height != + frame_size->height || + decoder->client_frame_size.width != + frame_size->width) { + decoder->client_frame_size = *frame_size; + ddl_set_default_decoder_buffer_req(decoder, + true); + } + DDL_MSG_LOW("set VCD_I_FRAME_SIZE width = %d" + " height = %d\n", + frame_size->width, frame_size->height); + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_BUFFER_FORMAT: + { + struct vcd_property_buffer_format *tile = + (struct vcd_property_buffer_format *) + property_value; + if (sizeof(struct vcd_property_buffer_format) == + property_hdr->sz && + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) && + tile->buffer_format == VCD_BUFFER_FORMAT_TILE_4x2) { + if (tile->buffer_format != + decoder->buf_format.buffer_format) { + decoder->buf_format = *tile; + ddl_set_default_decoder_buffer_req( + decoder, true); + } + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_H264_MV_BUFFER: + { + int index, buffer_size; + u8 *phys_addr; + u8 *virt_addr; + struct vcd_property_h264_mv_buffer *mv_buff = + (struct vcd_property_h264_mv_buffer *) + property_value; + DDL_MSG_LOW("Entered VCD_I_H264_MV_BUFFER Virt: %p, Phys %p," + "fd: %d size: %d count: %d\n", + mv_buff->kernel_virtual_addr, + mv_buff->physical_addr, + mv_buff->pmem_fd, + mv_buff->size, mv_buff->count); + if ((property_hdr->sz == sizeof(struct + vcd_property_h264_mv_buffer)) && + (DDLCLIENT_STATE_IS(ddl, + DDL_CLIENT_WAIT_FOR_INITCODEC) || + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB) || + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN))) { + phys_addr = mv_buff->dev_addr; + virt_addr = mv_buff->kernel_virtual_addr; + buffer_size = mv_buff->size/mv_buff->count; + + for (index = 0; index < mv_buff->count; index++) { + ddl->codec_data.decoder.hw_bufs. + h264_mv[index].align_physical_addr + = phys_addr; + ddl->codec_data.decoder.hw_bufs. + h264_mv[index].align_virtual_addr + = virt_addr; + ddl->codec_data.decoder.hw_bufs. + h264_mv[index].buffer_size + = buffer_size; + ddl->codec_data.decoder.hw_bufs. + h264_mv[index].physical_base_addr + = phys_addr; + ddl->codec_data.decoder.hw_bufs. + h264_mv[index].virtual_base_addr + = virt_addr; + DDL_MSG_LOW("Assigned %d buffer for " + "virt: %p, phys %p for " + "h264_mv_buffers " + "of size: %d\n", + index, virt_addr, + phys_addr, buffer_size); + phys_addr += buffer_size; + virt_addr += buffer_size; + } + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_FREE_H264_MV_BUFFER: + { + memset(&decoder->hw_bufs.h264_mv, 0, sizeof(struct + ddl_buf_addr) * DDL_MAX_BUFFER_COUNT); + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_OUTPUT_ORDER: + { + if (sizeof(u32) == property_hdr->sz && + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) { + decoder->output_order = + *(u32 *)property_value; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_DEC_PICTYPE: + { + if ((sizeof(u32) == property_hdr->sz) && + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) { + decoder->idr_only_decoding = + *(u32 *)property_value; + ddl_set_default_decoder_buffer_req( + decoder, true); + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_METADATA_ENABLE: + case VCD_I_METADATA_HEADER: + DDL_MSG_MED("Meta Data Interface is Requested"); + vcd_status = ddl_set_metadata_params(ddl, property_hdr, + property_value); + vcd_status = VCD_S_SUCCESS; + break; + case VCD_I_FRAME_RATE: + vcd_status = VCD_S_SUCCESS; + break; + case VCD_I_CONT_ON_RECONFIG: + { + DDL_MSG_LOW("Set property VCD_I_CONT_ON_RECONFIG\n"); + if (sizeof(u32) == property_hdr->sz && + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) { + decoder->cont_mode = *(u32 *)property_value; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_DISABLE_DMX: + { + int disable_dmx_allowed = 0; + DDL_MSG_LOW("Set property VCD_I_DISABLE_DMX\n"); + if (res_trk_get_disable_dmx() && + ((decoder->codec.codec == VCD_CODEC_H264) || + (decoder->codec.codec == VCD_CODEC_VC1) || + (decoder->codec.codec == VCD_CODEC_VC1_RCV))) + disable_dmx_allowed = 1; + + if (sizeof(u32) == property_hdr->sz && + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) && + disable_dmx_allowed) { + decoder->dmx_disable = *(u32 *)property_value; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_REQ_PERF_LEVEL: + vcd_status = VCD_S_SUCCESS; + break; + default: + vcd_status = VCD_ERR_ILLEGAL_OP; + break; + } + return vcd_status; +} + +static u32 ddl_check_valid_enc_level(struct vcd_property_codec *codec, + struct vcd_property_profile *profile, + struct vcd_property_level *level) +{ + u32 status = false; + + if (codec && profile && level) { + switch (codec->codec) { + case VCD_CODEC_MPEG4: + status = (profile->profile == + VCD_PROFILE_MPEG4_SP) && + (level->level >= VCD_LEVEL_MPEG4_0) && + (level->level <= VCD_LEVEL_MPEG4_6) && + (VCD_LEVEL_MPEG4_3b != level->level); + status = status || + ((profile->profile == + VCD_PROFILE_MPEG4_ASP) && + (level->level >= VCD_LEVEL_MPEG4_0) && + (level->level <= VCD_LEVEL_MPEG4_5)); + break; + case VCD_CODEC_H264: + status = (level->level >= VCD_LEVEL_H264_1) && + (level->level <= VCD_LEVEL_H264_4); + break; + case VCD_CODEC_H263: + status = (level->level >= VCD_LEVEL_H263_10) && + (level->level <= VCD_LEVEL_H263_70); + break; + default: + break; + } + } + return status; +} + +static u32 ddl_set_enc_property(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, + void *property_value) +{ + struct ddl_encoder_data *encoder = + &(ddl->codec_data.encoder); + u32 vcd_status = VCD_ERR_ILLEGAL_PARM; + + if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME) || + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE) || + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) { + vcd_status = ddl_set_enc_dynamic_property(ddl, + property_hdr, property_value); + } + if (vcd_status) { + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) || + vcd_status != VCD_ERR_ILLEGAL_OP) { + DDL_MSG_ERROR("ddl_set_enc_property:" + "Fails_as_not_in_open_state"); + return VCD_ERR_ILLEGAL_OP; + } + } else + return vcd_status; + + switch (property_hdr->prop_id) { + case VCD_I_FRAME_SIZE: + { + struct vcd_property_frame_size *frame_size = + (struct vcd_property_frame_size *) property_value; + if ((sizeof(struct vcd_property_frame_size) == + property_hdr->sz) && + (DDL_ALLOW_ENC_FRAMESIZE(frame_size->width, + frame_size->height))) { + if (encoder->frame_size.height != frame_size->height || + encoder->frame_size.width != + frame_size->width) { + ddl_calculate_stride(frame_size, false); + encoder->frame_size = *frame_size; + ddl_set_default_encoder_buffer_req(encoder); + } + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_CODEC: + { + struct vcd_property_codec *codec = + (struct vcd_property_codec *) property_value; + if ((sizeof(struct vcd_property_codec) == + property_hdr->sz) && + (ddl_codec_type_transact(ddl, false, codec->codec))) { + if (codec->codec != encoder->codec.codec) { + encoder->codec = *codec; + ddl_set_default_enc_property(ddl); + } + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_REQ_IFRAME: + vcd_status = VCD_S_SUCCESS; + break; + case VCD_I_INTRA_PERIOD: + { + struct vcd_property_i_period *i_period = + (struct vcd_property_i_period *)property_value; + if (sizeof(struct vcd_property_i_period) == + property_hdr->sz && + i_period->b_frames <= DDL_MAX_NUM_OF_B_FRAME) { + encoder->i_period = *i_period; + encoder->client_input_buf_req.min_count = + i_period->b_frames + 1; + encoder->client_input_buf_req.actual_count = + DDL_MAX(encoder->client_input_buf_req.\ + actual_count, encoder->\ + client_input_buf_req.min_count); + encoder->client_output_buf_req.min_count = + i_period->b_frames + 2; + encoder->client_output_buf_req.actual_count = + DDL_MAX(encoder->client_output_buf_req.\ + actual_count, encoder->\ + client_output_buf_req.min_count); + ddl->extra_output_buf_count = + i_period->b_frames - 1; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_PROFILE: + { + struct vcd_property_profile *profile = + (struct vcd_property_profile *)property_value; + + if ((sizeof(struct vcd_property_profile) == + property_hdr->sz) && (( + (encoder->codec.codec == VCD_CODEC_MPEG4) && ( + profile->profile == VCD_PROFILE_MPEG4_SP || + profile->profile == VCD_PROFILE_MPEG4_ASP)) || + ((encoder->codec.codec == VCD_CODEC_H264) && + (profile->profile >= VCD_PROFILE_H264_BASELINE) && + (profile->profile <= VCD_PROFILE_H264_HIGH)) || + ((encoder->codec.codec == VCD_CODEC_H263) && + (profile->profile == VCD_PROFILE_H263_BASELINE)))) { + encoder->profile = *profile; + vcd_status = VCD_S_SUCCESS; + if (profile->profile == VCD_PROFILE_H264_BASELINE) + encoder->entropy_control.entropy_sel = + VCD_ENTROPY_SEL_CAVLC; + else + encoder->entropy_control.entropy_sel = + VCD_ENTROPY_SEL_CABAC; + } + } + break; + case VCD_I_LEVEL: + { + struct vcd_property_level *level = + (struct vcd_property_level *) property_value; + + if ((sizeof(struct vcd_property_level) == + property_hdr->sz) && (ddl_check_valid_enc_level + (&encoder->codec, + &encoder->profile, level))) { + encoder->level = *level; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_MULTI_SLICE: + { + struct vcd_property_multi_slice *multi_slice = + (struct vcd_property_multi_slice *) + property_value; + DDL_MSG_HIGH("VCD_I_MULTI_SLICE eMSliceSel %d nMSliceSize %d" + "Tot#of MB %d encoder->frame_size.width = %d" + "encoder->frame_size.height = %d", + (int)multi_slice->m_slice_sel, + multi_slice->m_slice_size, + DDL_NO_OF_MB(encoder->frame_size.width, + encoder->frame_size.height), + encoder->frame_size.width, + encoder->frame_size.height); + switch (multi_slice->m_slice_sel) { + case VCD_MSLICE_OFF: + vcd_status = VCD_S_SUCCESS; + break; + case VCD_MSLICE_BY_GOB: + if (encoder->codec.codec == VCD_CODEC_H263) + vcd_status = VCD_S_SUCCESS; + break; + case VCD_MSLICE_BY_MB_COUNT: + { + if ((multi_slice->m_slice_size >= 1) && + (multi_slice->m_slice_size <= + DDL_NO_OF_MB(encoder->frame_size.width, + encoder->frame_size.height))) { + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_MSLICE_BY_BYTE_COUNT: + if (multi_slice->m_slice_size > 0) + vcd_status = VCD_S_SUCCESS; + break; + default: + break; + } + if (sizeof(struct vcd_property_multi_slice) == + property_hdr->sz && !vcd_status) { + encoder->multi_slice = *multi_slice; + if (multi_slice->m_slice_sel == VCD_MSLICE_OFF) + encoder->multi_slice.m_slice_size = 0; + } + } + break; + case VCD_I_RATE_CONTROL: + { + struct vcd_property_rate_control *rate_control = + (struct vcd_property_rate_control *) + property_value; + if (sizeof(struct vcd_property_rate_control) == + property_hdr->sz && + rate_control->rate_control >= + VCD_RATE_CONTROL_OFF && + rate_control->rate_control <= + VCD_RATE_CONTROL_CBR_CFR) { + encoder->rc = *rate_control; + ddl_set_default_enc_rc_params(encoder); + vcd_status = VCD_S_SUCCESS; + } + + } + break; + case VCD_I_SHORT_HEADER: + if (sizeof(struct vcd_property_short_header) == + property_hdr->sz && + encoder->codec.codec == + VCD_CODEC_MPEG4) { + encoder->short_header = + *(struct vcd_property_short_header *) + property_value; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_VOP_TIMING: + { + struct vcd_property_vop_timing *vop_time = + (struct vcd_property_vop_timing *) + property_value; + + if ((sizeof(struct vcd_property_vop_timing) == + property_hdr->sz) && + (encoder->frame_rate.fps_numerator <= + vop_time->vop_time_resolution) && + (encoder->codec.codec == VCD_CODEC_MPEG4)) { + encoder->vop_timing = *vop_time; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_HEADER_EXTENSION: + if (sizeof(u32) == property_hdr->sz && + encoder->codec.codec == VCD_CODEC_MPEG4) { + encoder->hdr_ext_control = *(u32 *)property_value; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_ENTROPY_CTRL: + { + struct vcd_property_entropy_control *entropy_control = + (struct vcd_property_entropy_control *) + property_value; + if (sizeof(struct vcd_property_entropy_control) == + property_hdr->sz && + encoder->codec.codec == VCD_CODEC_H264 && + entropy_control->entropy_sel >= + VCD_ENTROPY_SEL_CAVLC && + entropy_control->entropy_sel <= + VCD_ENTROPY_SEL_CABAC) { + if ((entropy_control->entropy_sel == + VCD_ENTROPY_SEL_CABAC) && + (encoder->entropy_control.cabac_model == + VCD_CABAC_MODEL_NUMBER_1 || + encoder->entropy_control.cabac_model == + VCD_CABAC_MODEL_NUMBER_2)) { + vcd_status = VCD_ERR_ILLEGAL_PARM; + } else { + encoder->entropy_control = *entropy_control; + vcd_status = VCD_S_SUCCESS; + } + } + } + break; + case VCD_I_DEBLOCKING: + { + struct vcd_property_db_config *db_config = + (struct vcd_property_db_config *) property_value; + if (sizeof(struct vcd_property_db_config) == + property_hdr->sz && + encoder->codec.codec == VCD_CODEC_H264 && + db_config->db_config >= + VCD_DB_ALL_BLOCKING_BOUNDARY && + db_config->db_config <= + VCD_DB_SKIP_SLICE_BOUNDARY) { + encoder->db_control = *db_config; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_QP_RANGE: + { + struct vcd_property_qp_range *qp = + (struct vcd_property_qp_range *)property_value; + + if ((sizeof(struct vcd_property_qp_range) == + property_hdr->sz) && (qp->min_qp <= + qp->max_qp) && ((encoder->codec.codec == + VCD_CODEC_H264 && qp->max_qp <= DDL_MAX_H264_QP) || + (qp->max_qp <= DDL_MAX_MPEG4_QP))) { + encoder->qp_range = *qp; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_SESSION_QP: + { + struct vcd_property_session_qp *qp = + (struct vcd_property_session_qp *)property_value; + if ((sizeof(struct vcd_property_session_qp) == + property_hdr->sz) && + (qp->i_frame_qp >= encoder->qp_range.min_qp) && + (qp->i_frame_qp <= encoder->qp_range.max_qp) && + (qp->p_frame_qp >= encoder->qp_range.min_qp) && + (qp->p_frame_qp <= encoder->qp_range.max_qp)) { + encoder->session_qp = *qp; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_RC_LEVEL_CONFIG: + { + struct vcd_property_rc_level *rc_level = + (struct vcd_property_rc_level *) property_value; + if (sizeof(struct vcd_property_rc_level) == + property_hdr->sz && + (encoder->rc.rate_control >= + VCD_RATE_CONTROL_VBR_VFR || + encoder->rc.rate_control <= + VCD_RATE_CONTROL_CBR_VFR) && + (!rc_level->mb_level_rc || + encoder->codec.codec == VCD_CODEC_H264)) { + encoder->rc_level = *rc_level; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_FRAME_LEVEL_RC: + { + struct vcd_property_frame_level_rc_params + *frame_level_rc = + (struct vcd_property_frame_level_rc_params *) + property_value; + if ((sizeof(struct vcd_property_frame_level_rc_params) == + property_hdr->sz) && + (frame_level_rc->reaction_coeff) && + (encoder->rc_level.frame_level_rc)) { + encoder->frame_level_rc = *frame_level_rc; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_ADAPTIVE_RC: + if ((sizeof(struct vcd_property_adaptive_rc_params) == + property_hdr->sz) && + (encoder->codec.codec == VCD_CODEC_H264) && + (encoder->rc_level.mb_level_rc)) { + encoder->adaptive_rc = + *(struct vcd_property_adaptive_rc_params *) + property_value; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_BUFFER_FORMAT: + { + struct vcd_property_buffer_format *buffer_format = + (struct vcd_property_buffer_format *) + property_value; + + if (sizeof(struct vcd_property_buffer_format) == + property_hdr->sz && + ((buffer_format->buffer_format == + VCD_BUFFER_FORMAT_NV12_16M2KA) || + (VCD_BUFFER_FORMAT_TILE_4x2 == + buffer_format->buffer_format))) { + if (buffer_format->buffer_format != + encoder->buf_format.buffer_format) { + encoder->buf_format = *buffer_format; + ddl_set_default_encoder_buffer_req(encoder); + } + vcd_status = VCD_S_SUCCESS; + } + } + break; + case DDL_I_INPUT_BUF_REQ: + { + struct vcd_buffer_requirement *buffer_req = + (struct vcd_buffer_requirement *)property_value; + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz && (ddl_valid_buffer_requirement( + &encoder->input_buf_req, buffer_req))) { + encoder->client_input_buf_req = *buffer_req; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case DDL_I_OUTPUT_BUF_REQ: + { + struct vcd_buffer_requirement *buffer_req = + (struct vcd_buffer_requirement *)property_value; + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz && (ddl_valid_buffer_requirement( + &encoder->output_buf_req, buffer_req))) { + encoder->client_output_buf_req = *buffer_req; + encoder->client_output_buf_req.sz = + DDL_ALIGN(buffer_req->sz, + DDL_KILO_BYTE(4)); + DDL_MSG_LOW("%s encoder->client_output_buf_req.sz" + " = %d\n", __func__, + encoder->client_output_buf_req.sz); + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_RECON_BUFFERS: + { + int index, index_hw_bufs = -1; + struct vcd_property_enc_recon_buffer *recon_buffers = + (struct vcd_property_enc_recon_buffer *)property_value; + for (index = 0; index < 4; index++) { + if (!encoder->hw_bufs.dpb_y[index]. + align_physical_addr) { + index_hw_bufs = index; + break; + } else + continue; + } + if (index_hw_bufs == -1) { + DDL_MSG_HIGH("ERROR: value of index_hw_bufs"); + vcd_status = VCD_ERR_ILLEGAL_PARM; + } else { + if (property_hdr->sz == sizeof(struct + vcd_property_enc_recon_buffer)) { + encoder->hw_bufs.dpb_y[index_hw_bufs]. + align_physical_addr = + recon_buffers->dev_addr; + encoder->hw_bufs.dpb_y[index_hw_bufs]. + align_virtual_addr = + recon_buffers->kernel_virtual_addr; + encoder->hw_bufs.dpb_y[index_hw_bufs]. + buffer_size = recon_buffers->buffer_size; + encoder->hw_bufs.dpb_c[index_hw_bufs]. + align_physical_addr = + recon_buffers->dev_addr + + ddl_get_yuv_buf_size( + encoder->frame_size.width, + encoder->frame_size.height, + DDL_YUV_BUF_TYPE_TILE); + encoder->hw_bufs.dpb_c[index_hw_bufs]. + align_virtual_addr = + recon_buffers->kernel_virtual_addr + + recon_buffers->ysize; + DDL_MSG_LOW("Y::KVirt: %p,KPhys: %p" + "UV::KVirt: %p,KPhys: %p\n", + encoder->hw_bufs.dpb_y[index_hw_bufs]. + align_virtual_addr, + encoder->hw_bufs.dpb_y[index_hw_bufs]. + align_physical_addr, + encoder->hw_bufs.dpb_c[index_hw_bufs]. + align_virtual_addr, + encoder->hw_bufs.dpb_c[index_hw_bufs]. + align_physical_addr); + vcd_status = VCD_S_SUCCESS; + } + } + } + break; + case VCD_I_FREE_RECON_BUFFERS: + { + memset(&encoder->hw_bufs.dpb_y, 0, + sizeof(struct ddl_buf_addr) * 4); + memset(&encoder->hw_bufs.dpb_c, 0, + sizeof(struct ddl_buf_addr) * 4); + vcd_status = VCD_S_SUCCESS; + break; + } + case VCD_I_METADATA_ENABLE: + case VCD_I_METADATA_HEADER: + DDL_MSG_LOW("Meta Data Interface is Requested"); + if (!res_trk_check_for_sec_session()) { + if (!encoder->slice_delivery_info.enable) { + vcd_status = ddl_set_metadata_params(ddl, + property_hdr, property_value); + } else { + DDL_MSG_ERROR("Ignoring meta data settting in " + "slice mode: %s\n", __func__); + vcd_status = VCD_S_SUCCESS; + } + } else { + DDL_MSG_ERROR("Meta Data Interface is not " + "supported in secure session"); + vcd_status = VCD_ERR_ILLEGAL_OP; + } + break; + case VCD_I_META_BUFFER_MODE: + vcd_status = VCD_S_SUCCESS; + break; + case VCD_I_ENABLE_SPS_PPS_FOR_IDR: + { + struct vcd_property_sps_pps_for_idr_enable *sps_pps = + (struct vcd_property_sps_pps_for_idr_enable *) property_value; + + if ((sizeof(struct vcd_property_sps_pps_for_idr_enable)) == + property_hdr->sz) { + DDL_MSG_LOW("SPS PPS generation for IDR Encode " + "is Requested"); + encoder->sps_pps.sps_pps_for_idr_enable_flag = + sps_pps->sps_pps_for_idr_enable_flag; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_SLICE_DELIVERY_MODE: + { + size_t output_buf_size; + u32 num_mb, num_slices; + struct vcd_property_hdr slice_property_hdr; + struct vcd_property_meta_data_enable slice_meta_data; + DDL_MSG_HIGH("Set property VCD_I_SLICE_DELIVERY_MODE\n"); + if (sizeof(u32) == property_hdr->sz && + encoder->codec.codec == VCD_CODEC_H264 && + encoder->multi_slice.m_slice_sel + == VCD_MSLICE_BY_MB_COUNT && + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) { + encoder->slice_delivery_info.enable + = *(u32 *)property_value; + DDL_MSG_HIGH("set encoder->slice_delivery_mode = %u\n", + encoder->slice_delivery_info.enable); + output_buf_size = + encoder->client_output_buf_req.sz; + num_mb = DDL_NO_OF_MB(encoder->frame_size.width, + encoder->frame_size.height); + num_slices = num_mb/ + encoder->multi_slice.m_slice_size; + num_slices = ((num_mb - num_slices * + encoder->multi_slice.m_slice_size) > 0) + ? (num_slices + 1) : num_slices; + encoder->slice_delivery_info.num_slices = + num_slices; + if (num_slices <= DDL_MAX_NUM_BFRS_FOR_SLICE_BATCH) { + DDL_MSG_HIGH("%s: currently slice info " + "metadata is not supported when slice " + "delivery mode is enabled. hence " + "disabling slice info metadata.\n", + __func__); + slice_property_hdr.prop_id = + VCD_I_METADATA_ENABLE; + slice_property_hdr.sz = + sizeof(struct \ + vcd_property_meta_data_enable); + ddl_get_metadata_params(ddl, + &slice_property_hdr, + &slice_meta_data); + slice_meta_data.meta_data_enable_flag + &= ~VCD_METADATA_ENC_SLICE; + ddl_set_metadata_params(ddl, + &slice_property_hdr, + &slice_meta_data); + encoder->client_output_buf_req.min_count = + ((DDL_ENC_SLICE_BATCH_FACTOR * num_slices + 2) + > DDL_MAX_BUFFER_COUNT) + ? DDL_MAX_BUFFER_COUNT : + (DDL_ENC_SLICE_BATCH_FACTOR * num_slices + 2); + output_buf_size = + encoder->client_output_buf_req.sz/num_slices; + encoder->client_output_buf_req.sz = + DDL_ALIGN(output_buf_size, DDL_KILO_BYTE(4)); + encoder->output_buf_req = + encoder->client_output_buf_req; + DDL_MSG_HIGH("%s num_mb = %u num_slices = %u " + "output_buf_count = %u " + "output_buf_size = %u aligned size = %u\n", + __func__, num_mb, num_slices, + encoder->client_output_buf_req.min_count, + output_buf_size, + encoder->client_output_buf_req.sz); + vcd_status = VCD_S_SUCCESS; + } + } + break; + } + case VCD_REQ_PERF_LEVEL: + vcd_status = VCD_S_SUCCESS; + break; + default: + DDL_MSG_ERROR("INVALID ID %d\n", (int)property_hdr->prop_id); + vcd_status = VCD_ERR_ILLEGAL_OP; + break; + } + return vcd_status; +} + +static u32 ddl_get_dec_property(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value) +{ + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + struct vcd_property_frame_size *fz_size; + u32 vcd_status = VCD_ERR_ILLEGAL_PARM; + DDL_MSG_HIGH("property_hdr->prop_id:%x\n", property_hdr->prop_id); + switch (property_hdr->prop_id) { + case VCD_I_FRAME_SIZE: + if (sizeof(struct vcd_property_frame_size) == + property_hdr->sz) { + ddl_calculate_stride(&decoder->client_frame_size, + !decoder->progressive_only); + fz_size = + &decoder->client_frame_size; + fz_size->stride = + DDL_TILE_ALIGN(fz_size->width, + DDL_TILE_ALIGN_WIDTH); + fz_size->scan_lines = + DDL_TILE_ALIGN(fz_size->height, + DDL_TILE_ALIGN_HEIGHT); + *(struct vcd_property_frame_size *) + property_value = + decoder->client_frame_size; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_PROFILE: + if (sizeof(struct vcd_property_profile) == + property_hdr->sz) { + *(struct vcd_property_profile *)property_value = + decoder->profile; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_LEVEL: + if (sizeof(struct vcd_property_level) == + property_hdr->sz) { + *(struct vcd_property_level *)property_value = + decoder->level; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_PROGRESSIVE_ONLY: + if (sizeof(u32) == property_hdr->sz) { + *(u32 *)property_value = + decoder->progressive_only; + vcd_status = VCD_S_SUCCESS; + } + break; + case DDL_I_INPUT_BUF_REQ: + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz) { + *(struct vcd_buffer_requirement *) + property_value = + decoder->client_input_buf_req; + vcd_status = VCD_S_SUCCESS; + } + break; + case DDL_I_OUTPUT_BUF_REQ: + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz) { + *(struct vcd_buffer_requirement *) + property_value = decoder->client_output_buf_req; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_CODEC: + if (sizeof(struct vcd_property_codec) == + property_hdr->sz) { + *(struct vcd_property_codec *) property_value = + decoder->codec; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_BUFFER_FORMAT: + if (sizeof(struct vcd_property_buffer_format) == + property_hdr->sz) { + *(struct vcd_property_buffer_format *) + property_value = decoder->buf_format; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_POST_FILTER: + if (sizeof(struct vcd_property_post_filter) == + property_hdr->sz) { + *(struct vcd_property_post_filter *) + property_value = + decoder->post_filter; + vcd_status = VCD_S_SUCCESS; + } + break; + case DDL_I_SEQHDR_ALIGN_BYTES: + if (sizeof(u32) == property_hdr->sz) { + *(u32 *)property_value = + DDL_LINEAR_BUFFER_ALIGN_BYTES; + vcd_status = VCD_S_SUCCESS; + } + break; + case DDL_I_FRAME_PROC_UNITS: + if (sizeof(u32) == property_hdr->sz) { + if (!decoder->progressive_only && + (decoder->client_frame_size.width * + decoder->client_frame_size.height) <= + DDL_FRAME_VGA_SIZE) { + *(u32 *) property_value = DDL_NO_OF_MB( + DDL_FRAME_720P_WIDTH, + DDL_FRAME_720P_HEIGHT); + } else { + *(u32 *) property_value = DDL_NO_OF_MB( + decoder->client_frame_size.width, + decoder->client_frame_size.height); + } + vcd_status = VCD_S_SUCCESS; + } + break; + case DDL_I_DPB_RETRIEVE: + if (sizeof(struct ddl_frame_data_tag) == + property_hdr->sz) { + vcd_status = ddl_decoder_dpb_transact(decoder, + (struct ddl_frame_data_tag *) + property_value, DDL_DPB_OP_RETRIEVE); + } + break; + case VCD_I_GET_H264_MV_SIZE: + if (property_hdr->sz == sizeof(struct + vcd_property_buffer_size)) { + struct vcd_property_buffer_size *mv_size = + (struct vcd_property_buffer_size *) property_value; + mv_size->size = ddl_get_yuv_buf_size(mv_size->width, + mv_size->height, DDL_YUV_BUF_TYPE_TILE); + mv_size->alignment = DDL_TILE_BUFFER_ALIGN_BYTES; + DDL_MSG_LOW("w: %d, h: %d, S: %d, " + "A: %d", mv_size->width, + mv_size->height, mv_size->size, + mv_size->alignment); + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_OUTPUT_ORDER: + { + if (sizeof(u32) == property_hdr->sz) { + *(u32 *)property_value = decoder->output_order; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_METADATA_ENABLE: + case VCD_I_METADATA_HEADER: + DDL_MSG_ERROR("Meta Data Interface is Requested"); + vcd_status = ddl_get_metadata_params(ddl, property_hdr, + property_value); + vcd_status = VCD_S_SUCCESS; + break; + case VCD_I_CONT_ON_RECONFIG: + if (sizeof(u32) == property_hdr->sz) { + *(u32 *)property_value = decoder->cont_mode; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_DISABLE_DMX_SUPPORT: + if (sizeof(u32) == property_hdr->sz) { + *(u32 *)property_value = res_trk_get_disable_dmx(); + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_DISABLE_DMX: + if (sizeof(u32) == property_hdr->sz) { + *(u32 *)property_value = decoder->dmx_disable; + vcd_status = VCD_S_SUCCESS; + } + break; + default: + vcd_status = VCD_ERR_ILLEGAL_OP; + break; + } + return vcd_status; +} + +static u32 ddl_get_enc_property(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value) +{ + struct ddl_encoder_data *encoder = &ddl->codec_data.encoder; + u32 vcd_status = VCD_ERR_ILLEGAL_PARM; + + switch (property_hdr->prop_id) { + case VCD_I_CODEC: + if (sizeof(struct vcd_property_codec) == + property_hdr->sz) { + *(struct vcd_property_codec *) property_value = + encoder->codec; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_FRAME_SIZE: + if (sizeof(struct vcd_property_frame_size) == + property_hdr->sz) { + *(struct vcd_property_frame_size *) + property_value = encoder->frame_size; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_FRAME_RATE: + if (sizeof(struct vcd_property_frame_rate) == + property_hdr->sz) { + *(struct vcd_property_frame_rate *) + property_value = encoder->frame_rate; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_TARGET_BITRATE: + if (sizeof(struct vcd_property_target_bitrate) == + property_hdr->sz) { + *(struct vcd_property_target_bitrate *) + property_value = encoder->target_bit_rate; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_RATE_CONTROL: + if (sizeof(struct vcd_property_rate_control) == + property_hdr->sz) { + *(struct vcd_property_rate_control *) + property_value = encoder->rc; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_PROFILE: + if (sizeof(struct vcd_property_profile) == + property_hdr->sz) { + *(struct vcd_property_profile *) property_value = + encoder->profile; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_LEVEL: + if (sizeof(struct vcd_property_level) == + property_hdr->sz) { + *(struct vcd_property_level *) property_value = + encoder->level; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_MULTI_SLICE: + if (sizeof(struct vcd_property_multi_slice) == + property_hdr->sz) { + *(struct vcd_property_multi_slice *) + property_value = encoder->multi_slice; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_SEQ_HEADER: + { + struct vcd_sequence_hdr *seq_hdr = + (struct vcd_sequence_hdr *) property_value; + + if (!encoder->seq_header_length) { + seq_hdr->sequence_header_len = + encoder->seq_header_length; + vcd_status = VCD_ERR_NO_SEQ_HDR; + } else if (sizeof(struct vcd_sequence_hdr) == + property_hdr->sz && + encoder->seq_header_length <= + seq_hdr->sequence_header_len) { + memcpy(seq_hdr->sequence_header, + encoder->seq_header.align_virtual_addr, + encoder->seq_header_length); + seq_hdr->sequence_header_len = + encoder->seq_header_length; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case DDL_I_SEQHDR_PRESENT: + if (sizeof(u32) == property_hdr->sz) { + if ((encoder->codec.codec == + VCD_CODEC_MPEG4 && + !encoder->short_header.short_header) || + encoder->codec.codec == VCD_CODEC_H264) + *(u32 *) property_value = 0x1; + else + *(u32 *) property_value = 0x0; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_VOP_TIMING: + if (sizeof(struct vcd_property_vop_timing) == + property_hdr->sz) { + *(struct vcd_property_vop_timing *) + property_value = encoder->vop_timing; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_SHORT_HEADER: + if (sizeof(struct vcd_property_short_header) == + property_hdr->sz) { + if (encoder->codec.codec == VCD_CODEC_MPEG4) { + *(struct vcd_property_short_header *) + property_value = + encoder->short_header; + vcd_status = VCD_S_SUCCESS; + } else + vcd_status = VCD_ERR_ILLEGAL_OP; + } + break; + case VCD_I_ENTROPY_CTRL: + if (sizeof(struct vcd_property_entropy_control) == + property_hdr->sz) { + if (encoder->codec.codec == VCD_CODEC_H264) { + *(struct vcd_property_entropy_control *) + property_value = + encoder->entropy_control; + vcd_status = VCD_S_SUCCESS; + } else + vcd_status = VCD_ERR_ILLEGAL_OP; + } + break; + case VCD_I_DEBLOCKING: + if (sizeof(struct vcd_property_db_config) == + property_hdr->sz) { + if (encoder->codec.codec == VCD_CODEC_H264) { + *(struct vcd_property_db_config *) + property_value = + encoder->db_control; + vcd_status = VCD_S_SUCCESS; + } else + vcd_status = VCD_ERR_ILLEGAL_OP; + } + break; + case VCD_I_INTRA_PERIOD: + if (sizeof(struct vcd_property_i_period) == + property_hdr->sz) { + *(struct vcd_property_i_period *) + property_value = encoder->i_period; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_QP_RANGE: + if (sizeof(struct vcd_property_qp_range) == + property_hdr->sz) { + *(struct vcd_property_qp_range *) + property_value = encoder->qp_range; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_SESSION_QP: + if (sizeof(struct vcd_property_session_qp) == + property_hdr->sz) { + *(struct vcd_property_session_qp *) + property_value = encoder->session_qp; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_RC_LEVEL_CONFIG: + if (sizeof(struct vcd_property_rc_level) == + property_hdr->sz) { + *(struct vcd_property_rc_level *) + property_value = encoder->rc_level; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_FRAME_LEVEL_RC: + if (sizeof(struct vcd_property_frame_level_rc_params) == + property_hdr->sz) { + *(struct vcd_property_frame_level_rc_params *) + property_value = encoder->frame_level_rc; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_ADAPTIVE_RC: + if (sizeof(struct vcd_property_adaptive_rc_params) == + property_hdr->sz) { + *(struct vcd_property_adaptive_rc_params *) + property_value = encoder->adaptive_rc; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_INTRA_REFRESH: + if (sizeof(struct vcd_property_intra_refresh_mb_number) == + property_hdr->sz) { + *(struct vcd_property_intra_refresh_mb_number *) + property_value = encoder->intra_refresh; + vcd_status = VCD_S_SUCCESS; + } + break; + case DDL_I_INPUT_BUF_REQ: + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz) { + *(struct vcd_buffer_requirement *) + property_value = encoder->client_input_buf_req; + vcd_status = VCD_S_SUCCESS; + } + break; + case DDL_I_OUTPUT_BUF_REQ: + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz) { + *(struct vcd_buffer_requirement *) + property_value = encoder->client_output_buf_req; + DDL_MSG_LOW("%s encoder->client_output_buf_req = %d\n", + __func__, + encoder->client_output_buf_req.sz); + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_BUFFER_FORMAT: + if (sizeof(struct vcd_property_buffer_format) == + property_hdr->sz) { + *(struct vcd_property_buffer_format *) + property_value = encoder->buf_format; + vcd_status = VCD_S_SUCCESS; + } + break; + case DDL_I_FRAME_PROC_UNITS: + if (sizeof(u32) == property_hdr->sz && + encoder->frame_size.width && + encoder->frame_size.height) { + *(u32 *)property_value = DDL_NO_OF_MB( + encoder->frame_size.width, + encoder->frame_size.height); + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_HEADER_EXTENSION: + if (sizeof(u32) == property_hdr->sz && + encoder->codec.codec == VCD_CODEC_MPEG4) { + *(u32 *) property_value = + encoder->hdr_ext_control; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_GET_RECON_BUFFER_SIZE: + { + u32 ysize, uvsize; + if (property_hdr->sz == sizeof(struct + vcd_property_buffer_size)) { + struct vcd_property_buffer_size *recon_buff_size = + (struct vcd_property_buffer_size *) property_value; + + ysize = ddl_get_yuv_buf_size(recon_buff_size->width, + recon_buff_size->height, DDL_YUV_BUF_TYPE_TILE); + uvsize = ddl_get_yuv_buf_size(recon_buff_size->width, + recon_buff_size->height/2, + DDL_YUV_BUF_TYPE_TILE); + recon_buff_size->size = ysize + uvsize; + recon_buff_size->alignment = + DDL_TILE_BUFFER_ALIGN_BYTES; + DDL_MSG_LOW("w: %d, h: %d, S: %d, A: %d", + recon_buff_size->width, recon_buff_size->height, + recon_buff_size->size, recon_buff_size->alignment); + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_METADATA_ENABLE: + case VCD_I_METADATA_HEADER: + DDL_MSG_ERROR("Meta Data Interface is Requested"); + vcd_status = ddl_get_metadata_params(ddl, property_hdr, + property_value); + vcd_status = VCD_S_SUCCESS; + break; + case VCD_I_ENABLE_SPS_PPS_FOR_IDR: + if (sizeof(struct vcd_property_sps_pps_for_idr_enable) == + property_hdr->sz) { + *(struct vcd_property_sps_pps_for_idr_enable *) + property_value = encoder->sps_pps; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_SLICE_DELIVERY_MODE: + if (sizeof(struct vcd_property_slice_delivery_info) == + property_hdr->sz) { + *(struct vcd_property_slice_delivery_info *) + property_value = encoder->slice_delivery_info; + vcd_status = VCD_S_SUCCESS; + } + break; + default: + vcd_status = VCD_ERR_ILLEGAL_OP; + break; + } + return vcd_status; +} + +static u32 ddl_set_enc_dynamic_property(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value) +{ + struct ddl_encoder_data *encoder = &ddl->codec_data.encoder; + u32 vcd_status = VCD_ERR_ILLEGAL_PARM; + u32 dynamic_prop_change = 0x0; + + switch (property_hdr->prop_id) { + case VCD_I_REQ_IFRAME: + if (sizeof(struct vcd_property_req_i_frame) == + property_hdr->sz) { + dynamic_prop_change |= DDL_ENC_REQ_IFRAME; + vcd_status = VCD_S_SUCCESS; + } + break; + case VCD_I_TARGET_BITRATE: + { + struct vcd_property_target_bitrate *bitrate = + (struct vcd_property_target_bitrate *)property_value; + + if (sizeof(struct vcd_property_target_bitrate) == + property_hdr->sz && bitrate->target_bitrate && + bitrate->target_bitrate <= DDL_MAX_BIT_RATE) { + encoder->target_bit_rate = *bitrate; + dynamic_prop_change = DDL_ENC_CHANGE_BITRATE; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_INTRA_PERIOD: + { + struct vcd_property_i_period *i_period = + (struct vcd_property_i_period *)property_value; + + if (sizeof(struct vcd_property_i_period) == + property_hdr->sz) { + encoder->i_period = *i_period; + dynamic_prop_change = DDL_ENC_CHANGE_IPERIOD; + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_FRAME_RATE: + { + struct vcd_property_frame_rate *frame_rate = + (struct vcd_property_frame_rate *) + property_value; + if (sizeof(struct vcd_property_frame_rate) == + property_hdr->sz && + frame_rate->fps_denominator && + frame_rate->fps_numerator && + frame_rate->fps_denominator <= + frame_rate->fps_numerator) { + encoder->frame_rate = *frame_rate; + dynamic_prop_change = DDL_ENC_CHANGE_FRAMERATE; + if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) && + (encoder->codec.codec != VCD_CODEC_MPEG4 || + encoder->short_header.short_header)) { + ddl_set_default_enc_vop_timing(encoder); + } + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_INTRA_REFRESH: + { + struct vcd_property_intra_refresh_mb_number + *intra_refresh_mb_num = + (struct vcd_property_intra_refresh_mb_number *) + property_value; + u32 frame_mb_num = DDL_NO_OF_MB(encoder->frame_size.width, + encoder->frame_size.height); + + if ((sizeof(struct vcd_property_intra_refresh_mb_number) == + property_hdr->sz) && + (intra_refresh_mb_num->cir_mb_number <= frame_mb_num)) { + encoder->intra_refresh = *intra_refresh_mb_num; + dynamic_prop_change = DDL_ENC_CHANGE_CIR; + vcd_status = VCD_S_SUCCESS; + } + } + break; + default: + vcd_status = VCD_ERR_ILLEGAL_OP; + break; + } + + if (!vcd_status && (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME) + || DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE))) + encoder->dynamic_prop_change |= dynamic_prop_change; + + return vcd_status; +} + +void ddl_set_default_dec_property(struct ddl_client_context *ddl) +{ + struct ddl_decoder_data *decoder = + &(ddl->codec_data.decoder); + + if (decoder->codec.codec >= VCD_CODEC_MPEG2 && + decoder->codec.codec <= VCD_CODEC_XVID) + decoder->post_filter.post_filter = false; + else + decoder->post_filter.post_filter = false; + decoder->buf_format.buffer_format = VCD_BUFFER_FORMAT_TILE_4x2; + decoder->client_frame_size.height = VCD_DDL_TEST_DEFAULT_HEIGHT; + decoder->client_frame_size.width = VCD_DDL_TEST_DEFAULT_WIDTH; + decoder->client_frame_size.stride = VCD_DDL_TEST_DEFAULT_WIDTH; + decoder->client_frame_size.scan_lines = VCD_DDL_TEST_DEFAULT_HEIGHT; + decoder->progressive_only = 1; + decoder->idr_only_decoding = false; + decoder->output_order = VCD_DEC_ORDER_DISPLAY; + decoder->field_needed_for_prev_ip = 0; + decoder->cont_mode = 0; + decoder->reconfig_detected = false; + decoder->dmx_disable = false; + ddl_set_default_metadata_flag(ddl); + ddl_set_default_decoder_buffer_req(decoder, true); +} + +static void ddl_set_default_enc_property(struct ddl_client_context *ddl) +{ + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + + ddl_set_default_enc_profile(encoder); + ddl_set_default_enc_level(encoder); + encoder->rc.rate_control = VCD_RATE_CONTROL_VBR_VFR; + ddl_set_default_enc_rc_params(encoder); + ddl_set_default_enc_intra_period(encoder); + encoder->intra_refresh.cir_mb_number = 0; + ddl_set_default_enc_vop_timing(encoder); + encoder->multi_slice.m_slice_sel = VCD_MSLICE_OFF; + encoder->multi_slice.m_slice_size = 0; + ddl->b_count = 0; + encoder->short_header.short_header = false; + encoder->entropy_control.entropy_sel = VCD_ENTROPY_SEL_CAVLC; + encoder->entropy_control.cabac_model = VCD_CABAC_MODEL_NUMBER_0; + encoder->db_control.db_config = + VCD_DB_ALL_BLOCKING_BOUNDARY; + encoder->db_control.slice_alpha_offset = 0; + encoder->db_control.slice_beta_offset = 0; + encoder->recon_buf_format.buffer_format = + VCD_BUFFER_FORMAT_TILE_1x1; + encoder->buf_format.buffer_format = VCD_BUFFER_FORMAT_NV12_16M2KA; + encoder->hdr_ext_control = 0; + encoder->mb_info_enable = false; + encoder->num_references_for_p_frame = DDL_MIN_NUM_REF_FOR_P_FRAME; + if (encoder->codec.codec == VCD_CODEC_MPEG4) + encoder->closed_gop = true; + ddl_set_default_metadata_flag(ddl); + ddl_set_default_encoder_buffer_req(encoder); + encoder->slice_delivery_info.enable = 0; + encoder->slice_delivery_info.num_slices = 0; + encoder->slice_delivery_info.num_slices_enc = 0; +} + +static void ddl_set_default_enc_profile(struct ddl_encoder_data *encoder) +{ + enum vcd_codec codec = encoder->codec.codec; + + if (codec == VCD_CODEC_MPEG4) + encoder->profile.profile = VCD_PROFILE_MPEG4_SP; + else if (codec == VCD_CODEC_H264) + encoder->profile.profile = VCD_PROFILE_H264_BASELINE; + else + encoder->profile.profile = VCD_PROFILE_H263_BASELINE; +} + +static void ddl_set_default_enc_level(struct ddl_encoder_data *encoder) +{ + enum vcd_codec codec = encoder->codec.codec; + + if (codec == VCD_CODEC_MPEG4) + encoder->level.level = VCD_LEVEL_MPEG4_1; + else if (codec == VCD_CODEC_H264) + encoder->level.level = VCD_LEVEL_H264_1; + else + encoder->level.level = VCD_LEVEL_H263_10; +} + +static void ddl_set_default_enc_vop_timing( + struct ddl_encoder_data *encoder) +{ + if (encoder->codec.codec == VCD_CODEC_MPEG4) { + encoder->vop_timing.vop_time_resolution = + (encoder->frame_rate.fps_numerator << 1) / + encoder->frame_rate.fps_denominator; + } else + encoder->vop_timing.vop_time_resolution = + DDL_FRAMERATE_SCALE(DDL_INITIAL_FRAME_RATE); +} + +static void ddl_set_default_enc_intra_period( + struct ddl_encoder_data *encoder) +{ + switch (encoder->rc.rate_control) { + default: + case VCD_RATE_CONTROL_VBR_VFR: + case VCD_RATE_CONTROL_VBR_CFR: + case VCD_RATE_CONTROL_CBR_VFR: + case VCD_RATE_CONTROL_OFF: + encoder->i_period.p_frames = + ((encoder->frame_rate.fps_numerator << 1) / + encoder->frame_rate.fps_denominator) - 1; + break; + case VCD_RATE_CONTROL_CBR_CFR: + encoder->i_period.p_frames = + ((encoder->frame_rate.fps_numerator >> 1) / + encoder->frame_rate.fps_denominator) - 1; + break; + } + encoder->i_period.b_frames = DDL_DEFAULT_NUM_OF_B_FRAME; +} + +static void ddl_set_default_enc_rc_params( + struct ddl_encoder_data *encoder) +{ + enum vcd_codec codec = encoder->codec.codec; + encoder->rc_level.frame_level_rc = true; + encoder->qp_range.min_qp = 0x1; + if (codec == VCD_CODEC_H264) { + encoder->qp_range.min_qp = 0x1; + encoder->qp_range.max_qp = 0x33; + encoder->session_qp.i_frame_qp = 0x14; + encoder->session_qp.p_frame_qp = 0x14; + encoder->session_qp.b_frame_qp = 0x14; + encoder->rc_level.mb_level_rc = true; + encoder->adaptive_rc.disable_activity_region_flag = true; + encoder->adaptive_rc.disable_dark_region_as_flag = true; + encoder->adaptive_rc.disable_smooth_region_as_flag = true; + encoder->adaptive_rc.disable_static_region_as_flag = true; + } else { + encoder->qp_range.max_qp = 0x1f; + encoder->qp_range.min_qp = 0x1; + encoder->session_qp.i_frame_qp = 0xd; + encoder->session_qp.p_frame_qp = 0xd; + encoder->session_qp.b_frame_qp = 0xd; + encoder->rc_level.frame_level_rc = true; + encoder->rc_level.mb_level_rc = false; + } + switch (encoder->rc.rate_control) { + case VCD_RATE_CONTROL_VBR_CFR: + encoder->r_cframe_skip = 0; + encoder->frame_level_rc.reaction_coeff = 0x1f4; + break; + case VCD_RATE_CONTROL_CBR_VFR: + encoder->r_cframe_skip = 1; + if (codec != VCD_CODEC_H264) { + encoder->session_qp.i_frame_qp = 0xf; + encoder->session_qp.p_frame_qp = 0xf; + encoder->session_qp.b_frame_qp = 0xf; + } + encoder->frame_level_rc.reaction_coeff = 0x14; + break; + case VCD_RATE_CONTROL_CBR_CFR: + encoder->r_cframe_skip = 0; + encoder->frame_level_rc.reaction_coeff = 0x6; + break; + case VCD_RATE_CONTROL_OFF: + encoder->r_cframe_skip = 0; + encoder->rc_level.frame_level_rc = false; + encoder->rc_level.mb_level_rc = false; + break; + case VCD_RATE_CONTROL_VBR_VFR: + default: + encoder->r_cframe_skip = 1; + encoder->frame_level_rc.reaction_coeff = 0x1f4; + break; + } +} + +void ddl_set_default_encoder_buffer_req(struct ddl_encoder_data *encoder) +{ + u32 y_cb_cr_size, y_size; + memset(&encoder->hw_bufs.dpb_y, 0, sizeof(struct ddl_buf_addr) * 4); + memset(&encoder->hw_bufs.dpb_c, 0, sizeof(struct ddl_buf_addr) * 4); + + y_cb_cr_size = ddl_get_yuv_buffer_size(&encoder->frame_size, + &encoder->buf_format, false, + encoder->hdr.decoding, &y_size); + encoder->input_buf_size.size_yuv = y_cb_cr_size; + encoder->input_buf_size.size_y = y_size; + encoder->input_buf_size.size_c = y_cb_cr_size - y_size; + memset(&encoder->input_buf_req , 0 , + sizeof(struct vcd_buffer_requirement)); + encoder->input_buf_req.min_count = 3; + encoder->input_buf_req.actual_count = + encoder->input_buf_req.min_count; + encoder->input_buf_req.max_count = DDL_MAX_BUFFER_COUNT; + encoder->input_buf_req.sz = y_cb_cr_size; + if (encoder->buf_format.buffer_format == + VCD_BUFFER_FORMAT_NV12_16M2KA) + encoder->input_buf_req.align = + DDL_LINEAR_BUFFER_ALIGN_BYTES; + else if (VCD_BUFFER_FORMAT_TILE_4x2 == + encoder->buf_format.buffer_format) + encoder->input_buf_req.align = DDL_TILE_BUFFER_ALIGN_BYTES; + encoder->client_input_buf_req = encoder->input_buf_req; + memset(&encoder->output_buf_req , 0 , + sizeof(struct vcd_buffer_requirement)); + encoder->output_buf_req.min_count = encoder->i_period.b_frames + 2; + encoder->output_buf_req.actual_count = + encoder->output_buf_req.min_count + 3; + encoder->output_buf_req.max_count = DDL_MAX_BUFFER_COUNT; + encoder->output_buf_req.align = DDL_LINEAR_BUFFER_ALIGN_BYTES; + if (y_cb_cr_size >= VCD_DDL_720P_YUV_BUF_SIZE) + y_cb_cr_size = y_cb_cr_size>>1; + encoder->output_buf_req.sz = + DDL_ALIGN(y_cb_cr_size, DDL_KILO_BYTE(4)); + ddl_set_default_encoder_metadata_buffer_size(encoder); + encoder->client_output_buf_req = encoder->output_buf_req; + DDL_MSG_LOW("%s encoder->client_output_buf_req.sz = %d\n", + __func__, encoder->client_output_buf_req.sz); +} + +u32 ddl_set_default_decoder_buffer_req(struct ddl_decoder_data *decoder, + u32 estimate) +{ + struct vcd_property_frame_size *frame_size; + struct vcd_buffer_requirement *input_buf_req; + struct vcd_buffer_requirement *output_buf_req; + u32 min_dpb, y_cb_cr_size; + + if (!decoder->codec.codec) + return false; + if (estimate) { + if (!decoder->cont_mode) + min_dpb = ddl_decoder_min_num_dpb(decoder); + else + min_dpb = res_trk_get_min_dpb_count(); + frame_size = &decoder->client_frame_size; + output_buf_req = &decoder->client_output_buf_req; + input_buf_req = &decoder->client_input_buf_req; + y_cb_cr_size = ddl_get_yuv_buffer_size(frame_size, + &decoder->buf_format, + (!decoder->progressive_only), + decoder->hdr.decoding, NULL); + } else { + frame_size = &decoder->frame_size; + output_buf_req = &decoder->actual_output_buf_req; + input_buf_req = &decoder->actual_input_buf_req; + min_dpb = decoder->min_dpb_num; + y_cb_cr_size = decoder->y_cb_cr_size; + if ((decoder->buf_format.buffer_format == + VCD_BUFFER_FORMAT_TILE_4x2) && + (frame_size->height < MDP_MIN_TILE_HEIGHT)) { + frame_size->height = MDP_MIN_TILE_HEIGHT; + ddl_calculate_stride(frame_size, + !decoder->progressive_only); + y_cb_cr_size = ddl_get_yuv_buffer_size( + frame_size, + &decoder->buf_format, + (!decoder->progressive_only), + decoder->hdr.decoding, NULL); + } else + y_cb_cr_size = decoder->y_cb_cr_size; + } + memset(output_buf_req, 0, + sizeof(struct vcd_buffer_requirement)); + if (!decoder->idr_only_decoding && !decoder->cont_mode) + output_buf_req->actual_count = min_dpb + 4; + else + output_buf_req->actual_count = min_dpb; + output_buf_req->min_count = min_dpb; + output_buf_req->max_count = DDL_MAX_BUFFER_COUNT; + output_buf_req->sz = y_cb_cr_size; + DDL_MSG_LOW("output_buf_req->sz : %d", output_buf_req->sz); + if (decoder->buf_format.buffer_format != VCD_BUFFER_FORMAT_NV12) + output_buf_req->align = DDL_TILE_BUFFER_ALIGN_BYTES; + else + output_buf_req->align = DDL_LINEAR_BUFFER_ALIGN_BYTES; + ddl_set_default_decoder_metadata_buffer_size(decoder, frame_size, + output_buf_req); + + decoder->min_output_buf_req = *output_buf_req; + memset(input_buf_req, 0, + sizeof(struct vcd_buffer_requirement)); + input_buf_req->min_count = 1; + input_buf_req->actual_count = input_buf_req->min_count + 1; + input_buf_req->max_count = DDL_MAX_BUFFER_COUNT; + input_buf_req->sz = (1024 * 1024 * 2); + input_buf_req->align = DDL_LINEAR_BUFFER_ALIGN_BYTES; + decoder->min_input_buf_req = *input_buf_req; + return true; +} + +u32 ddl_get_yuv_buffer_size(struct vcd_property_frame_size *frame_size, + struct vcd_property_buffer_format *buf_format, + u32 interlace, u32 decoding, u32 *pn_c_offset) +{ + struct vcd_property_frame_size frame_sz = *frame_size; + u32 total_memory_size = 0, c_offset = 0; + ddl_calculate_stride(&frame_sz, interlace); + if (buf_format->buffer_format == VCD_BUFFER_FORMAT_TILE_4x2) { + u32 component_mem_size, width_round_up; + u32 height_round_up, height_chroma = (frame_sz.scan_lines >> 1); + + width_round_up = + DDL_ALIGN(frame_sz.stride, DDL_TILE_ALIGN_WIDTH); + height_round_up = + DDL_ALIGN(frame_sz.scan_lines, + DDL_TILE_ALIGN_HEIGHT); + component_mem_size = width_round_up * height_round_up; + component_mem_size = DDL_ALIGN(component_mem_size, + DDL_TILE_MULTIPLY_FACTOR); + c_offset = component_mem_size; + total_memory_size = ((component_mem_size + + DDL_TILE_BUF_ALIGN_GUARD_BYTES) & + DDL_TILE_BUF_ALIGN_MASK); + height_round_up = DDL_ALIGN(height_chroma, + DDL_TILE_ALIGN_HEIGHT); + component_mem_size = width_round_up * height_round_up; + component_mem_size = DDL_ALIGN(component_mem_size, + DDL_TILE_MULTIPLY_FACTOR); + total_memory_size += component_mem_size; + } else { + if (decoding) + total_memory_size = frame_sz.scan_lines * + frame_sz.stride; + else + total_memory_size = frame_sz.height * frame_sz.stride; + c_offset = DDL_ALIGN(total_memory_size, + DDL_LINEAR_MULTIPLY_FACTOR); + total_memory_size = c_offset + DDL_ALIGN( + total_memory_size >> 1, DDL_LINEAR_MULTIPLY_FACTOR); + } + if (pn_c_offset) + *pn_c_offset = c_offset; + return total_memory_size; +} + + +void ddl_calculate_stride(struct vcd_property_frame_size *frame_size, + u32 interlace) +{ + frame_size->stride = DDL_ALIGN(frame_size->width, + DDL_LINEAR_ALIGN_WIDTH); + if (interlace) + frame_size->scan_lines = DDL_ALIGN(frame_size->height, + DDL_TILE_ALIGN_HEIGHT); + else + frame_size->scan_lines = DDL_ALIGN(frame_size->height, + DDL_LINEAR_ALIGN_HEIGHT); +} + + +static u32 ddl_valid_buffer_requirement(struct vcd_buffer_requirement + *original_buf_req, struct vcd_buffer_requirement *req_buf_req) +{ + u32 status = false; + + if (original_buf_req->max_count >= req_buf_req->actual_count && + original_buf_req->min_count <= + req_buf_req->actual_count && + !((original_buf_req->align - (u32)0x1) & + req_buf_req->align) && + /*original_buf_req->align <= req_buf_req->align,*/ + original_buf_req->sz <= req_buf_req->sz) + status = true; + else { + DDL_MSG_ERROR("ddl_valid_buf_req:Failed"); + DDL_MSG_ERROR("codec_buf_req: min_cnt=%d, mx_cnt=%d, " + "align=%d, sz=%d\n", original_buf_req->min_count, + original_buf_req->max_count, original_buf_req->align, + original_buf_req->sz); + DDL_MSG_ERROR("client_buffs: actual_count=%d, align=%d, " + "sz=%d\n", req_buf_req->actual_count, + req_buf_req->align, req_buf_req->sz); + } + return status; +} + +static u32 ddl_decoder_min_num_dpb(struct ddl_decoder_data *decoder) +{ + u32 min_dpb = 0; + + if (decoder->idr_only_decoding) { + min_dpb = DDL_MIN_BUFFER_COUNT; + if (decoder->post_filter.post_filter) + min_dpb *= 2; + return min_dpb; + } + + switch (decoder->codec.codec) { + case VCD_CODEC_H264: + { + u32 yuv_size_in_mb = DDL_MIN(DDL_NO_OF_MB( + decoder->client_frame_size.stride, + decoder->client_frame_size.scan_lines), + MAX_FRAME_SIZE_L4PT0_MBS); + min_dpb = DDL_MIN((MAX_DPB_SIZE_L4PT0_MBS / + yuv_size_in_mb), 16); + min_dpb += 2; + } + break; + case VCD_CODEC_H263: + min_dpb = 3; + break; + default: + case VCD_CODEC_MPEG1: + case VCD_CODEC_MPEG2: + case VCD_CODEC_MPEG4: + case VCD_CODEC_DIVX_3: + case VCD_CODEC_DIVX_4: + case VCD_CODEC_DIVX_5: + case VCD_CODEC_DIVX_6: + case VCD_CODEC_XVID: + case VCD_CODEC_VC1: + case VCD_CODEC_VC1_RCV: + min_dpb = 4; + if (decoder->post_filter.post_filter) + min_dpb *= 2; + break; + } + return min_dpb; +} + +static u32 ddl_set_dec_buffers(struct ddl_decoder_data *decoder, + struct ddl_property_dec_pic_buffers *dpb) +{ + u32 vcd_status = VCD_S_SUCCESS, loopc; + + + for (loopc = 0; !vcd_status && + loopc < dpb->no_of_dec_pic_buf; ++loopc) { + if ((!DDL_ADDR_IS_ALIGNED(dpb->dec_pic_buffers[loopc]. + vcd_frm.physical, + decoder->client_output_buf_req.align)) || + (dpb->dec_pic_buffers[loopc].vcd_frm.alloc_len < + decoder->client_output_buf_req.sz)) + vcd_status = VCD_ERR_ILLEGAL_PARM; + } + if (vcd_status) { + DDL_MSG_ERROR("ddl_set_prop:" + "Dpb_align_fail_or_alloc_size_small"); + return vcd_status; + } + if (decoder->dp_buf.no_of_dec_pic_buf) { + kfree(decoder->dp_buf.dec_pic_buffers); + decoder->dp_buf.no_of_dec_pic_buf = 0; + } + decoder->dp_buf.dec_pic_buffers = + kmalloc(dpb->no_of_dec_pic_buf * + sizeof(struct ddl_frame_data_tag), GFP_KERNEL); + if (!decoder->dp_buf.dec_pic_buffers) { + DDL_MSG_ERROR("ddl_dec_set_prop:Dpb_container_alloc_failed"); + return VCD_ERR_ALLOC_FAIL; + } + decoder->dp_buf.no_of_dec_pic_buf = dpb->no_of_dec_pic_buf; + for (loopc = 0; loopc < dpb->no_of_dec_pic_buf; ++loopc) + decoder->dp_buf.dec_pic_buffers[loopc] = + dpb->dec_pic_buffers[loopc]; + decoder->dpb_mask.client_mask = 0; + decoder->dpb_mask.hw_mask = 0; + decoder->dynamic_prop_change = 0; + return VCD_S_SUCCESS; +} + +void ddl_set_initial_default_values(struct ddl_client_context *ddl) +{ + + if (ddl->decoding) { + ddl->codec_data.decoder.codec.codec = VCD_CODEC_MPEG4; + ddl_set_default_dec_property(ddl); + } else { + struct ddl_encoder_data *encoder = + &(ddl->codec_data.encoder); + encoder->codec.codec = VCD_CODEC_MPEG4; + encoder->target_bit_rate.target_bitrate = 64000; + encoder->frame_size.width = VCD_DDL_TEST_DEFAULT_WIDTH; + encoder->frame_size.height = VCD_DDL_TEST_DEFAULT_HEIGHT; + encoder->frame_size.scan_lines = + VCD_DDL_TEST_DEFAULT_HEIGHT; + encoder->frame_size.stride = VCD_DDL_TEST_DEFAULT_WIDTH; + encoder->frame_rate.fps_numerator = DDL_INITIAL_FRAME_RATE; + encoder->frame_rate.fps_denominator = 1; + ddl_set_default_enc_property(ddl); + encoder->sps_pps.sps_pps_for_idr_enable_flag = false; + } +} diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c new file mode 100644 index 000000000000..6d8c4b91c89b --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c @@ -0,0 +1,876 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#include "vcd_ddl_shared_mem.h" + +#define VIDC_SM_EXTENDED_DECODE_STATUS_ADDR 0x0000 +#define VIDC_SM_EXT_DEC_STATUS_RESOLUTION_CHANGE_BMSK 0x1 +#define VIDC_SM_EXT_DEC_STATUS_RESOLUTION_CHANGE_SHFT 0x0 +#define VIDC_SM_EXT_DEC_STATUS_MORE_FIELD_NEEDED_BMSK 0x4 +#define VIDC_SM_EXT_DEC_STATUS_MORE_FIELD_NEEDED_SHFT 0x2 + +#define VIDC_SM_SET_FRAME_TAG_ADDR 0x0004 +#define VIDC_SM_GET_FRAME_TAG_TOP_ADDR 0x0008 +#define VIDC_SM_GET_FRAME_TAG_BOTTOM_ADDR 0x000c +#define VIDC_SM_PIC_TIME_TOP_ADDR 0x0010 +#define VIDC_SM_PIC_TIME_BOTTOM_ADDR 0x0014 +#define VIDC_SM_START_BYTE_NUM_ADDR 0x0018 + +#define VIDC_SM_CROP_INFO1_ADDR 0x0020 +#define VIDC_SM_CROP_INFO1_RIGHT_OFFSET_BMSK 0xffff0000 +#define VIDC_SM_CROP_INFO1_RIGHT_OFFSET_SHFT 16 +#define VIDC_SM_CROP_INFO1_LEFT_OFFSET_BMSK 0x0000ffff +#define VIDC_SM_CROP_INFO1_LEFT_OFFSET_SHFT 0 + +#define VIDC_SM_CROP_INFO2_ADDR 0x0024 +#define VIDC_SM_CROP_INFO2_BOTTOM_OFFSET_BMSK 0xffff0000 +#define VIDC_SM_CROP_INFO2_BOTTOM_OFFSET_SHFT 16 +#define VIDC_SM_CROP_INFO2_TOP_OFFSET_BMSK 0x0000ffff +#define VIDC_SM_CROP_INFO2_TOP_OFFSET_SHFT 0 + +#define VIDC_SM_DISP_PIC_PROFILE_ADDR 0x007c +#define VIDC_SM_DISP_PIC_PROFILE_DISP_PIC_LEVEL_BMASK 0x0000ff00 +#define VIDC_SM_DISP_PIC_PROFILE_DISP_PIC_LEVEL_SHFT 8 +#define VIDC_SM_DISP_PIC_PROFILE_DISP_PIC_PROFILE_BMASK 0x0000001f +#define VIDC_SM_DISP_PIC_PROFILE_DISP_PIC_PROFILE_SHFT 0 + +#define VIDC_SM_DISP_PIC_FRAME_TYPE_ADDR 0x00c0 +#define VIDC_SM_DISP_PIC_FRAME_TYPE_BMSK 0x00000003 +#define VIDC_SM_DISP_PIC_FRAME_TYPE_SHFT 0 + +#define VIDC_SM_FREE_LUMA_DPB_ADDR 0x00c4 +#define VIDC_SM_FREE_LUMA_DPB_BMSK 0xffffffff +#define VIDC_SM_FREE_LUMA_DPB_SHFT 0 + +#define VIDC_SM_FREE_LUMA_DPB_DEC_ORDER_ADDR 0x00fc +#define VIDC_SM_FREE_LUMA_DPB_DEC_ORDER_BMSK 0xffffffff +#define VIDC_SM_FREE_LUMA_DPB_DEC_ORDER_SHFT 0 + +#define VIDC_SM_DEC_ORDER_WIDTH_ADDR 0x00e8 +#define VIDC_SM_DEC_ORDER_WIDTH_BMSK 0xffffffff +#define VIDC_SM_DEC_ORDER_WIDTH_SHFT 0 + +#define VIDC_SM_DEC_ORDER_HEIGHT_ADDR 0x00ec +#define VIDC_SM_DEC_ORDER_HEIGHT_BMSK 0xffffffff +#define VIDC_SM_DEC_ORDER_HEIGHT_SHFT 0 + +#define VIDC_SM_DEC_CROP_INFO1_ADDR 0x00f4 +#define VIDC_SM_DEC_CROP_INFO1_RIGHT_OFFSET_BMSK 0xffff0000 +#define VIDC_SM_DEC_CROP_INFO1_RIGHT_OFFSET_SHFT 16 +#define VIDC_SM_DEC_CROP_INFO1_LEFT_OFFSET_BMSK 0x0000ffff +#define VIDC_SM_DEC_CROP_INFO1_LEFT_OFFSET_SHFT 0 + +#define VIDC_SM_DEC_CROP_INFO2_ADDR 0x00f8 +#define VIDC_SM_DEC_CROP_INFO2_BOTTOM_OFFSET_BMSK 0xffff0000 +#define VIDC_SM_DEC_CROP_INFO2_BOTTOM_OFFSET_SHFT 16 +#define VIDC_SM_DEC_CROP_INFO2_TOP_OFFSET_BMSK 0x0000ffff +#define VIDC_SM_DEC_CROP_INFO2_TOP_OFFSET_SHFT 0 + +#define VIDC_SM_IDR_DECODING_ONLY_ADDR 0x0108 +#define VIDC_SM_IDR_DECODING_ONLY_BMSK 0x00000001 +#define VIDC_SM_IDR_DECODING_ONLY_SHIFT 0 + +#define VIDC_SM_ENC_EXT_CTRL_ADDR 0x0028 +#define VIDC_SM_ENC_EXT_CTRL_VBV_BUFFER_SIZE_BMSK 0xffff0000 +#define VIDC_SM_ENC_EXT_CTRL_VBV_BUFFER_SIZE_SHFT 16 +#define VIDC_SM_ENC_EXT_CTRL_H263_CPCFC_ENABLE_BMSK 0x80 +#define VIDC_SM_ENC_EXT_CTRL_H263_CPCFC_ENABLE_SHFT 7 +#define VIDC_SM_ENC_EXT_CTRL_SPS_PPS_CONTROL_BMSK 0X100 +#define VIDC_SM_ENC_EXT_CTRL_SPS_PPS_CONTROL_SHFT 8 +#define VIDC_SM_ENC_EXT_CTRL_SEQ_HDR_CTRL_BMSK 0x8 +#define VIDC_SM_ENC_EXT_CTRL_SEQ_HDR_CTRL_SHFT 3 +#define VIDC_SM_ENC_EXT_CTRL_FRAME_SKIP_ENABLE_BMSK 0x6 +#define VIDC_SM_ENC_EXT_CTRL_FRAME_SKIP_ENABLE_SHFT 1 +#define VIDC_SM_ENC_EXT_CTRL_HEC_ENABLE_BMSK 0x1 +#define VIDC_SM_ENC_EXT_CTRL_HEC_ENABLE_SHFT 0 + +#define VIDC_SM_ENC_PARAM_CHANGE_ADDR 0x002c +#define VIDC_SM_ENC_PARAM_CHANGE_RC_BIT_RATE_BMSK 0x4 +#define VIDC_SM_ENC_PARAM_CHANGE_RC_BIT_RATE_SHFT 2 +#define VIDC_SM_ENC_PARAM_CHANGE_RC_FRAME_RATE_BMSK 0x2 +#define VIDC_SM_ENC_PARAM_CHANGE_RC_FRAME_RATE_SHFT 1 +#define VIDC_SM_ENC_PARAM_CHANGE_I_PERIOD_BMSK 0x1 +#define VIDC_SM_ENC_PARAM_CHANGE_I_PERIOD_SHFT 0 + +#define VIDC_SM_ENC_VOP_TIMING_ADDR 0x0030 +#define VIDC_SM_ENC_VOP_TIMING_ENABLE_BMSK 0x80000000 +#define VIDC_SM_ENC_VOP_TIMING_ENABLE_SHFT 31 +#define VIDC_SM_ENC_VOP_TIMING_TIME_RESOLUTION_BMSK 0x7fff0000 +#define VIDC_SM_ENC_VOP_TIMING_TIME_RESOLUTION_SHFT 16 +#define VIDC_SM_ENC_VOP_TIMING_FRAME_DELTA_BMSK 0x0000ffff +#define VIDC_SM_ENC_VOP_TIMING_FRAME_DELTA_SHFT 0 + +#define VIDC_SM_ENC_HEC_PERIOD_ADDR 0x0034 + +#define VIDC_SM_H264_REF_L0_ADDR 0x005c +#define VIDC_SM_H264_REF_L0_CHRO_BTM_FLG_1_BMSK 0x80000000 +#define VIDC_SM_H264_REF_L0_CHRO_BTM_FLG_1_SHFT 31 +#define VIDC_SM_H264_REF_L0_CHRO_REF_1_BMSK 0x7f000000 +#define VIDC_SM_H264_REF_L0_CHRO_REF_1_SHFT 24 +#define VIDC_SM_H264_REF_L0_CHRO_BTM_FLG_0_BMSK 0x00800000 +#define VIDC_SM_H264_REF_L0_CHRO_BTM_FLG_0_SHFT 23 +#define VIDC_SM_H264_REF_L0_CHRO_REF_0_BMSK 0x007f0000 +#define VIDC_SM_H264_REF_L0_CHRO_REF_0_SHFT 16 +#define VIDC_SM_H264_REF_L0_LUMA_BTM_FLG_1_BMSK 0x00008000 +#define VIDC_SM_H264_REF_L0_LUMA_BTM_FLG_1_SHFT 15 +#define VIDC_SM_H264_REF_L0_LUMA_REF_1_BMSK 0x00007f00 +#define VIDC_SM_H264_REF_L0_LUMA_REF_1_SHFT 8 +#define VIDC_SM_H264_REF_L0_LUMA_BTM_FLG_0_BMSK 0x00000080 +#define VIDC_SM_H264_REF_L0_LUMA_BTM_FLG_0_SHFT 7 +#define VIDC_SM_H264_REF_L0_LUMA_REF_0_BMSK 0x0000007f +#define VIDC_SM_H264_REF_L0_LUMA_REF_0_SHFT 0 + +#define VIDC_SM_H264_REF_L1_ADDR 0x0060 +#define VIDC_SM_H264_REF_L1_CHRO_BTM_FLG_0_BMSK 0x00800000 +#define VIDC_SM_H264_REF_L1_CHRO_BTM_FLG_0_SHFT 23 +#define VIDC_SM_H264_REF_L1_CHRO_REF_0_BMSK 0x007f0000 +#define VIDC_SM_H264_REF_L1_CHRO_REF_0_SHFT 16 +#define VIDC_SM_H264_REF_L1_LUMA_BTM_FLG_0_BMSK 0x00000080 +#define VIDC_SM_H264_REF_L1_LUMA_BTM_FLG_0_SHFT 7 +#define VIDC_SM_H264_REF_L1_LUMA_REF_0_BMSK 0x0000007f +#define VIDC_SM_H264_REF_L1_LUMA_REF_0_SHFT 0 + +#define VIDC_SM_P_B_FRAME_QP_ADDR 0x0070 +#define VIDC_SM_P_B_FRAME_QP_B_FRAME_QP_BMASK 0x00000fc0 +#define VIDC_SM_P_B_FRAME_QP_B_FRAME_QP_SHFT 6 +#define VIDC_SM_P_B_FRAME_QP_P_FRAME_QP_BMASK 0x0000003f +#define VIDC_SM_P_B_FRAME_QP_P_FRAME_QP_SHFT 0 + +#define VIDC_SM_NEW_RC_BIT_RATE_ADDR 0x0090 +#define VIDC_SM_NEW_RC_BIT_RATE_VALUE_BMASK 0xffffffff +#define VIDC_SM_NEW_RC_BIT_RATE_VALUE_SHFT 0 +#define VIDC_SM_NEW_RC_FRAME_RATE_ADDR 0x0094 +#define VIDC_SM_NEW_RC_FRAME_RATE_VALUE_BMASK 0xffffffff +#define VIDC_SM_NEW_RC_FRAME_RATE_VALUE_SHFT 0 +#define VIDC_SM_NEW_I_PERIOD_ADDR 0x0098 +#define VIDC_SM_NEW_I_PERIOD_VALUE_BMASK 0xffffffff +#define VIDC_SM_NEW_I_PERIOD_VALUE_SHFT 0 + +#define VIDC_SM_BATCH_INPUT_ADDR 0x00a4 +#define VIDC_SM_BATCH_INPUT_ADDR_VALUE_BMSK 0xffffffff +#define VIDC_SM_BATCH_INPUT_ADDRL_VALUE_SHFT 0 +#define VIDC_SM_BATCH_OUTPUT_ADDR 0x00a8 +#define VIDC_SM_BATCH_OUTPUT_ADDR_VALUE_BMSK 0xffffffff +#define VIDC_SM_BATCH_OUTPUT_ADDR_VALUE_SHFT 0 +#define VIDC_SM_BATCH_OUTPUT_SIZE_ADDR 0x00ac +#define VIDC_SM_BATCH_OUTPUT_SIZE_VALUE_BMSK 0xffffffff +#define VIDC_SM_BATCH_OUTPUT_SIZE_VALUE_SHFT 0 +#define VIDC_SM_ENC_SLICE_BATCH_INT_CTRL_ADDR 0x01c8 +#define VIDC_SM_ENC_SLICE_BATCH_INT_CTRL_VALUE_BMSK 0x1 +#define VIDC_SM_ENC_SLICE_BATCH_INT_CTRL_VALUE_SHFT 0 +#define VIDC_SM_ENC_NUM_OF_SLICE_ADDR 0x01cc +#define VIDC_SM_ENC_NUM_OF_SLICE_VALUE_BMSK 0xffffffff +#define VIDC_SM_ENC_NUM_OF_SLICE_VALUE_SHFT 0 +#define VIDC_SM_ENC_NUM_OF_SLICE_COMP_ADDR 0x01d0 +#define VIDC_SM_ENC_NUM_OF_SLICE_COMP_VALUE_BMSK 0xffffffff +#define VIDC_SM_ENC_NUM_OF_SLICE_COMP_VALUE_SHFT 0 + +#define VIDC_SM_ALLOCATED_LUMA_DPB_SIZE_ADDR 0x0064 +#define VIDC_SM_ALLOCATED_CHROMA_DPB_SIZE_ADDR 0x0068 +#define VIDC_SM_ALLOCATED_MV_SIZE_ADDR 0x006c +#define VIDC_SM_FLUSH_CMD_TYPE_ADDR 0x0080 +#define VIDC_SM_FLUSH_CMD_INBUF1_ADDR 0x0084 +#define VIDC_SM_FLUSH_CMD_INBUF2_ADDR 0x0088 +#define VIDC_SM_FLUSH_CMD_OUTBUF_ADDR 0x008c +#define VIDC_SM_MIN_LUMA_DPB_SIZE_ADDR 0x00b0 +#define VIDC_SM_MIN_CHROMA_DPB_SIZE_ADDR 0x00bc + + +#define VIDC_SM_METADATA_ENABLE_ADDR 0x0038 +#define VIDC_SM_METADATA_ENABLE_EXTRADATA_BMSK 0x40 +#define VIDC_SM_METADATA_ENABLE_EXTRADATA_SHFT 6 +#define VIDC_SM_METADATA_ENABLE_ENC_SLICE_SIZE_BMSK 0x20 +#define VIDC_SM_METADATA_ENABLE_ENC_SLICE_SIZE_SHFT 5 +#define VIDC_SM_METADATA_ENABLE_VUI_BMSK 0x10 +#define VIDC_SM_METADATA_ENABLE_VUI_SHFT 4 +#define VIDC_SM_METADATA_ENABLE_SEI_VIDC_BMSK 0x8 +#define VIDC_SM_METADATA_ENABLE_SEI_VIDC_SHFT 3 +#define VIDC_SM_METADATA_ENABLE_VC1_PARAM_BMSK 0x4 +#define VIDC_SM_METADATA_ENABLE_VC1_PARAM_SHFT 2 +#define VIDC_SM_METADATA_ENABLE_CONCEALED_MB_BMSK 0x2 +#define VIDC_SM_METADATA_ENABLE_CONCEALED_MB_SHFT 1 +#define VIDC_SM_METADATA_ENABLE_QP_BMSK 0x1 +#define VIDC_SM_METADATA_ENABLE_QP_SHFT 0 + +#define VIDC_SM_ASPECT_RATIO_INFO_ADDR 0x00c8 +#define VIDC_SM_MPEG4_ASPECT_RATIO_INFO_BMSK 0xf +#define VIDC_SM_MPEG4_ASPECT_RATIO_INFO_SHFT 0x0 +#define VIDC_SM_EXTENDED_PAR_ADDR 0x00cc +#define VIDC_SM_EXTENDED_PAR_WIDTH_BMSK 0xffff0000 +#define VIDC_SM_EXTENDED_PAR_WIDTH_SHFT 16 +#define VIDC_SM_EXTENDED_PAR_HEIGHT_BMSK 0x0000ffff +#define VIDC_SM_EXTENDED_PAR_HEIGHT_SHFT 0x0 + +#define VIDC_SM_METADATA_STATUS_ADDR 0x003c +#define VIDC_SM_METADATA_STATUS_STATUS_BMSK 0x1 +#define VIDC_SM_METADATA_STATUS_STATUS_SHFT 0 + +#define VIDC_SM_METADATA_DISPLAY_INDEX_ADDR 0x0040 +#define VIDC_SM_EXT_METADATA_START_ADDR_ADDR 0x0044 + +#define VIDC_SM_PUT_EXTRADATA_ADDR 0x0048 +#define VIDC_SM_PUT_EXTRADATA_PUT_BMSK 0x1 +#define VIDC_SM_PUT_EXTRADATA_PUT_SHFT 0 + +#define VIDC_SM_EXTRADATA_ADDR_ADDR 0x004c + +#define VIDC_SM_CHROMA_ADDR_CHANGE_ADDR 0x0148 +#define VIDC_SM_CHROMA_ADDR_CHANGE_BMASK 0x00000001 +#define VIDC_SM_CHROMA_ADDR_CHANGE_SHFT 0 + +#define VIDC_SM_ERROR_CONCEALMENT_CONFIG_ADDR 0x0154 + +#define VIDC_SM_ERROR_CONCEALMENT_CONFIG_INTER_SLICE_BMSK 0x0c +#define VIDC_SM_ERROR_CONCEALMENT_CONFIG_INTER_SLICE_SHFT 2 +#define VIDC_SM_ERROR_CONCEALMENT_CONFIG_INTRA_SLICE_BMSK 0X02 +#define VIDC_SM_ERROR_CONCEALMENT_CONFIG_INTRA_SLICE_SHFT 1 +#define VIDC_SM_ERROR_CONCEALMENT_CONFIG_CONCEAL_ENABLE_BMSK 0x01 +#define VIDC_SM_ERROR_CONCEALMENT_CONFIG_CONCEAL_ENABLE_SHFT 0 + +#define VIDC_SM_SEI_ENABLE_ADDR 0x0180 +#define VIDC_SM_SEI_ENABLE_RECOVERY_POINT_SEI_BMSK 0x00000001 +#define VIDC_SM_SEI_ENABLE_RECOVERY_POINT_SEI_SHFT 0 + +#define VIDC_SM_NUM_STUFF_BYTES_CONSUME_ADDR 0X01ac + +#define VIDC_SM_TIMEOUT_VALUE_ADDR 0x0158 +#define VIDC_SM_TIMEOUT_VALUE_BMSK 0xffffffff +#define VIDC_SM_TIMEOUT_VALUE_SHFT 0 + +#define VIDC_SM_ENC_EXT_CTRL_CLOSED_GOP_ENABLE_BMSK 0x40 +#define VIDC_SM_ENC_EXT_CTRL_CLOSED_GOP_ENABLE_SHFT 6 + +#define DDL_MEM_WRITE_32(base, offset, val) ddl_mem_write_32(\ + (u32 *) ((u8 *) (base)->align_virtual_addr + (offset)), (val)) +#define DDL_MEM_READ_32(base, offset) ddl_mem_read_32(\ + (u32 *) ((u8 *) (base)->align_virtual_addr + (offset))) + +#define DDL_SHARED_MEM_11BIT_RIGHT_SHIFT 11 + +static void ddl_mem_write_32(u32 *addr, u32 data) +{ + *addr = data; +} + +static u32 ddl_mem_read_32(u32 *addr) +{ + return *addr; +} + +void vidc_sm_get_extended_decode_status(struct ddl_buf_addr *shared_mem, + u32 *more_field_needed, + u32 *resl_change) +{ + u32 decode_status = DDL_MEM_READ_32(shared_mem, + VIDC_SM_EXTENDED_DECODE_STATUS_ADDR); + if (more_field_needed) + *more_field_needed = + VIDC_GETFIELD(decode_status, + VIDC_SM_EXT_DEC_STATUS_MORE_FIELD_NEEDED_BMSK, + VIDC_SM_EXT_DEC_STATUS_MORE_FIELD_NEEDED_SHFT); + if (resl_change) + *resl_change = + VIDC_GETFIELD(decode_status, + VIDC_SM_EXT_DEC_STATUS_RESOLUTION_CHANGE_BMSK, + VIDC_SM_EXT_DEC_STATUS_RESOLUTION_CHANGE_SHFT); +} + +void vidc_sm_set_frame_tag(struct ddl_buf_addr *shared_mem, + u32 frame_tag) +{ + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_SET_FRAME_TAG_ADDR, frame_tag); +} + +void vidc_sm_get_frame_tags(struct ddl_buf_addr *shared_mem, + u32 *pn_frame_tag_top, u32 *pn_frame_tag_bottom) +{ + *pn_frame_tag_top = DDL_MEM_READ_32(shared_mem, + VIDC_SM_GET_FRAME_TAG_TOP_ADDR); + *pn_frame_tag_bottom = DDL_MEM_READ_32(shared_mem, + VIDC_SM_GET_FRAME_TAG_BOTTOM_ADDR); +} + +void vidc_sm_get_picture_times(struct ddl_buf_addr *shared_mem, + u32 *pn_time_top, u32 *pn_time_bottom) +{ + *pn_time_top = DDL_MEM_READ_32(shared_mem, VIDC_SM_PIC_TIME_TOP_ADDR); + *pn_time_bottom = DDL_MEM_READ_32(shared_mem, + VIDC_SM_PIC_TIME_BOTTOM_ADDR); +} + +void vidc_sm_set_start_byte_number(struct ddl_buf_addr *shared_mem, + u32 byte_num) +{ + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_START_BYTE_NUM_ADDR, byte_num); +} + +void vidc_sm_get_crop_info(struct ddl_buf_addr *shared_mem, + u32 *pn_left, u32 *pn_right, u32 *pn_top, u32 *pn_bottom) +{ + u32 info1, info2; + + info1 = DDL_MEM_READ_32(shared_mem, VIDC_SM_CROP_INFO1_ADDR); + + *pn_left = VIDC_GETFIELD(info1, VIDC_SM_CROP_INFO1_LEFT_OFFSET_BMSK, + VIDC_SM_CROP_INFO1_LEFT_OFFSET_SHFT); + *pn_right = VIDC_GETFIELD(info1, VIDC_SM_CROP_INFO1_RIGHT_OFFSET_BMSK, + VIDC_SM_CROP_INFO1_RIGHT_OFFSET_SHFT); + info2 = DDL_MEM_READ_32(shared_mem, VIDC_SM_CROP_INFO2_ADDR); + *pn_top = VIDC_GETFIELD(info2, VIDC_SM_CROP_INFO2_TOP_OFFSET_BMSK, + VIDC_SM_CROP_INFO2_TOP_OFFSET_SHFT); + *pn_bottom = VIDC_GETFIELD(info2, + VIDC_SM_CROP_INFO2_BOTTOM_OFFSET_BMSK, + VIDC_SM_CROP_INFO2_BOTTOM_OFFSET_SHFT); +} + +void vidc_sm_get_displayed_picture_frame(struct ddl_buf_addr + *shared_mem, u32 *n_disp_picture_frame) +{ + u32 disp_pict_frame; + + disp_pict_frame = DDL_MEM_READ_32(shared_mem, + VIDC_SM_DISP_PIC_FRAME_TYPE_ADDR); + *n_disp_picture_frame = VIDC_GETFIELD(disp_pict_frame, + VIDC_SM_DISP_PIC_FRAME_TYPE_BMSK, + VIDC_SM_DISP_PIC_FRAME_TYPE_SHFT); +} +void vidc_sm_get_available_luma_dpb_address(struct ddl_buf_addr + *shared_mem, u32 *pn_free_luma_dpb_address) +{ + *pn_free_luma_dpb_address = DDL_MEM_READ_32(shared_mem, + VIDC_SM_FREE_LUMA_DPB_ADDR); +} + +void vidc_sm_get_available_luma_dpb_dec_order_address( + struct ddl_buf_addr *shared_mem, + u32 *pn_free_luma_dpb_address) +{ + *pn_free_luma_dpb_address = DDL_MEM_READ_32(shared_mem, + VIDC_SM_FREE_LUMA_DPB_DEC_ORDER_ADDR); +} + +void vidc_sm_get_dec_order_resl( + struct ddl_buf_addr *shared_mem, u32 *width, u32 *height) +{ + *width = DDL_MEM_READ_32(shared_mem, + VIDC_SM_DEC_ORDER_WIDTH_ADDR); + *height = DDL_MEM_READ_32(shared_mem, + VIDC_SM_DEC_ORDER_HEIGHT_ADDR); +} + +void vidc_sm_get_dec_order_crop_info( + struct ddl_buf_addr *shared_mem, u32 *left, + u32 *right, u32 *top, u32 *bottom) +{ + u32 crop_data; + crop_data = DDL_MEM_READ_32(shared_mem, + VIDC_SM_DEC_CROP_INFO1_ADDR); + *left = VIDC_GETFIELD(crop_data, + VIDC_SM_DEC_CROP_INFO1_LEFT_OFFSET_BMSK, + VIDC_SM_DEC_CROP_INFO1_LEFT_OFFSET_SHFT); + *right = VIDC_GETFIELD(crop_data, + VIDC_SM_DEC_CROP_INFO1_RIGHT_OFFSET_BMSK, + VIDC_SM_DEC_CROP_INFO1_RIGHT_OFFSET_SHFT); + crop_data = DDL_MEM_READ_32(shared_mem, + VIDC_SM_DEC_CROP_INFO2_ADDR); + *top = VIDC_GETFIELD(crop_data, + VIDC_SM_DEC_CROP_INFO2_TOP_OFFSET_BMSK, + VIDC_SM_DEC_CROP_INFO2_TOP_OFFSET_SHFT); + *bottom = VIDC_GETFIELD(crop_data, + VIDC_SM_DEC_CROP_INFO2_BOTTOM_OFFSET_BMSK, + VIDC_SM_DEC_CROP_INFO2_BOTTOM_OFFSET_SHFT); +} + +void vidc_sm_set_extended_encoder_control(struct ddl_buf_addr + *shared_mem, u32 hec_enable, + enum VIDC_SM_frame_skip frame_skip_mode, + u32 seq_hdr_in_band, u32 vbv_buffer_size, u32 cpcfc_enable, + u32 sps_pps_control, u32 closed_gop_enable) +{ + u32 enc_ctrl; + + enc_ctrl = VIDC_SETFIELD((hec_enable) ? 1 : 0, + VIDC_SM_ENC_EXT_CTRL_HEC_ENABLE_SHFT, + VIDC_SM_ENC_EXT_CTRL_HEC_ENABLE_BMSK) | + VIDC_SETFIELD((u32) frame_skip_mode, + VIDC_SM_ENC_EXT_CTRL_FRAME_SKIP_ENABLE_SHFT, + VIDC_SM_ENC_EXT_CTRL_FRAME_SKIP_ENABLE_BMSK) | + VIDC_SETFIELD((seq_hdr_in_band) ? 1 : 0 , + VIDC_SM_ENC_EXT_CTRL_SEQ_HDR_CTRL_SHFT , + VIDC_SM_ENC_EXT_CTRL_SEQ_HDR_CTRL_BMSK) | + VIDC_SETFIELD(vbv_buffer_size, + VIDC_SM_ENC_EXT_CTRL_VBV_BUFFER_SIZE_SHFT, + VIDC_SM_ENC_EXT_CTRL_VBV_BUFFER_SIZE_BMSK) | + VIDC_SETFIELD((cpcfc_enable) ? 1 : 0, + VIDC_SM_ENC_EXT_CTRL_H263_CPCFC_ENABLE_SHFT, + VIDC_SM_ENC_EXT_CTRL_H263_CPCFC_ENABLE_BMSK) | + VIDC_SETFIELD((sps_pps_control) ? 1 : 0, + VIDC_SM_ENC_EXT_CTRL_SPS_PPS_CONTROL_SHFT, + VIDC_SM_ENC_EXT_CTRL_SPS_PPS_CONTROL_BMSK) | + VIDC_SETFIELD(closed_gop_enable, + VIDC_SM_ENC_EXT_CTRL_CLOSED_GOP_ENABLE_SHFT, + VIDC_SM_ENC_EXT_CTRL_CLOSED_GOP_ENABLE_BMSK); + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_ENC_EXT_CTRL_ADDR, enc_ctrl); +} + +void vidc_sm_set_encoder_param_change(struct ddl_buf_addr *shared_mem, + u32 bit_rate_chg, u32 frame_rate_chg, u32 i_period_chg) +{ + u32 enc_param_chg; + + enc_param_chg = VIDC_SETFIELD((bit_rate_chg) ? 1 : 0, + VIDC_SM_ENC_PARAM_CHANGE_RC_BIT_RATE_SHFT, + VIDC_SM_ENC_PARAM_CHANGE_RC_BIT_RATE_BMSK) | + VIDC_SETFIELD((frame_rate_chg) ? 1 : 0, + VIDC_SM_ENC_PARAM_CHANGE_RC_FRAME_RATE_SHFT, + VIDC_SM_ENC_PARAM_CHANGE_RC_FRAME_RATE_BMSK) | + VIDC_SETFIELD((i_period_chg) ? 1 : 0, + VIDC_SM_ENC_PARAM_CHANGE_I_PERIOD_SHFT, + VIDC_SM_ENC_PARAM_CHANGE_I_PERIOD_BMSK); + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_ENC_PARAM_CHANGE_ADDR, + enc_param_chg); +} + +void vidc_sm_set_encoder_vop_time(struct ddl_buf_addr *shared_mem, + u32 vop_time_enable, u32 time_resolution, u32 frame_delta) +{ + u32 vop_time; + + vop_time = VIDC_SETFIELD((vop_time_enable) ? 1 : 0, + VIDC_SM_ENC_VOP_TIMING_ENABLE_SHFT , + VIDC_SM_ENC_VOP_TIMING_ENABLE_BMSK) | + VIDC_SETFIELD(time_resolution , + VIDC_SM_ENC_VOP_TIMING_TIME_RESOLUTION_SHFT, + VIDC_SM_ENC_VOP_TIMING_TIME_RESOLUTION_BMSK) | + VIDC_SETFIELD(frame_delta, + VIDC_SM_ENC_VOP_TIMING_FRAME_DELTA_SHFT, + VIDC_SM_ENC_VOP_TIMING_FRAME_DELTA_BMSK); + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_ENC_VOP_TIMING_ADDR, vop_time); +} + +void vidc_sm_set_encoder_hec_period(struct ddl_buf_addr *shared_mem, + u32 hec_period) +{ + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_ENC_HEC_PERIOD_ADDR, + hec_period); +} + +void vidc_sm_get_h264_encoder_reference_list0(struct ddl_buf_addr + *shared_mem, enum VIDC_SM_ref_picture *pe_luma_picture0, + u32 *pn_luma_picture_index0, enum VIDC_SM_ref_picture + *pe_luma_picture1, u32 *pn_luma_picture_index1, + enum VIDC_SM_ref_picture *pe_chroma_picture0, + u32 *pn_chroma_picture_index0, + enum VIDC_SM_ref_picture *pe_chroma_picture1, + u32 *pn_chroma_picture_index1) +{ + u32 ref_list; + + ref_list = DDL_MEM_READ_32(shared_mem, VIDC_SM_H264_REF_L0_ADDR); + + *pe_luma_picture0 = (enum VIDC_SM_ref_picture) + VIDC_GETFIELD(ref_list, + VIDC_SM_H264_REF_L0_LUMA_BTM_FLG_0_BMSK, + VIDC_SM_H264_REF_L0_LUMA_BTM_FLG_0_SHFT); + *pn_luma_picture_index0 = + VIDC_GETFIELD(ref_list, + VIDC_SM_H264_REF_L0_LUMA_REF_0_BMSK, + VIDC_SM_H264_REF_L0_LUMA_REF_0_SHFT); + *pe_luma_picture1 = (enum VIDC_SM_ref_picture) + VIDC_GETFIELD(ref_list, + VIDC_SM_H264_REF_L0_LUMA_BTM_FLG_1_BMSK, + VIDC_SM_H264_REF_L0_LUMA_BTM_FLG_1_SHFT); + *pn_luma_picture_index1 = VIDC_GETFIELD(ref_list, + VIDC_SM_H264_REF_L0_LUMA_REF_1_BMSK, + VIDC_SM_H264_REF_L0_LUMA_REF_1_SHFT); + *pe_chroma_picture0 = (enum VIDC_SM_ref_picture) + VIDC_GETFIELD(ref_list, + VIDC_SM_H264_REF_L0_CHRO_BTM_FLG_0_BMSK, + VIDC_SM_H264_REF_L0_CHRO_BTM_FLG_0_SHFT); + *pn_chroma_picture_index0 = VIDC_GETFIELD(ref_list, + VIDC_SM_H264_REF_L0_CHRO_REF_0_BMSK, + VIDC_SM_H264_REF_L0_CHRO_REF_0_SHFT); + *pe_chroma_picture1 = (enum VIDC_SM_ref_picture) + VIDC_GETFIELD(ref_list, + VIDC_SM_H264_REF_L0_CHRO_BTM_FLG_1_BMSK, + VIDC_SM_H264_REF_L0_CHRO_BTM_FLG_1_SHFT); + *pn_chroma_picture_index1 = + VIDC_GETFIELD(ref_list, + VIDC_SM_H264_REF_L0_CHRO_REF_1_BMSK, + VIDC_SM_H264_REF_L0_CHRO_REF_1_SHFT); +} + +void vidc_sm_get_h264_encoder_reference_list1(struct ddl_buf_addr + *shared_mem, enum VIDC_SM_ref_picture *pe_luma_picture, + u32 *pn_luma_picture_index, + enum VIDC_SM_ref_picture *pe_chroma_picture, + u32 *pn_chroma_picture_index) +{ + u32 ref_list; + + ref_list = DDL_MEM_READ_32(shared_mem, VIDC_SM_H264_REF_L1_ADDR); + + *pe_luma_picture = (enum VIDC_SM_ref_picture) + VIDC_GETFIELD(ref_list, + VIDC_SM_H264_REF_L1_LUMA_BTM_FLG_0_BMSK, + VIDC_SM_H264_REF_L1_LUMA_BTM_FLG_0_SHFT); + *pn_luma_picture_index = + VIDC_GETFIELD(ref_list, + VIDC_SM_H264_REF_L1_LUMA_REF_0_BMSK, + VIDC_SM_H264_REF_L1_LUMA_REF_0_SHFT); + *pe_chroma_picture = (enum VIDC_SM_ref_picture) + VIDC_GETFIELD(ref_list, + VIDC_SM_H264_REF_L1_CHRO_BTM_FLG_0_BMSK, + VIDC_SM_H264_REF_L1_CHRO_BTM_FLG_0_SHFT); + *pn_chroma_picture_index = VIDC_GETFIELD(ref_list, + VIDC_SM_H264_REF_L1_CHRO_REF_0_BMSK, + VIDC_SM_H264_REF_L1_CHRO_REF_0_SHFT); +} + +void vidc_sm_set_allocated_dpb_size(struct ddl_buf_addr *shared_mem, + u32 y_size, u32 c_size) +{ + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_ALLOCATED_LUMA_DPB_SIZE_ADDR, + y_size); + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_ALLOCATED_CHROMA_DPB_SIZE_ADDR, + c_size); +} + +void vidc_sm_set_allocated_h264_mv_size(struct ddl_buf_addr *shared_mem, + u32 mv_size) +{ + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_ALLOCATED_MV_SIZE_ADDR, + mv_size); +} + +void vidc_sm_get_min_yc_dpb_sizes(struct ddl_buf_addr *shared_mem, + u32 *pn_min_luma_dpb_size, u32 *pn_min_chroma_dpb_size) +{ + *pn_min_luma_dpb_size = DDL_MEM_READ_32(shared_mem, + VIDC_SM_MIN_LUMA_DPB_SIZE_ADDR); + *pn_min_chroma_dpb_size = DDL_MEM_READ_32(shared_mem, + VIDC_SM_MIN_CHROMA_DPB_SIZE_ADDR); +} + +void vidc_sm_set_concealment_color(struct ddl_buf_addr *shared_mem, + u32 conceal_ycolor, u32 conceal_ccolor) +{ + u32 conceal_color; + + conceal_color = (((conceal_ycolor << 8) & 0xff00) | + (conceal_ccolor & 0xff)); + DDL_MEM_WRITE_32(shared_mem, 0x00f0, conceal_color); +} + +void vidc_sm_set_metadata_enable(struct ddl_buf_addr *shared_mem, + u32 extradata_enable, u32 qp_enable, u32 concealed_mb_enable, + u32 vc1Param_enable, u32 sei_nal_enable, u32 vui_enable, + u32 enc_slice_size_enable) +{ + u32 metadata_enable; + + metadata_enable = VIDC_SETFIELD((extradata_enable) ? 1 : 0, + VIDC_SM_METADATA_ENABLE_EXTRADATA_SHFT, + VIDC_SM_METADATA_ENABLE_EXTRADATA_BMSK) | + VIDC_SETFIELD((enc_slice_size_enable) ? 1 : 0, + VIDC_SM_METADATA_ENABLE_ENC_SLICE_SIZE_SHFT, + VIDC_SM_METADATA_ENABLE_ENC_SLICE_SIZE_BMSK) | + VIDC_SETFIELD((vui_enable) ? 1 : 0, + VIDC_SM_METADATA_ENABLE_VUI_SHFT, + VIDC_SM_METADATA_ENABLE_VUI_BMSK) | + VIDC_SETFIELD((sei_nal_enable) ? 1 : 0, + VIDC_SM_METADATA_ENABLE_SEI_VIDC_SHFT, + VIDC_SM_METADATA_ENABLE_SEI_VIDC_BMSK) | + VIDC_SETFIELD((vc1Param_enable) ? 1 : 0, + VIDC_SM_METADATA_ENABLE_VC1_PARAM_SHFT, + VIDC_SM_METADATA_ENABLE_VC1_PARAM_BMSK) | + VIDC_SETFIELD((concealed_mb_enable) ? 1 : 0, + VIDC_SM_METADATA_ENABLE_CONCEALED_MB_SHFT, + VIDC_SM_METADATA_ENABLE_CONCEALED_MB_BMSK) | + VIDC_SETFIELD((qp_enable) ? 1 : 0, + VIDC_SM_METADATA_ENABLE_QP_SHFT, + VIDC_SM_METADATA_ENABLE_QP_BMSK); + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_METADATA_ENABLE_ADDR, + metadata_enable); +} + +void vidc_sm_get_metadata_status(struct ddl_buf_addr + *shared_mem, u32 *pb_metadata_present) +{ + u32 status; + + status = DDL_MEM_READ_32(shared_mem, VIDC_SM_METADATA_STATUS_ADDR); + *pb_metadata_present = (u32) VIDC_GETFIELD(status, + VIDC_SM_METADATA_STATUS_STATUS_BMSK, + VIDC_SM_METADATA_STATUS_STATUS_SHFT); +} + +void vidc_sm_get_metadata_display_index(struct ddl_buf_addr *shared_mem, + u32 *pn_dixplay_index) +{ + *pn_dixplay_index = DDL_MEM_READ_32(shared_mem, + VIDC_SM_METADATA_DISPLAY_INDEX_ADDR); +} + +void vidc_sm_set_metadata_start_address(struct ddl_buf_addr *shared_mem, + u32 address) +{ + u32 address_shift = address; + + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_EXT_METADATA_START_ADDR_ADDR, + address_shift); +} + +void vidc_sm_set_extradata_presence(struct ddl_buf_addr *shared_mem, + u32 extradata_present) +{ + u32 put_extradata; + + put_extradata = VIDC_SETFIELD((extradata_present) ? 1 : 0, + VIDC_SM_PUT_EXTRADATA_PUT_SHFT, + VIDC_SM_PUT_EXTRADATA_PUT_BMSK); + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_PUT_EXTRADATA_ADDR, + put_extradata); +} + +void vidc_sm_set_extradata_addr(struct ddl_buf_addr *shared_mem, + u32 extradata_addr) +{ + u32 address_shift = extradata_addr; + + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_EXTRADATA_ADDR_ADDR, + address_shift); +} + +void vidc_sm_set_pand_b_frame_qp(struct ddl_buf_addr *shared_mem, + u32 b_frame_qp, u32 p_frame_qp) +{ + u32 nP_B_frame_qp; + + nP_B_frame_qp = VIDC_SETFIELD(b_frame_qp, + VIDC_SM_P_B_FRAME_QP_B_FRAME_QP_SHFT, + VIDC_SM_P_B_FRAME_QP_B_FRAME_QP_BMASK); + nP_B_frame_qp |= VIDC_SETFIELD(p_frame_qp, + VIDC_SM_P_B_FRAME_QP_P_FRAME_QP_SHFT, + VIDC_SM_P_B_FRAME_QP_P_FRAME_QP_BMASK); + DDL_MEM_WRITE_32(shared_mem , VIDC_SM_P_B_FRAME_QP_ADDR, + nP_B_frame_qp); +} + + +void vidc_sm_get_profile_info(struct ddl_buf_addr *shared_mem, + struct ddl_profile_info_type *ddl_profile_info) +{ + u32 disp_pic_profile; + + disp_pic_profile = DDL_MEM_READ_32(shared_mem, + VIDC_SM_DISP_PIC_PROFILE_ADDR); + ddl_profile_info->bit_depth_chroma_minus8 = + (disp_pic_profile & 0x00380000) >> 19; + ddl_profile_info->bit_depth_luma_minus8 = + (disp_pic_profile & 0x00070000) >> 16; + ddl_profile_info->pic_profile = VIDC_GETFIELD( + disp_pic_profile, + VIDC_SM_DISP_PIC_PROFILE_DISP_PIC_PROFILE_BMASK, + VIDC_SM_DISP_PIC_PROFILE_DISP_PIC_PROFILE_SHFT); + ddl_profile_info->pic_level = VIDC_GETFIELD( + disp_pic_profile, + VIDC_SM_DISP_PIC_PROFILE_DISP_PIC_LEVEL_BMASK, + VIDC_SM_DISP_PIC_PROFILE_DISP_PIC_LEVEL_SHFT); + ddl_profile_info->chroma_format_idc = + (disp_pic_profile & 0x60) >> 5; +} + +void vidc_sm_set_encoder_new_bit_rate(struct ddl_buf_addr *shared_mem, + u32 new_bit_rate) +{ + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_NEW_RC_BIT_RATE_ADDR, + new_bit_rate); +} + +void vidc_sm_set_encoder_new_frame_rate(struct ddl_buf_addr *shared_mem, + u32 new_frame_rate) +{ + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_NEW_RC_FRAME_RATE_ADDR, + new_frame_rate); +} + +void vidc_sm_set_encoder_new_i_period(struct ddl_buf_addr *shared_mem, + u32 new_i_period) +{ + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_NEW_I_PERIOD_ADDR, + new_i_period); +} +void vidc_sm_set_encoder_init_rc_value(struct ddl_buf_addr *shared_mem, + u32 new_rc_value) +{ + DDL_MEM_WRITE_32(shared_mem, 0x011C, new_rc_value); + +} +void vidc_sm_set_idr_decode_only(struct ddl_buf_addr *shared_mem, + u32 enable) +{ + u32 idr_decode_only = VIDC_SETFIELD((enable) ? 1 : 0, + VIDC_SM_IDR_DECODING_ONLY_SHIFT, + VIDC_SM_IDR_DECODING_ONLY_BMSK + ); + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_IDR_DECODING_ONLY_ADDR, + idr_decode_only); +} + +void vidc_sm_set_chroma_addr_change(struct ddl_buf_addr *shared_mem, + u32 addr_change) +{ + u32 chroma_addr_change = VIDC_SETFIELD((addr_change) ? 1 : 0, + VIDC_SM_CHROMA_ADDR_CHANGE_SHFT, + VIDC_SM_CHROMA_ADDR_CHANGE_BMASK); + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_CHROMA_ADDR_CHANGE_ADDR, + chroma_addr_change); + +} + +void vidc_sm_set_mpeg4_profile_override(struct ddl_buf_addr *shared_mem, + enum vidc_sm_mpeg4_profileinfo profile_info) +{ + u32 profile_enforce = 0; + if (shared_mem != NULL) { + profile_enforce = 1; + switch (profile_info) { + case VIDC_SM_PROFILE_INFO_ASP: + profile_enforce |= 4; + break; + case VIDC_SM_PROFILE_INFO_SP: + profile_enforce |= 2; + break; + case VIDC_SM_PROFILE_INFO_DISABLE: + default: + profile_enforce = 0; + break; + } + DDL_MEM_WRITE_32(shared_mem, 0x15c, profile_enforce); + } +} +void vidc_sm_set_decoder_sei_enable(struct ddl_buf_addr *shared_mem, + u32 sei_enable) +{ + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_SEI_ENABLE_ADDR, sei_enable); +} + +void vidc_sm_get_decoder_sei_enable(struct ddl_buf_addr *shared_mem, + u32 *sei_enable) +{ + *sei_enable = DDL_MEM_READ_32(shared_mem, VIDC_SM_SEI_ENABLE_ADDR); +} + +void vidc_sm_set_error_concealment_config(struct ddl_buf_addr *shared_mem, + u32 inter_slice, u32 intra_slice, u32 conceal_config_enable) +{ + u32 error_conceal_config = 0; + + error_conceal_config = VIDC_SETFIELD(inter_slice, + VIDC_SM_ERROR_CONCEALMENT_CONFIG_INTER_SLICE_SHFT, + VIDC_SM_ERROR_CONCEALMENT_CONFIG_INTER_SLICE_BMSK); + + error_conceal_config |= VIDC_SETFIELD(intra_slice, + VIDC_SM_ERROR_CONCEALMENT_CONFIG_INTRA_SLICE_SHFT, + VIDC_SM_ERROR_CONCEALMENT_CONFIG_INTRA_SLICE_BMSK); + + error_conceal_config |= VIDC_SETFIELD(conceal_config_enable, + VIDC_SM_ERROR_CONCEALMENT_CONFIG_CONCEAL_ENABLE_SHFT, + VIDC_SM_ERROR_CONCEALMENT_CONFIG_CONCEAL_ENABLE_BMSK); + + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_ERROR_CONCEALMENT_CONFIG_ADDR, + error_conceal_config); +} + +void vidc_sm_set_decoder_stuff_bytes_consumption( + struct ddl_buf_addr *shared_mem, + enum vidc_sm_num_stuff_bytes_consume_info consume_info) +{ + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_NUM_STUFF_BYTES_CONSUME_ADDR, + consume_info); +} + +void vidc_sm_get_aspect_ratio_info(struct ddl_buf_addr *shared_mem, + struct vcd_aspect_ratio *aspect_ratio_info) +{ + u32 extended_par_info = 0; + aspect_ratio_info->aspect_ratio = DDL_MEM_READ_32(shared_mem, + VIDC_SM_ASPECT_RATIO_INFO_ADDR); + + if (aspect_ratio_info->aspect_ratio == 0x0f) { + extended_par_info = DDL_MEM_READ_32(shared_mem, + VIDC_SM_EXTENDED_PAR_ADDR); + aspect_ratio_info->extended_par_width = + VIDC_GETFIELD(extended_par_info, + VIDC_SM_EXTENDED_PAR_WIDTH_BMSK, + VIDC_SM_EXTENDED_PAR_WIDTH_SHFT); + aspect_ratio_info->extended_par_height = + VIDC_GETFIELD(extended_par_info, + VIDC_SM_EXTENDED_PAR_HEIGHT_BMSK, + VIDC_SM_EXTENDED_PAR_HEIGHT_SHFT); + } +} + +void vidc_sm_set_encoder_slice_batch_int_ctrl(struct ddl_buf_addr *shared_mem, + u32 slice_batch_int_enable) +{ + u32 slice_batch_int_ctrl = VIDC_SETFIELD((slice_batch_int_enable) ? + 1 : 0, + VIDC_SM_ENC_EXT_CTRL_HEC_ENABLE_SHFT, + VIDC_SM_ENC_EXT_CTRL_HEC_ENABLE_BMSK); + DDL_MEM_WRITE_32(shared_mem, + VIDC_SM_ENC_SLICE_BATCH_INT_CTRL_ADDR, + slice_batch_int_ctrl); +} + +void vidc_sm_get_num_slices_comp(struct ddl_buf_addr *shared_mem, + u32 *num_slices_comp) +{ + *num_slices_comp = DDL_MEM_READ_32(shared_mem, + VIDC_SM_ENC_NUM_OF_SLICE_COMP_ADDR); +} + +void vidc_sm_set_encoder_batch_config(struct ddl_buf_addr *shared_mem, + u32 num_slices, + u32 input_addr, u32 output_addr, + u32 output_buffer_size) +{ + DDL_MEM_WRITE_32(shared_mem, + VIDC_SM_ENC_NUM_OF_SLICE_ADDR, + num_slices); + DDL_MEM_WRITE_32(shared_mem, + VIDC_SM_BATCH_INPUT_ADDR, + input_addr); + DDL_MEM_WRITE_32(shared_mem, + VIDC_SM_BATCH_OUTPUT_ADDR, + output_addr); + DDL_MEM_WRITE_32(shared_mem, + VIDC_SM_BATCH_OUTPUT_SIZE_ADDR, + output_buffer_size); +} + +void vidc_sm_get_encoder_batch_output_size(struct ddl_buf_addr *shared_mem, + u32 *output_buffer_size) +{ + *output_buffer_size = DDL_MEM_READ_32(shared_mem, + VIDC_SM_BATCH_OUTPUT_SIZE_ADDR); +} + +void vidc_sm_set_video_core_timeout_value(struct ddl_buf_addr *shared_mem, + u32 timeout) +{ + DDL_MEM_WRITE_32(shared_mem, VIDC_SM_TIMEOUT_VALUE_ADDR, + timeout); +} + diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h new file mode 100644 index 000000000000..fd7745414281 --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h @@ -0,0 +1,196 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#ifndef _VCD_DDL_SHARED_MEM_H_ +#define _VCD_DDL_SHARED_MEM_H_ + +#include "vcd_ddl.h" + +#define VIDC_SM_PROFILE_MPEG4_SIMPLE (0) +#define VIDC_SM_PROFILE_MPEG4_ADV_SIMPLE (1) + +#define VIDC_SM_PROFILE_H264_BASELINE (0) +#define VIDC_SM_PROFILE_H264_MAIN (1) +#define VIDC_SM_PROFILE_H264_HIGH (2) + +#define VIDC_SM_PROFILE_H263_BASELINE (0) + +#define VIDC_SM_PROFILE_VC1_SIMPLE (0) +#define VIDC_SM_PROFILE_VC1_MAIN (1) +#define VIDC_SM_PROFILE_VC1_ADVANCED (2) + +#define VIDC_SM_PROFILE_MPEG2_MAIN (4) +#define VIDC_SM_PROFILE_MPEG2_SIMPLE (5) + +#define VIDC_SM_LEVEL_MPEG2_LOW (10) +#define VIDC_SM_LEVEL_MPEG2_MAIN (8) +#define VIDC_SM_LEVEL_MPEG2_HIGH_1440 (6) +#define VIDC_SM_LEVEL_MPEG2_HIGH (4) + +#define VIDC_SM_LEVEL_VC1_LOW (0) +#define VIDC_SM_LEVEL_VC1_MEDIUM (2) +#define VIDC_SM_LEVEL_VC1_HIGH (4) + +#define VIDC_SM_LEVEL_VC1_ADV_0 (0) +#define VIDC_SM_LEVEL_VC1_ADV_1 (1) +#define VIDC_SM_LEVEL_VC1_ADV_2 (2) +#define VIDC_SM_LEVEL_VC1_ADV_3 (3) +#define VIDC_SM_LEVEL_VC1_ADV_4 (4) + +#define VIDC_SM_RECOVERY_POINT_SEI (1) +enum VIDC_SM_frame_skip { + VIDC_SM_FRAME_SKIP_DISABLE = 0, + VIDC_SM_FRAME_SKIP_ENABLE_LEVEL = 1, + VIDC_SM_FRAME_SKIP_ENABLE_VBV = 2 +}; +enum VIDC_SM_ref_picture { + VIDC_SM_REF_PICT_FRAME_OR_TOP_FIELD = 0, + VIDC_SM_REF_PICT_BOTTOM_FIELD = 1 +}; + +struct ddl_profile_info_type { + u32 bit_depth_chroma_minus8; + u32 bit_depth_luma_minus8; + u32 pic_level; + u32 chroma_format_idc; + u32 pic_profile; +}; + +enum vidc_sm_mpeg4_profileinfo { + VIDC_SM_PROFILE_INFO_DISABLE = 0, + VIDC_SM_PROFILE_INFO_SP = 1, + VIDC_SM_PROFILE_INFO_ASP = 2, + VIDC_SM_PROFILE_INFO_MAX = 0x7fffffff +}; + +enum vidc_sm_num_stuff_bytes_consume_info { + VIDC_SM_NUM_STUFF_BYTES_CONSUME_ALL = 0x0, + VIDC_SM_NUM_STUFF_BYTES_CONSUME_NONE = 0xffffffff +}; + +void vidc_sm_get_extended_decode_status(struct ddl_buf_addr *shared_mem, + u32 *more_field_needed, + u32 *resl_change); +void vidc_sm_set_frame_tag(struct ddl_buf_addr *shared_mem, + u32 frame_tag); +void vidc_sm_get_frame_tags(struct ddl_buf_addr *shared_mem, + u32 *pn_frame_tag_top, u32 *pn_frame_tag_bottom); +void vidc_sm_get_picture_times(struct ddl_buf_addr *shared_mem, + u32 *pn_time_top, u32 *pn_time_bottom); +void vidc_sm_set_start_byte_number(struct ddl_buf_addr *shared_mem, + u32 byte_num); +void vidc_sm_get_crop_info(struct ddl_buf_addr *shared_mem, u32 *pn_left, + u32 *pn_right, u32 *pn_top, u32 *pn_bottom); +void vidc_sm_get_displayed_picture_frame(struct ddl_buf_addr + *shared_mem, u32 *n_disp_picture_frame); +void vidc_sm_get_available_luma_dpb_address( + struct ddl_buf_addr *shared_mem, u32 *pn_free_luma_dpb_address); +void vidc_sm_get_available_luma_dpb_dec_order_address( + struct ddl_buf_addr *shared_mem, u32 *pn_free_luma_dpb_address); +void vidc_sm_get_dec_order_resl( + struct ddl_buf_addr *shared_mem, u32 *width, u32 *height); +void vidc_sm_get_dec_order_crop_info( + struct ddl_buf_addr *shared_mem, u32 *left, + u32 *right, u32 *top, u32 *bottom); +void vidc_sm_set_extended_encoder_control( + struct ddl_buf_addr *shared_mem, u32 hec_enable, + enum VIDC_SM_frame_skip frame_skip_mode, u32 seq_hdr_in_band, + u32 vbv_buffer_size, u32 cpcfc_enable, u32 sps_pps_control, + u32 closed_gop_enable); +void vidc_sm_set_encoder_param_change(struct ddl_buf_addr *shared_mem, + u32 bit_rate_chg, u32 frame_rate_chg, u32 i_period_chg); +void vidc_sm_set_encoder_vop_time(struct ddl_buf_addr *shared_mem, + u32 vop_time_enable, u32 time_resolution, u32 frame_delta); +void vidc_sm_set_encoder_hec_period(struct ddl_buf_addr *shared_mem, + u32 hec_period); +void vidc_sm_get_h264_encoder_reference_list0( + struct ddl_buf_addr *shared_mem, + enum VIDC_SM_ref_picture *pe_luma_picture0, + u32 *pn_luma_picture_index0, + enum VIDC_SM_ref_picture *pe_luma_picture1, + u32 *pn_luma_picture_index1, + enum VIDC_SM_ref_picture *pe_chroma_picture0, + u32 *pn_chroma_picture_index0, + enum VIDC_SM_ref_picture *pe_chroma_picture1, + u32 *pn_chroma_picture_index1); + +void vidc_sm_get_h264_encoder_reference_list1( + struct ddl_buf_addr *shared_mem, + enum VIDC_SM_ref_picture *pe_luma_picture, + u32 *pn_luma_picture_index, + enum VIDC_SM_ref_picture *pe_chroma_picture, + u32 *pn_chroma_picture_index); +void vidc_sm_set_allocated_dpb_size(struct ddl_buf_addr *shared_mem, + u32 y_size, u32 c_size); +void vidc_sm_set_allocated_h264_mv_size(struct ddl_buf_addr *shared_mem, + u32 mv_size); +void vidc_sm_get_min_yc_dpb_sizes(struct ddl_buf_addr *shared_mem, + u32 *pn_min_luma_dpb_size, u32 *pn_min_chroma_dpb_size); +void vidc_sm_set_metadata_enable(struct ddl_buf_addr *shared_mem, + u32 extradata_enable, u32 qp_enable, u32 concealed_mb_enable, + u32 vc1Param_enable, u32 sei_nal_enable, u32 vui_enable, + u32 enc_slice_size_enable); +void vidc_sm_get_metadata_status(struct ddl_buf_addr *shared_mem, + u32 *pb_metadata_present); +void vidc_sm_get_metadata_display_index(struct ddl_buf_addr *shared_mem, + u32 *pn_dixplay_index); +void vidc_sm_set_metadata_start_address(struct ddl_buf_addr *shared_mem, + u32 address); +void vidc_sm_set_extradata_presence(struct ddl_buf_addr *shared_mem, + u32 extradata_present); +void vidc_sm_set_extradata_addr(struct ddl_buf_addr *shared_mem, + u32 extradata_addr); +void vidc_sm_set_pand_b_frame_qp(struct ddl_buf_addr *shared_mem, + u32 b_frame_qp, u32 p_frame_qp); +void vidc_sm_get_profile_info(struct ddl_buf_addr *shared_mem, + struct ddl_profile_info_type *ddl_profile_info); +void vidc_sm_set_encoder_new_bit_rate(struct ddl_buf_addr *shared_mem, + u32 new_bit_rate); +void vidc_sm_set_encoder_new_frame_rate(struct ddl_buf_addr *shared_mem, + u32 new_frame_rate); +void vidc_sm_set_encoder_new_i_period(struct ddl_buf_addr *shared_mem, + u32 new_i_period); +void vidc_sm_set_encoder_init_rc_value(struct ddl_buf_addr *shared_mem, + u32 new_rc_value); +void vidc_sm_set_idr_decode_only(struct ddl_buf_addr *shared_mem, + u32 enable); +void vidc_sm_set_concealment_color(struct ddl_buf_addr *shared_mem, + u32 conceal_ycolor, u32 conceal_ccolor); +void vidc_sm_set_chroma_addr_change(struct ddl_buf_addr *shared_mem, + u32 addr_change); +void vidc_sm_set_mpeg4_profile_override(struct ddl_buf_addr *shared_mem, + enum vidc_sm_mpeg4_profileinfo profile_info); +void vidc_sm_set_decoder_sei_enable(struct ddl_buf_addr *shared_mem, + u32 sei_enable); +void vidc_sm_get_decoder_sei_enable(struct ddl_buf_addr *shared_mem, + u32 *sei_enable); +void vidc_sm_set_error_concealment_config(struct ddl_buf_addr *shared_mem, + u32 inter_slice, u32 intra_slice, u32 conceal_config_enable); +void vidc_sm_set_decoder_stuff_bytes_consumption( + struct ddl_buf_addr *shared_mem, + enum vidc_sm_num_stuff_bytes_consume_info consume_info); +void vidc_sm_get_aspect_ratio_info(struct ddl_buf_addr *shared_mem, + struct vcd_aspect_ratio *aspect_ratio_info); +void vidc_sm_set_encoder_slice_batch_int_ctrl(struct ddl_buf_addr *shared_mem, + u32 slice_batch_int_enable); +void vidc_sm_get_num_slices_comp(struct ddl_buf_addr *shared_mem, + u32 *num_slices_comp); +void vidc_sm_set_encoder_batch_config(struct ddl_buf_addr *shared_mem, + u32 num_slices, + u32 input_addr, u32 output_addr, + u32 output_buffer_size); +void vidc_sm_get_encoder_batch_output_size(struct ddl_buf_addr *shared_mem, + u32 *output_buffer_size); +void vidc_sm_set_video_core_timeout_value(struct ddl_buf_addr *shared_mem, + u32 timeout); +#endif diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c new file mode 100644 index 000000000000..c74234c8325f --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c @@ -0,0 +1,518 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#include +#include +#include +#include +#include "vcd_ddl_utils.h" +#include "vcd_ddl.h" +#include "vcd_res_tracker_api.h" + +struct time_data { + unsigned int ddl_t1; + unsigned int ddl_ttotal; + unsigned int ddl_count; +}; +static struct time_data proc_time[MAX_TIME_DATA]; +#define DDL_MSG_TIME(x...) printk(KERN_DEBUG x) +static unsigned int vidc_mmu_subsystem[] = { + MSM_SUBSYSTEM_VIDEO, MSM_SUBSYSTEM_VIDEO_FWARE}; + +#ifdef DDL_BUF_LOG +static void ddl_print_buffer(struct ddl_context *ddl_context, + struct ddl_buf_addr *buf, u32 idx, u8 *str); +static void ddl_print_port(struct ddl_context *ddl_context, + struct ddl_buf_addr *buf); +static void ddl_print_buffer_port(struct ddl_context *ddl_context, + struct ddl_buf_addr *buf, u32 idx, u8 *str); +#endif +void *ddl_pmem_alloc(struct ddl_buf_addr *addr, size_t sz, u32 alignment) +{ + u32 alloc_size, offset = 0 ; + u32 index = 0; + struct ddl_context *ddl_context; + struct msm_mapped_buffer *mapped_buffer = NULL; + unsigned long iova = 0; + unsigned long buffer_size = 0; + unsigned long *kernel_vaddr = NULL; + unsigned long ionflag = 0; + unsigned long flags = 0; + int ret = 0; + ion_phys_addr_t phyaddr = 0; + size_t len = 0; + int rc = 0; + DBG_PMEM("\n%s() IN: Requested alloc size(%u)", __func__, (u32)sz); + if (!addr) { + DDL_MSG_ERROR("\n%s() Invalid Parameters", __func__); + goto bail_out; + } + ddl_context = ddl_get_context(); + res_trk_set_mem_type(addr->mem_type); + alloc_size = (sz + alignment); + if (res_trk_get_enable_ion()) { + if (!ddl_context->video_ion_client) + ddl_context->video_ion_client = + res_trk_get_ion_client(); + if (!ddl_context->video_ion_client) { + DDL_MSG_ERROR("%s() :DDL ION Client Invalid handle\n", + __func__); + goto bail_out; + } + alloc_size = (alloc_size+4095) & ~4095; + addr->alloc_handle = ion_alloc( + ddl_context->video_ion_client, alloc_size, SZ_4K, + res_trk_get_mem_type()); + if (IS_ERR_OR_NULL(addr->alloc_handle)) { + DDL_MSG_ERROR("%s() :DDL ION alloc failed\n", + __func__); + goto bail_out; + } + if (res_trk_check_for_sec_session() || + addr->mem_type == DDL_FW_MEM) + ionflag = UNCACHED; + else + ionflag = CACHED; + kernel_vaddr = (unsigned long *) ion_map_kernel( + ddl_context->video_ion_client, + addr->alloc_handle, ionflag); + if (IS_ERR_OR_NULL(kernel_vaddr)) { + DDL_MSG_ERROR("%s() :DDL ION map failed\n", + __func__); + goto free_ion_alloc; + } + addr->virtual_base_addr = (u8 *) kernel_vaddr; + if (res_trk_check_for_sec_session()) { + rc = ion_phys(ddl_context->video_ion_client, + addr->alloc_handle, &phyaddr, + &len); + if (rc || !phyaddr) { + DDL_MSG_ERROR( + "%s():DDL ION client physical failed\n", + __func__); + goto unmap_ion_alloc; + } + addr->alloced_phys_addr = phyaddr; + } else { + ret = ion_map_iommu(ddl_context->video_ion_client, + addr->alloc_handle, + VIDEO_DOMAIN, + VIDEO_MAIN_POOL, + SZ_4K, + 0, + &iova, + &buffer_size, + UNCACHED, 0); + if (ret) { + DDL_MSG_ERROR( + "%s():DDL ION ion map iommu failed\n", + __func__); + goto unmap_ion_alloc; + } + addr->alloced_phys_addr = (phys_addr_t) iova; + } + if (!addr->alloced_phys_addr) { + DDL_MSG_ERROR("%s():DDL ION client physical failed\n", + __func__); + goto unmap_ion_alloc; + } + addr->mapped_buffer = NULL; + addr->physical_base_addr = (u8 *) addr->alloced_phys_addr; + addr->align_physical_addr = (u8 *) DDL_ALIGN((u32) + addr->physical_base_addr, alignment); + offset = (u32)(addr->align_physical_addr - + addr->physical_base_addr); + addr->align_virtual_addr = addr->virtual_base_addr + offset; + addr->buffer_size = alloc_size; + } else { + addr->alloced_phys_addr = (phys_addr_t) + allocate_contiguous_memory_nomap(alloc_size, + res_trk_get_mem_type(), SZ_4K); + if (!addr->alloced_phys_addr) { + DDL_MSG_ERROR("%s() : acm alloc failed (%d)\n", + __func__, alloc_size); + goto bail_out; + } + flags = MSM_SUBSYSTEM_MAP_IOVA | MSM_SUBSYSTEM_MAP_KADDR; + if (alignment == DDL_KILO_BYTE(128)) + index = 1; + else if (alignment > SZ_4K) + flags |= MSM_SUBSYSTEM_ALIGN_IOVA_8K; + + addr->mapped_buffer = + msm_subsystem_map_buffer((unsigned long)addr->alloced_phys_addr, + alloc_size, flags, &vidc_mmu_subsystem[index], + sizeof(vidc_mmu_subsystem[index])/sizeof(unsigned int)); + if (IS_ERR(addr->mapped_buffer)) { + pr_err(" %s() buffer map failed", __func__); + goto free_acm_alloc; + } + mapped_buffer = addr->mapped_buffer; + if (!mapped_buffer->vaddr || !mapped_buffer->iova[0]) { + pr_err("%s() map buffers failed\n", __func__); + goto free_map_buffers; + } + addr->physical_base_addr = (u8 *)mapped_buffer->iova[0]; + addr->virtual_base_addr = mapped_buffer->vaddr; + addr->align_physical_addr = (u8 *) DDL_ALIGN((u32) + addr->physical_base_addr, alignment); + offset = (u32)(addr->align_physical_addr - + addr->physical_base_addr); + addr->align_virtual_addr = addr->virtual_base_addr + offset; + addr->buffer_size = sz; + } + return addr->virtual_base_addr; +free_map_buffers: + msm_subsystem_unmap_buffer(addr->mapped_buffer); + addr->mapped_buffer = NULL; +free_acm_alloc: + free_contiguous_memory_by_paddr( + (unsigned long)addr->alloced_phys_addr); + addr->alloced_phys_addr = (phys_addr_t)NULL; + return NULL; +unmap_ion_alloc: + ion_unmap_kernel(ddl_context->video_ion_client, + addr->alloc_handle); + addr->virtual_base_addr = NULL; + addr->alloced_phys_addr = (phys_addr_t)NULL; +free_ion_alloc: + ion_free(ddl_context->video_ion_client, + addr->alloc_handle); + addr->alloc_handle = NULL; +bail_out: + return NULL; +} + +void ddl_pmem_free(struct ddl_buf_addr *addr) +{ + struct ddl_context *ddl_context; + ddl_context = ddl_get_context(); + if (!addr) { + pr_err("%s() invalid args\n", __func__); + return; + } + if (ddl_context->video_ion_client) { + if (!IS_ERR_OR_NULL(addr->alloc_handle)) { + ion_unmap_kernel(ddl_context->video_ion_client, + addr->alloc_handle); + if (!res_trk_check_for_sec_session()) { + ion_unmap_iommu(ddl_context->video_ion_client, + addr->alloc_handle, + VIDEO_DOMAIN, + VIDEO_MAIN_POOL); + } + ion_free(ddl_context->video_ion_client, + addr->alloc_handle); + } + } else { + if (addr->mapped_buffer) + msm_subsystem_unmap_buffer(addr->mapped_buffer); + if (addr->alloced_phys_addr) + free_contiguous_memory_by_paddr( + (unsigned long)addr->alloced_phys_addr); + } + memset(addr, 0, sizeof(struct ddl_buf_addr)); +} + +#ifdef DDL_BUF_LOG + +static void ddl_print_buffer(struct ddl_context *ddl_context, + struct ddl_buf_addr *buf, u32 idx, u8 *str) +{ + struct ddl_buf_addr *base_ram; + s32 offset; + size_t sz, KB = 0; + + base_ram = &ddl_context->dram_base_a; + offset = (s32) DDL_ADDR_OFFSET(*base_ram, *buf); + sz = buf->buffer_size; + if (sz > 0) { + if (!(sz % 1024)) { + sz /= 1024; + KB++; + if (!(sz % 1024)) { + sz /= 1024; + KB++; + } + } + } + DDL_MSG_LOW("\n%12s [%2d]: 0x%08x [0x%04x], 0x%08x(%d%s), %s", + str, idx, (u32) buf->align_physical_addr, + (offset > 0) ? offset : 0, buf->buffer_size, sz, + ((2 == KB) ? "MB" : (1 == KB) ? "KB" : ""), + (((u32) buf->virtual_base_addr) ? "Alloc" : "")); +} + +static void ddl_print_port(struct ddl_context *ddl_context, + struct ddl_buf_addr *buf) +{ + struct ddl_buf_addr *a = &ddl_context->dram_base_a; + struct ddl_buf_addr *b = &ddl_context->dram_base_b; + + if (!buf->align_physical_addr || !buf->buffer_size) + return; + if (buf->align_physical_addr >= a->align_physical_addr && + buf->align_physical_addr + buf->buffer_size <= + a->align_physical_addr + a->buffer_size) + DDL_MSG_LOW(" -A [0x%x]-", DDL_ADDR_OFFSET(*a, *buf)); + else if (buf->align_physical_addr >= b->align_physical_addr && + buf->align_physical_addr + buf->buffer_size <= + b->align_physical_addr + b->buffer_size) + DDL_MSG_LOW(" -B [0x%x]-", DDL_ADDR_OFFSET(*b, *buf)); + else + DDL_MSG_LOW(" -?-"); +} + +static void ddl_print_buffer_port(struct ddl_context *ddl_context, + struct ddl_buf_addr *buf, u32 idx, u8 *str) +{ + DDL_MSG_LOW("\n"); + ddl_print_buffer(ddl_context, buf, idx, str); + ddl_print_port(ddl_context, buf); +} + +void ddl_list_buffers(struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context; + u32 i; + + ddl_context = ddl->ddl_context; + DDL_MSG_LOW("\n\n"); + DDL_MSG_LOW("\n Buffer : Start [offs], Size \ + (Size), Alloc/Port"); + DDL_MSG_LOW("\n-------------------------------------------------------\ + -------------------------"); + ddl_print_buffer(ddl_context, &ddl_context->dram_base_a, 0, + "dram_base_a"); + ddl_print_buffer(ddl_context, &ddl_context->dram_base_b, 0, + "dram_base_b"); + if (ddl->codec_data.hdr.decoding) { + struct ddl_dec_buffers *dec_bufs = + &ddl->codec_data.decoder.hw_bufs; + for (i = 0; i < 32; i++) + ddl_print_buffer_port(ddl_context, + &dec_bufs->h264Mv[i], i, "h264Mv"); + ddl_print_buffer_port(ddl_context, + &dec_bufs->h264Vert_nb_mv, 0, "h264Vert_nb_mv"); + ddl_print_buffer_port(ddl_context, + &dec_bufs->h264Nb_ip, 0, "h264Nb_ip"); + ddl_print_buffer_port(ddl_context, + &dec_bufs->nb_dcac, 0, "nb_dcac"); + ddl_print_buffer_port(ddl_context, + &dec_bufs->upnb_mv, 0, "upnb_mv"); + ddl_print_buffer_port(ddl_context, + &dec_bufs->sub_anchor_mv, 0, "sub_anchor_mv"); + ddl_print_buffer_port(ddl_context, + &dec_bufs->overlay_xform, 0, "overlay_xform"); + ddl_print_buffer_port(ddl_context, + &dec_bufs->bit_plane3, 0, "bit_plane3"); + ddl_print_buffer_port(ddl_context, + &dec_bufs->bit_plane2, 0, "bit_plane2"); + ddl_print_buffer_port(ddl_context, + &dec_bufs->bit_plane1, 0, "bit_plane1"); + ddl_print_buffer_port(ddl_context, + dec_bufs->stx_parser, 0, "stx_parser"); + ddl_print_buffer_port(ddl_context, + &dec_bufs->desc, 0, "desc"); + ddl_print_buffer_port(ddl_context, + &dec_bufs->context, 0, "context"); + } else { + struct ddl_enc_buffers *enc_bufs = + &ddl->codec_data.encoder.hw_bufs; + + for (i = 0; i < 4; i++) + ddl_print_buffer_port(ddl_context, + &enc_bufs->dpb_y[i], i, "dpb_y"); + for (i = 0; i < 4; i++) + ddl_print_buffer_port(ddl_context, + &enc_bufs->dpb_c[i], i, "dpb_c"); + ddl_print_buffer_port(ddl_context, &enc_bufs->mv, 0, "mv"); + ddl_print_buffer_port(ddl_context, + &enc_bufs->col_zero, 0, "col_zero"); + ddl_print_buffer_port(ddl_context, &enc_bufs->md, 0, "md"); + ddl_print_buffer_port(ddl_context, + &enc_bufs->pred, 0, "pred"); + ddl_print_buffer_port(ddl_context, + &enc_bufs->nbor_info, 0, "nbor_info"); + ddl_print_buffer_port(ddl_context, + &enc_bufs->acdc_coef, 0, "acdc_coef"); + ddl_print_buffer_port(ddl_context, + &enc_bufs->context, 0, "context"); + } +} +#endif + +u32 ddl_fw_init(struct ddl_buf_addr *dram_base) +{ + u8 *dest_addr; + dest_addr = DDL_GET_ALIGNED_VITUAL(*dram_base); + DDL_MSG_LOW("FW Addr / FW Size : %x/%d", (u32)vidc_video_codec_fw, + vidc_video_codec_fw_size); + if (res_trk_check_for_sec_session() && res_trk_is_cp_enabled()) { + if (res_trk_enable_footswitch()) { + pr_err("Failed to enable footswitch"); + return false; + } + if (res_trk_enable_iommu_clocks()) { + res_trk_disable_footswitch(); + pr_err("Failed to enable iommu clocks\n"); + return false; + } + dram_base->pil_cookie = pil_get("vidc"); + if (res_trk_disable_iommu_clocks()) + pr_err("Failed to disable iommu clocks\n"); + if (IS_ERR_OR_NULL(dram_base->pil_cookie)) { + res_trk_disable_footswitch(); + pr_err("pil_get failed\n"); + return false; + } + } else { + if (vidc_video_codec_fw_size > dram_base->buffer_size || + !vidc_video_codec_fw) + return false; + memcpy(dest_addr, vidc_video_codec_fw, + vidc_video_codec_fw_size); + } + return true; +} + +void ddl_fw_release(struct ddl_buf_addr *dram_base) +{ + void *cookie = dram_base->pil_cookie; + if (res_trk_is_cp_enabled() && + res_trk_check_for_sec_session()) { + res_trk_close_secure_session(); + if (IS_ERR_OR_NULL(cookie)) { + pr_err("Invalid params"); + return; + } + if (res_trk_enable_footswitch()) { + pr_err("Failed to enable footswitch"); + return; + } + if (res_trk_enable_iommu_clocks()) { + res_trk_disable_footswitch(); + pr_err("Failed to enable iommu clocks\n"); + return; + } + pil_put(cookie); + if (res_trk_disable_iommu_clocks()) + pr_err("Failed to disable iommu clocks\n"); + if (res_trk_disable_footswitch()) + pr_err("Failed to disable footswitch\n"); + } else { + if (res_trk_check_for_sec_session()) + res_trk_close_secure_session(); + res_trk_release_fw_addr(); + } +} + +void ddl_set_core_start_time(const char *func_name, u32 index) +{ + u32 act_time; + struct timeval ddl_tv; + struct time_data *time_data = &proc_time[index]; + do_gettimeofday(&ddl_tv); + act_time = (ddl_tv.tv_sec * 1000) + (ddl_tv.tv_usec / 1000); + if (!time_data->ddl_t1) { + time_data->ddl_t1 = act_time; + DDL_MSG_LOW("\n%s(): Start Time (%u)", func_name, act_time); + } else if (vidc_msg_timing) { + DDL_MSG_TIME("\n%s(): Timer already started! St(%u) Act(%u)", + func_name, time_data->ddl_t1, act_time); + } +} + +void ddl_calc_core_proc_time(const char *func_name, u32 index, + struct ddl_client_context *ddl) +{ + struct time_data *time_data = &proc_time[index]; + struct ddl_decoder_data *decoder = NULL; + if (time_data->ddl_t1) { + int ddl_t2; + struct timeval ddl_tv; + do_gettimeofday(&ddl_tv); + ddl_t2 = (ddl_tv.tv_sec * 1000) + (ddl_tv.tv_usec / 1000); + time_data->ddl_ttotal += (ddl_t2 - time_data->ddl_t1); + time_data->ddl_count++; + if (vidc_msg_timing) { + DDL_MSG_TIME("\n%s(): cnt(%u) End Time (%u)" + "Diff(%u) Avg(%u)", + func_name, time_data->ddl_count, ddl_t2, + ddl_t2 - time_data->ddl_t1, + time_data->ddl_ttotal/time_data->ddl_count); + } + if ((index == DEC_OP_TIME) && (time_data->ddl_count > 2) && + (time_data->ddl_count < 6)) { + decoder = &(ddl->codec_data.decoder); + decoder->dec_time_sum = decoder->dec_time_sum + + ddl_t2 - time_data->ddl_t1; + if (time_data->ddl_count == 5) + decoder->avg_dec_time = + decoder->dec_time_sum / 3; + } + time_data->ddl_t1 = 0; + } +} + +void ddl_calc_core_proc_time_cnt(const char *func_name, u32 index, u32 count) +{ + struct time_data *time_data = &proc_time[index]; + if (time_data->ddl_t1) { + int ddl_t2; + struct timeval ddl_tv; + do_gettimeofday(&ddl_tv); + ddl_t2 = (ddl_tv.tv_sec * 1000) + (ddl_tv.tv_usec / 1000); + time_data->ddl_ttotal += (ddl_t2 - time_data->ddl_t1); + time_data->ddl_count += count; + DDL_MSG_TIME("\n%s(): cnt(%u) End Time (%u) Diff(%u) Avg(%u)", + func_name, time_data->ddl_count, ddl_t2, + ddl_t2 - time_data->ddl_t1, + time_data->ddl_ttotal/time_data->ddl_count); + time_data->ddl_t1 = 0; + } +} + +void ddl_update_core_start_time(const char *func_name, u32 index) +{ + u32 act_time; + struct timeval ddl_tv; + struct time_data *time_data = &proc_time[index]; + do_gettimeofday(&ddl_tv); + act_time = (ddl_tv.tv_sec * 1000) + (ddl_tv.tv_usec / 1000); + time_data->ddl_t1 = act_time; + DDL_MSG_LOW("\n%s(): Start time updated Act(%u)", + func_name, act_time); +} + +void ddl_reset_core_time_variables(u32 index) +{ + proc_time[index].ddl_t1 = 0; + proc_time[index].ddl_ttotal = 0; + proc_time[index].ddl_count = 0; +} + +int ddl_get_core_decode_proc_time(u32 *ddl_handle) +{ + int avg_time = 0; + struct ddl_client_context *ddl = + (struct ddl_client_context *) ddl_handle; + avg_time = ddl_vidc_decode_get_avg_time(ddl); + return avg_time; +} + +void ddl_reset_avg_dec_time(u32 *ddl_handle) +{ + struct ddl_client_context *ddl = + (struct ddl_client_context *) ddl_handle; + ddl_vidc_decode_reset_avg_time(ddl); +} diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h new file mode 100644 index 000000000000..565fa93c937b --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.h @@ -0,0 +1,78 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#ifndef _VCD_DDL_UTILS_H_ +#define _VCD_DDL_UTILS_H_ + +#include +#include + +extern u32 vidc_msg_pmem; +extern u32 vidc_msg_timing; + +enum timing_data { + DEC_OP_TIME, + DEC_IP_TIME, + ENC_OP_TIME, + ENC_SLICE_OP_TIME, + MAX_TIME_DATA +}; + +#define DBG_PMEM(x...) \ +do { \ + if (vidc_msg_pmem) \ + printk(KERN_DEBUG x); \ +} while (0) + +#ifdef DDL_MSG_LOG +#define DDL_MSG_LOW(x...) printk(KERN_INFO x) +#define DDL_MSG_MED(x...) printk(KERN_INFO x) +#define DDL_MSG_HIGH(x...) printk(KERN_INFO x) +#else +#define DDL_MSG_LOW(x...) +#define DDL_MSG_MED(x...) +#define DDL_MSG_HIGH(x...) +#endif + +#define DDL_MSG_ERROR(x...) printk(KERN_INFO x) +#define DDL_MSG_FATAL(x...) printk(KERN_INFO x) + +#define DDL_ALIGN_SIZE(sz, guard_bytes, align_mask) \ + (((u32)(sz) + guard_bytes) & align_mask) +#define DDL_ADDR_IS_ALIGNED(addr, align_bytes) \ + (!((u32)(addr) & ((align_bytes) - 1))) +#define DDL_ALIGN(val, grid) ((!(grid)) ? (val) : \ + ((((val) + (grid) - 1) / (grid)) * (grid))) +#define DDL_ALIGN_FLOOR(val, grid) ((!(grid)) ? (val) : \ + (((val) / (grid)) * (grid))) +#define DDL_OFFSET(base, addr) ((!(addr)) ? 0 : (u32)((u8 *) \ + (addr) - (u8 *) (base))) +#define DDL_ADDR_OFFSET(base, addr) DDL_OFFSET((base).align_physical_addr, \ + (addr).align_physical_addr) +#define DDL_GET_ALIGNED_VITUAL(x) ((x).align_virtual_addr) +#define DDL_KILO_BYTE(x) ((x)*1024) +#define DDL_MEGA_BYTE(x) ((x)*1024*1024) +#define DDL_FRAMERATE_SCALE(x) ((x) * 1000) + +#define DDL_MIN(x, y) ((x < y) ? x : y) +#define DDL_MAX(x, y) ((x > y) ? x : y) +#define DDL_MEMCPY(dest, src, len) memcpy((dest), (src), (len)) +#define DDL_MEMSET(src, value, len) memset((src), (value), (len)) + +void ddl_set_core_start_time(const char *func_name, u32 index); +void ddl_reset_core_time_variables(u32 index); +void ddl_calc_core_proc_time_cnt(const char *func_name, u32 index, u32 count); +void ddl_update_core_start_time(const char *func_name, u32 index); +int ddl_get_core_decode_proc_time(u32 *ddl_handle); +void ddl_reset_avg_dec_time(u32 *ddl_handle); +#endif diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c new file mode 100644 index 000000000000..6c2fa5e0fddd --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_vidc.c @@ -0,0 +1,1182 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#include "vcd_ddl.h" +#include "vcd_ddl_metadata.h" +#include "vcd_ddl_shared_mem.h" +#include "vcd_core.h" + +#if defined(PIX_CACHE_DISABLE) +#define DDL_PIX_CACHE_ENABLE false +#else +#define DDL_PIX_CACHE_ENABLE true +#endif +static unsigned int run_cnt; + +void ddl_vidc_core_init(struct ddl_context *ddl_context) +{ + struct vidc_1080P_pix_cache_config pixel_cache_config; + + vidc_1080p_do_sw_reset(VIDC_1080P_RESET_IN_SEQ_FIRST_STAGE); + msleep(DDL_SW_RESET_SLEEP); + vidc_1080p_do_sw_reset(VIDC_1080P_RESET_IN_SEQ_SECOND_STAGE); + vidc_1080p_init_memory_controller( + (u32) ddl_context->dram_base_a.align_physical_addr, + (u32) ddl_context->dram_base_b.align_physical_addr); + vidc_1080p_clear_returned_channel_inst_id(); + ddl_context->vidc_decode_seq_start[0] = + vidc_1080p_decode_seq_start_ch0; + ddl_context->vidc_decode_seq_start[1] = + vidc_1080p_decode_seq_start_ch1; + ddl_context->vidc_decode_init_buffers[0] = + vidc_1080p_decode_init_buffers_ch0; + ddl_context->vidc_decode_init_buffers[1] = + vidc_1080p_decode_init_buffers_ch1; + ddl_context->vidc_decode_frame_start[0] = + vidc_1080p_decode_frame_start_ch0; + ddl_context->vidc_decode_frame_start[1] = + vidc_1080p_decode_frame_start_ch1; + ddl_context->vidc_set_dec_resolution[0] = + vidc_1080p_set_dec_resolution_ch0; + ddl_context->vidc_set_dec_resolution[1] = + vidc_1080p_set_dec_resolution_ch1; + ddl_context->vidc_encode_seq_start[0] = + vidc_1080p_encode_seq_start_ch0; + ddl_context->vidc_encode_seq_start[1] = + vidc_1080p_encode_seq_start_ch1; + ddl_context->vidc_encode_frame_start[0] = + vidc_1080p_encode_frame_start_ch0; + ddl_context->vidc_encode_frame_start[1] = + vidc_1080p_encode_frame_start_ch1; + ddl_context->vidc_encode_slice_batch_start[0] = + vidc_1080p_encode_slice_batch_start_ch0; + ddl_context->vidc_encode_slice_batch_start[1] = + vidc_1080p_encode_slice_batch_start_ch1; + vidc_1080p_release_sw_reset(); + ddl_context->pix_cache_enable = DDL_PIX_CACHE_ENABLE; + if (ddl_context->pix_cache_enable) { + vidc_pix_cache_sw_reset(); + pixel_cache_config.cache_enable = true; + pixel_cache_config.prefetch_en = true; + pixel_cache_config.port_select = VIDC_1080P_PIX_CACHE_PORT_B; + pixel_cache_config.statistics_off = true; + pixel_cache_config.page_size = + VIDC_1080P_PIX_CACHE_PAGE_SIZE_1K; + vidc_pix_cache_init_config(&pixel_cache_config); + } +} + +void ddl_vidc_core_term(struct ddl_context *ddl_context) +{ + if (ddl_context->pix_cache_enable) { + u32 pix_cache_idle = false; + u32 counter = 0; + + vidc_pix_cache_set_halt(true); + + do { + msleep(DDL_SW_RESET_SLEEP); + vidc_pix_cache_get_status_idle(&pix_cache_idle); + counter++; + } while (!pix_cache_idle && + counter < DDL_PIXEL_CACHE_STATUS_READ_RETRY); + + if (!pix_cache_idle) { + ddl_context->cmd_err_status = + DDL_PIXEL_CACHE_NOT_IDLE; + ddl_handle_core_errors(ddl_context); + } + } +} + +void ddl_vidc_channel_set(struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + enum vcd_codec *vcd_codec; + enum vidc_1080p_codec codec = VIDC_1080P_H264_DECODE; + const enum vidc_1080p_decode_p_cache_enable + dec_pix_cache = VIDC_1080P_DECODE_PCACHE_DISABLE; + const enum vidc_1080p_encode_p_cache_enable + enc_pix_cache = VIDC_1080P_ENCODE_PCACHE_ENABLE; + u32 pix_cache_ctrl, ctxt_mem_offset, ctxt_mem_size; + + if (ddl->decoding) { + ddl_set_core_start_time(__func__, DEC_OP_TIME); + vcd_codec = &(ddl->codec_data.decoder.codec.codec); + pix_cache_ctrl = (u32)dec_pix_cache; + ctxt_mem_offset = DDL_ADDR_OFFSET(ddl_context->dram_base_a, + ddl->codec_data.decoder.hw_bufs.context) >> 11; + ctxt_mem_size = + ddl->codec_data.decoder.hw_bufs.context.buffer_size; + } else { + vcd_codec = &(ddl->codec_data.encoder.codec.codec); + pix_cache_ctrl = (u32)enc_pix_cache; + ctxt_mem_offset = DDL_ADDR_OFFSET(ddl_context->dram_base_a, + ddl->codec_data.encoder.hw_bufs.context) >> 11; + ctxt_mem_size = + ddl->codec_data.encoder.hw_bufs.context.buffer_size; + } + switch (*vcd_codec) { + default: + case VCD_CODEC_MPEG4: + if (ddl->decoding) + codec = VIDC_1080P_MPEG4_DECODE; + else + codec = VIDC_1080P_MPEG4_ENCODE; + break; + case VCD_CODEC_H264: + if (ddl->decoding) + codec = VIDC_1080P_H264_DECODE; + else + codec = VIDC_1080P_H264_ENCODE; + break; + case VCD_CODEC_DIVX_3: + if (ddl->decoding) + codec = VIDC_1080P_DIVX311_DECODE; + break; + case VCD_CODEC_DIVX_4: + if (ddl->decoding) + codec = VIDC_1080P_DIVX412_DECODE; + break; + case VCD_CODEC_DIVX_5: + if (ddl->decoding) + codec = VIDC_1080P_DIVX502_DECODE; + break; + case VCD_CODEC_DIVX_6: + if (ddl->decoding) + codec = VIDC_1080P_DIVX503_DECODE; + break; + case VCD_CODEC_XVID: + if (ddl->decoding) + codec = VIDC_1080P_MPEG4_DECODE; + break; + case VCD_CODEC_H263: + if (ddl->decoding) + codec = VIDC_1080P_H263_DECODE; + else + codec = VIDC_1080P_H263_ENCODE; + break; + case VCD_CODEC_MPEG1: + case VCD_CODEC_MPEG2: + if (ddl->decoding) + codec = VIDC_1080P_MPEG2_DECODE; + break; + case VCD_CODEC_VC1: + if (ddl->decoding) + codec = VIDC_1080P_VC1_DECODE; + break; + case VCD_CODEC_VC1_RCV: + if (ddl->decoding) + codec = VIDC_1080P_VC1_RCV_DECODE; + break; + } + ddl->cmd_state = DDL_CMD_CHANNEL_SET; + DDL_MSG_LOW("ddl_state_transition: %s ~~> DDL_CLIENT_WAIT_FOR_CHDONE", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_CHDONE; + vidc_1080p_set_host2risc_cmd(VIDC_1080P_HOST2RISC_CMD_OPEN_CH, + (u32)codec, pix_cache_ctrl, ctxt_mem_offset, + ctxt_mem_size); +} + +void ddl_vidc_decode_init_codec(struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + struct vidc_1080p_dec_seq_start_param seq_start_param; + u32 seq_size; + + ddl_set_core_start_time(__func__, DEC_OP_TIME); + vidc_1080p_set_decode_mpeg4_pp_filter(decoder->post_filter.post_filter); + vidc_sm_set_concealment_color(&ddl->shared_mem[ddl->command_channel], + DDL_CONCEALMENT_Y_COLOR, DDL_CONCEALMENT_C_COLOR); + + vidc_sm_set_error_concealment_config( + &ddl->shared_mem[ddl->command_channel], + VIDC_SM_ERR_CONCEALMENT_INTER_SLICE_MB_COPY, + VIDC_SM_ERR_CONCEALMENT_INTRA_SLICE_COLOR_CONCEALMENT, + VIDC_SM_ERR_CONCEALMENT_ENABLE); + + ddl_vidc_metadata_enable(ddl); + vidc_sm_set_metadata_start_address(&ddl->shared_mem + [ddl->command_channel], + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + ddl->codec_data.decoder.meta_data_input)); + + vidc_sm_set_idr_decode_only(&ddl->shared_mem[ddl->command_channel], + decoder->idr_only_decoding); + + if ((decoder->codec.codec == VCD_CODEC_DIVX_3) || + (decoder->codec.codec == VCD_CODEC_VC1_RCV || + decoder->codec.codec == VCD_CODEC_VC1)) + ddl_context->vidc_set_dec_resolution + [ddl->command_channel](decoder->client_frame_size.width, + decoder->client_frame_size.height); + else + ddl_context->vidc_set_dec_resolution + [ddl->command_channel](0x0, 0x0); + DDL_MSG_LOW("HEADER-PARSE-START"); + DDL_MSG_LOW("ddl_state_transition: %s ~~>" + "DDL_CLIENT_WAIT_FOR_INITCODECDONE", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_INITCODECDONE; + ddl->cmd_state = DDL_CMD_HEADER_PARSE; + seq_start_param.cmd_seq_num = ++ddl_context->cmd_seq_num; + seq_start_param.inst_id = ddl->instance_id; + seq_start_param.shared_mem_addr_offset = DDL_ADDR_OFFSET( + ddl_context->dram_base_a, ddl->shared_mem + [ddl->command_channel]); + seq_start_param.stream_buffer_addr_offset = + DDL_OFFSET(ddl_context->dram_base_a.align_physical_addr, + decoder->decode_config.sequence_header); + seq_start_param.stream_buffersize = + decoder->client_input_buf_req.sz; + seq_size = decoder->decode_config.sequence_header_len + + DDL_LINEAR_BUFFER_ALIGN_BYTES + VCD_SEQ_HDR_PADDING_BYTES; + if (seq_start_param.stream_buffersize < seq_size) + seq_start_param.stream_buffersize = seq_size; + seq_start_param.stream_frame_size = + decoder->decode_config.sequence_header_len; + seq_start_param.descriptor_buffer_addr_offset = + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + decoder->hw_bufs.desc), + seq_start_param.descriptor_buffer_size = + decoder->hw_bufs.desc.buffer_size; + if ((decoder->codec.codec == VCD_CODEC_MPEG4) || + (decoder->codec.codec == VCD_CODEC_DIVX_4) || + (decoder->codec.codec == VCD_CODEC_DIVX_5) || + (decoder->codec.codec == VCD_CODEC_DIVX_6) || + (decoder->codec.codec == VCD_CODEC_XVID)) + vidc_sm_set_mpeg4_profile_override( + &ddl->shared_mem[ddl->command_channel], + VIDC_SM_PROFILE_INFO_ASP); + if (VCD_CODEC_H264 == decoder->codec.codec) + vidc_sm_set_decoder_sei_enable( + &ddl->shared_mem[ddl->command_channel], + VIDC_SM_RECOVERY_POINT_SEI); + ddl_context->vidc_decode_seq_start[ddl->command_channel]( + &seq_start_param); + + vidc_sm_set_decoder_stuff_bytes_consumption( + &ddl->shared_mem[ddl->command_channel], + VIDC_SM_NUM_STUFF_BYTES_CONSUME_NONE); +} + +void ddl_vidc_decode_dynamic_property(struct ddl_client_context *ddl, + u32 enable) +{ + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + struct vcd_frame_data *bit_stream = + &(ddl->input_frame.vcd_frm); + struct ddl_context *ddl_context = ddl->ddl_context; + + if (!enable) { + if (decoder->dynmic_prop_change_req) + decoder->dynmic_prop_change_req = false; + return; + } + if ((decoder->dynamic_prop_change & DDL_DEC_REQ_OUTPUT_FLUSH)) { + decoder->dynmic_prop_change_req = true; + decoder->dynamic_prop_change &= ~(DDL_DEC_REQ_OUTPUT_FLUSH); + decoder->dpb_mask.hw_mask = 0; + decoder->flush_pending = true; + } + if (((decoder->meta_data_enable_flag & VCD_METADATA_PASSTHROUGH)) && + ((VCD_FRAME_FLAG_EXTRADATA & bit_stream->flags))) { + u32 extradata_presence = true; + u8* tmp = ((u8 *) bit_stream->physical + + bit_stream->offset + + bit_stream->data_len + 3); + u32 extra_data_start = (u32) ((u32)tmp & ~3); + + extra_data_start = extra_data_start - + (u32)ddl_context->dram_base_a.align_physical_addr; + decoder->dynmic_prop_change_req = true; + vidc_sm_set_extradata_addr(&ddl->shared_mem + [ddl->command_channel], extra_data_start); + vidc_sm_set_extradata_presence(&ddl->shared_mem + [ddl->command_channel], extradata_presence); + } +} + +void ddl_vidc_encode_dynamic_property(struct ddl_client_context *ddl, + u32 enable) +{ + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + u32 frame_rate_change = false, bit_rate_change = false; + u32 i_period_change = false, reset_req = false; + + if (!enable) { + if (encoder->dynmic_prop_change_req) { + reset_req = true; + encoder->dynmic_prop_change_req = false; + } + } else { + if ((encoder->dynamic_prop_change & DDL_ENC_REQ_IFRAME)) { + encoder->intra_frame_insertion = true; + encoder->dynamic_prop_change &= + ~(DDL_ENC_REQ_IFRAME); + } + if ((encoder->dynamic_prop_change & + DDL_ENC_CHANGE_BITRATE)) { + bit_rate_change = true; + vidc_sm_set_encoder_new_bit_rate( + &ddl->shared_mem[ddl->command_channel], + encoder->target_bit_rate.target_bitrate); + encoder->dynamic_prop_change &= + ~(DDL_ENC_CHANGE_BITRATE); + } + if ((encoder->dynamic_prop_change + & DDL_ENC_CHANGE_IPERIOD)) { + i_period_change = true; + vidc_sm_set_encoder_new_i_period( + &ddl->shared_mem[ddl->command_channel], + encoder->i_period.p_frames); + encoder->dynamic_prop_change &= + ~(DDL_ENC_CHANGE_IPERIOD); + } + if ((encoder->dynamic_prop_change + & DDL_ENC_CHANGE_FRAMERATE)) { + frame_rate_change = true; + vidc_sm_set_encoder_new_frame_rate( + &ddl->shared_mem[ddl->command_channel], + (u32)(DDL_FRAMERATE_SCALE(encoder->\ + frame_rate.fps_numerator) / + encoder->frame_rate.fps_denominator)); + encoder->dynamic_prop_change &= + ~(DDL_ENC_CHANGE_FRAMERATE); + } + } + if ((enable) || (reset_req)) { + vidc_sm_set_encoder_param_change( + &ddl->shared_mem[ddl->command_channel], + bit_rate_change, frame_rate_change, + i_period_change); + } +} + +static void ddl_vidc_encode_set_profile_level( + struct ddl_client_context *ddl) +{ + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + u32 encode_profile, level = 0; + + switch (encoder->profile.profile) { + default: + case VCD_PROFILE_MPEG4_SP: + encode_profile = VIDC_1080P_PROFILE_MPEG4_SIMPLE; + break; + case VCD_PROFILE_MPEG4_ASP: + encode_profile = VIDC_1080P_PROFILE_MPEG4_ADV_SIMPLE; + break; + case VCD_PROFILE_H264_BASELINE: + encode_profile = VIDC_1080P_PROFILE_H264_BASELINE; + break; + case VCD_PROFILE_H264_MAIN: + encode_profile = VIDC_1080P_PROFILE_H264_MAIN; + break; + case VCD_PROFILE_H264_HIGH: + encode_profile = VIDC_1080P_PROFILE_H264_HIGH; + break; + } + switch (encoder->level.level) { + default: + case VCD_LEVEL_MPEG4_0: + level = VIDC_1080P_MPEG4_LEVEL0; + break; + case VCD_LEVEL_MPEG4_0b: + level = VIDC_1080P_MPEG4_LEVEL0b; + break; + case VCD_LEVEL_MPEG4_1: + level = VIDC_1080P_MPEG4_LEVEL1; + break; + case VCD_LEVEL_MPEG4_2: + level = VIDC_1080P_MPEG4_LEVEL2; + break; + case VCD_LEVEL_MPEG4_3: + level = VIDC_1080P_MPEG4_LEVEL3; + break; + case VCD_LEVEL_MPEG4_3b: + level = VIDC_1080P_MPEG4_LEVEL3b; + break; + case VCD_LEVEL_MPEG4_4: + level = VIDC_1080P_MPEG4_LEVEL4; + break; + case VCD_LEVEL_MPEG4_4a: + level = VIDC_1080P_MPEG4_LEVEL4a; + break; + case VCD_LEVEL_MPEG4_5: + level = VIDC_1080P_MPEG4_LEVEL5; + break; + case VCD_LEVEL_MPEG4_6: + level = VIDC_1080P_MPEG4_LEVEL6; + break; + case VCD_LEVEL_MPEG4_7: + level = VIDC_1080P_MPEG4_LEVEL7; + break; + case VCD_LEVEL_H264_1: + level = VIDC_1080P_H264_LEVEL1; + break; + case VCD_LEVEL_H264_1b: + level = VIDC_1080P_H264_LEVEL1b; + break; + case VCD_LEVEL_H264_1p1: + level = VIDC_1080P_H264_LEVEL1p1; + break; + case VCD_LEVEL_H264_1p2: + level = VIDC_1080P_H264_LEVEL1p2; + break; + case VCD_LEVEL_H264_1p3: + level = VIDC_1080P_H264_LEVEL1p3; + break; + case VCD_LEVEL_H264_2: + level = VIDC_1080P_H264_LEVEL2; + break; + case VCD_LEVEL_H264_2p1: + level = VIDC_1080P_H264_LEVEL2p1; + break; + case VCD_LEVEL_H264_2p2: + level = VIDC_1080P_H264_LEVEL2p2; + break; + case VCD_LEVEL_H264_3: + level = VIDC_1080P_H264_LEVEL3; + break; + case VCD_LEVEL_H264_3p1: + level = VIDC_1080P_H264_LEVEL3p1; + break; + case VCD_LEVEL_H264_3p2: + level = VIDC_1080P_H264_LEVEL3p2; + break; + case VCD_LEVEL_H264_4: + level = VIDC_1080P_H264_LEVEL4; + break; + case VCD_LEVEL_H263_10: + level = VIDC_1080P_H263_LEVEL10; + break; + case VCD_LEVEL_H263_20: + level = VIDC_1080P_H263_LEVEL20; + break; + case VCD_LEVEL_H263_30: + level = VIDC_1080P_H263_LEVEL30; + break; + case VCD_LEVEL_H263_40: + level = VIDC_1080P_H263_LEVEL40; + break; + case VCD_LEVEL_H263_45: + level = VIDC_1080P_H263_LEVEL45; + break; + case VCD_LEVEL_H263_50: + level = VIDC_1080P_H263_LEVEL50; + break; + case VCD_LEVEL_H263_60: + level = VIDC_1080P_H263_LEVEL60; + break; + case VCD_LEVEL_H263_70: + level = VIDC_1080P_H263_LEVEL70; + break; + } + vidc_1080p_set_encode_profile_level(encode_profile, level); +} + +static void ddl_vidc_encode_set_multi_slice_info( + struct ddl_encoder_data *encoder) +{ + enum vidc_1080p_MSlice_selection m_slice_sel; + u32 i_multi_slice_size = 0, i_multi_slice_byte = 0; + + if (!encoder) { + DDL_MSG_ERROR("Invalid Parameter"); + return; + } + + switch (encoder->multi_slice.m_slice_sel) { + default: + case VCD_MSLICE_OFF: + m_slice_sel = VIDC_1080P_MSLICE_DISABLE; + break; + case VCD_MSLICE_BY_GOB: + case VCD_MSLICE_BY_MB_COUNT: + m_slice_sel = VIDC_1080P_MSLICE_BY_MB_COUNT; + i_multi_slice_size = encoder->multi_slice.m_slice_size; + break; + case VCD_MSLICE_BY_BYTE_COUNT: + m_slice_sel = VIDC_1080P_MSLICE_BY_BYTE_COUNT; + i_multi_slice_byte = encoder->multi_slice.m_slice_size; + break; + } + vidc_1080p_set_encode_multi_slice_control(m_slice_sel, + i_multi_slice_size, i_multi_slice_byte); +} + +static void ddl_vidc_encode_set_batch_slice_info( + struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + DDL_MSG_LOW("%s\n", __func__); + encoder->batch_frame.slice_batch_out.buffer_size = + encoder->output_buf_req.sz; + DDL_MSG_LOW("encoder->batch_frame.slice_batch_out.buffer_size = %d\n", + encoder->batch_frame.slice_batch_out.buffer_size); + vidc_sm_set_encoder_batch_config( + &ddl->shared_mem[ddl->command_channel], + 1, + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + encoder->batch_frame.slice_batch_in), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + encoder->batch_frame.slice_batch_out), + encoder->batch_frame.slice_batch_out.buffer_size); + vidc_sm_set_encoder_slice_batch_int_ctrl( + &ddl->shared_mem[ddl->command_channel], + 0); +} + +void ddl_vidc_encode_init_codec(struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + struct ddl_enc_buffers *enc_buffers = &encoder->hw_bufs; + struct vidc_1080p_enc_seq_start_param seq_start_param; + enum vidc_1080p_memory_access_method mem_access_method; + enum vidc_1080p_DBConfig db_config; + enum VIDC_SM_frame_skip r_cframe_skip = + VIDC_SM_FRAME_SKIP_DISABLE; + u32 index, luma[4], chroma[4], hdr_ext_control = false; + const u32 recon_bufs = 4; + u32 h263_cpfc_enable = false; + u32 scaled_frame_rate; + + ddl_vidc_encode_set_profile_level(ddl); + vidc_1080p_set_encode_frame_size(encoder->frame_size.width, + encoder->frame_size.height); + vidc_1080p_encode_set_qp_params(encoder->qp_range.max_qp, + encoder->qp_range.min_qp); + vidc_1080p_encode_set_rc_config(encoder->rc_level.frame_level_rc, + encoder->rc_level.mb_level_rc, + encoder->session_qp.i_frame_qp); + if (encoder->hdr_ext_control > 0) + hdr_ext_control = true; + if (encoder->r_cframe_skip > 0) + r_cframe_skip = VIDC_SM_FRAME_SKIP_ENABLE_LEVEL; + scaled_frame_rate = DDL_FRAMERATE_SCALE(encoder->\ + frame_rate.fps_numerator) / + encoder->frame_rate.fps_denominator; + if ((encoder->codec.codec == VCD_CODEC_H263) && + (DDL_FRAMERATE_SCALE(DDL_INITIAL_FRAME_RATE) + != scaled_frame_rate)) + h263_cpfc_enable = true; + vidc_sm_set_extended_encoder_control(&ddl->shared_mem + [ddl->command_channel], hdr_ext_control, + r_cframe_skip, false, 0, + h263_cpfc_enable, encoder->sps_pps.sps_pps_for_idr_enable_flag, + encoder->closed_gop); + vidc_sm_set_encoder_init_rc_value(&ddl->shared_mem + [ddl->command_channel], + encoder->target_bit_rate.target_bitrate); + vidc_sm_set_encoder_hec_period(&ddl->shared_mem + [ddl->command_channel], encoder->hdr_ext_control); + vidc_sm_set_encoder_vop_time(&ddl->shared_mem + [ddl->command_channel], true, + encoder->vop_timing.vop_time_resolution, 0); + if (encoder->rc_level.frame_level_rc) + vidc_1080p_encode_set_frame_level_rc_params( + scaled_frame_rate, + encoder->target_bit_rate.target_bitrate, + encoder->frame_level_rc.reaction_coeff); + if (encoder->rc_level.mb_level_rc) + vidc_1080p_encode_set_mb_level_rc_params( + encoder->adaptive_rc.disable_dark_region_as_flag, + encoder->adaptive_rc.disable_smooth_region_as_flag, + encoder->adaptive_rc.disable_static_region_as_flag, + encoder->adaptive_rc.disable_activity_region_flag); + if ((!encoder->rc_level.frame_level_rc) && + (!encoder->rc_level.mb_level_rc)) + vidc_sm_set_pand_b_frame_qp( + &ddl->shared_mem[ddl->command_channel], + encoder->session_qp.b_frame_qp, + encoder->session_qp.p_frame_qp); + if (encoder->codec.codec == VCD_CODEC_MPEG4) { + vidc_1080p_set_mpeg4_encode_quarter_pel_control(false); + vidc_1080p_set_encode_field_picture_structure(false); + } + if (encoder->codec.codec == VCD_CODEC_H264) { + enum vidc_1080p_entropy_sel entropy_sel; + switch (encoder->entropy_control.entropy_sel) { + default: + case VCD_ENTROPY_SEL_CAVLC: + entropy_sel = VIDC_1080P_ENTROPY_SEL_CAVLC; + break; + case VCD_ENTROPY_SEL_CABAC: + entropy_sel = VIDC_1080P_ENTROPY_SEL_CABAC; + break; + } + vidc_1080p_set_h264_encode_entropy(entropy_sel); + switch (encoder->db_control.db_config) { + default: + case VCD_DB_ALL_BLOCKING_BOUNDARY: + db_config = VIDC_1080P_DB_ALL_BLOCKING_BOUNDARY; + break; + case VCD_DB_DISABLE: + db_config = VIDC_1080P_DB_DISABLE; + break; + case VCD_DB_SKIP_SLICE_BOUNDARY: + db_config = VIDC_1080P_DB_SKIP_SLICE_BOUNDARY; + break; + } + vidc_1080p_set_h264_encode_loop_filter(db_config, + encoder->db_control.slice_alpha_offset, + encoder->db_control.slice_beta_offset); + vidc_1080p_set_h264_encoder_p_frame_ref_count(encoder->\ + num_references_for_p_frame); + if (encoder->profile.profile == VCD_PROFILE_H264_HIGH) + vidc_1080p_set_h264_encode_8x8transform_control(true); + } + vidc_1080p_set_encode_picture(encoder->i_period.p_frames, + encoder->i_period.b_frames); + vidc_1080p_set_encode_circular_intra_refresh( + encoder->intra_refresh.cir_mb_number); + ddl_vidc_encode_set_multi_slice_info(encoder); + ddl_vidc_metadata_enable(ddl); + if (encoder->meta_data_enable_flag) + vidc_sm_set_metadata_start_address(&ddl->shared_mem + [ddl->command_channel], DDL_ADDR_OFFSET( + ddl_context->dram_base_a, + ddl->codec_data.encoder.meta_data_input)); + luma[0] = DDL_ADDR_OFFSET(ddl_context->dram_base_a, + enc_buffers->dpb_y[0]); + luma[1] = DDL_ADDR_OFFSET(ddl_context->dram_base_a, + enc_buffers->dpb_y[1]); + if (encoder->hw_bufs.dpb_count == DDL_ENC_MAX_DPB_BUFFERS) { + luma[2] = DDL_ADDR_OFFSET(ddl_context->dram_base_b, + enc_buffers->dpb_y[2]); + luma[3] = DDL_ADDR_OFFSET(ddl_context->dram_base_b, + enc_buffers->dpb_y[3]); + } + for (index = 0; index < recon_bufs; index++) + chroma[index] = DDL_ADDR_OFFSET(ddl_context->dram_base_b, + enc_buffers->dpb_c[index]); + vidc_1080p_set_encode_recon_buffers(recon_bufs, luma, chroma); + switch (encoder->codec.codec) { + case VCD_CODEC_MPEG4: + vidc_1080p_set_mpeg4_encode_work_buffers( + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + enc_buffers->col_zero), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + enc_buffers->acdc_coef), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + enc_buffers->mv)); + break; + case VCD_CODEC_H263: + vidc_1080p_set_h263_encode_work_buffers( + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + enc_buffers->mv), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + enc_buffers->acdc_coef)); + break; + case VCD_CODEC_H264: + vidc_1080p_set_h264_encode_work_buffers( + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + enc_buffers->mv), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + enc_buffers->col_zero), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + enc_buffers->md), + DDL_ADDR_OFFSET(ddl_context->dram_base_b, + enc_buffers->pred), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + enc_buffers->nbor_info), + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + enc_buffers->mb_info)); + break; + default: + break; + } + if (encoder->buf_format.buffer_format == + VCD_BUFFER_FORMAT_NV12_16M2KA) + mem_access_method = VIDC_1080P_TILE_LINEAR; + else + mem_access_method = VIDC_1080P_TILE_64x32; + vidc_1080p_set_encode_input_frame_format(mem_access_method); + vidc_1080p_set_encode_padding_control(0, 0, 0, 0); + DDL_MSG_LOW("ddl_state_transition: %s ~~>" + "DDL_CLIENT_WAIT_FOR_INITCODECDONE", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_INITCODECDONE; + ddl->cmd_state = DDL_CMD_INIT_CODEC; + vidc_1080p_set_encode_field_picture_structure(false); + seq_start_param.cmd_seq_num = ++ddl_context->cmd_seq_num; + seq_start_param.inst_id = ddl->instance_id; + seq_start_param.shared_mem_addr_offset = DDL_ADDR_OFFSET( + ddl_context->dram_base_a, ddl->shared_mem + [ddl->command_channel]); + seq_start_param.stream_buffer_addr_offset = DDL_ADDR_OFFSET( + ddl_context->dram_base_a, encoder->seq_header); + seq_start_param.stream_buffer_size = + encoder->seq_header.buffer_size; + encoder->seq_header_length = 0; + ddl_context->vidc_encode_seq_start[ddl->command_channel]( + &seq_start_param); +} + +void ddl_vidc_channel_end(struct ddl_client_context *ddl) +{ + DDL_MSG_LOW("ddl_state_transition: %s ~~> DDL_CLIENT_WAIT_FOR_CHEND", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_CHEND; + ddl->cmd_state = DDL_CMD_CHANNEL_END; + vidc_1080p_set_host2risc_cmd(VIDC_1080P_HOST2RISC_CMD_CLOSE_CH, + ddl->instance_id, 0, 0, 0); +} + +void ddl_vidc_encode_frame_run(struct ddl_client_context *ddl) +{ + struct vidc_1080p_enc_frame_start_param enc_param; + struct ddl_context *ddl_context = ddl->ddl_context; + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + struct ddl_enc_buffers *enc_buffers = &(encoder->hw_bufs); + struct vcd_frame_data *stream = &(ddl->output_frame.vcd_frm); + struct vcd_frame_data *input_vcd_frm = + &(ddl->input_frame.vcd_frm); + u32 dpb_addr_y[4], dpb_addr_c[4]; + u32 index, y_addr, c_addr; + + DDL_MSG_LOW("%s\n", __func__); + ddl_vidc_encode_set_metadata_output_buf(ddl); + + encoder->enc_frame_info.meta_data_exists = false; + + y_addr = DDL_OFFSET(ddl_context->dram_base_b.align_physical_addr, + input_vcd_frm->physical); + c_addr = (y_addr + encoder->input_buf_size.size_y); + if (input_vcd_frm->flags & VCD_FRAME_FLAG_EOS) { + enc_param.encode = VIDC_1080P_ENC_TYPE_LAST_FRAME_DATA; + DDL_MSG_LOW("ddl_state_transition: %s ~~>" + "DDL_CLIENT_WAIT_FOR_EOS_DONE", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_EOS_DONE; + } else { + enc_param.encode = VIDC_1080P_ENC_TYPE_FRAME_DATA; + DDL_MSG_LOW("ddl_state_transition: %s ~~>" + "DDL_CLIENT_WAIT_FOR_FRAME_DONE", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME_DONE; + } + ddl->cmd_state = DDL_CMD_ENCODE_FRAME; + if (encoder->dynamic_prop_change) { + encoder->dynmic_prop_change_req = true; + ddl_vidc_encode_dynamic_property(ddl, true); + } + + vidc_1080p_set_encode_circular_intra_refresh( + encoder->intra_refresh.cir_mb_number); + ddl_vidc_encode_set_multi_slice_info(encoder); + enc_param.cmd_seq_num = ++ddl_context->cmd_seq_num; + enc_param.inst_id = ddl->instance_id; + enc_param.shared_mem_addr_offset = DDL_ADDR_OFFSET( + ddl_context->dram_base_a, + ddl->shared_mem[ddl->command_channel]); + enc_param.current_y_addr_offset = y_addr; + enc_param.current_c_addr_offset = c_addr; + enc_param.stream_buffer_addr_offset = DDL_OFFSET( + ddl_context->dram_base_a.align_physical_addr, stream->physical); + enc_param.stream_buffer_size = + encoder->client_output_buf_req.sz; + + enc_param.intra_frame = encoder->intra_frame_insertion; + if (encoder->intra_frame_insertion) + encoder->intra_frame_insertion = false; + enc_param.input_flush = false; + enc_param.slice_enable = false; + vidc_sm_set_encoder_vop_time( + &ddl->shared_mem[ddl->command_channel], true, + encoder->vop_timing.vop_time_resolution, + ddl->input_frame.frm_delta); + vidc_sm_set_frame_tag(&ddl->shared_mem[ddl->command_channel], + ddl->input_frame.vcd_frm.ip_frm_tag); + if (ddl_context->pix_cache_enable) { + for (index = 0; index < enc_buffers->dpb_count; + index++) { + dpb_addr_y[index] = + (u32) VIDC_1080P_DEC_DPB_RESET_VALUE; + dpb_addr_c[index] = (u32) enc_buffers->dpb_c + [index].align_physical_addr; + } + + dpb_addr_y[index] = (u32) input_vcd_frm->physical; + dpb_addr_c[index] = (u32) input_vcd_frm->physical + + encoder->input_buf_size.size_y; + + vidc_pix_cache_init_luma_chroma_base_addr( + enc_buffers->dpb_count + 1, dpb_addr_y, dpb_addr_c); + vidc_pix_cache_set_frame_size(encoder->frame_size.width, + encoder->frame_size.height); + vidc_pix_cache_set_frame_range(enc_buffers->sz_dpb_y, + enc_buffers->sz_dpb_c); + vidc_pix_cache_clear_cache_tags(); + } + ddl_context->vidc_encode_frame_start[ddl->command_channel] ( + &enc_param); +} + +void ddl_vidc_encode_frame_continue(struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + struct vcd_frame_data *input_vcd_frm = &(ddl->input_frame.vcd_frm); + u32 address_offset; + address_offset = (u32)(ddl->output_frame.vcd_frm.physical - + ddl_context->dram_base_a.align_physical_addr) >> + DDL_VIDC_1080P_BASE_OFFSET_SHIFT; + DDL_MSG_LOW("%s\n", __func__); + if (VCD_FRAME_FLAG_EOS & input_vcd_frm->flags) + ddl->client_state = DDL_CLIENT_WAIT_FOR_EOS_DONE; + else + ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME_DONE; + ddl->cmd_state = DDL_CMD_ENCODE_CONTINUE; + vidc_1080p_set_host2risc_cmd(VIDC_1080P_HOST2RISC_CMD_CONTINUE_ENC, + address_offset, + 0, 0, 0); +} + +void ddl_vidc_encode_slice_batch_run(struct ddl_client_context *ddl) +{ + struct vidc_1080p_enc_frame_start_param enc_param; + struct ddl_context *ddl_context = ddl->ddl_context; + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + struct ddl_enc_buffers *enc_buffers = &(encoder->hw_bufs); + struct vcd_frame_data *input_vcd_frm = + &(ddl->input_frame.vcd_frm); + u32 dpb_addr_y[4], dpb_addr_c[4]; + u32 index, y_addr, c_addr; + u32 bitstream_size; + struct vidc_1080p_enc_slice_batch_in_param *slice_batch_in = + (struct vidc_1080p_enc_slice_batch_in_param *) + encoder->batch_frame.slice_batch_in.align_virtual_addr; + DDL_MSG_LOW("%s\n", __func__); + DDL_MEMSET(slice_batch_in, 0, + sizeof(struct vidc_1080p_enc_slice_batch_in_param)); + DDL_MEMSET(encoder->batch_frame.slice_batch_in.align_virtual_addr, 0, + sizeof(struct vidc_1080p_enc_slice_batch_in_param)); + encoder->batch_frame.out_frm_next_frmindex = 0; + encoder->batch_frame.first_output_frame_tag = 0; + bitstream_size = encoder->batch_frame.output_frame[0].vcd_frm.alloc_len; + encoder->output_buf_req.sz = bitstream_size; + y_addr = DDL_OFFSET(ddl_context->dram_base_b.align_physical_addr, + input_vcd_frm->physical); + c_addr = (y_addr + encoder->input_buf_size.size_y); + enc_param.encode = VIDC_1080P_ENC_TYPE_SLICE_BATCH_START; + DDL_MSG_LOW("ddl_state_transition: %s ~~>" + "DDL_CLIENT_WAIT_FOR_FRAME_DONE", + ddl_get_state_string(ddl->client_state)); + slice_batch_in->cmd_type = VIDC_1080P_ENC_TYPE_SLICE_BATCH_START; + ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME_DONE; + ddl->cmd_state = DDL_CMD_ENCODE_FRAME; + vidc_1080p_set_encode_circular_intra_refresh( + encoder->intra_refresh.cir_mb_number); + ddl_vidc_encode_set_multi_slice_info(encoder); + enc_param.cmd_seq_num = ++ddl_context->cmd_seq_num; + enc_param.inst_id = ddl->instance_id; + enc_param.shared_mem_addr_offset = DDL_ADDR_OFFSET( + ddl_context->dram_base_a, + ddl->shared_mem[ddl->command_channel]); + enc_param.current_y_addr_offset = y_addr; + enc_param.current_c_addr_offset = c_addr; + enc_param.stream_buffer_size = bitstream_size; + slice_batch_in->num_stream_buffer = + encoder->batch_frame.num_output_frames; + slice_batch_in->stream_buffer_size = bitstream_size; + DDL_MSG_LOW("%s slice_batch_in->num_stream_buffer = %u size = %u\n", + __func__, slice_batch_in->num_stream_buffer, + slice_batch_in->stream_buffer_size); + for (index = 0; index < encoder->batch_frame.num_output_frames; + index++) { + slice_batch_in->stream_buffer_addr_offset[index] = + ((DDL_OFFSET(ddl_context->dram_base_b.align_physical_addr, + encoder->batch_frame.output_frame[index].vcd_frm.physical)) >> + DDL_VIDC_1080P_BASE_OFFSET_SHIFT); + } + slice_batch_in->input_size = VIDC_1080P_SLICE_BATCH_IN_SIZE(index); + enc_param.intra_frame = encoder->intra_frame_insertion; + if (encoder->intra_frame_insertion) + encoder->intra_frame_insertion = false; + enc_param.input_flush = false; + enc_param.slice_enable = + encoder->slice_delivery_info.enable; + vidc_sm_set_encoder_vop_time( + &ddl->shared_mem[ddl->command_channel], true, + encoder->vop_timing.vop_time_resolution, + ddl->input_frame.frm_delta); + vidc_sm_set_frame_tag(&ddl->shared_mem[ddl->command_channel], + ddl->input_frame.vcd_frm.ip_frm_tag); + DDL_MSG_LOW("%sdpb_count = %d\n", __func__, enc_buffers->dpb_count); + if (ddl_context->pix_cache_enable) { + for (index = 0; index < enc_buffers->dpb_count; + index++) { + dpb_addr_y[index] = + (u32) VIDC_1080P_DEC_DPB_RESET_VALUE; + dpb_addr_c[index] = (u32) enc_buffers->dpb_c + [index].align_physical_addr; + } + + dpb_addr_y[index] = (u32) input_vcd_frm->physical; + dpb_addr_c[index] = (u32) input_vcd_frm->physical + + encoder->input_buf_size.size_y; + + vidc_pix_cache_init_luma_chroma_base_addr( + enc_buffers->dpb_count + 1, dpb_addr_y, dpb_addr_c); + vidc_pix_cache_set_frame_size(encoder->frame_size.width, + encoder->frame_size.height); + vidc_pix_cache_set_frame_range(enc_buffers->sz_dpb_y, + enc_buffers->sz_dpb_c); + vidc_pix_cache_clear_cache_tags(); + } + if ((!encoder->rc_level.frame_level_rc) && + (!encoder->rc_level.mb_level_rc)) { + encoder->session_qp.p_frame_qp++; + if (encoder->session_qp.p_frame_qp > encoder->qp_range.max_qp) + encoder->session_qp.p_frame_qp = + encoder->qp_range.min_qp; + vidc_sm_set_pand_b_frame_qp( + &ddl->shared_mem[ddl->command_channel], + encoder->session_qp.b_frame_qp, + encoder->session_qp.p_frame_qp); + } + + if (vidc_msg_timing) { + if (run_cnt < 2) { + ddl_reset_core_time_variables(ENC_OP_TIME); + ddl_reset_core_time_variables(ENC_SLICE_OP_TIME); + run_cnt++; + } + ddl_update_core_start_time(__func__, ENC_SLICE_OP_TIME); + ddl_set_core_start_time(__func__, ENC_OP_TIME); + } + ddl_vidc_encode_set_batch_slice_info(ddl); + ddl_context->vidc_encode_slice_batch_start[ddl->command_channel] ( + &enc_param); +} + +u32 ddl_vidc_decode_set_buffers(struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + u32 vcd_status = VCD_S_SUCCESS; + struct vidc_1080p_dec_init_buffers_param init_buf_param; + u32 size_y = 0; + u32 size_c = 0; + + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB)) { + DDL_MSG_ERROR("STATE-CRITICAL"); + return VCD_ERR_FAIL; + } + ddl_set_vidc_timeout(ddl); + ddl_vidc_decode_set_metadata_output(decoder); + if (decoder->dp_buf.no_of_dec_pic_buf < + decoder->client_output_buf_req.actual_count) + return VCD_ERR_BAD_STATE; + if (decoder->codec.codec == VCD_CODEC_H264) { + vidc_sm_set_allocated_h264_mv_size( + &ddl->shared_mem[ddl->command_channel], + decoder->hw_bufs.h264_mv[0].buffer_size); + } + if (vcd_status) + return vcd_status; +#ifdef DDL_BUF_LOG + ddl_list_buffers(ddl); +#endif + ddl_set_core_start_time(__func__, DEC_OP_TIME); + ddl_decoder_dpb_transact(decoder, NULL, DDL_DPB_OP_INIT); + if (ddl_decoder_dpb_init(ddl) == VCD_ERR_FAIL) + return VCD_ERR_FAIL; + DDL_MSG_LOW("ddl_state_transition: %s ~~> DDL_CLIENT_WAIT_FOR_DPBDONE", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_DPBDONE; + ddl->cmd_state = DDL_CMD_DECODE_SET_DPB; + if (decoder->cont_mode) { + size_y = ddl_get_yuv_buf_size(decoder->client_frame_size.width, + decoder->client_frame_size.height, + DDL_YUV_BUF_TYPE_TILE); + size_c = ddl_get_yuv_buf_size(decoder->client_frame_size.width, + (decoder->client_frame_size.height >> 1), + DDL_YUV_BUF_TYPE_TILE); + vidc_sm_set_allocated_dpb_size( + &ddl->shared_mem[ddl->command_channel], + size_y, + size_c); + } else { + vidc_sm_set_allocated_dpb_size( + &ddl->shared_mem[ddl->command_channel], + decoder->dpb_buf_size.size_y, + decoder->dpb_buf_size.size_c); + } + init_buf_param.cmd_seq_num = ++ddl_context->cmd_seq_num; + init_buf_param.inst_id = ddl->instance_id; + init_buf_param.shared_mem_addr_offset = DDL_ADDR_OFFSET( + ddl_context->dram_base_a, ddl->shared_mem + [ddl->command_channel]); + init_buf_param.dpb_count = decoder->dp_buf.no_of_dec_pic_buf; + init_buf_param.dmx_disable = decoder->dmx_disable; + ddl_context->vidc_decode_init_buffers[ddl->command_channel] ( + &init_buf_param); + return VCD_S_SUCCESS; +} + +void ddl_vidc_decode_frame_run(struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + struct vcd_frame_data *bit_stream = + &(ddl->input_frame.vcd_frm); + struct ddl_dec_buffers *dec_buffers = &decoder->hw_bufs; + struct ddl_mask *dpb_mask = &ddl->codec_data.decoder.dpb_mask; + struct vidc_1080p_dec_frame_start_param dec_param; + u32 dpb_addr_y[32], index; + ddl_set_core_start_time(__func__, DEC_OP_TIME); + ddl_set_core_start_time(__func__, DEC_IP_TIME); + if ((!bit_stream->data_len) || (!bit_stream->physical)) { + ddl_vidc_decode_eos_run(ddl); + return; + } + DDL_MSG_LOW("ddl_state_transition: %s ~~" + "DDL_CLIENT_WAIT_FOR_FRAME_DONE", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_FRAME_DONE; + ddl_vidc_decode_dynamic_property(ddl, true); + ddl_decoder_dpb_transact(decoder, NULL, DDL_DPB_OP_SET_MASK); + ddl->cmd_state = DDL_CMD_DECODE_FRAME; + dec_param.cmd_seq_num = ++ddl_context->cmd_seq_num; + dec_param.inst_id = ddl->instance_id; + dec_param.shared_mem_addr_offset = DDL_ADDR_OFFSET( + ddl_context->dram_base_a, ddl->shared_mem + [ddl->command_channel]); + dec_param.stream_buffer_addr_offset = DDL_OFFSET( + ddl_context->dram_base_a.align_physical_addr, + bit_stream->physical); + dec_param.stream_frame_size = bit_stream->data_len; + dec_param.stream_buffersize = decoder->client_input_buf_req.sz; + dec_param.descriptor_buffer_addr_offset = DDL_ADDR_OFFSET( + ddl_context->dram_base_a, dec_buffers->desc); + dec_param.descriptor_buffer_size = dec_buffers->desc.buffer_size; + dec_param.release_dpb_bit_mask = dpb_mask->hw_mask; + dec_param.decode = VIDC_1080P_DEC_TYPE_FRAME_DATA; + dec_param.dpb_count = decoder->dp_buf.no_of_dec_pic_buf; + dec_param.dmx_disable = decoder->dmx_disable; + if (decoder->dmx_disable) + ddl_fill_dec_desc_buffer(ddl); + if (decoder->flush_pending) { + dec_param.dpb_flush = true; + decoder->flush_pending = false; + } else + dec_param.dpb_flush = false; + vidc_sm_set_frame_tag(&ddl->shared_mem[ddl->command_channel], + bit_stream->ip_frm_tag); + if (ddl_context->pix_cache_enable) { + for (index = 0; index < + decoder->dp_buf.no_of_dec_pic_buf; index++) { + dpb_addr_y[index] = (u32) + decoder->dp_buf.dec_pic_buffers + [index].vcd_frm.physical; + } + vidc_pix_cache_init_luma_chroma_base_addr( + decoder->dp_buf.no_of_dec_pic_buf, + dpb_addr_y, NULL); + vidc_pix_cache_set_frame_range(decoder->dpb_buf_size.size_y, + decoder->dpb_buf_size.size_c); + vidc_pix_cache_clear_cache_tags(); + } + ddl_context->vidc_decode_frame_start[ddl->command_channel] ( + &dec_param); +} + +void ddl_vidc_decode_eos_run(struct ddl_client_context *ddl) +{ + struct ddl_context *ddl_context = ddl->ddl_context; + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + struct vcd_frame_data *bit_stream = + &(ddl->input_frame.vcd_frm); + struct ddl_dec_buffers *dec_buffers = &(decoder->hw_bufs); + struct ddl_mask *dpb_mask = + &(ddl->codec_data.decoder.dpb_mask); + struct vidc_1080p_dec_frame_start_param dec_param; + + DDL_MSG_LOW("ddl_state_transition: %s ~~> DDL_CLIENT_WAIT_FOR_EOS_DONE", + ddl_get_state_string(ddl->client_state)); + ddl->client_state = DDL_CLIENT_WAIT_FOR_EOS_DONE; + if (decoder->output_order == VCD_DEC_ORDER_DECODE) + decoder->dynamic_prop_change |= DDL_DEC_REQ_OUTPUT_FLUSH; + ddl_vidc_decode_dynamic_property(ddl, true); + ddl_decoder_dpb_transact(decoder, NULL, DDL_DPB_OP_SET_MASK); + decoder->dynmic_prop_change_req = true; + ddl->cmd_state = DDL_CMD_EOS; + memset(&dec_param, 0, sizeof(dec_param)); + dec_param.cmd_seq_num = ++ddl_context->cmd_seq_num; + dec_param.inst_id = ddl->instance_id; + dec_param.shared_mem_addr_offset = DDL_ADDR_OFFSET( + ddl_context->dram_base_a, + ddl->shared_mem[ddl->command_channel]); + dec_param.descriptor_buffer_addr_offset = DDL_ADDR_OFFSET( + ddl_context->dram_base_a, dec_buffers->desc); + dec_param.descriptor_buffer_size = dec_buffers->desc.buffer_size; + dec_param.release_dpb_bit_mask = dpb_mask->hw_mask; + dec_param.decode = VIDC_1080P_DEC_TYPE_LAST_FRAME_DATA; + dec_param.dpb_count = decoder->dp_buf.no_of_dec_pic_buf; + if (decoder->flush_pending) { + dec_param.dpb_flush = true; + decoder->flush_pending = false; + } else + dec_param.dpb_flush = false; + vidc_sm_set_frame_tag(&ddl->shared_mem[ddl->command_channel], + bit_stream->ip_frm_tag); + ddl_context->vidc_decode_frame_start[ddl->command_channel] ( + &dec_param); +} + +void ddl_vidc_encode_eos_run(struct ddl_client_context *ddl) +{ + struct vidc_1080p_enc_frame_start_param enc_param; + struct ddl_context *ddl_context = ddl->ddl_context; + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + DDL_MSG_LOW("%s\n", __func__); + ddl->client_state = DDL_CLIENT_WAIT_FOR_EOS_DONE; + ddl_vidc_encode_dynamic_property(ddl, true); + ddl->client_state = DDL_CMD_EOS; + DDL_MEMSET(&enc_param, 0, sizeof(enc_param)); + enc_param.encode = VIDC_1080P_ENC_TYPE_LAST_FRAME_DATA; + enc_param.cmd_seq_num = ++ddl_context->cmd_seq_num; + enc_param.inst_id = ddl->instance_id; + enc_param.shared_mem_addr_offset = + DDL_ADDR_OFFSET(ddl_context->dram_base_a, + ddl->shared_mem[ddl->command_channel]); + enc_param.current_y_addr_offset = 0; + enc_param.current_c_addr_offset = 0; + enc_param.stream_buffer_size = 0; + enc_param.intra_frame = encoder->intra_frame_insertion; + vidc_sm_set_frame_tag(&ddl->shared_mem[ddl->command_channel], + ddl->input_frame.vcd_frm.ip_frm_tag); + ddl_context->vidc_encode_frame_start[ddl->command_channel]( + &enc_param); +} + +int ddl_vidc_decode_get_avg_time(struct ddl_client_context *ddl) +{ + int avg_time = 0; + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + avg_time = decoder->avg_dec_time; + return avg_time; +} + +void ddl_vidc_decode_reset_avg_time(struct ddl_client_context *ddl) +{ + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + decoder->avg_dec_time = 0; + decoder->dec_time_sum = 0; +} diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc.c b/drivers/video/msm/vidc/1080p/ddl/vidc.c new file mode 100644 index 000000000000..00f75a9b0579 --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vidc.c @@ -0,0 +1,1108 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#include "vidc.h" +#include "vidc_hwio.h" + + +#define VIDC_1080P_INIT_CH_INST_ID 0x0000ffff +#define VIDC_1080P_RESET_VI 0x3f7 +#define VIDC_1080P_RESET_VI_RISC 0x3f6 +#define VIDC_1080P_RESET_VI_VIDC_RISC 0x3f2 +#define VIDC_1080P_RESET_ALL 0 +#define VIDC_1080P_RESET_RISC 0x3fe +#define VIDC_1080P_RESET_NONE 0x3ff +#define VIDC_1080P_INTERRUPT_CLEAR 0 +#define VIDC_1080P_MAX_H264DECODER_DPB 32 +#define VIDC_1080P_MAX_DEC_RECON_BUF 32 + +#define VIDC_1080P_SI_RG7_DISPLAY_STATUS_MASK 0x00000007 +#define VIDC_1080P_SI_RG7_DISPLAY_STATUS_SHIFT 0 +#define VIDC_1080P_SI_RG7_DISPLAY_CODING_MASK 0x00000008 +#define VIDC_1080P_SI_RG7_DISPLAY_CODING_SHIFT 3 +#define VIDC_1080P_SI_RG7_DISPLAY_RES_MASK 0x00000030 +#define VIDC_1080P_SI_RG7_DISPLAY_RES_SHIFT 4 + +#define VIDC_1080P_SI_RG7_DISPLAY_CROP_MASK 0x00000040 +#define VIDC_1080P_SI_RG7_DISPLAY_CROP_SHIFT 6 + +#define VIDC_1080P_SI_RG7_DISPLAY_CORRECT_MASK 0x00000180 +#define VIDC_1080P_SI_RG7_DISPLAY_CORRECT_SHIFT 7 +#define VIDC_1080P_SI_RG8_DECODE_FRAMETYPE_MASK 0x00000007 + +#define VIDC_1080P_SI_RG10_NUM_DPB_BMSK 0x00003fff +#define VIDC_1080P_SI_RG10_NUM_DPB_SHFT 0 +#define VIDC_1080P_SI_RG10_DPB_FLUSH_BMSK 0x00004000 +#define VIDC_1080P_SI_RG10_DPB_FLUSH_SHFT 14 +#define VIDC_1080P_SI_RG10_DMX_DISABLE_BMSK 0x00008000 +#define VIDC_1080P_SI_RG10_DMX_DISABLE_SHFT 15 + +#define VIDC_1080P_SI_RG11_DECODE_STATUS_MASK 0x00000007 +#define VIDC_1080P_SI_RG11_DECODE_STATUS_SHIFT 0 +#define VIDC_1080P_SI_RG11_DECODE_CODING_MASK 0x00000008 +#define VIDC_1080P_SI_RG11_DECODE_CODING_SHIFT 3 +#define VIDC_1080P_SI_RG11_DECODE_RES_MASK 0x000000C0 +#define VIDC_1080P_SI_RG11_DECODE_RES_SHIFT 6 +#define VIDC_1080P_SI_RG11_DECODE_CROPP_MASK 0x00000100 +#define VIDC_1080P_SI_RG11_DECODE_CROPP_SHIFT 8 + +#define VIDC_1080P_SI_RG11_DECODE_CORRECT_MASK 0x00000600 +#define VIDC_1080P_SI_RG11_DECODE_CORRECT_SHIFT 9 +#define VIDC_1080P_BASE_OFFSET_SHIFT 11 + + +#define VIDC_1080P_H264DEC_LUMA_ADDR HWIO_REG_759068_ADDR +#define VIDC_1080P_H264DEC_CHROMA_ADDR HWIO_REG_515200_ADDR +#define VIDC_1080P_H264DEC_MV_PLANE_ADDR HWIO_REG_466192_ADDR + +#define VIDC_1080P_DEC_LUMA_ADDR HWIO_REG_759068_ADDR +#define VIDC_1080P_DEC_CHROMA_ADDR HWIO_REG_515200_ADDR + +#define VIDC_1080P_DEC_TYPE_SEQ_HEADER 0x00010000 +#define VIDC_1080P_DEC_TYPE_FRAME_DATA 0x00020000 +#define VIDC_1080P_DEC_TYPE_LAST_FRAME_DATA 0x00030000 +#define VIDC_1080P_DEC_TYPE_INIT_BUFFERS 0x00040000 + +#define VIDC_1080P_ENC_TYPE_SEQ_HEADER 0x00010000 +#define VIDC_1080P_ENC_TYPE_FRAME_DATA 0x00020000 +#define VIDC_1080P_ENC_TYPE_LAST_FRAME_DATA 0x00030000 + +#define VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_BMSK 0x00004000 +#define VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_SHFT 14 +#define VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_BMSK 0x80000000 +#define VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_SHFT 31 +#define VIDC_1080P_MAX_INTRA_PERIOD 0xffff + +u8 *VIDC_BASE_PTR; + +void vidc_1080p_do_sw_reset(enum vidc_1080p_reset init_flag) +{ + if (init_flag == VIDC_1080P_RESET_IN_SEQ_FIRST_STAGE) { + u32 sw_reset_value = 0; + + VIDC_HWIO_IN(REG_557899, &sw_reset_value); + sw_reset_value &= (~HWIO_REG_557899_RSTN_VI_BMSK); + VIDC_HWIO_OUT(REG_557899, sw_reset_value); + sw_reset_value &= (~HWIO_REG_557899_RSTN_RISC_BMSK); + VIDC_HWIO_OUT(REG_557899, sw_reset_value); + sw_reset_value &= (~(HWIO_REG_557899_RSTN_VIDCCORE_BMSK | + HWIO_REG_557899_RSTN_DMX_BMSK)); + + VIDC_HWIO_OUT(REG_557899, sw_reset_value); + } else if (init_flag == VIDC_1080P_RESET_IN_SEQ_SECOND_STAGE) { + VIDC_HWIO_OUT(REG_557899, VIDC_1080P_RESET_ALL); + VIDC_HWIO_OUT(REG_557899, VIDC_1080P_RESET_RISC); + } +} + +void vidc_1080p_release_sw_reset(void) +{ + u32 nAxiCtl; + u32 nAxiStatus; + u32 nRdWrBurst; + u32 nOut_Order; + + nOut_Order = VIDC_SETFIELD(1, HWIO_REG_5519_AXI_AOOORD_SHFT, + HWIO_REG_5519_AXI_AOOORD_BMSK); + VIDC_HWIO_OUT(REG_5519, nOut_Order); + + nOut_Order = VIDC_SETFIELD(1, HWIO_REG_606364_AXI_AOOOWR_SHFT, + HWIO_REG_606364_AXI_AOOOWR_BMSK); + VIDC_HWIO_OUT(REG_606364, nOut_Order); + + nAxiCtl = VIDC_SETFIELD(1, HWIO_REG_471159_AXI_HALT_REQ_SHFT, + HWIO_REG_471159_AXI_HALT_REQ_BMSK); + + VIDC_HWIO_OUT(REG_471159, nAxiCtl); + + do { + VIDC_HWIO_IN(REG_437878, &nAxiStatus); + nAxiStatus = VIDC_GETFIELD(nAxiStatus, + HWIO_REG_437878_AXI_HALT_ACK_BMSK, + HWIO_REG_437878_AXI_HALT_ACK_SHFT); + } while (0x3 != nAxiStatus); + + nAxiCtl = VIDC_SETFIELD(1, + HWIO_REG_471159_AXI_RESET_SHFT, + HWIO_REG_471159_AXI_RESET_BMSK); + + VIDC_HWIO_OUT(REG_471159, nAxiCtl); + VIDC_HWIO_OUT(REG_471159, 0); + + nRdWrBurst = VIDC_SETFIELD(8, + HWIO_REG_922106_XBAR_OUT_MAX_RD_BURST_SHFT, + HWIO_REG_922106_XBAR_OUT_MAX_RD_BURST_BMSK) | + VIDC_SETFIELD(8, HWIO_REG_922106_XBAR_OUT_MAX_WR_BURST_SHFT, + HWIO_REG_922106_XBAR_OUT_MAX_WR_BURST_BMSK); + + VIDC_HWIO_OUT(REG_922106, nRdWrBurst); + + VIDC_HWIO_OUT(REG_666957, VIDC_1080P_INIT_CH_INST_ID); + VIDC_HWIO_OUT(REG_313350, VIDC_1080P_INIT_CH_INST_ID); + VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY); + VIDC_HWIO_OUT(REG_611794, VIDC_1080P_HOST2RISC_CMD_EMPTY); + VIDC_HWIO_OUT(REG_557899, VIDC_1080P_RESET_NONE); +} + +void vidc_1080p_clear_interrupt(void) +{ + VIDC_HWIO_OUT(REG_575377, VIDC_1080P_INTERRUPT_CLEAR); +} + +void vidc_1080p_set_host2risc_cmd(enum vidc_1080p_host2risc_cmd + host2risc_command, u32 host2risc_arg1, u32 host2risc_arg2, + u32 host2risc_arg3, u32 host2risc_arg4) +{ + VIDC_HWIO_OUT(REG_611794, VIDC_1080P_HOST2RISC_CMD_EMPTY); + VIDC_HWIO_OUT(REG_356340, host2risc_arg1); + VIDC_HWIO_OUT(REG_899023, host2risc_arg2); + VIDC_HWIO_OUT(REG_987762, host2risc_arg3); + VIDC_HWIO_OUT(REG_544000, host2risc_arg4); + VIDC_HWIO_OUT(REG_611794, host2risc_command); +} + +void vidc_1080p_get_risc2host_cmd(u32 *pn_risc2host_command, + u32 *pn_risc2host_arg1, u32 *pn_risc2host_arg2, + u32 *pn_risc2host_arg3, u32 *pn_risc2host_arg4) +{ + VIDC_HWIO_IN(REG_695082, pn_risc2host_command); + VIDC_HWIO_IN(REG_156596, pn_risc2host_arg1); + VIDC_HWIO_IN(REG_222292, pn_risc2host_arg2); + VIDC_HWIO_IN(REG_790962, pn_risc2host_arg3); + VIDC_HWIO_IN(REG_679882, pn_risc2host_arg4); +} + +void vidc_1080p_get_risc2host_cmd_status(u32 err_status, + u32 *dec_err_status, u32 *disp_err_status) +{ + *dec_err_status = VIDC_GETFIELD(err_status, + VIDC_RISC2HOST_ARG2_VIDC_DEC_ERROR_STATUS_BMSK, + VIDC_RISC2HOST_ARG2_VIDC_DEC_ERROR_STATUS_SHFT); + *disp_err_status = VIDC_GETFIELD(err_status, + VIDC_RISC2HOST_ARG2_VIDC_DISP_ERROR_STATUS_BMSK, + VIDC_RISC2HOST_ARG2_VIDC_DISP_ERROR_STATUS_SHFT); + +} + +void vidc_1080p_clear_risc2host_cmd(void) +{ + VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY); +} + +void vidc_1080p_get_fw_version(u32 *pn_fw_version) +{ + VIDC_HWIO_IN(REG_653206, pn_fw_version); +} + +void vidc_1080p_get_fw_status(u32 *pn_fw_status) +{ + VIDC_HWIO_IN(REG_350619, pn_fw_status); +} + +void vidc_1080p_init_memory_controller(u32 dram_base_addr_a, + u32 dram_base_addr_b) +{ + VIDC_HWIO_OUT(REG_64440, dram_base_addr_a); + VIDC_HWIO_OUT(REG_675915, dram_base_addr_b); +} + +void vidc_1080p_get_memory_controller_status(u32 *pb_mc_abusy, + u32 *pb_mc_bbusy) +{ + u32 mc_status = 0; + + VIDC_HWIO_IN(REG_399911, &mc_status); + *pb_mc_abusy = (u32) ((mc_status & + HWIO_REG_399911_MC_BUSY_A_BMSK) >> + HWIO_REG_399911_MC_BUSY_A_SHFT); + *pb_mc_bbusy = (u32) ((mc_status & + HWIO_REG_399911_MC_BUSY_B_BMSK) >> + HWIO_REG_399911_MC_BUSY_B_SHFT); +} + +void vidc_1080p_set_h264_decode_buffers(u32 dpb, u32 dec_vert_nb_mv_offset, + u32 dec_nb_ip_offset, u32 *pn_dpb_luma_offset, + u32 *pn_dpb_chroma_offset, u32 *pn_mv_buffer_offset) +{ + u32 count = 0, num_dpb_used = dpb; + u8 *vidc_dpb_luma_reg = (u8 *) VIDC_1080P_H264DEC_LUMA_ADDR; + u8 *vidc_dpb_chroma_reg = (u8 *) VIDC_1080P_H264DEC_CHROMA_ADDR; + u8 *vidc_mv_buffer_reg = (u8 *) VIDC_1080P_H264DEC_MV_PLANE_ADDR; + + VIDC_HWIO_OUT(REG_931311, (dec_vert_nb_mv_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_16277, (dec_nb_ip_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + if (num_dpb_used > VIDC_1080P_MAX_H264DECODER_DPB) + num_dpb_used = VIDC_1080P_MAX_H264DECODER_DPB; + for (count = 0; count < num_dpb_used; count++) { + VIDC_OUT_DWORD(vidc_dpb_luma_reg, + (pn_dpb_luma_offset[count] >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_OUT_DWORD(vidc_dpb_chroma_reg, + (pn_dpb_chroma_offset[count] >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_OUT_DWORD(vidc_mv_buffer_reg, + (pn_mv_buffer_offset[count] >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + vidc_dpb_luma_reg += 4; + vidc_dpb_chroma_reg += 4; + vidc_mv_buffer_reg += 4; + } +} + +void vidc_1080p_set_decode_recon_buffers(u32 recon_buffer, + u32 *pn_dec_luma, u32 *pn_dec_chroma) +{ + u32 count = 0, recon_buf_to_program = recon_buffer; + u8 *dec_recon_luma_reg = (u8 *) VIDC_1080P_DEC_LUMA_ADDR; + u8 *dec_recon_chroma_reg = (u8 *) VIDC_1080P_DEC_CHROMA_ADDR; + + if (recon_buf_to_program > VIDC_1080P_MAX_DEC_RECON_BUF) + recon_buf_to_program = VIDC_1080P_MAX_DEC_RECON_BUF; + for (count = 0; count < recon_buf_to_program; count++) { + VIDC_OUT_DWORD(dec_recon_luma_reg, (pn_dec_luma[count] >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_OUT_DWORD(dec_recon_chroma_reg, + (pn_dec_chroma[count] >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + dec_recon_luma_reg += 4; + dec_recon_chroma_reg += 4; + } +} + +void vidc_1080p_set_mpeg4_divx_decode_work_buffers(u32 nb_dcac_buffer_offset, + u32 upnb_mv_buffer_offset, u32 sub_anchor_buffer_offset, + u32 overlay_transform_buffer_offset, u32 stx_parser_buffer_offset) +{ + VIDC_HWIO_OUT(REG_931311, (nb_dcac_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_16277, (upnb_mv_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_654169, (sub_anchor_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_802794, + (overlay_transform_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_252167, (stx_parser_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); +} + +void vidc_1080p_set_h263_decode_work_buffers(u32 nb_dcac_buffer_offset, + u32 upnb_mv_buffer_offset, u32 sub_anchor_buffer_offset, + u32 overlay_transform_buffer_offset) +{ + VIDC_HWIO_OUT(REG_931311, (nb_dcac_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_16277, (upnb_mv_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_654169, (sub_anchor_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_802794, + (overlay_transform_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); +} + +void vidc_1080p_set_vc1_decode_work_buffers(u32 nb_dcac_buffer_offset, + u32 upnb_mv_buffer_offset, u32 sub_anchor_buffer_offset, + u32 overlay_transform_buffer_offset, u32 bitplain1Buffer_offset, + u32 bitplain2Buffer_offset, u32 bitplain3Buffer_offset) +{ + VIDC_HWIO_OUT(REG_931311, (nb_dcac_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_16277, (upnb_mv_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_654169, (sub_anchor_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_802794, + (overlay_transform_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_724376, (bitplain3Buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_551674, (bitplain2Buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_115991, (bitplain1Buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); +} + +void vidc_1080p_set_encode_recon_buffers(u32 recon_buffer, + u32 *pn_enc_luma, u32 *pn_enc_chroma) +{ + if (recon_buffer > 0) { + VIDC_HWIO_OUT(REG_294579, (pn_enc_luma[0] >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_759068, (pn_enc_chroma[0] >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + } + if (recon_buffer > 1) { + VIDC_HWIO_OUT(REG_616802, (pn_enc_luma[1] >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_833502, (pn_enc_chroma[1] >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + } + if (recon_buffer > 2) { + VIDC_HWIO_OUT(REG_61427, (pn_enc_luma[2] >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_68356, (pn_enc_chroma[2] >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + } + if (recon_buffer > 3) { + VIDC_HWIO_OUT(REG_23318, (pn_enc_luma[3] >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_127855, (pn_enc_chroma[3] >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + } +} + +void vidc_1080p_set_h264_encode_work_buffers(u32 up_row_mv_buffer_offset, + u32 direct_colzero_flag_buffer_offset, + u32 upper_intra_md_buffer_offset, + u32 upper_intra_pred_buffer_offset, u32 nbor_infor_buffer_offset, + u32 mb_info_offset) +{ + VIDC_HWIO_OUT(REG_515200, (up_row_mv_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_69832, + (direct_colzero_flag_buffer_offset>> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_256132, + (upper_intra_md_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_475648, + (upper_intra_pred_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_29510, (nbor_infor_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_175929, (mb_info_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); +} + +void vidc_1080p_set_h263_encode_work_buffers(u32 up_row_mv_buffer_offset, + u32 up_row_inv_quanti_coeff_buffer_offset) +{ + VIDC_HWIO_OUT(REG_515200, (up_row_mv_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_29510, ( + up_row_inv_quanti_coeff_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); +} + +void vidc_1080p_set_mpeg4_encode_work_buffers(u32 skip_flag_buffer_offset, + u32 up_row_inv_quanti_coeff_buffer_offset, u32 upper_mv_offset) +{ + VIDC_HWIO_OUT(REG_69832, (skip_flag_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_29510, ( + up_row_inv_quanti_coeff_buffer_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); + VIDC_HWIO_OUT(REG_515200, (upper_mv_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT)); +} + +void vidc_1080p_set_encode_frame_size(u32 hori_size, u32 vert_size) +{ + VIDC_HWIO_OUT(REG_934655, hori_size); + VIDC_HWIO_OUT(REG_179070, vert_size); +} + +void vidc_1080p_set_encode_profile_level(u32 encode_profile, u32 enc_level) +{ + u32 profile_level = 0; + + profile_level = VIDC_SETFIELD(enc_level, + HWIO_REG_63643_LEVEL_SHFT, + HWIO_REG_63643_LEVEL_BMSK) | + VIDC_SETFIELD(encode_profile, + HWIO_REG_63643_PROFILE_SHFT, + HWIO_REG_63643_PROFILE_BMSK); + VIDC_HWIO_OUT(REG_63643, profile_level); +} + +void vidc_1080p_set_encode_field_picture_structure(u32 enc_field_picture) +{ + VIDC_HWIO_OUT(REG_786024, enc_field_picture); +} + +void vidc_1080p_set_decode_mpeg4_pp_filter(u32 lf_enables) +{ + VIDC_HWIO_OUT(REG_152500, lf_enables); +} + +void vidc_1080p_set_decode_qp_save_control(u32 enable_q_pout) +{ + VIDC_HWIO_OUT(REG_143629, enable_q_pout); +} + +void vidc_1080p_get_returned_channel_inst_id(u32 *pn_rtn_chid) +{ + VIDC_HWIO_IN(REG_607589, pn_rtn_chid); +} + +void vidc_1080p_clear_returned_channel_inst_id(void) +{ + VIDC_HWIO_OUT(REG_607589, VIDC_1080P_INIT_CH_INST_ID); +} + +void vidc_1080p_get_decode_seq_start_result( + struct vidc_1080p_seq_hdr_info *seq_hdr_info) +{ + u32 dec_disp_result; + u32 frame = 0; + VIDC_HWIO_IN(REG_845544, &seq_hdr_info->img_size_y); + VIDC_HWIO_IN(REG_859906, &seq_hdr_info->img_size_x); + VIDC_HWIO_IN(REG_490078, &seq_hdr_info->min_num_dpb); + VIDC_HWIO_IN(REG_489688, &seq_hdr_info->dec_frm_size); + VIDC_HWIO_IN(REG_853667, &dec_disp_result); + seq_hdr_info->disp_progressive = VIDC_GETFIELD(dec_disp_result, + VIDC_1080P_SI_RG7_DISPLAY_CODING_MASK, + VIDC_1080P_SI_RG7_DISPLAY_CODING_SHIFT); + seq_hdr_info->disp_crop_exists = VIDC_GETFIELD(dec_disp_result, + VIDC_1080P_SI_RG7_DISPLAY_CROP_MASK, + VIDC_1080P_SI_RG7_DISPLAY_CROP_SHIFT); + VIDC_HWIO_IN(REG_692991, &dec_disp_result); + seq_hdr_info->dec_progressive = VIDC_GETFIELD(dec_disp_result, + VIDC_1080P_SI_RG11_DECODE_CODING_MASK, + VIDC_1080P_SI_RG11_DECODE_CODING_SHIFT); + seq_hdr_info->dec_crop_exists = VIDC_GETFIELD(dec_disp_result, + VIDC_1080P_SI_RG11_DECODE_CROPP_MASK, + VIDC_1080P_SI_RG11_DECODE_CROPP_SHIFT); + VIDC_HWIO_IN(REG_760102, &frame); + seq_hdr_info->data_partition = ((frame & 0x8) >> 3); +} + +void vidc_1080p_get_decoded_frame_size(u32 *pn_decoded_size) +{ + VIDC_HWIO_IN(REG_489688, pn_decoded_size); +} + +void vidc_1080p_get_display_frame_result( + struct vidc_1080p_dec_disp_info *dec_disp_info) +{ + u32 display_result; + VIDC_HWIO_IN(REG_640904, &dec_disp_info->display_y_addr); + VIDC_HWIO_IN(REG_60114, &dec_disp_info->display_c_addr); + VIDC_HWIO_IN(REG_853667, &display_result); + VIDC_HWIO_IN(REG_845544, &dec_disp_info->img_size_y); + VIDC_HWIO_IN(REG_859906, &dec_disp_info->img_size_x); + dec_disp_info->display_status = + (enum vidc_1080p_display_status) + VIDC_GETFIELD(display_result, + VIDC_1080P_SI_RG7_DISPLAY_STATUS_MASK, + VIDC_1080P_SI_RG7_DISPLAY_STATUS_SHIFT); + dec_disp_info->display_coding = + (enum vidc_1080p_display_coding) + VIDC_GETFIELD(display_result, VIDC_1080P_SI_RG7_DISPLAY_CODING_MASK, + VIDC_1080P_SI_RG7_DISPLAY_CODING_SHIFT); + dec_disp_info->disp_resl_change = VIDC_GETFIELD(display_result, + VIDC_1080P_SI_RG7_DISPLAY_RES_MASK, + VIDC_1080P_SI_RG7_DISPLAY_RES_SHIFT); + dec_disp_info->disp_crop_exists = VIDC_GETFIELD(display_result, + VIDC_1080P_SI_RG7_DISPLAY_CROP_MASK, + VIDC_1080P_SI_RG7_DISPLAY_CROP_SHIFT); + dec_disp_info->display_correct = VIDC_GETFIELD(display_result, + VIDC_1080P_SI_RG7_DISPLAY_CORRECT_MASK, + VIDC_1080P_SI_RG7_DISPLAY_CORRECT_SHIFT); +} + +void vidc_1080p_get_decode_frame( + enum vidc_1080p_decode_frame *pe_frame) +{ + u32 frame = 0; + + VIDC_HWIO_IN(REG_760102, &frame); + *pe_frame = (enum vidc_1080p_decode_frame) + (frame & VIDC_1080P_SI_RG8_DECODE_FRAMETYPE_MASK); +} + +void vidc_1080p_get_decode_frame_result( + struct vidc_1080p_dec_disp_info *dec_disp_info) +{ + u32 decode_result; + + VIDC_HWIO_IN(REG_378318, &dec_disp_info->decode_y_addr); + VIDC_HWIO_IN(REG_203487, &dec_disp_info->decode_c_addr); + VIDC_HWIO_IN(REG_692991, &decode_result); + dec_disp_info->decode_status = (enum vidc_1080p_display_status) + VIDC_GETFIELD(decode_result, + VIDC_1080P_SI_RG11_DECODE_STATUS_MASK, + VIDC_1080P_SI_RG11_DECODE_STATUS_SHIFT); + dec_disp_info->decode_coding = (enum vidc_1080p_display_coding) + VIDC_GETFIELD(decode_result, + VIDC_1080P_SI_RG11_DECODE_CODING_MASK, + VIDC_1080P_SI_RG11_DECODE_CODING_SHIFT); + dec_disp_info->dec_resl_change = VIDC_GETFIELD(decode_result, + VIDC_1080P_SI_RG11_DECODE_RES_MASK, + VIDC_1080P_SI_RG11_DECODE_RES_SHIFT); + dec_disp_info->dec_crop_exists = VIDC_GETFIELD(decode_result, + VIDC_1080P_SI_RG11_DECODE_CROPP_MASK, + VIDC_1080P_SI_RG11_DECODE_CROPP_SHIFT); + dec_disp_info->decode_correct = VIDC_GETFIELD(decode_result, + VIDC_1080P_SI_RG11_DECODE_CORRECT_MASK, + VIDC_1080P_SI_RG11_DECODE_CORRECT_SHIFT); +} + +void vidc_1080p_decode_seq_start_ch0( + struct vidc_1080p_dec_seq_start_param *param) +{ + VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY); + VIDC_HWIO_OUT(REG_666957, VIDC_1080P_INIT_CH_INST_ID); + VIDC_HWIO_OUT(REG_117192, + param->stream_buffer_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_145068, param->stream_frame_size); + VIDC_HWIO_OUT(REG_921356, + param->descriptor_buffer_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_190381, param->stream_buffersize); + VIDC_HWIO_OUT(REG_85655, param->descriptor_buffer_size); + VIDC_HWIO_OUT(REG_889944, param->shared_mem_addr_offset); + VIDC_HWIO_OUT(REG_404623, 0); + VIDC_HWIO_OUT(REG_397087, param->cmd_seq_num); + VIDC_HWIO_OUT(REG_666957, VIDC_1080P_DEC_TYPE_SEQ_HEADER | + param->inst_id); +} + +void vidc_1080p_decode_seq_start_ch1( + struct vidc_1080p_dec_seq_start_param *param) +{ + VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY); + VIDC_HWIO_OUT(REG_313350, VIDC_1080P_INIT_CH_INST_ID); + VIDC_HWIO_OUT(REG_980194, + param->stream_buffer_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_936704, param->stream_frame_size); + VIDC_HWIO_OUT(REG_821977, + param->descriptor_buffer_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_887095, param->stream_buffersize); + VIDC_HWIO_OUT(REG_576987, param->descriptor_buffer_size); + VIDC_HWIO_OUT(REG_652528, param->shared_mem_addr_offset); + VIDC_HWIO_OUT(REG_404623, 0); + VIDC_HWIO_OUT(REG_254093, param->cmd_seq_num); + VIDC_HWIO_OUT(REG_313350, VIDC_1080P_DEC_TYPE_SEQ_HEADER | + param->inst_id); +} + +void vidc_1080p_decode_frame_start_ch0( + struct vidc_1080p_dec_frame_start_param *param) +{ + u32 dpb_config; + + VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY); + VIDC_HWIO_OUT(REG_666957, VIDC_1080P_INIT_CH_INST_ID); + if ((param->decode == VIDC_1080P_DEC_TYPE_LAST_FRAME_DATA) && + ((!param->stream_buffer_addr_offset) || + (!param->stream_frame_size))) { + VIDC_HWIO_OUT(REG_117192, 0); + VIDC_HWIO_OUT(REG_145068, 0); + VIDC_HWIO_OUT(REG_190381, 0); + } else { + VIDC_HWIO_OUT(REG_117192, + param->stream_buffer_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_145068, + param->stream_frame_size); + VIDC_HWIO_OUT(REG_190381, + param->stream_buffersize); + } + dpb_config = VIDC_SETFIELD(param->dmx_disable, + VIDC_1080P_SI_RG10_DMX_DISABLE_SHFT, + VIDC_1080P_SI_RG10_DMX_DISABLE_BMSK) | + VIDC_SETFIELD(param->dpb_flush, + VIDC_1080P_SI_RG10_DPB_FLUSH_SHFT, + VIDC_1080P_SI_RG10_DPB_FLUSH_BMSK) | + VIDC_SETFIELD(param->dpb_count, + VIDC_1080P_SI_RG10_NUM_DPB_SHFT, + VIDC_1080P_SI_RG10_NUM_DPB_BMSK); + VIDC_HWIO_OUT(REG_921356, + param->descriptor_buffer_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_85655, param->descriptor_buffer_size); + VIDC_HWIO_OUT(REG_86830, param->release_dpb_bit_mask); + VIDC_HWIO_OUT(REG_889944, param->shared_mem_addr_offset); + VIDC_HWIO_OUT(REG_404623, dpb_config); + VIDC_HWIO_OUT(REG_397087, param->cmd_seq_num); + VIDC_HWIO_OUT(REG_666957, (u32)param->decode | + param->inst_id); +} + + +void vidc_1080p_decode_frame_start_ch1( + struct vidc_1080p_dec_frame_start_param *param) +{ + u32 dpb_config; + + VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY); + VIDC_HWIO_OUT(REG_313350, VIDC_1080P_INIT_CH_INST_ID); + if ((param->decode == VIDC_1080P_DEC_TYPE_LAST_FRAME_DATA) && + ((!param->stream_buffer_addr_offset) || + (!param->stream_frame_size))) { + VIDC_HWIO_OUT(REG_980194, 0); + VIDC_HWIO_OUT(REG_936704, 0); + VIDC_HWIO_OUT(REG_887095, 0); + } else { + VIDC_HWIO_OUT(REG_980194, + param->stream_buffer_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_936704, + param->stream_frame_size); + VIDC_HWIO_OUT(REG_887095, + param->stream_buffersize); + } + dpb_config = VIDC_SETFIELD(param->dmx_disable, + VIDC_1080P_SI_RG10_DMX_DISABLE_SHFT, + VIDC_1080P_SI_RG10_DMX_DISABLE_BMSK) | + VIDC_SETFIELD(param->dpb_flush, + VIDC_1080P_SI_RG10_DPB_FLUSH_SHFT, + VIDC_1080P_SI_RG10_DPB_FLUSH_BMSK) | + VIDC_SETFIELD(param->dpb_count, + VIDC_1080P_SI_RG10_NUM_DPB_SHFT, + VIDC_1080P_SI_RG10_NUM_DPB_BMSK); + VIDC_HWIO_OUT(REG_821977, + param->descriptor_buffer_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_576987, param->descriptor_buffer_size); + VIDC_HWIO_OUT(REG_70448, param->release_dpb_bit_mask); + VIDC_HWIO_OUT(REG_652528, param->shared_mem_addr_offset); + VIDC_HWIO_OUT(REG_220637, dpb_config); + VIDC_HWIO_OUT(REG_254093, param->cmd_seq_num); + VIDC_HWIO_OUT(REG_313350, (u32)param->decode | + param->inst_id); +} + +void vidc_1080p_decode_init_buffers_ch0( + struct vidc_1080p_dec_init_buffers_param *param) +{ + u32 dpb_config; + VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY); + VIDC_HWIO_OUT(REG_666957, VIDC_1080P_INIT_CH_INST_ID); + dpb_config = VIDC_SETFIELD(param->dmx_disable, + VIDC_1080P_SI_RG10_DMX_DISABLE_SHFT, + VIDC_1080P_SI_RG10_DMX_DISABLE_BMSK) | + VIDC_SETFIELD(param->dpb_count, + VIDC_1080P_SI_RG10_NUM_DPB_SHFT, + VIDC_1080P_SI_RG10_NUM_DPB_BMSK); + VIDC_HWIO_OUT(REG_889944, param->shared_mem_addr_offset); + VIDC_HWIO_OUT(REG_404623, dpb_config); + VIDC_HWIO_OUT(REG_397087, param->cmd_seq_num); + VIDC_HWIO_OUT(REG_666957, VIDC_1080P_DEC_TYPE_INIT_BUFFERS | + param->inst_id); +} + +void vidc_1080p_decode_init_buffers_ch1( + struct vidc_1080p_dec_init_buffers_param *param) +{ + u32 dpb_config; + VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY); + VIDC_HWIO_OUT(REG_313350, VIDC_1080P_INIT_CH_INST_ID); + dpb_config = VIDC_SETFIELD(param->dmx_disable, + VIDC_1080P_SI_RG10_DMX_DISABLE_SHFT, + VIDC_1080P_SI_RG10_DMX_DISABLE_BMSK) | + VIDC_SETFIELD(param->dpb_count, + VIDC_1080P_SI_RG10_NUM_DPB_SHFT, + VIDC_1080P_SI_RG10_NUM_DPB_BMSK); + VIDC_HWIO_OUT(REG_652528, param->shared_mem_addr_offset); + VIDC_HWIO_OUT(REG_220637, dpb_config); + VIDC_HWIO_OUT(REG_254093, param->cmd_seq_num); + VIDC_HWIO_OUT(REG_313350, VIDC_1080P_DEC_TYPE_INIT_BUFFERS | + param->inst_id); +} + +void vidc_1080p_set_dec_resolution_ch0(u32 width, u32 height) +{ + VIDC_HWIO_OUT(REG_612810, height); + VIDC_HWIO_OUT(REG_175608, width); +} + +void vidc_1080p_set_dec_resolution_ch1(u32 width, u32 height) +{ + VIDC_HWIO_OUT(REG_655721, height); + VIDC_HWIO_OUT(REG_548308, width); +} + +void vidc_1080p_get_encode_frame_info( + struct vidc_1080p_enc_frame_info *frame_info) +{ + VIDC_HWIO_IN(REG_845544, &(frame_info->enc_frame_size)); + VIDC_HWIO_IN(REG_859906, + &(frame_info->enc_picture_count)); + VIDC_HWIO_IN(REG_490078, + &(frame_info->enc_write_pointer)); + VIDC_HWIO_IN(REG_640904, + (u32 *)(&(frame_info->enc_frame))); + VIDC_HWIO_IN(REG_60114, + &(frame_info->enc_luma_address)); + frame_info->enc_luma_address = frame_info->enc_luma_address << + VIDC_1080P_BASE_OFFSET_SHIFT; + VIDC_HWIO_IN(REG_489688, + &(frame_info->enc_chroma_address)); + frame_info->enc_chroma_address = frame_info->\ + enc_chroma_address << VIDC_1080P_BASE_OFFSET_SHIFT; +} + +void vidc_1080p_encode_seq_start_ch0( + struct vidc_1080p_enc_seq_start_param *param) +{ + VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY); + VIDC_HWIO_OUT(REG_666957, VIDC_1080P_INIT_CH_INST_ID); + VIDC_HWIO_OUT(REG_117192, + param->stream_buffer_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_921356, param->stream_buffer_size); + VIDC_HWIO_OUT(REG_889944, param->shared_mem_addr_offset); + VIDC_HWIO_OUT(REG_397087, param->cmd_seq_num); + VIDC_HWIO_OUT(REG_666957, VIDC_1080P_ENC_TYPE_SEQ_HEADER | + param->inst_id); +} + +void vidc_1080p_encode_seq_start_ch1( + struct vidc_1080p_enc_seq_start_param *param) +{ + VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY); + VIDC_HWIO_OUT(REG_313350, VIDC_1080P_INIT_CH_INST_ID); + VIDC_HWIO_OUT(REG_980194, + param->stream_buffer_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_821977, param->stream_buffer_size); + VIDC_HWIO_OUT(REG_652528, param->shared_mem_addr_offset); + VIDC_HWIO_OUT(REG_254093, param->cmd_seq_num); + VIDC_HWIO_OUT(REG_313350, VIDC_1080P_ENC_TYPE_SEQ_HEADER | + param->inst_id); +} + +void vidc_1080p_encode_frame_start_ch0( + struct vidc_1080p_enc_frame_start_param *param) +{ + u32 input_flush; + VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY); + VIDC_HWIO_OUT(REG_666957, VIDC_1080P_INIT_CH_INST_ID); + VIDC_HWIO_OUT(REG_117192, + param->stream_buffer_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_921356, param->stream_buffer_size); + VIDC_HWIO_OUT(REG_612810, param->current_y_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_175608, param->current_c_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_190381, param->intra_frame); + VIDC_HWIO_OUT(REG_889944, param->shared_mem_addr_offset); + input_flush = VIDC_SETFIELD(param->input_flush, + VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_SHFT, + VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_BMSK); + input_flush |= VIDC_SETFIELD(param->slice_enable, + VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_SHFT, + VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_BMSK); + VIDC_HWIO_OUT(REG_404623, input_flush); + VIDC_HWIO_OUT(REG_397087, param->cmd_seq_num); + + VIDC_HWIO_OUT(REG_666957, (u32)param->encode | + param->inst_id); +} + +void vidc_1080p_encode_frame_start_ch1( + struct vidc_1080p_enc_frame_start_param *param) +{ + u32 input_flush; + VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY); + VIDC_HWIO_OUT(REG_313350, VIDC_1080P_INIT_CH_INST_ID); + VIDC_HWIO_OUT(REG_980194, + param->stream_buffer_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_821977, param->stream_buffer_size); + VIDC_HWIO_OUT(REG_655721, param->current_y_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_548308, param->current_c_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_887095, param->intra_frame); + VIDC_HWIO_OUT(REG_652528, param->shared_mem_addr_offset); + input_flush = VIDC_SETFIELD(param->input_flush, + VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_SHFT, + VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_BMSK); + input_flush |= VIDC_SETFIELD(param->slice_enable, + VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_SHFT, + VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_BMSK); + + VIDC_HWIO_OUT(REG_404623, input_flush); + VIDC_HWIO_OUT(REG_254093, param->cmd_seq_num); + VIDC_HWIO_OUT(REG_313350, (u32)param->encode | + param->inst_id); +} + +void vidc_1080p_encode_slice_batch_start_ch0( + struct vidc_1080p_enc_frame_start_param *param) +{ + u32 input_flush; + VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY); + VIDC_HWIO_OUT(REG_666957, VIDC_1080P_INIT_CH_INST_ID); + VIDC_HWIO_OUT(REG_612810, param->current_y_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_175608, param->current_c_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_190381, param->intra_frame); + VIDC_HWIO_OUT(REG_889944, param->shared_mem_addr_offset); + input_flush = VIDC_SETFIELD(param->input_flush, + VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_SHFT, + VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_BMSK); + input_flush |= VIDC_SETFIELD(param->slice_enable, + VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_SHFT, + VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_BMSK); + VIDC_HWIO_OUT(REG_404623, input_flush); + VIDC_HWIO_OUT(REG_397087, param->cmd_seq_num); + + VIDC_HWIO_OUT(REG_666957, (u32)param->encode | + param->inst_id); + +} + +void vidc_1080p_encode_slice_batch_start_ch1( + struct vidc_1080p_enc_frame_start_param *param) +{ + u32 input_flush; + VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY); + VIDC_HWIO_OUT(REG_313350, VIDC_1080P_INIT_CH_INST_ID); + VIDC_HWIO_OUT(REG_655721, param->current_y_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_548308, param->current_c_addr_offset >> + VIDC_1080P_BASE_OFFSET_SHIFT); + VIDC_HWIO_OUT(REG_887095, param->intra_frame); + VIDC_HWIO_OUT(REG_652528, param->shared_mem_addr_offset); + input_flush = VIDC_SETFIELD(param->input_flush, + VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_SHFT, + VIDC_1080P_SI_RG10_ENCODE_INPUT_BUFFER_FLUSH_BMSK); + input_flush |= VIDC_SETFIELD(param->slice_enable, + VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_SHFT, + VIDC_1080P_SI_RG10_ENCODE_SLICE_IF_ENABLE_BMSK); + + VIDC_HWIO_OUT(REG_404623, input_flush); + VIDC_HWIO_OUT(REG_254093, param->cmd_seq_num); + VIDC_HWIO_OUT(REG_313350, (u32)param->encode | + param->inst_id); + +} + +void vidc_1080p_set_encode_picture(u32 number_p, u32 number_b) +{ + u32 picture, ifrm_ctrl; + if (number_p >= VIDC_1080P_MAX_INTRA_PERIOD) + ifrm_ctrl = 0; + else + ifrm_ctrl = number_p + 1; + picture = VIDC_SETFIELD(1 , + HWIO_REG_783891_ENC_PIC_TYPE_USE_SHFT, + HWIO_REG_783891_ENC_PIC_TYPE_USE_BMSK) | + VIDC_SETFIELD(ifrm_ctrl, + HWIO_REG_783891_I_FRM_CTRL_SHFT, + HWIO_REG_783891_I_FRM_CTRL_BMSK) + | VIDC_SETFIELD(number_b , + HWIO_REG_783891_B_FRM_CTRL_SHFT , + HWIO_REG_783891_B_FRM_CTRL_BMSK); + VIDC_HWIO_OUT(REG_783891, picture); +} + +void vidc_1080p_set_encode_multi_slice_control( + enum vidc_1080p_MSlice_selection multiple_slice_selection, + u32 mslice_mb, u32 mslice_byte) +{ + VIDC_HWIO_OUT(REG_226332, multiple_slice_selection); + VIDC_HWIO_OUT(REG_696136, mslice_mb); + VIDC_HWIO_OUT(REG_515564, mslice_byte); +} + +void vidc_1080p_set_encode_circular_intra_refresh(u32 cir_num) +{ + VIDC_HWIO_OUT(REG_886210, cir_num); +} + +void vidc_1080p_set_encode_input_frame_format( + enum vidc_1080p_memory_access_method memory_format) +{ + VIDC_HWIO_OUT(REG_645603, memory_format); +} + +void vidc_1080p_set_encode_padding_control(u32 pad_ctrl_on, + u32 cr_pad_val, u32 cb_pad_val, u32 luma_pad_val) +{ + u32 padding = VIDC_SETFIELD(pad_ctrl_on , + HWIO_REG_811733_PAD_CTRL_ON_SHFT, + HWIO_REG_811733_PAD_CTRL_ON_BMSK) | + VIDC_SETFIELD(cr_pad_val , + HWIO_REG_811733_CR_PAD_VIDC_SHFT , + HWIO_REG_811733_CR_PAD_VIDC_BMSK) | + VIDC_SETFIELD(cb_pad_val , + HWIO_REG_811733_CB_PAD_VIDC_SHFT , + HWIO_REG_811733_CB_PAD_VIDC_BMSK) | + VIDC_SETFIELD(luma_pad_val , + HWIO_REG_811733_LUMA_PAD_VIDC_SHFT , + HWIO_REG_811733_LUMA_PAD_VIDC_BMSK) ; + VIDC_HWIO_OUT(REG_811733, padding); +} + +void vidc_1080p_encode_set_rc_config(u32 enable_frame_level_rc, + u32 enable_mb_level_rc_flag, u32 frame_qp) +{ + u32 rc_config = VIDC_SETFIELD(enable_frame_level_rc , + HWIO_REG_559908_FR_RC_EN_SHFT , + HWIO_REG_559908_FR_RC_EN_BMSK) | + VIDC_SETFIELD(enable_mb_level_rc_flag , + HWIO_REG_559908_MB_RC_EN_SHFT, + HWIO_REG_559908_MB_RC_EN_BMSK) | + VIDC_SETFIELD(frame_qp , + HWIO_REG_559908_FRAME_QP_SHFT , + HWIO_REG_559908_FRAME_QP_BMSK); + VIDC_HWIO_OUT(REG_559908, rc_config); +} + +void vidc_1080p_encode_set_frame_level_rc_params(u32 rc_frame_rate, + u32 target_bitrate, u32 reaction_coeff) +{ + VIDC_HWIO_OUT(REG_977937, rc_frame_rate); + VIDC_HWIO_OUT(REG_166135, target_bitrate); + VIDC_HWIO_OUT(REG_550322, reaction_coeff); +} + +void vidc_1080p_encode_set_qp_params(u32 max_qp, u32 min_qp) +{ + u32 qbound = VIDC_SETFIELD(max_qp , HWIO_REG_109072_MAX_QP_SHFT, + HWIO_REG_109072_MAX_QP_BMSK) | + VIDC_SETFIELD(min_qp, + HWIO_REG_109072_MIN_QP_SHFT , + HWIO_REG_109072_MIN_QP_BMSK); + VIDC_HWIO_OUT(REG_109072, qbound); +} + +void vidc_1080p_encode_set_mb_level_rc_params(u32 disable_dark_region_as_flag, + u32 disable_smooth_region_as_flag , u32 disable_static_region_as_flag, + u32 disable_activity_region_flag) +{ + u32 rc_active_feature = VIDC_SETFIELD( + disable_dark_region_as_flag, + HWIO_REG_949086_DARK_DISABLE_SHFT, + HWIO_REG_949086_DARK_DISABLE_BMSK) | + VIDC_SETFIELD( + disable_smooth_region_as_flag, + HWIO_REG_949086_SMOOTH_DISABLE_SHFT, + HWIO_REG_949086_SMOOTH_DISABLE_BMSK) | + VIDC_SETFIELD( + disable_static_region_as_flag, + HWIO_REG_949086_STATIC_DISABLE_SHFT, + HWIO_REG_949086_STATIC_DISABLE_BMSK) | + VIDC_SETFIELD( + disable_activity_region_flag, + HWIO_REG_949086_ACT_DISABLE_SHFT, + HWIO_REG_949086_ACT_DISABLE_BMSK); + VIDC_HWIO_OUT(REG_949086, rc_active_feature); +} + +void vidc_1080p_set_h264_encode_entropy( + enum vidc_1080p_entropy_sel entropy_sel) +{ + VIDC_HWIO_OUT(REG_447796, entropy_sel); +} + +void vidc_1080p_set_h264_encode_loop_filter( + enum vidc_1080p_DBConfig db_config, u32 slice_alpha_offset, + u32 slice_beta_offset) +{ + VIDC_HWIO_OUT(REG_152500, db_config); + VIDC_HWIO_OUT(REG_266285, slice_alpha_offset); + VIDC_HWIO_OUT(REG_964731, slice_beta_offset); +} + +void vidc_1080p_set_h264_encoder_p_frame_ref_count(u32 max_reference) +{ + u32 ref_frames; + ref_frames = VIDC_SETFIELD(max_reference, + HWIO_REG_744348_P_SHFT, + HWIO_REG_744348_P_BMSK); + VIDC_HWIO_OUT(REG_744348, ref_frames); +} + +void vidc_1080p_set_h264_encode_8x8transform_control(u32 enable_8x8transform) +{ + VIDC_HWIO_OUT(REG_672163, enable_8x8transform); +} + +void vidc_1080p_set_mpeg4_encode_quarter_pel_control( + u32 enable_mpeg4_quarter_pel) +{ + VIDC_HWIO_OUT(REG_330132, enable_mpeg4_quarter_pel); +} + +void vidc_1080p_set_device_base_addr(u8 *mapped_va) +{ + VIDC_BASE_PTR = mapped_va; +} + +void vidc_1080p_get_intra_bias(u32 *bias) +{ + u32 intra_bias; + + VIDC_HWIO_IN(REG_676866, &intra_bias); + *bias = VIDC_GETFIELD(intra_bias, + HWIO_REG_676866_RMSK, + HWIO_REG_676866_SHFT); +} + +void vidc_1080p_set_intra_bias(u32 bias) +{ + u32 intra_bias; + + intra_bias = VIDC_SETFIELD(bias, + HWIO_REG_676866_SHFT, + HWIO_REG_676866_RMSK); + VIDC_HWIO_OUT(REG_676866, intra_bias); +} + +void vidc_1080p_get_bi_directional_bias(u32 *bi_directional_bias) +{ + u32 nbi_direct_bias; + + VIDC_HWIO_IN(REG_54267, &nbi_direct_bias); + *bi_directional_bias = VIDC_GETFIELD(nbi_direct_bias, + HWIO_REG_54267_RMSK, + HWIO_REG_54267_SHFT); +} + +void vidc_1080p_set_bi_directional_bias(u32 bi_directional_bias) +{ + u32 nbi_direct_bias; + + nbi_direct_bias = VIDC_SETFIELD(bi_directional_bias, + HWIO_REG_54267_SHFT, + HWIO_REG_54267_RMSK); + VIDC_HWIO_OUT(REG_54267, nbi_direct_bias); +} + +void vidc_1080p_get_encoder_sequence_header_size(u32 *seq_header_size) +{ + VIDC_HWIO_IN(REG_845544, seq_header_size); +} + +void vidc_1080p_get_intermedia_stage_debug_counter( + u32 *intermediate_stage_counter) +{ + VIDC_HWIO_IN(REG_805993, intermediate_stage_counter); +} + +void vidc_1080p_get_exception_status(u32 *exception_status) +{ + VIDC_HWIO_IN(REG_493355, exception_status); +} + +void vidc_1080p_frame_start_realloc(u32 instance_id) +{ + VIDC_HWIO_OUT(REG_695082, VIDC_1080P_RISC2HOST_CMD_EMPTY); + VIDC_HWIO_OUT(REG_666957, VIDC_1080P_INIT_CH_INST_ID); + VIDC_HWIO_OUT(REG_666957, + VIDC_1080P_DEC_TYPE_FRAME_START_REALLOC | instance_id); +} diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc.h b/drivers/video/msm/vidc/1080p/ddl/vidc.h new file mode 100644 index 000000000000..39d3e8fd887a --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vidc.h @@ -0,0 +1,586 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#ifndef _VIDC_H_ +#define _VIDC_H_ + +#include "vidc_hwio_reg.h" + +#define VIDC_1080P_RISC2HOST_CMD_EMPTY 0 +#define VIDC_1080P_RISC2HOST_CMD_OPEN_CH_RET 1 +#define VIDC_1080P_RISC2HOST_CMD_CLOSE_CH_RET 2 +#define VIDC_1080P_RISC2HOST_CMD_SEQ_DONE_RET 4 +#define VIDC_1080P_RISC2HOST_CMD_FRAME_DONE_RET 5 +#define VIDC_1080P_RISC2HOST_CMD_SLICE_DONE_RET 6 +#define VIDC_1080P_RISC2HOST_CMD_ENC_COMPLETE_RET 7 +#define VIDC_1080P_RISC2HOST_CMD_SYS_INIT_RET 8 +#define VIDC_1080P_RISC2HOST_CMD_FW_STATUS_RET 9 +#define VIDC_1080P_RISC2HOST_CMD_FLUSH_COMMAND_RET 12 +#define VIDC_1080P_RISC2HOST_CMD_ABORT_RET 13 +#define VIDC_1080P_RISC2HOST_CMD_BATCH_ENC_RET 14 +#define VIDC_1080P_RISC2HOST_CMD_INIT_BUFFERS_RET 15 +#define VIDC_1080P_RISC2HOST_CMD_EDFU_INT_RET 16 +#define VIDC_1080P_RISC2HOST_CMD_ERROR_RET 32 + +#define VIDC_RISC2HOST_ARG2_VIDC_DISP_ERROR_STATUS_BMSK 0xffff0000 +#define VIDC_RISC2HOST_ARG2_VIDC_DISP_ERROR_STATUS_SHFT 16 +#define VIDC_RISC2HOST_ARG2_VIDC_DEC_ERROR_STATUS_BMSK 0x0000ffff +#define VIDC_RISC2HOST_ARG2_VIDC_DEC_ERROR_STATUS_SHFT 0 + +#define VIDC_1080P_ERROR_INVALID_CHANNEL_NUMBER 1 +#define VIDC_1080P_ERROR_INVALID_COMMAND_ID 2 +#define VIDC_1080P_ERROR_CHANNEL_ALREADY_IN_USE 3 +#define VIDC_1080P_ERROR_CHANNEL_NOT_OPEN_BEFORE_CHANNEL_CLOSE 4 +#define VIDC_1080P_ERROR_OPEN_CH_ERROR_SEQ_START 5 +#define VIDC_1080P_ERROR_SEQ_START_ALREADY_CALLED 6 +#define VIDC_1080P_ERROR_OPEN_CH_ERROR_INIT_BUFFERS 7 +#define VIDC_1080P_ERROR_SEQ_START_ERROR_INIT_BUFFERS 8 +#define VIDC_1080P_ERROR_INIT_BUFFER_ALREADY_CALLED 9 +#define VIDC_1080P_ERROR_OPEN_CH_ERROR_FRAME_START 10 +#define VIDC_1080P_ERROR_SEQ_START_ERROR_FRAME_START 11 +#define VIDC_1080P_ERROR_INIT_BUFFERS_ERROR_FRAME_START 12 +#define VIDC_1080P_ERROR_RESOLUTION_CHANGED 13 +#define VIDC_1080P_ERROR_INVALID_COMMAND_LAST_FRAME 14 +#define VIDC_1080P_ERROR_INVALID_COMMAND 15 +#define VIDC_1080P_ERROR_INVALID_CODEC_TYPE 16 + +#define VIDC_1080P_ERROR_MEM_ALLOCATION_FAILED 20 +#define VIDC_1080P_ERROR_INSUFFICIENT_CONTEXT_SIZE 25 +#define VIDC_1080P_ERROR_UNSUPPORTED_FEATURE_IN_PROFILE 27 +#define VIDC_1080P_ERROR_RESOLUTION_NOT_SUPPORTED 28 + +#define VIDC_1080P_ERROR_HEADER_NOT_FOUND 52 +#define VIDC_1080P_ERROR_VOS_END_CODE_RECEIVED 53 +#define VIDC_1080P_ERROR_FRAME_RATE_NOT_SUPPORTED 62 +#define VIDC_1080P_ERROR_INVALID_QP_VALUE 63 +#define VIDC_1080P_ERROR_INVALID_RC_REACTION_COEFFICIENT 64 +#define VIDC_1080P_ERROR_INVALID_CPB_SIZE_AT_GIVEN_LEVEL 65 +#define VIDC_1080P_ERROR_B_FRAME_NOT_SUPPORTED 66 +#define VIDC_1080P_ERROR_ALLOC_DPB_SIZE_NOT_SUFFICIENT 71 +#define VIDC_1080P_ERROR_NUM_DPB_OUT_OF_RANGE 74 +#define VIDC_1080P_ERROR_NULL_METADATA_INPUT_POINTER 77 +#define VIDC_1080P_ERROR_NULL_DPB_POINTER 78 +#define VIDC_1080P_ERROR_NULL_OTH_EXT_BUFADDR 79 +#define VIDC_1080P_ERROR_NULL_MV_POINTER 80 +#define VIDC_1080P_ERROR_DIVIDE_BY_ZERO 81 +#define VIDC_1080P_ERROR_BIT_STREAM_BUF_EXHAUST 82 +#define VIDC_1080P_ERROR_DESCRIPTOR_BUFFER_EMPTY 83 +#define VIDC_1080P_ERROR_DMA_TX_NOT_COMPLETE 84 +#define VIDC_1080P_ERROR_DESCRIPTOR_TABLE_ENTRY_INVALID 85 +#define VIDC_1080P_ERROR_MB_COEFF_NOT_DONE 86 +#define VIDC_1080P_ERROR_CODEC_SLICE_NOT_DONE 87 +#define VIDC_1080P_ERROR_VIDC_CORE_TIME_OUT 88 +#define VIDC_1080P_ERROR_VC1_BITPLANE_DECODE_ERR 89 +#define VIDC_1080P_ERROR_VSP_NOT_READY 90 +#define VIDC_1080P_ERROR_BUFFER_FULL_STATE 91 + +#define VIDC_1080P_ERROR_RESOLUTION_MISMATCH 112 +#define VIDC_1080P_ERROR_NV_QUANT_ERR 113 +#define VIDC_1080P_ERROR_SYNC_MARKER_ERR 114 +#define VIDC_1080P_ERROR_FEATURE_NOT_SUPPORTED 115 +#define VIDC_1080P_ERROR_MEM_CORRUPTION 116 +#define VIDC_1080P_ERROR_INVALID_REFERENCE_FRAME 117 +#define VIDC_1080P_ERROR_PICTURE_CODING_TYPE_ERR 118 +#define VIDC_1080P_ERROR_MV_RANGE_ERR 119 +#define VIDC_1080P_ERROR_PICTURE_STRUCTURE_ERR 120 +#define VIDC_1080P_ERROR_SLICE_ADDR_INVALID 121 +#define VIDC_1080P_ERROR_NON_PAIRED_FIELD_NOT_SUPPORTED 122 +#define VIDC_1080P_ERROR_NON_FRAME_DATA_RECEIVED 123 +#define VIDC_1080P_ERROR_NO_BUFFER_RELEASED_FROM_HOST 125 +#define VIDC_1080P_ERROR_NULL_FW_DEBUG_INFO_POINTER 126 +#define VIDC_1080P_ERROR_ALLOC_DEBUG_INFO_SIZE_INSUFFICIENT 127 +#define VIDC_1080P_ERROR_NALU_HEADER_ERROR 128 +#define VIDC_1080P_ERROR_SPS_PARSE_ERROR 129 +#define VIDC_1080P_ERROR_PPS_PARSE_ERROR 130 +#define VIDC_1080P_ERROR_SLICE_PARSE_ERROR 131 +#define VIDC_1080P_ERROR_SYNC_POINT_NOT_RECEIVED 171 + +#define VIDC_1080P_WARN_COMMAND_FLUSHED 145 +#define VIDC_1080P_WARN_METADATA_NO_SPACE_NUM_CONCEAL_MB 150 +#define VIDC_1080P_WARN_METADATA_NO_SPACE_QP 151 +#define VIDC_1080P_WARN_METADATA_NO_SPACE_CONCEAL_MB 152 +#define VIDC_1080P_WARN_METADATA_NO_SPACE_VC1_PARAM 153 +#define VIDC_1080P_WARN_METADATA_NO_SPACE_SEI 154 +#define VIDC_1080P_WARN_METADATA_NO_SPACE_VUI 155 +#define VIDC_1080P_WARN_METADATA_NO_SPACE_EXTRA 156 +#define VIDC_1080P_WARN_METADATA_NO_SPACE_DATA_NONE 157 +#define VIDC_1080P_WARN_FRAME_RATE_UNKNOWN 158 +#define VIDC_1080P_WARN_ASPECT_RATIO_UNKNOWN 159 +#define VIDC_1080P_WARN_COLOR_PRIMARIES_UNKNOWN 160 +#define VIDC_1080P_WARN_TRANSFER_CHAR_UNKNOWN 161 +#define VIDC_1080P_WARN_MATRIX_COEFF_UNKNOWN 162 +#define VIDC_1080P_WARN_NON_SEQ_SLICE_ADDR 163 +#define VIDC_1080P_WARN_BROKEN_LINK 164 +#define VIDC_1080P_WARN_FRAME_CONCEALED 165 +#define VIDC_1080P_WARN_PROFILE_UNKNOWN 166 +#define VIDC_1080P_WARN_LEVEL_UNKNOWN 167 +#define VIDC_1080P_WARN_BIT_RATE_NOT_SUPPORTED 168 +#define VIDC_1080P_WARN_COLOR_DIFF_FORMAT_NOT_SUPPORTED 169 +#define VIDC_1080P_WARN_NULL_EXTRA_METADATA_POINTER 170 +#define VIDC_1080P_WARN_DEBLOCKING_NOT_DONE 178 +#define VIDC_1080P_WARN_INCOMPLETE_FRAME 179 +#define VIDC_1080P_WARN_METADATA_NO_SPACE_MB_INFO 180 +#define VIDC_1080P_WARN_METADATA_NO_SPACE_SLICE_SIZE 181 +#define VIDC_1080P_WARN_RESOLUTION_WARNING 182 + +#define VIDC_1080P_WARN_NO_LONG_TERM_REFERENCE 183 +#define VIDC_1080P_WARN_NO_SPACE_MPEG2_DATA_DUMP 190 +#define VIDC_1080P_WARN_METADATA_NO_SPACE_MISSING_MB 191 + +#define VIDC_1080P_H264_ENC_TYPE_P 0 +#define VIDC_1080P_H264_ENC_TYPE_B 1 +#define VIDC_1080P_H264_ENC_TYPE_IDR 2 +#define VIDC_1080P_MP4_H263_ENC_TYPE_I 0 +#define VIDC_1080P_MP4_H263_ENC_TYPE_P 1 +#define VIDC_1080P_MP4_H263_ENC_TYPE_B 2 + +#define VIDC_1080P_MPEG4_LEVEL0 0 +#define VIDC_1080P_MPEG4_LEVEL0b 9 +#define VIDC_1080P_MPEG4_LEVEL1 1 +#define VIDC_1080P_MPEG4_LEVEL2 2 +#define VIDC_1080P_MPEG4_LEVEL3 3 +#define VIDC_1080P_MPEG4_LEVEL3b 7 +#define VIDC_1080P_MPEG4_LEVEL4 4 +#define VIDC_1080P_MPEG4_LEVEL4a 4 +#define VIDC_1080P_MPEG4_LEVEL5 5 +#define VIDC_1080P_MPEG4_LEVEL6 6 +#define VIDC_1080P_MPEG4_LEVEL7 7 + +#define VIDC_1080P_H264_LEVEL1 10 +#define VIDC_1080P_H264_LEVEL1b 9 +#define VIDC_1080P_H264_LEVEL1p1 11 +#define VIDC_1080P_H264_LEVEL1p2 12 +#define VIDC_1080P_H264_LEVEL1p3 13 +#define VIDC_1080P_H264_LEVEL2 20 +#define VIDC_1080P_H264_LEVEL2p1 21 +#define VIDC_1080P_H264_LEVEL2p2 22 +#define VIDC_1080P_H264_LEVEL3 30 +#define VIDC_1080P_H264_LEVEL3p1 31 +#define VIDC_1080P_H264_LEVEL3p2 32 +#define VIDC_1080P_H264_LEVEL4 40 +#define VIDC_1080P_H264_LEVEL5p1 51 +#define VIDC_1080P_H264_LEVEL_MAX VIDC_1080P_H264_LEVEL5p1 + +#define VIDC_1080P_H263_LEVEL10 10 +#define VIDC_1080P_H263_LEVEL20 20 +#define VIDC_1080P_H263_LEVEL30 30 +#define VIDC_1080P_H263_LEVEL40 40 +#define VIDC_1080P_H263_LEVEL45 45 +#define VIDC_1080P_H263_LEVEL50 50 +#define VIDC_1080P_H263_LEVEL60 60 +#define VIDC_1080P_H263_LEVEL70 70 + +#define VIDC_1080P_BUS_ERROR_HANDLER 0x01 +#define VIDC_1080P_ILLEVIDC_INSTRUCTION_HANDLER 0x02 +#define VIDC_1080P_TICK_HANDLER 0x04 +#define VIDC_1080P_TRAP_HANDLER 0x10 +#define VIDC_1080P_ALIGN_HANDLER 0x20 +#define VIDC_1080P_RANGE_HANDLER 0x40 +#define VIDC_1080P_DTLB_MISS_EXCEPTION_HANDLER 0x80 +#define VIDC_1080P_ITLB_MISS_EXCEPTION_HANDLER 0x100 +#define VIDC_1080P_DATA_PAGE_FAULT_EXCEPTION_HANDLER 0x200 +#define VIDC_1080P_INST_PAGE_FAULT_EXCEPTION_HANDLER 0x400 +#define VIDC_1080P_SLICE_BATCH_MAX_STRM_BFR 8 +#define VIDC_1080P_SLICE_BATCH_IN_SIZE(idx) (4 * sizeof(u32) + \ + idx * sizeof(u32)) +enum vidc_1080p_reset{ + VIDC_1080P_RESET_IN_SEQ_FIRST_STAGE = 0x0, + VIDC_1080P_RESET_IN_SEQ_SECOND_STAGE = 0x1, +}; +enum vidc_1080p_memory_access_method{ + VIDC_1080P_TILE_LINEAR = 0, + VIDC_1080P_TILE_16x16 = 2, + VIDC_1080P_TILE_64x32 = 3, + VIDC_1080P_TILE_32BIT = 0x7FFFFFFF +}; +enum vidc_1080p_host2risc_cmd{ + VIDC_1080P_HOST2RISC_CMD_EMPTY = 0, + VIDC_1080P_HOST2RISC_CMD_OPEN_CH = 1, + VIDC_1080P_HOST2RISC_CMD_CLOSE_CH = 2, + VIDC_1080P_HOST2RISC_CMD_SYS_INIT = 3, + VIDC_1080P_HOST2RISC_CMD_FLUSH_COMMMAND = 4, + VIDC_1080P_HOST2RISC_CMD_CONTINUE_ENC = 7, + VIDC_1080P_HOST2RISC_CMD_ABORT_ENC = 8, + VIDC_1080P_HOST2RISC_CMD_32BIT = 0x7FFFFFFF +}; +enum vidc_1080p_decode_p_cache_enable{ + VIDC_1080P_DECODE_PCACHE_ENABLE_P = 0, + VIDC_1080P_DECODE_PCACHE_ENABLE_B = 1, + VIDC_1080P_DECODE_PCACHE_ENABLE_PB = 2, + VIDC_1080P_DECODE_PCACHE_DISABLE = 3, + VIDC_1080P_DECODE_PCACHE_32BIT = 0x7FFFFFFF +}; +enum vidc_1080p_encode_p_cache_enable{ + VIDC_1080P_ENCODE_PCACHE_ENABLE = 0, + VIDC_1080P_ENCODE_PCACHE_DISABLE = 3, + VIDC_1080P_ENCODE_PCACHE_32BIT = 0x7FFFFFFF +}; +enum vidc_1080p_codec{ + VIDC_1080P_H264_DECODE = 0, + VIDC_1080P_VC1_DECODE = 1, + VIDC_1080P_MPEG4_DECODE = 2, + VIDC_1080P_MPEG2_DECODE = 3, + VIDC_1080P_H263_DECODE = 4, + VIDC_1080P_VC1_RCV_DECODE = 5, + VIDC_1080P_DIVX311_DECODE = 6, + VIDC_1080P_DIVX412_DECODE = 7, + VIDC_1080P_DIVX502_DECODE = 8, + VIDC_1080P_DIVX503_DECODE = 9, + VIDC_1080P_H264_ENCODE = 16, + VIDC_1080P_MPEG4_ENCODE = 17, + VIDC_1080P_H263_ENCODE = 18, + VIDC_1080P_CODEC_32BIT = 0x7FFFFFFF +}; +enum vidc_1080p_entropy_sel{ + VIDC_1080P_ENTROPY_SEL_CAVLC = 0, + VIDC_1080P_ENTROPY_SEL_CABAC = 1, + VIDC_1080P_ENTROPY_32BIT = 0x7FFFFFFF +}; +enum vidc_1080p_DBConfig{ + VIDC_1080P_DB_ALL_BLOCKING_BOUNDARY = 0, + VIDC_1080P_DB_DISABLE = 1, + VIDC_1080P_DB_SKIP_SLICE_BOUNDARY = 2, + VIDC_1080P_DB_32BIT = 0x7FFFFFFF +}; +enum vidc_1080p_MSlice_selection{ + VIDC_1080P_MSLICE_DISABLE = 0, + VIDC_1080P_MSLICE_BY_MB_COUNT = 1, + VIDC_1080P_MSLICE_BY_BYTE_COUNT = 3, + VIDC_1080P_MSLICE_32BIT = 0x7FFFFFFF +}; +enum vidc_1080p_display_status{ + VIDC_1080P_DISPLAY_STATUS_DECODE_ONLY = 0, + VIDC_1080P_DISPLAY_STATUS_DECODE_AND_DISPLAY = 1, + VIDC_1080P_DISPLAY_STATUS_DISPLAY_ONLY = 2, + VIDC_1080P_DISPLAY_STATUS_DPB_EMPTY = 3, + VIDC_1080P_DISPLAY_STATUS_NOOP = 4, + VIDC_1080P_DISPLAY_STATUS_32BIT = 0x7FFFFFFF +}; +enum vidc_1080p_display_coding{ + VIDC_1080P_DISPLAY_CODING_PROGRESSIVE_SCAN = 0, + VIDC_1080P_DISPLAY_CODING_INTERLACED = 1, + VIDC_1080P_DISPLAY_CODING_32BIT = 0x7FFFFFFF +}; +enum vidc_1080p_decode_frame{ + VIDC_1080P_DECODE_FRAMETYPE_NOT_CODED = 0, + VIDC_1080P_DECODE_FRAMETYPE_I = 1, + VIDC_1080P_DECODE_FRAMETYPE_P = 2, + VIDC_1080P_DECODE_FRAMETYPE_B = 3, + VIDC_1080P_DECODE_FRAMETYPE_OTHERS = 4, + VIDC_1080P_DECODE_FRAMETYPE_32BIT = 0x7FFFFFFF +}; +enum vidc_1080P_decode_frame_correct_type { + VIDC_1080P_DECODE_NOT_CORRECT = 0, + VIDC_1080P_DECODE_CORRECT = 1, + VIDC_1080P_DECODE_APPROX_CORRECT = 2, + VIDC_1080P_DECODE_CORRECTTYPE_32BIT = 0x7FFFFFFF +}; +enum vidc_1080p_encode_frame{ + VIDC_1080P_ENCODE_FRAMETYPE_NOT_CODED = 0, + VIDC_1080P_ENCODE_FRAMETYPE_I = 1, + VIDC_1080P_ENCODE_FRAMETYPE_P = 2, + VIDC_1080P_ENCODE_FRAMETYPE_B = 3, + VIDC_1080P_ENCODE_FRAMETYPE_SKIPPED = 4, + VIDC_1080P_ENCODE_FRAMETYPE_OTHERS = 5, + VIDC_1080P_ENCODE_FRAMETYPE_32BIT = 0x7FFFFFFF + +}; + +enum vidc_1080p_decode_idc_format { + VIDC_1080P_IDCFORMAT_MONOCHROME = 0, + VIDC_1080P_IDCFORMAT_420 = 1, + VIDC_1080P_IDCFORMAT_422 = 2, + VIDC_1080P_IDCFORMAT_444 = 3, + VIDC_1080P_IDCFORMAT_OTHERS = 4, + VIDC_1080P_IDCFORMAT_32BIT = 0x7FFFFFFF +}; + +#define VIDC_1080P_PROFILE_MPEG4_SIMPLE 0x00000000 +#define VIDC_1080P_PROFILE_MPEG4_ADV_SIMPLE 0x00000001 + +#define VIDC_1080P_PROFILE_H264_MAIN 0x00000000 +#define VIDC_1080P_PROFILE_H264_HIGH 0x00000001 +#define VIDC_1080P_PROFILE_H264_BASELINE 0x00000002 + + +enum vidc_1080p_decode{ + VIDC_1080P_DEC_TYPE_SEQ_HEADER = 0x00010000, + VIDC_1080P_DEC_TYPE_FRAME_DATA = 0x00020000, + VIDC_1080P_DEC_TYPE_LAST_FRAME_DATA = 0x00030000, + VIDC_1080P_DEC_TYPE_INIT_BUFFERS = 0x00040000, + VIDC_1080P_DEC_TYPE_FRAME_START_REALLOC = 0x00050000, + VIDC_1080P_DEC_TYPE_32BIT = 0x7FFFFFFF +}; +enum vidc_1080p_encode{ + VIDC_1080P_ENC_TYPE_SEQ_HEADER = 0x00010000, + VIDC_1080P_ENC_TYPE_FRAME_DATA = 0x00020000, + VIDC_1080P_ENC_TYPE_LAST_FRAME_DATA = 0x00030000, + VIDC_1080P_ENC_TYPE_SLICE_BATCH_START = 0x00070000, + VIDC_1080P_ENC_TYPE_32BIT = 0x7FFFFFFF +}; +struct vidc_1080p_dec_seq_start_param{ + u32 cmd_seq_num; + u32 inst_id; + u32 shared_mem_addr_offset; + u32 stream_buffer_addr_offset; + u32 stream_buffersize; + u32 stream_frame_size; + u32 descriptor_buffer_addr_offset; + u32 descriptor_buffer_size; +}; +struct vidc_1080p_dec_frame_start_param{ + u32 cmd_seq_num; + u32 inst_id; + u32 shared_mem_addr_offset; + u32 stream_buffer_addr_offset; + u32 stream_buffersize; + u32 stream_frame_size; + u32 descriptor_buffer_addr_offset; + u32 descriptor_buffer_size; + u32 release_dpb_bit_mask; + u32 dpb_count; + u32 dpb_flush; + u32 dmx_disable; + enum vidc_1080p_decode decode; +}; +struct vidc_1080p_dec_init_buffers_param{ + u32 cmd_seq_num; + u32 inst_id; + u32 shared_mem_addr_offset; + u32 dpb_count; + u32 dmx_disable; +}; +struct vidc_1080p_seq_hdr_info{ + u32 img_size_x; + u32 img_size_y; + u32 dec_frm_size; + u32 min_num_dpb; + u32 min_luma_dpb_size; + u32 min_chroma_dpb_size; + u32 profile; + u32 level; + u32 disp_progressive; + u32 disp_crop_exists; + u32 dec_progressive; + u32 dec_crop_exists; + u32 crop_right_offset; + u32 crop_left_offset; + u32 crop_bottom_offset; + u32 crop_top_offset; + u32 data_partition; +}; +struct vidc_1080p_enc_seq_start_param{ + u32 cmd_seq_num; + u32 inst_id; + u32 shared_mem_addr_offset; + u32 stream_buffer_addr_offset; + u32 stream_buffer_size; +}; +struct vidc_1080p_enc_frame_start_param{ + u32 cmd_seq_num; + u32 inst_id; + u32 shared_mem_addr_offset; + u32 current_y_addr_offset; + u32 current_c_addr_offset; + u32 stream_buffer_addr_offset; + u32 stream_buffer_size; + u32 intra_frame; + u32 input_flush; + u32 slice_enable; + enum vidc_1080p_encode encode; +}; +struct vidc_1080p_enc_frame_info{ + u32 enc_frame_size; + u32 enc_picture_count; + u32 enc_write_pointer; + u32 enc_luma_address; + u32 enc_chroma_address; + enum vidc_1080p_encode_frame enc_frame; + u32 meta_data_exists; +}; +struct vidc_1080p_enc_slice_batch_in_param { + u32 cmd_type; + u32 input_size; + u32 num_stream_buffer; + u32 stream_buffer_size; + u32 stream_buffer_addr_offset[VIDC_1080P_SLICE_BATCH_MAX_STRM_BFR]; +}; +struct vidc_1080p_enc_slice_info { + u32 stream_buffer_idx; + u32 stream_buffer_size; +}; +struct vidc_1080p_enc_slice_batch_out_param { + u32 cmd_type; + u32 output_size; + struct vidc_1080p_enc_slice_info slice_info + [VIDC_1080P_SLICE_BATCH_MAX_STRM_BFR]; +}; +struct vidc_1080p_dec_disp_info{ + u32 disp_resl_change; + u32 dec_resl_change; + u32 reconfig_flush_done; + u32 img_size_x; + u32 img_size_y; + u32 display_y_addr; + u32 display_c_addr; + u32 decode_y_addr; + u32 decode_c_addr; + u32 tag_top; + u32 pic_time_top; + u32 tag_bottom; + u32 pic_time_bottom; + u32 metadata_exists; + u32 disp_crop_exists; + u32 dec_crop_exists; + u32 crop_right_offset; + u32 crop_left_offset; + u32 crop_bottom_offset; + u32 crop_top_offset; + u32 input_bytes_consumed; + u32 input_is_interlace; + u32 input_frame_num; + enum vidc_1080p_display_status display_status; + enum vidc_1080p_display_status decode_status; + enum vidc_1080p_display_coding display_coding; + enum vidc_1080p_display_coding decode_coding; + enum vidc_1080P_decode_frame_correct_type display_correct; + enum vidc_1080P_decode_frame_correct_type decode_correct; + enum vidc_1080p_decode_frame input_frame; +}; +void vidc_1080p_do_sw_reset(enum vidc_1080p_reset init_flag); +void vidc_1080p_release_sw_reset(void); +void vidc_1080p_clear_interrupt(void); +void vidc_1080p_set_host2risc_cmd( + enum vidc_1080p_host2risc_cmd host2risc_command, + u32 host2risc_arg1, u32 host2risc_arg2, + u32 host2risc_arg3, u32 host2risc_arg4); +void vidc_1080p_get_risc2host_cmd(u32 *pn_risc2host_command, + u32 *pn_risc2host_arg1, u32 *pn_risc2host_arg2, + u32 *pn_risc2host_arg3, u32 *pn_risc2host_arg4); +void vidc_1080p_get_risc2host_cmd_status(u32 err_status, + u32 *dec_err_status, u32 *disp_err_status); +void vidc_1080p_clear_risc2host_cmd(void); +void vidc_1080p_get_fw_version(u32 *pn_fw_version); +void vidc_1080p_get_fw_status(u32 *pn_fw_status); +void vidc_1080p_init_memory_controller(u32 dram_base_addr_a, + u32 dram_base_addr_b); +void vidc_1080p_get_memory_controller_status(u32 *pb_mc_abusy, + u32 *pb_mc_bbusy); +void vidc_1080p_set_h264_decode_buffers(u32 dpb, u32 dec_vert_nb_mv_offset, + u32 dec_nb_ip_offset, u32 *pn_dpb_luma_offset, + u32 *pn_dpb_chroma_offset, u32 *pn_mv_buffer_offset); +void vidc_1080p_set_decode_recon_buffers(u32 recon_buffer, u32 *pn_dec_luma, + u32 *pn_dec_chroma); +void vidc_1080p_set_mpeg4_divx_decode_work_buffers(u32 nb_dcac_buffer_offset, + u32 upnb_mv_buffer_offset, u32 sub_anchor_buffer_offset, + u32 overlay_transform_buffer_offset, u32 stx_parser_buffer_offset); +void vidc_1080p_set_h263_decode_work_buffers(u32 nb_dcac_buffer_offset, + u32 upnb_mv_buffer_offset, u32 sub_anchor_buffer_offset, + u32 overlay_transform_buffer_offset); +void vidc_1080p_set_vc1_decode_work_buffers(u32 nb_dcac_buffer_offset, + u32 upnb_mv_buffer_offset, u32 sub_anchor_buffer_offset, + u32 overlay_transform_buffer_offset, u32 bitplain1Buffer_offset, + u32 bitplain2Buffer_offset, u32 bitplain3Buffer_offset); +void vidc_1080p_set_encode_recon_buffers(u32 recon_buffer, u32 *pn_enc_luma, + u32 *pn_enc_chroma); +void vidc_1080p_set_h264_encode_work_buffers(u32 up_row_mv_buffer_offset, + u32 direct_colzero_flag_buffer_offset, + u32 upper_intra_md_buffer_offset, + u32 upper_intra_pred_buffer_offset, u32 nbor_infor_buffer_offset, + u32 mb_info_offset); +void vidc_1080p_set_h263_encode_work_buffers(u32 up_row_mv_buffer_offset, + u32 up_row_inv_quanti_coeff_buffer_offset); +void vidc_1080p_set_mpeg4_encode_work_buffers(u32 skip_flag_buffer_offset, + u32 up_row_inv_quanti_coeff_buffer_offset, u32 upper_mv_offset); +void vidc_1080p_set_encode_frame_size(u32 hori_size, u32 vert_size); +void vidc_1080p_set_encode_profile_level(u32 encode_profile, u32 enc_level); +void vidc_1080p_set_encode_field_picture_structure(u32 enc_field_picture); +void vidc_1080p_set_decode_mpeg4_pp_filter(u32 lf_enables); +void vidc_1080p_set_decode_qp_save_control(u32 enable_q_pout); +void vidc_1080p_get_returned_channel_inst_id(u32 *pn_rtn_chid); +void vidc_1080p_clear_returned_channel_inst_id(void); +void vidc_1080p_get_decode_seq_start_result( + struct vidc_1080p_seq_hdr_info *seq_hdr_info); +void vidc_1080p_get_decoded_frame_size(u32 *pn_decoded_size); +void vidc_1080p_get_display_frame_result( + struct vidc_1080p_dec_disp_info *dec_disp_info); +void vidc_1080p_get_decode_frame( + enum vidc_1080p_decode_frame *pe_frame); +void vidc_1080p_get_decode_frame_result( + struct vidc_1080p_dec_disp_info *dec_disp_info); +void vidc_1080p_decode_seq_start_ch0( + struct vidc_1080p_dec_seq_start_param *param); +void vidc_1080p_decode_seq_start_ch1( + struct vidc_1080p_dec_seq_start_param *param); +void vidc_1080p_decode_init_buffers_ch0 + (struct vidc_1080p_dec_init_buffers_param *param); +void vidc_1080p_decode_init_buffers_ch1( + struct vidc_1080p_dec_init_buffers_param *param); +void vidc_1080p_decode_frame_start_ch0( + struct vidc_1080p_dec_frame_start_param *param); +void vidc_1080p_decode_frame_start_ch1( + struct vidc_1080p_dec_frame_start_param *param); +void vidc_1080p_set_dec_resolution_ch0(u32 width, u32 height); +void vidc_1080p_set_dec_resolution_ch1(u32 width, u32 height); +void vidc_1080p_get_encode_frame_info( + struct vidc_1080p_enc_frame_info *frame_info); +void vidc_1080p_encode_seq_start_ch0( + struct vidc_1080p_enc_seq_start_param *param); +void vidc_1080p_encode_seq_start_ch1( + struct vidc_1080p_enc_seq_start_param *param); +void vidc_1080p_encode_frame_start_ch0( + struct vidc_1080p_enc_frame_start_param *param); +void vidc_1080p_encode_frame_start_ch1( + struct vidc_1080p_enc_frame_start_param *param); +void vidc_1080p_encode_slice_batch_start_ch0( + struct vidc_1080p_enc_frame_start_param *param); +void vidc_1080p_encode_slice_batch_start_ch1( + struct vidc_1080p_enc_frame_start_param *param); +void vidc_1080p_set_encode_picture(u32 ifrm_ctrl, u32 number_b); +void vidc_1080p_set_encode_multi_slice_control( + enum vidc_1080p_MSlice_selection multiple_slice_selection, + u32 mslice_mb, u32 mslice_byte); +void vidc_1080p_set_encode_circular_intra_refresh(u32 cir_num); +void vidc_1080p_set_encode_input_frame_format( + enum vidc_1080p_memory_access_method memory_format); +void vidc_1080p_set_encode_padding_control(u32 pad_ctrl_on, + u32 cr_pad_val, u32 cb_pad_val, u32 luma_pad_val); +void vidc_1080p_encode_set_rc_config(u32 enable_frame_level_rc, + u32 enable_mb_level_rc_flag, u32 frame_qp); +void vidc_1080p_encode_set_frame_level_rc_params(u32 rc_frame_rate, + u32 target_bitrate, u32 reaction_coeff); +void vidc_1080p_encode_set_qp_params(u32 max_qp, u32 min_qp); +void vidc_1080p_encode_set_mb_level_rc_params(u32 disable_dark_region_as_flag, + u32 disable_smooth_region_as_flag , u32 disable_static_region_as_flag, + u32 disable_activity_region_flag); +void vidc_1080p_get_qp(u32 *pn_frame_qp); +void vidc_1080p_set_h264_encode_entropy( + enum vidc_1080p_entropy_sel entropy_sel); +void vidc_1080p_set_h264_encode_loop_filter( + enum vidc_1080p_DBConfig db_config, u32 slice_alpha_offset, + u32 slice_beta_offset); +void vidc_1080p_set_h264_encoder_p_frame_ref_count(u32 max_reference); +void vidc_1080p_set_h264_encode_8x8transform_control(u32 enable_8x8transform); +void vidc_1080p_set_mpeg4_encode_quarter_pel_control( + u32 enable_mpeg4_quarter_pel); +void vidc_1080p_set_device_base_addr(u8 *mapped_va); +void vidc_1080p_get_intra_bias(u32 *intra_bias); +void vidc_1080p_set_intra_bias(u32 intra_bias); +void vidc_1080p_get_bi_directional_bias(u32 *bi_directional_bias); +void vidc_1080p_set_bi_directional_bias(u32 bi_directional_bias); +void vidc_1080p_get_encoder_sequence_header_size(u32 *seq_header_size); +void vidc_1080p_get_intermedia_stage_debug_counter( + u32 *intermediate_stage_counter); +void vidc_1080p_get_exception_status(u32 *exception_status); +void vidc_1080p_frame_start_realloc(u32 instance_id); +#endif diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc_hwio.h b/drivers/video/msm/vidc/1080p/ddl/vidc_hwio.h new file mode 100644 index 000000000000..d63a45bb4204 --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vidc_hwio.h @@ -0,0 +1,115 @@ +/* Copyright (c) 2010, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#ifndef _VIDC_HWIO_H_ +#define _VIDC_HWIO_H_ + +#include "vidc_hwio_reg.h" + +#ifdef VIDC_REGISTER_LOG +#define VIDC_REG_OUT(x...) printk(KERN_DEBUG x) +#define VIDC_REG_IN(x...) printk(KERN_DEBUG x) +#else +#define VIDC_REG_OUT(x...) +#define VIDC_REG_IN(x...) +#endif + +#define __inpdw(port) __raw_readl(port) +#define __outpdw(port, val) __raw_writel(val, port) + +#define in_dword(addr) (__inpdw(addr)) +#define in_dword_masked(addr, mask) (__inpdw(addr) & (mask)) +#define out_dword(addr, val) __outpdw(addr, val) + +#define out_dword_masked(io, mask, val, shadow) \ +do { \ + shadow = (shadow & (u32)(~(mask))) | ((u32)((val) & (mask))); \ + out_dword(io, shadow); \ +} while (0) +#define out_dword_masked_ns(io, mask, val, current_reg_content) \ + out_dword(io, ((current_reg_content & (u32)(~(mask))) | \ + ((u32)((val) & (mask))))) + +#define HWIO_IN(hwiosym) HWIO_##hwiosym##_IN +#define HWIO_INI(hwiosym, index) HWIO_##hwiosym##_INI(index) +#define HWIO_INM(hwiosym, mask) HWIO_##hwiosym##_INM(mask) +#define HWIO_INF(hwiosym, field) (HWIO_INM(hwiosym, \ + HWIO_FMSK(hwiosym, field)) >> HWIO_SHFT(hwiosym, field)) + +#define HWIO_OUT(hwiosym, val) HWIO_##hwiosym##_OUT(val) +#define HWIO_OUTI(hwiosym, index, val) HWIO_##hwiosym##_OUTI(index, val) +#define HWIO_OUTM(hwiosym, mask, val) HWIO_##hwiosym##_OUTM(mask, val) +#define HWIO_OUTF(hwiosym, field, val) HWIO_OUTM(hwiosym, \ + HWIO_FMSK(hwiosym, field), (u32)(val) << HWIO_SHFT(hwiosym, field)) + +#define HWIO_SHFT(hwio_regsym, hwio_fldsym) \ + HWIO_##hwiosym##_##hwiofldsym##_SHFT +#define HWIO_FMSK(hwio_regsym, hwio_fldsym) \ + HWIO_##hwiosym##_##hwiofldsym##_BMSK + +#define VIDC_SETFIELD(val, shift, mask) \ + (((val) << (shift)) & (mask)) +#define VIDC_GETFIELD(val, mask, shift) \ + (((val) & (mask)) >> (shift)) + +#define VIDC_HWIO_OUT(hwiosym, val) \ +do { \ + VIDC_REG_OUT("\n(0x%x:"#hwiosym"=0x%x)", \ + HWIO_##hwiosym##_ADDR - VIDC_BASE_PTR, val); \ + mb(); \ + HWIO_OUT(hwiosym, val); \ +} while (0) +#define VIDC_HWIO_OUTI(hwiosym, index, val) \ +do { \ + VIDC_REG_OUT("\n(0x%x:"#hwiosym"(%d)=0x%x)", \ + HWIO_##hwiosym##_ADDR(index) - VIDC_BASE_PTR, index, val); \ + mb(); \ + HWIO_OUTI(hwiosym, index, val); \ +} while (0) +#define VIDC_HWIO_OUTF(hwiosym, field, val) \ +do { \ + VIDC_REG_OUT("\n(0x%x:"#hwiosym":0x%x:=0x%x)" , \ + HWIO_##hwiosym##_ADDR - VIDC_BASE_PTR, \ + HWIO_##hwiosym##_##field##_BMSK, val) \ + mb(); \ + HWIO_OUTF(hwiosym, field, val); \ +} while (0) +#define VIDC_OUT_DWORD(addr, val) \ +do { \ + VIDC_REG_OUT("\n(0x%x:"#addr"=0x%x)", \ + addr - VIDC_BASE_PTR, val); \ + mb(); \ + out_dword(addr, val); \ +} while (0) +#define VIDC_HWIO_IN(hwiosym, pval) \ +do { \ + mb(); \ + *pval = (u32) HWIO_IN(hwiosym); \ + VIDC_REG_IN("\n(0x%x:"#hwiosym"=0x%x)", \ + HWIO_##hwiosym##_ADDR - VIDC_BASE_PTR, *pval);\ +} while (0) +#define VIDC_HWIO_INI(hwiosym, index, pval) \ +do { \ + mb(); \ + *pval = (u32) HWIO_INI(hwiosym, index); \ + VIDC_REG_IN("(0x%x:"#hwiosym"(%d)==0x%x)", \ + HWIO_##hwiosym##_ADDR(index) - VIDC_BASE_PTR, index, *pval); \ +} while (0) +#define VIDC_HWIO_INF(hwiosym, mask, pval) \ +do { \ + mb(); \ + *pval = HWIO_INF(hwiosym, mask); \ + VIDC_REG_IN("\n(0x%x:"#hwiosym"=0x%x)", \ + HWIO_##hwiosym##_ADDR - VIDC_BASE_PTR, *pval); \ +} while (0) +#endif diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc_hwio_reg.h b/drivers/video/msm/vidc/1080p/ddl/vidc_hwio_reg.h new file mode 100644 index 000000000000..0de06bf62faf --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vidc_hwio_reg.h @@ -0,0 +1,4544 @@ +/* Copyright (c) 2010, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#ifndef _VIDC_HWIO_REG_H_ +#define _VIDC_HWIO_REG_H_ + +#include +#include +#include +#include "vidc.h" + +extern u8 *VIDC_BASE_PTR; + +#define VIDC_BASE VIDC_BASE_PTR + +#define VIDC_BLACKBIRD_REG_BASE (VIDC_BASE + 0x00000000) +#define VIDC_BLACKBIRD_REG_BASE_PHYS 0x04400000 + +#define HWIO_REG_557899_ADDR (VIDC_BLACKBIRD_REG_BASE + 00000000) +#define HWIO_REG_557899_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 00000000) +#define HWIO_REG_557899_RMSK 0x3ff +#define HWIO_REG_557899_SHFT 0 +#define HWIO_REG_557899_IN in_dword_masked(HWIO_REG_557899_ADDR,\ + HWIO_REG_557899_RMSK) +#define HWIO_REG_557899_INM(m) in_dword_masked(HWIO_REG_557899_ADDR, m) +#define HWIO_REG_557899_OUT(v) out_dword(HWIO_REG_557899_ADDR, v) +#define HWIO_REG_557899_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_557899_ADDR, m, v, HWIO_REG_557899_IN); +#define HWIO_REG_557899_RSTN_RG_MPEG2_BMSK 0x200 +#define HWIO_REG_557899_RSTN_RG_MPEG2_SHFT 0x9 +#define HWIO_REG_557899_RSTN_RG_MPEG4_BMSK 0x100 +#define HWIO_REG_557899_RSTN_RG_MPEG4_SHFT 0x8 +#define HWIO_REG_557899_RSTN_RG_VC1_BMSK 0x80 +#define HWIO_REG_557899_RSTN_RG_VC1_SHFT 0x7 +#define HWIO_REG_557899_RSTN_RG_H264_BMSK 0x40 +#define HWIO_REG_557899_RSTN_RG_H264_SHFT 0x6 +#define HWIO_REG_557899_RSTN_RG_COMMON_BMSK 0x20 +#define HWIO_REG_557899_RSTN_RG_COMMON_SHFT 0x5 +#define HWIO_REG_557899_RSTN_DMX_BMSK 0x10 +#define HWIO_REG_557899_RSTN_DMX_SHFT 0x4 +#define HWIO_REG_557899_RSTN_VI_BMSK 0x8 +#define HWIO_REG_557899_RSTN_VI_SHFT 0x3 +#define HWIO_REG_557899_RSTN_VIDCCORE_BMSK 0x4 +#define HWIO_REG_557899_RSTN_VIDCCORE_SHFT 0x2 +#define HWIO_REG_557899_RSTN_MC_BMSK 0x2 +#define HWIO_REG_557899_RSTN_MC_SHFT 0x1 +#define HWIO_REG_557899_RSTN_RISC_BMSK 0x1 +#define HWIO_REG_557899_RSTN_RISC_SHFT 0 + +#define HWIO_REG_575377_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000008) +#define HWIO_REG_575377_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000008) +#define HWIO_REG_575377_RMSK 0x1 +#define HWIO_REG_575377_SHFT 0 +#define HWIO_REG_575377_IN in_dword_masked(\ + HWIO_REG_575377_ADDR, HWIO_REG_575377_RMSK) +#define HWIO_REG_575377_INM(m) \ + in_dword_masked(HWIO_REG_575377_ADDR, m) +#define HWIO_REG_575377_OUT(v) \ + out_dword(HWIO_REG_575377_ADDR, v) +#define HWIO_REG_575377_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_575377_ADDR, m, v, HWIO_REG_575377_IN); +#define HWIO_REG_575377_INTERRUPT_BMSK 0x1 +#define HWIO_REG_575377_INTERRUPT_SHFT 0 + +#define HWIO_REG_611794_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000030) +#define HWIO_REG_611794_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000030) +#define HWIO_REG_611794_RMSK 0xffffffff +#define HWIO_REG_611794_SHFT 0 +#define HWIO_REG_611794_IN in_dword_masked(\ + HWIO_REG_611794_ADDR, HWIO_REG_611794_RMSK) +#define HWIO_REG_611794_INM(m) \ + in_dword_masked(HWIO_REG_611794_ADDR, m) +#define HWIO_REG_611794_OUT(v) \ + out_dword(HWIO_REG_611794_ADDR, v) +#define HWIO_REG_611794_OUTM(m, v) \ + out_dword_masked_ns(HWIO_REG_611794_ADDR, m, v,\ + HWIO_REG_611794_IN); +#define HWIO_REG_611794_HOST2RISC_COMMAND_BMSK 0xffffffff +#define HWIO_REG_611794_HOST2RISC_COMMAND_SHFT 0 + +#define HWIO_REG_356340_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000034) +#define HWIO_REG_356340_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000034) +#define HWIO_REG_356340_RMSK 0xffffffff +#define HWIO_REG_356340_SHFT 0 +#define HWIO_REG_356340_IN in_dword_masked(\ + HWIO_REG_356340_ADDR, HWIO_REG_356340_RMSK) +#define HWIO_REG_356340_INM(m) \ + in_dword_masked(HWIO_REG_356340_ADDR, m) +#define HWIO_REG_356340_OUT(v) \ + out_dword(HWIO_REG_356340_ADDR, v) +#define HWIO_REG_356340_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_356340_ADDR, m, v, HWIO_REG_356340_IN); +#define HWIO_REG_356340_HOST2RISC_ARG1_BMSK 0xffffffff +#define HWIO_REG_356340_HOST2RISC_ARG1_SHFT 0 + +#define HWIO_REG_899023_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000038) +#define HWIO_REG_899023_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000038) +#define HWIO_REG_899023_RMSK 0xffffffff +#define HWIO_REG_899023_SHFT 0 +#define HWIO_REG_899023_IN in_dword_masked(\ + HWIO_REG_899023_ADDR, HWIO_REG_899023_RMSK) +#define HWIO_REG_899023_INM(m) \ + in_dword_masked(HWIO_REG_899023_ADDR, m) +#define HWIO_REG_899023_OUT(v) \ + out_dword(HWIO_REG_899023_ADDR, v) +#define HWIO_REG_899023_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_899023_ADDR, m, v, HWIO_REG_899023_IN); +#define HWIO_REG_899023_HOST2RISC_ARG2_BMSK 0xffffffff +#define HWIO_REG_899023_HOST2RISC_ARG2_SHFT 0 + +#define HWIO_REG_987762_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000003c) +#define HWIO_REG_987762_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000003c) +#define HWIO_REG_987762_RMSK 0xffffffff +#define HWIO_REG_987762_SHFT 0 +#define HWIO_REG_987762_IN in_dword_masked(\ + HWIO_REG_987762_ADDR, HWIO_REG_987762_RMSK) +#define HWIO_REG_987762_INM(m) \ + in_dword_masked(HWIO_REG_987762_ADDR, m) +#define HWIO_REG_987762_OUT(v) \ + out_dword(HWIO_REG_987762_ADDR, v) +#define HWIO_REG_987762_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_987762_ADDR, m, v, HWIO_REG_987762_IN); +#define HWIO_REG_987762_HOST2RISC_ARG3_BMSK 0xffffffff +#define HWIO_REG_987762_HOST2RISC_ARG3_SHFT 0 + +#define HWIO_REG_544000_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000040) +#define HWIO_REG_544000_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000040) +#define HWIO_REG_544000_RMSK 0xffffffff +#define HWIO_REG_544000_SHFT 0 +#define HWIO_REG_544000_IN in_dword_masked(\ + HWIO_REG_544000_ADDR, HWIO_REG_544000_RMSK) +#define HWIO_REG_544000_INM(m) \ + in_dword_masked(HWIO_REG_544000_ADDR, m) +#define HWIO_REG_544000_OUT(v) \ + out_dword(HWIO_REG_544000_ADDR, v) +#define HWIO_REG_544000_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_544000_ADDR, m, v, HWIO_REG_544000_IN); +#define HWIO_REG_544000_HOST2RISC_ARG4_BMSK 0xffffffff +#define HWIO_REG_544000_HOST2RISC_ARG4_SHFT 0 + +#define HWIO_REG_695082_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000044) +#define HWIO_REG_695082_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000044) +#define HWIO_REG_695082_RMSK 0xffffffff +#define HWIO_REG_695082_SHFT 0 +#define HWIO_REG_695082_IN in_dword_masked(\ + HWIO_REG_695082_ADDR, HWIO_REG_695082_RMSK) +#define HWIO_REG_695082_INM(m) \ + in_dword_masked(HWIO_REG_695082_ADDR, m) +#define HWIO_REG_695082_OUT(v) \ + out_dword(HWIO_REG_695082_ADDR, v) +#define HWIO_REG_695082_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_695082_ADDR, m, v, HWIO_REG_695082_IN); +#define HWIO_REG_695082_RISC2HOST_COMMAND_BMSK 0xffffffff +#define HWIO_REG_695082_RISC2HOST_COMMAND_SHFT 0 + +#define HWIO_REG_156596_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000048) +#define HWIO_REG_156596_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000048) +#define HWIO_REG_156596_RMSK 0xffffffff +#define HWIO_REG_156596_SHFT 0 +#define HWIO_REG_156596_IN in_dword_masked(\ + HWIO_REG_156596_ADDR, HWIO_REG_156596_RMSK) +#define HWIO_REG_156596_INM(m) \ + in_dword_masked(HWIO_REG_156596_ADDR, m) +#define HWIO_REG_156596_OUT(v) \ + out_dword(HWIO_REG_156596_ADDR, v) +#define HWIO_REG_156596_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_156596_ADDR, m, v, HWIO_REG_156596_IN); +#define HWIO_REG_156596_REG_156596_BMSK 0xffffffff +#define HWIO_REG_156596_REG_156596_SHFT 0 + +#define HWIO_REG_222292_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000004c) +#define HWIO_REG_222292_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000004c) +#define HWIO_REG_222292_RMSK 0xffffffff +#define HWIO_REG_222292_SHFT 0 +#define HWIO_REG_222292_IN in_dword_masked(\ + HWIO_REG_222292_ADDR, HWIO_REG_222292_RMSK) +#define HWIO_REG_222292_INM(m) \ + in_dword_masked(HWIO_REG_222292_ADDR, m) +#define HWIO_REG_222292_OUT(v) \ + out_dword(HWIO_REG_222292_ADDR, v) +#define HWIO_REG_222292_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_222292_ADDR, m, v, HWIO_REG_222292_IN); +#define HWIO_REG_222292_REG_222292_BMSK 0xffffffff +#define HWIO_REG_222292_REG_222292_SHFT 0 + +#define HWIO_REG_790962_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000050) +#define HWIO_REG_790962_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000050) +#define HWIO_REG_790962_RMSK 0xffffffff +#define HWIO_REG_790962_SHFT 0 +#define HWIO_REG_790962_IN in_dword_masked(\ + HWIO_REG_790962_ADDR, HWIO_REG_790962_RMSK) +#define HWIO_REG_790962_INM(m) \ + in_dword_masked(HWIO_REG_790962_ADDR, m) +#define HWIO_REG_790962_OUT(v) \ + out_dword(HWIO_REG_790962_ADDR, v) +#define HWIO_REG_790962_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_790962_ADDR, m, v, HWIO_REG_790962_IN); +#define HWIO_REG_790962_REG_790962_BMSK 0xffffffff +#define HWIO_REG_790962_REG_790962_SHFT 0 + +#define HWIO_REG_679882_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000054) +#define HWIO_REG_679882_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000054) +#define HWIO_REG_679882_RMSK 0xffffffff +#define HWIO_REG_679882_SHFT 0 +#define HWIO_REG_679882_IN in_dword_masked(\ + HWIO_REG_679882_ADDR, HWIO_REG_679882_RMSK) +#define HWIO_REG_679882_INM(m) \ + in_dword_masked(HWIO_REG_679882_ADDR, m) +#define HWIO_REG_679882_OUT(v) \ + out_dword(HWIO_REG_679882_ADDR, v) +#define HWIO_REG_679882_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_679882_ADDR, m, v, HWIO_REG_679882_IN); +#define HWIO_REG_679882_REG_679882_BMSK 0xffffffff +#define HWIO_REG_679882_REG_679882_SHFT 0 + +#define HWIO_REG_653206_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000058) +#define HWIO_REG_653206_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000058) +#define HWIO_REG_653206_RMSK 0xffffff +#define HWIO_REG_653206_SHFT 0 +#define HWIO_REG_653206_IN in_dword_masked(\ + HWIO_REG_653206_ADDR, HWIO_REG_653206_RMSK) +#define HWIO_REG_653206_INM(m) \ + in_dword_masked(HWIO_REG_653206_ADDR, m) +#define HWIO_REG_653206_YEAR_BMSK 0xff0000 +#define HWIO_REG_653206_YEAR_SHFT 0x10 +#define HWIO_REG_653206_MONTH_BMSK 0xff00 +#define HWIO_REG_653206_MONTH_SHFT 0x8 +#define HWIO_REG_653206_DAY_BMSK 0xff +#define HWIO_REG_653206_DAY_SHFT 0 + +#define HWIO_REG_805993_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000064) +#define HWIO_REG_805993_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000064) +#define HWIO_REG_805993_RMSK 0xffffffff +#define HWIO_REG_805993_SHFT 0 +#define HWIO_REG_805993_IN in_dword_masked(\ + HWIO_REG_805993_ADDR, HWIO_REG_805993_RMSK) +#define HWIO_REG_805993_INM(m) \ + in_dword_masked(HWIO_REG_805993_ADDR, m) +#define HWIO_REG_805993_INTERMEDIATE_STAGE_COUNTER_BMSK 0xffffffff +#define HWIO_REG_805993_INTERMEDIATE_STAGE_COUNTER_SHFT 0 + +#define HWIO_REG_493355_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000068) +#define HWIO_REG_493355_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000068) +#define HWIO_REG_493355_RMSK 0xffffffff +#define HWIO_REG_493355_SHFT 0 +#define HWIO_REG_493355_IN in_dword_masked(\ + HWIO_REG_493355_ADDR, HWIO_REG_493355_RMSK) +#define HWIO_REG_493355_INM(m) \ + in_dword_masked(HWIO_REG_493355_ADDR, m) +#define HWIO_REG_493355_EXCEPTION_STATUS_BMSK 0xffffffff +#define HWIO_REG_493355_EXCEPTION_STATUS_SHFT 0 + +#define HWIO_REG_350619_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000080) +#define HWIO_REG_350619_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000080) +#define HWIO_REG_350619_RMSK 0x1 +#define HWIO_REG_350619_SHFT 0 +#define HWIO_REG_350619_IN in_dword_masked(\ + HWIO_REG_350619_ADDR, HWIO_REG_350619_RMSK) +#define HWIO_REG_350619_INM(m) \ + in_dword_masked(HWIO_REG_350619_ADDR, m) +#define HWIO_REG_350619_FIRMWARE_STATUS_BMSK 0x1 +#define HWIO_REG_350619_FIRMWARE_STATUS_SHFT 0 + +#define HWIO_REG_64440_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000508) +#define HWIO_REG_64440_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000508) +#define HWIO_REG_64440_RMSK 0xfffe0000 +#define HWIO_REG_64440_SHFT 0 +#define HWIO_REG_64440_IN in_dword_masked(\ + HWIO_REG_64440_ADDR, HWIO_REG_64440_RMSK) +#define HWIO_REG_64440_INM(m) \ + in_dword_masked(HWIO_REG_64440_ADDR, m) +#define HWIO_REG_64440_OUT(v) \ + out_dword(HWIO_REG_64440_ADDR, v) +#define HWIO_REG_64440_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_64440_ADDR, m, v,\ + HWIO_REG_64440_IN); +#define HWIO_REG_64440_MC_DRAMBASE_ADDR_BMSK 0xfffe0000 +#define HWIO_REG_64440_MC_DRAMBASE_ADDR_SHFT 0x11 + +#define HWIO_REG_675915_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000050c) +#define HWIO_REG_675915_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000050c) +#define HWIO_REG_675915_RMSK 0xfffe0000 +#define HWIO_REG_675915_SHFT 0 +#define HWIO_REG_675915_IN in_dword_masked(\ + HWIO_REG_675915_ADDR, HWIO_REG_675915_RMSK) +#define HWIO_REG_675915_INM(m) \ + in_dword_masked(HWIO_REG_675915_ADDR, m) +#define HWIO_REG_675915_OUT(v) \ + out_dword(HWIO_REG_675915_ADDR, v) +#define HWIO_REG_675915_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_675915_ADDR, m, v,\ + HWIO_REG_675915_IN); +#define HWIO_REG_675915_MC_DRAMBASE_ADDR_BMSK 0xfffe0000 +#define HWIO_REG_675915_MC_DRAMBASE_ADDR_SHFT 0x11 + +#define HWIO_REG_399911_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000510) +#define HWIO_REG_399911_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000510) +#define HWIO_REG_399911_RMSK 0x3 +#define HWIO_REG_399911_SHFT 0 +#define HWIO_REG_399911_IN in_dword_masked(\ + HWIO_REG_399911_ADDR, HWIO_REG_399911_RMSK) +#define HWIO_REG_399911_INM(m) in_dword_masked(HWIO_REG_399911_ADDR, m) +#define HWIO_REG_399911_MC_BUSY_B_BMSK 0x2 +#define HWIO_REG_399911_MC_BUSY_B_SHFT 0x1 +#define HWIO_REG_399911_MC_BUSY_A_BMSK 0x1 +#define HWIO_REG_399911_MC_BUSY_A_SHFT 0 + +#define HWIO_REG_515200_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000600) +#define HWIO_REG_515200_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000600) +#define HWIO_REG_515200_RMSK 0x1ffff +#define HWIO_REG_515200_SHFT 0 +#define HWIO_REG_515200_IN in_dword_masked(\ + HWIO_REG_515200_ADDR, HWIO_REG_515200_RMSK) +#define HWIO_REG_515200_INM(m) \ + in_dword_masked(HWIO_REG_515200_ADDR, m) +#define HWIO_REG_515200_OUT(v) \ + out_dword(HWIO_REG_515200_ADDR, v) +#define HWIO_REG_515200_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_515200_ADDR, m, v,\ + HWIO_REG_515200_IN); +#define HWIO_REG_515200_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_515200_BASE_ADDR_SHFT 0 + +#define HWIO_REG_29510_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000604) +#define HWIO_REG_29510_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000604) +#define HWIO_REG_29510_RMSK 0x1ffff +#define HWIO_REG_29510_SHFT 0 +#define HWIO_REG_29510_IN in_dword_masked(\ + HWIO_REG_29510_ADDR, HWIO_REG_29510_RMSK) +#define HWIO_REG_29510_INM(m) \ + in_dword_masked(HWIO_REG_29510_ADDR, m) +#define HWIO_REG_29510_OUT(v) \ + out_dword(HWIO_REG_29510_ADDR, v) +#define HWIO_REG_29510_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_29510_ADDR, m, v,\ + HWIO_REG_29510_IN); +#define HWIO_REG_29510_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_29510_BASE_ADDR_SHFT 0 + +#define HWIO_REG_256132_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000608) +#define HWIO_REG_256132_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000608) +#define HWIO_REG_256132_RMSK 0x1ffff +#define HWIO_REG_256132_SHFT 0 +#define HWIO_REG_256132_IN in_dword_masked(\ + HWIO_REG_256132_ADDR, HWIO_REG_256132_RMSK) +#define HWIO_REG_256132_INM(m) \ + in_dword_masked(HWIO_REG_256132_ADDR, m) +#define HWIO_REG_256132_OUT(v) \ + out_dword(HWIO_REG_256132_ADDR, v) +#define HWIO_REG_256132_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_256132_ADDR, m, v,\ + HWIO_REG_256132_IN); +#define HWIO_REG_256132_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_256132_BASE_ADDR_SHFT 0 + +#define HWIO_REG_885152_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000060c) +#define HWIO_REG_885152_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000060c) +#define HWIO_REG_885152_RMSK 0x1ffff +#define HWIO_REG_885152_SHFT 0 +#define HWIO_REG_885152_IN in_dword_masked(\ + HWIO_REG_885152_ADDR, HWIO_REG_885152_RMSK) +#define HWIO_REG_885152_INM(m) \ + in_dword_masked(HWIO_REG_885152_ADDR, m) +#define HWIO_REG_885152_OUT(v) \ + out_dword(HWIO_REG_885152_ADDR, v) +#define HWIO_REG_885152_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_885152_ADDR, m, v,\ + HWIO_REG_885152_IN); +#define HWIO_REG_885152_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_885152_BASE_ADDR_SHFT 0 + +#define HWIO_REG_69832_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000610) +#define HWIO_REG_69832_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000610) +#define HWIO_REG_69832_RMSK 0x1ffff +#define HWIO_REG_69832_SHFT 0 +#define HWIO_REG_69832_IN in_dword_masked(\ + HWIO_REG_69832_ADDR, HWIO_REG_69832_RMSK) +#define HWIO_REG_69832_INM(m) \ + in_dword_masked(HWIO_REG_69832_ADDR, m) +#define HWIO_REG_69832_OUT(v) \ + out_dword(HWIO_REG_69832_ADDR, v) +#define HWIO_REG_69832_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_69832_ADDR, m, v,\ + HWIO_REG_69832_IN); +#define HWIO_REG_69832_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_69832_BASE_ADDR_SHFT 0 + +#define HWIO_REG_686205_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000614) +#define HWIO_REG_686205_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000614) +#define HWIO_REG_686205_RMSK 0x1ffff +#define HWIO_REG_686205_SHFT 0 +#define HWIO_REG_686205_IN in_dword_masked(\ + HWIO_REG_686205_ADDR, HWIO_REG_686205_RMSK) +#define HWIO_REG_686205_INM(m) \ + in_dword_masked(HWIO_REG_686205_ADDR, m) +#define HWIO_REG_686205_OUT(v) \ + out_dword(HWIO_REG_686205_ADDR, v) +#define HWIO_REG_686205_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_686205_ADDR, m, v,\ + HWIO_REG_686205_IN); +#define HWIO_REG_686205_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_686205_BASE_ADDR_SHFT 0 + +#define HWIO_REG_728036_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000618) +#define HWIO_REG_728036_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000618) +#define HWIO_REG_728036_RMSK 0x1ffff +#define HWIO_REG_728036_SHFT 0 +#define HWIO_REG_728036_IN in_dword_masked(\ + HWIO_REG_728036_ADDR, HWIO_REG_728036_RMSK) +#define HWIO_REG_728036_INM(m) \ + in_dword_masked(HWIO_REG_728036_ADDR, m) +#define HWIO_REG_728036_OUT(v) \ + out_dword(HWIO_REG_728036_ADDR, v) +#define HWIO_REG_728036_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_728036_ADDR, m, v,\ + HWIO_REG_728036_IN); +#define HWIO_REG_728036_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_728036_BASE_ADDR_SHFT 0 + +#define HWIO_REG_294579_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000061c) +#define HWIO_REG_294579_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000061c) +#define HWIO_REG_294579_RMSK 0x1ffff +#define HWIO_REG_294579_SHFT 0 +#define HWIO_REG_294579_IN in_dword_masked(\ + HWIO_REG_294579_ADDR, HWIO_REG_294579_RMSK) +#define HWIO_REG_294579_INM(m) \ + in_dword_masked(HWIO_REG_294579_ADDR, m) +#define HWIO_REG_294579_OUT(v) \ + out_dword(HWIO_REG_294579_ADDR, v) +#define HWIO_REG_294579_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_294579_ADDR, m, v,\ + HWIO_REG_294579_IN); +#define HWIO_REG_294579_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_294579_BASE_ADDR_SHFT 0 + +#define HWIO_REG_61427_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000620) +#define HWIO_REG_61427_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000620) +#define HWIO_REG_61427_RMSK 0x1ffff +#define HWIO_REG_61427_SHFT 0 +#define HWIO_REG_61427_IN in_dword_masked(\ + HWIO_REG_61427_ADDR, HWIO_REG_61427_RMSK) +#define HWIO_REG_61427_INM(m) \ + in_dword_masked(HWIO_REG_61427_ADDR, m) +#define HWIO_REG_61427_OUT(v) \ + out_dword(HWIO_REG_61427_ADDR, v) +#define HWIO_REG_61427_OUTM(m , v) out_dword_masked_ns(\ + HWIO_REG_61427_ADDR, m, v,\ + HWIO_REG_61427_IN); +#define HWIO_REG_61427_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_61427_BASE_ADDR_SHFT 0 + +#define HWIO_REG_578196_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000624) +#define HWIO_REG_578196_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000624) +#define HWIO_REG_578196_RMSK 0x1ffff +#define HWIO_REG_578196_SHFT 0 +#define HWIO_REG_578196_IN in_dword_masked(\ + HWIO_REG_578196_ADDR, HWIO_REG_578196_RMSK) +#define HWIO_REG_578196_INM(m) \ + in_dword_masked(HWIO_REG_578196_ADDR, m) +#define HWIO_REG_578196_OUT(v) \ + out_dword(HWIO_REG_578196_ADDR, v) +#define HWIO_REG_578196_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_578196_ADDR, m, v,\ + HWIO_REG_578196_IN); +#define HWIO_REG_578196_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_578196_BASE_ADDR_SHFT 0 + +#define HWIO_REG_408588_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000628) +#define HWIO_REG_408588_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000628) +#define HWIO_REG_408588_RMSK 0x1ffff +#define HWIO_REG_408588_SHFT 0 +#define HWIO_REG_408588_IN in_dword_masked(\ + HWIO_REG_408588_ADDR, HWIO_REG_408588_RMSK) +#define HWIO_REG_408588_INM(m) \ + in_dword_masked(HWIO_REG_408588_ADDR, m) +#define HWIO_REG_408588_OUT(v) \ + out_dword(HWIO_REG_408588_ADDR, v) +#define HWIO_REG_408588_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_408588_ADDR, m, v,\ + HWIO_REG_408588_IN); +#define HWIO_REG_408588_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_408588_BASE_ADDR_SHFT 0 + +#define HWIO_REG_55617_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000062c) +#define HWIO_REG_55617_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000062c) +#define HWIO_REG_55617_RMSK 0x1ffff +#define HWIO_REG_55617_SHFT 0 +#define HWIO_REG_55617_IN in_dword_masked(\ + HWIO_REG_55617_ADDR, HWIO_REG_55617_RMSK) +#define HWIO_REG_55617_INM(m) \ + in_dword_masked(HWIO_REG_55617_ADDR, m) +#define HWIO_REG_55617_OUT(v) \ + out_dword(HWIO_REG_55617_ADDR, v) +#define HWIO_REG_55617_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_55617_ADDR, m, v,\ + HWIO_REG_55617_IN); +#define HWIO_REG_55617_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_55617_BASE_ADDR_SHFT 0 + +#define HWIO_REG_555239_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000630) +#define HWIO_REG_555239_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000630) +#define HWIO_REG_555239_RMSK 0x1ffff +#define HWIO_REG_555239_SHFT 0 +#define HWIO_REG_555239_IN in_dword_masked(\ + HWIO_REG_555239_ADDR, HWIO_REG_555239_RMSK) +#define HWIO_REG_555239_INM(m) \ + in_dword_masked(HWIO_REG_555239_ADDR, m) +#define HWIO_REG_555239_OUT(v) \ + out_dword(HWIO_REG_555239_ADDR, v) +#define HWIO_REG_555239_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_555239_ADDR, m, v,\ + HWIO_REG_555239_IN); +#define HWIO_REG_555239_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_555239_BASE_ADDR_SHFT 0 + +#define HWIO_REG_515333_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000634) +#define HWIO_REG_515333_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000634) +#define HWIO_REG_515333_RMSK 0x1ffff +#define HWIO_REG_515333_SHFT 0 +#define HWIO_REG_515333_IN in_dword_masked(\ + HWIO_REG_515333_ADDR, HWIO_REG_515333_RMSK) +#define HWIO_REG_515333_INM(m) \ + in_dword_masked(HWIO_REG_515333_ADDR, m) +#define HWIO_REG_515333_OUT(v) \ + out_dword(HWIO_REG_515333_ADDR, v) +#define HWIO_REG_515333_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_515333_ADDR, m, v,\ + HWIO_REG_515333_IN); +#define HWIO_REG_515333_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_515333_BASE_ADDR_SHFT 0 + +#define HWIO_REG_951675_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000638) +#define HWIO_REG_951675_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000638) +#define HWIO_REG_951675_RMSK 0x1ffff +#define HWIO_REG_951675_SHFT 0 +#define HWIO_REG_951675_IN in_dword_masked(\ + HWIO_REG_951675_ADDR, HWIO_REG_951675_RMSK) +#define HWIO_REG_951675_INM(m) \ + in_dword_masked(HWIO_REG_951675_ADDR, m) +#define HWIO_REG_951675_OUT(v) \ + out_dword(HWIO_REG_951675_ADDR, v) +#define HWIO_REG_951675_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_951675_ADDR, m, v,\ + HWIO_REG_951675_IN); +#define HWIO_REG_951675_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_951675_BASE_ADDR_SHFT 0 + +#define HWIO_REG_500775_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000063c) +#define HWIO_REG_500775_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000063c) +#define HWIO_REG_500775_RMSK 0x1ffff +#define HWIO_REG_500775_SHFT 0 +#define HWIO_REG_500775_IN in_dword_masked(\ + HWIO_REG_500775_ADDR, HWIO_REG_500775_RMSK) +#define HWIO_REG_500775_INM(m) \ + in_dword_masked(HWIO_REG_500775_ADDR, m) +#define HWIO_REG_500775_OUT(v) \ + out_dword(HWIO_REG_500775_ADDR, v) +#define HWIO_REG_500775_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_500775_ADDR, m, v,\ + HWIO_REG_500775_IN); +#define HWIO_REG_500775_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_500775_BASE_ADDR_SHFT 0 + +#define HWIO_REG_649786_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000640) +#define HWIO_REG_649786_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000640) +#define HWIO_REG_649786_RMSK 0x1ffff +#define HWIO_REG_649786_SHFT 0 +#define HWIO_REG_649786_IN in_dword_masked(\ + HWIO_REG_649786_ADDR, HWIO_REG_649786_RMSK) +#define HWIO_REG_649786_INM(m) \ + in_dword_masked(HWIO_REG_649786_ADDR, m) +#define HWIO_REG_649786_OUT(v) \ + out_dword(HWIO_REG_649786_ADDR, v) +#define HWIO_REG_649786_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_649786_ADDR, m, v,\ + HWIO_REG_649786_IN); +#define HWIO_REG_649786_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_649786_BASE_ADDR_SHFT 0 + +#define HWIO_REG_233366_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000644) +#define HWIO_REG_233366_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000644) +#define HWIO_REG_233366_RMSK 0x1ffff +#define HWIO_REG_233366_SHFT 0 +#define HWIO_REG_233366_IN in_dword_masked(\ + HWIO_REG_233366_ADDR, HWIO_REG_233366_RMSK) +#define HWIO_REG_233366_INM(m) \ + in_dword_masked(HWIO_REG_233366_ADDR, m) +#define HWIO_REG_233366_OUT(v) \ + out_dword(HWIO_REG_233366_ADDR, v) +#define HWIO_REG_233366_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_233366_ADDR, m, v,\ + HWIO_REG_233366_IN); +#define HWIO_REG_233366_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_233366_BASE_ADDR_SHFT 0 + +#define HWIO_REG_366750_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000648) +#define HWIO_REG_366750_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000648) +#define HWIO_REG_366750_RMSK 0x1ffff +#define HWIO_REG_366750_SHFT 0 +#define HWIO_REG_366750_IN in_dword_masked(\ + HWIO_REG_366750_ADDR, HWIO_REG_366750_RMSK) +#define HWIO_REG_366750_INM(m) \ + in_dword_masked(HWIO_REG_366750_ADDR, m) +#define HWIO_REG_366750_OUT(v) \ + out_dword(HWIO_REG_366750_ADDR, v) +#define HWIO_REG_366750_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_366750_ADDR, m, v,\ + HWIO_REG_366750_IN); +#define HWIO_REG_366750_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_366750_BASE_ADDR_SHFT 0 + +#define HWIO_REG_616292_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000064c) +#define HWIO_REG_616292_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000064c) +#define HWIO_REG_616292_RMSK 0x1ffff +#define HWIO_REG_616292_SHFT 0 +#define HWIO_REG_616292_IN in_dword_masked(\ + HWIO_REG_616292_ADDR, HWIO_REG_616292_RMSK) +#define HWIO_REG_616292_INM(m) \ + in_dword_masked(HWIO_REG_616292_ADDR, m) +#define HWIO_REG_616292_OUT(v) \ + out_dword(HWIO_REG_616292_ADDR, v) +#define HWIO_REG_616292_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_616292_ADDR, m, v,\ + HWIO_REG_616292_IN); +#define HWIO_REG_616292_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_616292_BASE_ADDR_SHFT 0 + +#define HWIO_REG_666754_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000650) +#define HWIO_REG_666754_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000650) +#define HWIO_REG_666754_RMSK 0x1ffff +#define HWIO_REG_666754_SHFT 0 +#define HWIO_REG_666754_IN in_dword_masked(\ + HWIO_REG_666754_ADDR, HWIO_REG_666754_RMSK) +#define HWIO_REG_666754_INM(m) \ + in_dword_masked(HWIO_REG_666754_ADDR, m) +#define HWIO_REG_666754_OUT(v) \ + out_dword(HWIO_REG_666754_ADDR, v) +#define HWIO_REG_666754_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_666754_ADDR, m, v,\ + HWIO_REG_666754_IN); +#define HWIO_REG_666754_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_666754_BASE_ADDR_SHFT 0 + +#define HWIO_REG_650155_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000654) +#define HWIO_REG_650155_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000654) +#define HWIO_REG_650155_RMSK 0x1ffff +#define HWIO_REG_650155_SHFT 0 +#define HWIO_REG_650155_IN in_dword_masked(\ + HWIO_REG_650155_ADDR, HWIO_REG_650155_RMSK) +#define HWIO_REG_650155_INM(m) \ + in_dword_masked(HWIO_REG_650155_ADDR, m) +#define HWIO_REG_650155_OUT(v) \ + out_dword(HWIO_REG_650155_ADDR, v) +#define HWIO_REG_650155_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_650155_ADDR, m, v,\ + HWIO_REG_650155_IN); +#define HWIO_REG_650155_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_650155_BASE_ADDR_SHFT 0 + +#define HWIO_REG_248198_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000658) +#define HWIO_REG_248198_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000658) +#define HWIO_REG_248198_RMSK 0x1ffff +#define HWIO_REG_248198_SHFT 0 +#define HWIO_REG_248198_IN in_dword_masked(\ + HWIO_REG_248198_ADDR, HWIO_REG_248198_RMSK) +#define HWIO_REG_248198_INM(m) \ + in_dword_masked(HWIO_REG_248198_ADDR, m) +#define HWIO_REG_248198_OUT(v) \ + out_dword(HWIO_REG_248198_ADDR, v) +#define HWIO_REG_248198_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_248198_ADDR, m, v,\ + HWIO_REG_248198_IN); +#define HWIO_REG_248198_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_248198_BASE_ADDR_SHFT 0 + +#define HWIO_REG_389428_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000065c) +#define HWIO_REG_389428_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000065c) +#define HWIO_REG_389428_RMSK 0x1ffff +#define HWIO_REG_389428_SHFT 0 +#define HWIO_REG_389428_IN in_dword_masked(\ + HWIO_REG_389428_ADDR, HWIO_REG_389428_RMSK) +#define HWIO_REG_389428_INM(m) \ + in_dword_masked(HWIO_REG_389428_ADDR, m) +#define HWIO_REG_389428_OUT(v) \ + out_dword(HWIO_REG_389428_ADDR, v) +#define HWIO_REG_389428_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_389428_ADDR, m, v,\ + HWIO_REG_389428_IN); +#define HWIO_REG_389428_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_389428_BASE_ADDR_SHFT 0 + +#define HWIO_REG_504308_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000660) +#define HWIO_REG_504308_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000660) +#define HWIO_REG_504308_RMSK 0x1ffff +#define HWIO_REG_504308_SHFT 0 +#define HWIO_REG_504308_IN in_dword_masked(\ + HWIO_REG_504308_ADDR, HWIO_REG_504308_RMSK) +#define HWIO_REG_504308_INM(m) \ + in_dword_masked(HWIO_REG_504308_ADDR, m) +#define HWIO_REG_504308_OUT(v) \ + out_dword(HWIO_REG_504308_ADDR, v) +#define HWIO_REG_504308_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_504308_ADDR, m, v,\ + HWIO_REG_504308_IN); +#define HWIO_REG_504308_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_504308_BASE_ADDR_SHFT 0 + +#define HWIO_REG_280814_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000664) +#define HWIO_REG_280814_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000664) +#define HWIO_REG_280814_RMSK 0x1ffff +#define HWIO_REG_280814_SHFT 0 +#define HWIO_REG_280814_IN in_dword_masked(\ + HWIO_REG_280814_ADDR, HWIO_REG_280814_RMSK) +#define HWIO_REG_280814_INM(m) \ + in_dword_masked(HWIO_REG_280814_ADDR, m) +#define HWIO_REG_280814_OUT(v) \ + out_dword(HWIO_REG_280814_ADDR, v) +#define HWIO_REG_280814_OUTM(m, v) \ + out_dword_masked_ns(HWIO_REG_280814_ADDR, m, v,\ + HWIO_REG_280814_IN); +#define HWIO_REG_280814_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_280814_BASE_ADDR_SHFT 0 + +#define HWIO_REG_785484_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000668) +#define HWIO_REG_785484_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000668) +#define HWIO_REG_785484_RMSK 0x1ffff +#define HWIO_REG_785484_SHFT 0 +#define HWIO_REG_785484_IN in_dword_masked(\ + HWIO_REG_785484_ADDR, HWIO_REG_785484_RMSK) +#define HWIO_REG_785484_INM(m) \ + in_dword_masked(HWIO_REG_785484_ADDR, m) +#define HWIO_REG_785484_OUT(v) \ + out_dword(HWIO_REG_785484_ADDR, v) +#define HWIO_REG_785484_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_785484_ADDR, m, v,\ + HWIO_REG_785484_IN); +#define HWIO_REG_785484_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_785484_BASE_ADDR_SHFT 0 + +#define HWIO_REG_218455_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000066c) +#define HWIO_REG_218455_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000066c) +#define HWIO_REG_218455_RMSK 0x1ffff +#define HWIO_REG_218455_SHFT 0 +#define HWIO_REG_218455_IN in_dword_masked(\ + HWIO_REG_218455_ADDR, HWIO_REG_218455_RMSK) +#define HWIO_REG_218455_INM(m) \ + in_dword_masked(HWIO_REG_218455_ADDR, m) +#define HWIO_REG_218455_OUT(v) \ + out_dword(HWIO_REG_218455_ADDR, v) +#define HWIO_REG_218455_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_218455_ADDR, m, v,\ + HWIO_REG_218455_IN); +#define HWIO_REG_218455_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_218455_BASE_ADDR_SHFT 0 + +#define HWIO_REG_886591_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000670) +#define HWIO_REG_886591_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000670) +#define HWIO_REG_886591_RMSK 0x1ffff +#define HWIO_REG_886591_SHFT 0 +#define HWIO_REG_886591_IN in_dword_masked(\ + HWIO_REG_886591_ADDR, HWIO_REG_886591_RMSK) +#define HWIO_REG_886591_INM(m) \ + in_dword_masked(HWIO_REG_886591_ADDR, m) +#define HWIO_REG_886591_OUT(v) \ + out_dword(HWIO_REG_886591_ADDR, v) +#define HWIO_REG_886591_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_886591_ADDR, m, v,\ + HWIO_REG_886591_IN); +#define HWIO_REG_886591_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_886591_BASE_ADDR_SHFT 0 + +#define HWIO_REG_912449_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000674) +#define HWIO_REG_912449_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000674) +#define HWIO_REG_912449_RMSK 0x1ffff +#define HWIO_REG_912449_SHFT 0 +#define HWIO_REG_912449_IN in_dword_masked(\ + HWIO_REG_912449_ADDR, HWIO_REG_912449_RMSK) +#define HWIO_REG_912449_INM(m) \ + in_dword_masked(HWIO_REG_912449_ADDR, m) +#define HWIO_REG_912449_OUT(v) \ + out_dword(HWIO_REG_912449_ADDR, v) +#define HWIO_REG_912449_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_912449_ADDR, m, v,\ + HWIO_REG_912449_IN); +#define HWIO_REG_912449_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_912449_BASE_ADDR_SHFT 0 + +#define HWIO_REG_1065_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000678) +#define HWIO_REG_1065_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000678) +#define HWIO_REG_1065_RMSK 0x1ffff +#define HWIO_REG_1065_SHFT 0 +#define HWIO_REG_1065_IN in_dword_masked(\ + HWIO_REG_1065_ADDR, HWIO_REG_1065_RMSK) +#define HWIO_REG_1065_INM(m) \ + in_dword_masked(HWIO_REG_1065_ADDR, m) +#define HWIO_REG_1065_OUT(v) \ + out_dword(HWIO_REG_1065_ADDR, v) +#define HWIO_REG_1065_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_1065_ADDR, m, v,\ + HWIO_REG_1065_IN); +#define HWIO_REG_1065_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_1065_BASE_ADDR_SHFT 0 + +#define HWIO_REG_61838_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000067c) +#define HWIO_REG_61838_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000067c) +#define HWIO_REG_61838_RMSK 0x1ffff +#define HWIO_REG_61838_SHFT 0 +#define HWIO_REG_61838_IN in_dword_masked(\ + HWIO_REG_61838_ADDR, HWIO_REG_61838_RMSK) +#define HWIO_REG_61838_INM(m) \ + in_dword_masked(HWIO_REG_61838_ADDR, m) +#define HWIO_REG_61838_OUT(v) \ + out_dword(HWIO_REG_61838_ADDR, v) +#define HWIO_REG_61838_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_61838_ADDR, m, v,\ + HWIO_REG_61838_IN); +#define HWIO_REG_61838_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_61838_BASE_ADDR_SHFT 0 + +#define HWIO_REG_169838_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000680) +#define HWIO_REG_169838_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000680) +#define HWIO_REG_169838_RMSK 0x1ffff +#define HWIO_REG_169838_SHFT 0 +#define HWIO_REG_169838_IN in_dword_masked(\ + HWIO_REG_169838_ADDR, HWIO_REG_169838_RMSK) +#define HWIO_REG_169838_INM(m) \ + in_dword_masked(HWIO_REG_169838_ADDR, m) +#define HWIO_REG_169838_OUT(v) \ + out_dword(HWIO_REG_169838_ADDR, v) +#define HWIO_REG_169838_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_169838_ADDR, m, v,\ + HWIO_REG_169838_IN); +#define HWIO_REG_169838_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_169838_BASE_ADDR_SHFT 0 + +#define HWIO_REG_986147_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000684) +#define HWIO_REG_986147_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000684) +#define HWIO_REG_986147_RMSK 0x1ffff +#define HWIO_REG_986147_SHFT 0 +#define HWIO_REG_986147_IN in_dword_masked(\ + HWIO_REG_986147_ADDR, HWIO_REG_986147_RMSK) +#define HWIO_REG_986147_INM(m) \ + in_dword_masked(HWIO_REG_986147_ADDR, m) +#define HWIO_REG_986147_OUT(v) \ + out_dword(HWIO_REG_986147_ADDR, v) +#define HWIO_REG_986147_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_986147_ADDR, m, v,\ + HWIO_REG_986147_IN); +#define HWIO_REG_986147_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_986147_BASE_ADDR_SHFT 0 + +#define HWIO_REG_678637_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000688) +#define HWIO_REG_678637_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000688) +#define HWIO_REG_678637_RMSK 0x1ffff +#define HWIO_REG_678637_SHFT 0 +#define HWIO_REG_678637_IN in_dword_masked(\ + HWIO_REG_678637_ADDR, HWIO_REG_678637_RMSK) +#define HWIO_REG_678637_INM(m) \ + in_dword_masked(HWIO_REG_678637_ADDR, m) +#define HWIO_REG_678637_OUT(v) \ + out_dword(HWIO_REG_678637_ADDR, v) +#define HWIO_REG_678637_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_678637_ADDR, m, v,\ + HWIO_REG_678637_IN); +#define HWIO_REG_678637_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_678637_BASE_ADDR_SHFT 0 + +#define HWIO_REG_931311_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000068c) +#define HWIO_REG_931311_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000068c) +#define HWIO_REG_931311_RMSK 0x1ffff +#define HWIO_REG_931311_SHFT 0 +#define HWIO_REG_931311_IN in_dword_masked(\ + HWIO_REG_931311_ADDR, HWIO_REG_931311_RMSK) +#define HWIO_REG_931311_INM(m) \ + in_dword_masked(HWIO_REG_931311_ADDR, m) +#define HWIO_REG_931311_OUT(v) \ + out_dword(HWIO_REG_931311_ADDR, v) +#define HWIO_REG_931311_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_931311_ADDR, m, v,\ + HWIO_REG_931311_IN); +#define HWIO_REG_931311_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_931311_BASE_ADDR_SHFT 0 + +#define HWIO_REG_16277_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000690) +#define HWIO_REG_16277_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000690) +#define HWIO_REG_16277_RMSK 0x1ffff +#define HWIO_REG_16277_SHFT 0 +#define HWIO_REG_16277_IN in_dword_masked(\ + HWIO_REG_16277_ADDR, HWIO_REG_16277_RMSK) +#define HWIO_REG_16277_INM(m) \ + in_dword_masked(HWIO_REG_16277_ADDR, m) +#define HWIO_REG_16277_OUT(v) \ + out_dword(HWIO_REG_16277_ADDR, v) +#define HWIO_REG_16277_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_16277_ADDR, m, v,\ + HWIO_REG_16277_IN); +#define HWIO_REG_16277_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_16277_BASE_ADDR_SHFT 0 + +#define HWIO_REG_654169_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000694) +#define HWIO_REG_654169_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000694) +#define HWIO_REG_654169_RMSK 0x1ffff +#define HWIO_REG_654169_SHFT 0 +#define HWIO_REG_654169_IN in_dword_masked(\ + HWIO_REG_654169_ADDR, HWIO_REG_654169_RMSK) +#define HWIO_REG_654169_INM(m) \ + in_dword_masked(HWIO_REG_654169_ADDR, m) +#define HWIO_REG_654169_OUT(v) \ + out_dword(HWIO_REG_654169_ADDR, v) +#define HWIO_REG_654169_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_654169_ADDR, m, v,\ + HWIO_REG_654169_IN); +#define HWIO_REG_654169_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_654169_BASE_ADDR_SHFT 0 + +#define HWIO_REG_802794_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000698) +#define HWIO_REG_802794_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000698) +#define HWIO_REG_802794_RMSK 0x1ffff +#define HWIO_REG_802794_SHFT 0 +#define HWIO_REG_802794_IN in_dword_masked(\ + HWIO_REG_802794_ADDR, HWIO_REG_802794_RMSK) +#define HWIO_REG_802794_INM(m) \ + in_dword_masked(HWIO_REG_802794_ADDR, m) +#define HWIO_REG_802794_OUT(v) \ + out_dword(HWIO_REG_802794_ADDR, v) +#define HWIO_REG_802794_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_802794_ADDR, m, v,\ + HWIO_REG_802794_IN); +#define HWIO_REG_802794_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_802794_BASE_ADDR_SHFT 0 + +#define HWIO_REG_724376_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000069c) +#define HWIO_REG_724376_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000069c) +#define HWIO_REG_724376_RMSK 0x1ffff +#define HWIO_REG_724376_SHFT 0 +#define HWIO_REG_724376_IN in_dword_masked(\ + HWIO_REG_724376_ADDR, HWIO_REG_724376_RMSK) +#define HWIO_REG_724376_INM(m) \ + in_dword_masked(HWIO_REG_724376_ADDR, m) +#define HWIO_REG_724376_OUT(v) \ + out_dword(HWIO_REG_724376_ADDR, v) +#define HWIO_REG_724376_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_724376_ADDR, m, v,\ + HWIO_REG_724376_IN); +#define HWIO_REG_724376_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_724376_BASE_ADDR_SHFT 0 + +#define HWIO_REG_551674_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006a0) +#define HWIO_REG_551674_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006a0) +#define HWIO_REG_551674_RMSK 0x1ffff +#define HWIO_REG_551674_SHFT 0 +#define HWIO_REG_551674_IN in_dword_masked(\ + HWIO_REG_551674_ADDR, HWIO_REG_551674_RMSK) +#define HWIO_REG_551674_INM(m) \ + in_dword_masked(HWIO_REG_551674_ADDR, m) +#define HWIO_REG_551674_OUT(v) \ + out_dword(HWIO_REG_551674_ADDR, v) +#define HWIO_REG_551674_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_551674_ADDR, m, v,\ + HWIO_REG_551674_IN); +#define HWIO_REG_551674_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_551674_BASE_ADDR_SHFT 0 + +#define HWIO_REG_115991_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006a4) +#define HWIO_REG_115991_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006a4) +#define HWIO_REG_115991_RMSK 0x1ffff +#define HWIO_REG_115991_SHFT 0 +#define HWIO_REG_115991_IN in_dword_masked(\ + HWIO_REG_115991_ADDR, HWIO_REG_115991_RMSK) +#define HWIO_REG_115991_INM(m) \ + in_dword_masked(HWIO_REG_115991_ADDR, m) +#define HWIO_REG_115991_OUT(v) \ + out_dword(HWIO_REG_115991_ADDR, v) +#define HWIO_REG_115991_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_115991_ADDR, m, v,\ + HWIO_REG_115991_IN); +#define HWIO_REG_115991_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_115991_BASE_ADDR_SHFT 0 + +#define HWIO_REG_252167_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006a8) +#define HWIO_REG_252167_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006a8) +#define HWIO_REG_252167_RMSK 0x1ffff +#define HWIO_REG_252167_SHFT 0 +#define HWIO_REG_252167_IN in_dword_masked(\ + HWIO_REG_252167_ADDR, HWIO_REG_252167_RMSK) +#define HWIO_REG_252167_INM(m) \ + in_dword_masked(HWIO_REG_252167_ADDR, m) +#define HWIO_REG_252167_OUT(v) \ + out_dword(HWIO_REG_252167_ADDR, v) +#define HWIO_REG_252167_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_252167_ADDR, m, v,\ + HWIO_REG_252167_IN); +#define HWIO_REG_252167_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_252167_BASE_ADDR_SHFT 0 + +#define HWIO_REG_695516_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006ac) +#define HWIO_REG_695516_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006ac) +#define HWIO_REG_695516_RMSK 0x1ffff +#define HWIO_REG_695516_SHFT 0 +#define HWIO_REG_695516_IN in_dword_masked(\ + HWIO_REG_695516_ADDR, HWIO_REG_695516_RMSK) +#define HWIO_REG_695516_INM(m) \ + in_dword_masked(HWIO_REG_695516_ADDR, m) +#define HWIO_REG_695516_OUT(v) \ + out_dword(HWIO_REG_695516_ADDR, v) +#define HWIO_REG_695516_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_695516_ADDR, m, v,\ + HWIO_REG_695516_IN); +#define HWIO_REG_695516_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_695516_BASE_ADDR_SHFT 0 + +#define HWIO_REG_152193_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006b0) +#define HWIO_REG_152193_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006b0) +#define HWIO_REG_152193_RMSK 0x1ffff +#define HWIO_REG_152193_SHFT 0 +#define HWIO_REG_152193_IN in_dword_masked(\ + HWIO_REG_152193_ADDR, HWIO_REG_152193_RMSK) +#define HWIO_REG_152193_INM(m) \ + in_dword_masked(HWIO_REG_152193_ADDR, m) +#define HWIO_REG_152193_OUT(v) \ + out_dword(HWIO_REG_152193_ADDR, v) +#define HWIO_REG_152193_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_152193_ADDR, m, v,\ + HWIO_REG_152193_IN); +#define HWIO_REG_152193_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_152193_BASE_ADDR_SHFT 0 + +#define HWIO_REG_358705_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006b4) +#define HWIO_REG_358705_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006b4) +#define HWIO_REG_358705_RMSK 0x1ffff +#define HWIO_REG_358705_SHFT 0 +#define HWIO_REG_358705_IN in_dword_masked(\ + HWIO_REG_358705_ADDR, HWIO_REG_358705_RMSK) +#define HWIO_REG_358705_INM(m) \ + in_dword_masked(HWIO_REG_358705_ADDR, m) +#define HWIO_REG_358705_OUT(v) \ + out_dword(HWIO_REG_358705_ADDR, v) +#define HWIO_REG_358705_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_358705_ADDR, m, v,\ + HWIO_REG_358705_IN); +#define HWIO_REG_358705_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_358705_BASE_ADDR_SHFT 0 + +#define HWIO_REG_457068_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006b8) +#define HWIO_REG_457068_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006b8) +#define HWIO_REG_457068_RMSK 0x1ffff +#define HWIO_REG_457068_SHFT 0 +#define HWIO_REG_457068_IN in_dword_masked(\ + HWIO_REG_457068_ADDR, HWIO_REG_457068_RMSK) +#define HWIO_REG_457068_INM(m) \ + in_dword_masked(HWIO_REG_457068_ADDR, m) +#define HWIO_REG_457068_OUT(v) \ + out_dword(HWIO_REG_457068_ADDR, v) +#define HWIO_REG_457068_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_457068_ADDR, m, v,\ + HWIO_REG_457068_IN); +#define HWIO_REG_457068_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_457068_BASE_ADDR_SHFT 0 + +#define HWIO_REG_485412_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006bc) +#define HWIO_REG_485412_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006bc) +#define HWIO_REG_485412_RMSK 0x1ffff +#define HWIO_REG_485412_SHFT 0 +#define HWIO_REG_485412_IN in_dword_masked(\ + HWIO_REG_485412_ADDR, HWIO_REG_485412_RMSK) +#define HWIO_REG_485412_INM(m) \ + in_dword_masked(HWIO_REG_485412_ADDR, m) +#define HWIO_REG_485412_OUT(v) \ + out_dword(HWIO_REG_485412_ADDR, v) +#define HWIO_REG_485412_OUTM(m, v) \ + out_dword_masked_ns(HWIO_REG_485412_ADDR, m, v,\ + HWIO_REG_485412_IN); +#define HWIO_REG_485412_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_485412_BASE_ADDR_SHFT 0 + +#define HWIO_REG_223131_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006c0) +#define HWIO_REG_223131_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006c0) +#define HWIO_REG_223131_RMSK 0x1ffff +#define HWIO_REG_223131_SHFT 0 +#define HWIO_REG_223131_IN in_dword_masked(\ + HWIO_REG_223131_ADDR, HWIO_REG_223131_RMSK) +#define HWIO_REG_223131_INM(m) \ + in_dword_masked(HWIO_REG_223131_ADDR, m) +#define HWIO_REG_223131_OUT(v) \ + out_dword(HWIO_REG_223131_ADDR, v) +#define HWIO_REG_223131_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_223131_ADDR, m, v,\ + HWIO_REG_223131_IN); +#define HWIO_REG_223131_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_223131_BASE_ADDR_SHFT 0 + +#define HWIO_REG_683737_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006c4) +#define HWIO_REG_683737_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006c4) +#define HWIO_REG_683737_RMSK 0x1ffff +#define HWIO_REG_683737_SHFT 0 +#define HWIO_REG_683737_IN in_dword_masked(\ + HWIO_REG_683737_ADDR, HWIO_REG_683737_RMSK) +#define HWIO_REG_683737_INM(m) \ + in_dword_masked(HWIO_REG_683737_ADDR, m) +#define HWIO_REG_683737_OUT(v) \ + out_dword(HWIO_REG_683737_ADDR, v) +#define HWIO_REG_683737_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_683737_ADDR, m, v,\ + HWIO_REG_683737_IN); +#define HWIO_REG_683737_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_683737_BASE_ADDR_SHFT 0 + +#define HWIO_REG_750474_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006c8) +#define HWIO_REG_750474_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006c8) +#define HWIO_REG_750474_RMSK 0x1ffff +#define HWIO_REG_750474_SHFT 0 +#define HWIO_REG_750474_IN in_dword_masked(\ + HWIO_REG_750474_ADDR, HWIO_REG_750474_RMSK) +#define HWIO_REG_750474_INM(m) \ + in_dword_masked(HWIO_REG_750474_ADDR, m) +#define HWIO_REG_750474_OUT(v) \ + out_dword(HWIO_REG_750474_ADDR, v) +#define HWIO_REG_750474_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_750474_ADDR, m, v,\ + HWIO_REG_750474_IN); +#define HWIO_REG_750474_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_750474_BASE_ADDR_SHFT 0 + +#define HWIO_REG_170086_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006cc) +#define HWIO_REG_170086_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006cc) +#define HWIO_REG_170086_RMSK 0x1ffff +#define HWIO_REG_170086_SHFT 0 +#define HWIO_REG_170086_IN in_dword_masked(\ + HWIO_REG_170086_ADDR, HWIO_REG_170086_RMSK) +#define HWIO_REG_170086_INM(m) \ + in_dword_masked(HWIO_REG_170086_ADDR, m) +#define HWIO_REG_170086_OUT(v) \ + out_dword(HWIO_REG_170086_ADDR, v) +#define HWIO_REG_170086_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_170086_ADDR, m, v,\ + HWIO_REG_170086_IN); +#define HWIO_REG_170086_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_170086_BASE_ADDR_SHFT 0 + +#define HWIO_REG_838595_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006d0) +#define HWIO_REG_838595_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006d0) +#define HWIO_REG_838595_RMSK 0x1ffff +#define HWIO_REG_838595_SHFT 0 +#define HWIO_REG_838595_IN in_dword_masked(\ + HWIO_REG_838595_ADDR, HWIO_REG_838595_RMSK) +#define HWIO_REG_838595_INM(m) \ + in_dword_masked(HWIO_REG_838595_ADDR, m) +#define HWIO_REG_838595_OUT(v) \ + out_dword(HWIO_REG_838595_ADDR, v) +#define HWIO_REG_838595_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_838595_ADDR, m, v,\ + HWIO_REG_838595_IN); +#define HWIO_REG_838595_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_838595_BASE_ADDR_SHFT 0 + +#define HWIO_REG_569788_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006d4) +#define HWIO_REG_569788_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006d4) +#define HWIO_REG_569788_RMSK 0x1ffff +#define HWIO_REG_569788_SHFT 0 +#define HWIO_REG_569788_IN in_dword_masked(\ + HWIO_REG_569788_ADDR, HWIO_REG_569788_RMSK) +#define HWIO_REG_569788_INM(m) \ + in_dword_masked(HWIO_REG_569788_ADDR, m) +#define HWIO_REG_569788_OUT(v) \ + out_dword(HWIO_REG_569788_ADDR, v) +#define HWIO_REG_569788_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_569788_ADDR, m, v,\ + HWIO_REG_569788_IN); +#define HWIO_REG_569788_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_569788_BASE_ADDR_SHFT 0 + +#define HWIO_REG_974527_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006d8) +#define HWIO_REG_974527_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006d8) +#define HWIO_REG_974527_RMSK 0x1ffff +#define HWIO_REG_974527_SHFT 0 +#define HWIO_REG_974527_IN in_dword_masked(\ + HWIO_REG_974527_ADDR, HWIO_REG_974527_RMSK) +#define HWIO_REG_974527_INM(m) \ + in_dword_masked(HWIO_REG_974527_ADDR, m) +#define HWIO_REG_974527_OUT(v) \ + out_dword(HWIO_REG_974527_ADDR, v) +#define HWIO_REG_974527_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_974527_ADDR, m, v,\ + HWIO_REG_974527_IN); +#define HWIO_REG_974527_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_974527_BASE_ADDR_SHFT 0 + +#define HWIO_REG_316806_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006dc) +#define HWIO_REG_316806_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006dc) +#define HWIO_REG_316806_RMSK 0x1ffff +#define HWIO_REG_316806_SHFT 0 +#define HWIO_REG_316806_IN in_dword_masked(\ + HWIO_REG_316806_ADDR, HWIO_REG_316806_RMSK) +#define HWIO_REG_316806_INM(m) \ + in_dword_masked(HWIO_REG_316806_ADDR, m) +#define HWIO_REG_316806_OUT(v) \ + out_dword(HWIO_REG_316806_ADDR, v) +#define HWIO_REG_316806_OUTM(m, v) \ + out_dword_masked_ns(HWIO_REG_316806_ADDR, m, v,\ + HWIO_REG_316806_IN); +#define HWIO_REG_316806_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_316806_BASE_ADDR_SHFT 0 + +#define HWIO_REG_900472_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006e0) +#define HWIO_REG_900472_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006e0) +#define HWIO_REG_900472_RMSK 0x1ffff +#define HWIO_REG_900472_SHFT 0 +#define HWIO_REG_900472_IN in_dword_masked(\ + HWIO_REG_900472_ADDR, HWIO_REG_900472_RMSK) +#define HWIO_REG_900472_INM(m) \ + in_dword_masked(HWIO_REG_900472_ADDR, m) +#define HWIO_REG_900472_OUT(v) \ + out_dword(HWIO_REG_900472_ADDR, v) +#define HWIO_REG_900472_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_900472_ADDR, m, v,\ + HWIO_REG_900472_IN); +#define HWIO_REG_900472_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_900472_BASE_ADDR_SHFT 0 + +#define HWIO_REG_256156_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006e4) +#define HWIO_REG_256156_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006e4) +#define HWIO_REG_256156_RMSK 0x1ffff +#define HWIO_REG_256156_SHFT 0 +#define HWIO_REG_256156_IN in_dword_masked(\ + HWIO_REG_256156_ADDR, HWIO_REG_256156_RMSK) +#define HWIO_REG_256156_INM(m) \ + in_dword_masked(HWIO_REG_256156_ADDR, m) +#define HWIO_REG_256156_OUT(v) \ + out_dword(HWIO_REG_256156_ADDR, v) +#define HWIO_REG_256156_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_256156_ADDR, m, v,\ + HWIO_REG_256156_IN); +#define HWIO_REG_256156_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_256156_BASE_ADDR_SHFT 0 + +#define HWIO_REG_335729_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006e8) +#define HWIO_REG_335729_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006e8) +#define HWIO_REG_335729_RMSK 0x1ffff +#define HWIO_REG_335729_SHFT 0 +#define HWIO_REG_335729_IN in_dword_masked(\ + HWIO_REG_335729_ADDR, HWIO_REG_335729_RMSK) +#define HWIO_REG_335729_INM(m) \ + in_dword_masked(HWIO_REG_335729_ADDR, m) +#define HWIO_REG_335729_OUT(v) \ + out_dword(HWIO_REG_335729_ADDR, v) +#define HWIO_REG_335729_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_335729_ADDR, m, v,\ + HWIO_REG_335729_IN); +#define HWIO_REG_335729_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_335729_BASE_ADDR_SHFT 0 + +#define HWIO_REG_303383_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006ec) +#define HWIO_REG_303383_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006ec) +#define HWIO_REG_303383_RMSK 0x1ffff +#define HWIO_REG_303383_SHFT 0 +#define HWIO_REG_303383_IN in_dword_masked(\ + HWIO_REG_303383_ADDR, HWIO_REG_303383_RMSK) +#define HWIO_REG_303383_INM(m) \ + in_dword_masked(HWIO_REG_303383_ADDR, m) +#define HWIO_REG_303383_OUT(v) \ + out_dword(HWIO_REG_303383_ADDR, v) +#define HWIO_REG_303383_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_303383_ADDR, m, v,\ + HWIO_REG_303383_IN); +#define HWIO_REG_303383_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_303383_BASE_ADDR_SHFT 0 + +#define HWIO_REG_180871_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006f0) +#define HWIO_REG_180871_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006f0) +#define HWIO_REG_180871_RMSK 0x1ffff +#define HWIO_REG_180871_SHFT 0 +#define HWIO_REG_180871_IN in_dword_masked(\ + HWIO_REG_180871_ADDR, HWIO_REG_180871_RMSK) +#define HWIO_REG_180871_INM(m) \ + in_dword_masked(HWIO_REG_180871_ADDR, m) +#define HWIO_REG_180871_OUT(v) \ + out_dword(HWIO_REG_180871_ADDR, v) +#define HWIO_REG_180871_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_180871_ADDR, m, v,\ + HWIO_REG_180871_IN); +#define HWIO_REG_180871_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_180871_BASE_ADDR_SHFT 0 + +#define HWIO_REG_514148_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006f4) +#define HWIO_REG_514148_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006f4) +#define HWIO_REG_514148_RMSK 0x1ffff +#define HWIO_REG_514148_SHFT 0 +#define HWIO_REG_514148_IN in_dword_masked(\ + HWIO_REG_514148_ADDR, HWIO_REG_514148_RMSK) +#define HWIO_REG_514148_INM(m) \ + in_dword_masked(HWIO_REG_514148_ADDR, m) +#define HWIO_REG_514148_OUT(v) \ + out_dword(HWIO_REG_514148_ADDR, v) +#define HWIO_REG_514148_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_514148_ADDR, m, v,\ + HWIO_REG_514148_IN); +#define HWIO_REG_514148_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_514148_BASE_ADDR_SHFT 0 + +#define HWIO_REG_578636_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006f8) +#define HWIO_REG_578636_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006f8) +#define HWIO_REG_578636_RMSK 0x1ffff +#define HWIO_REG_578636_SHFT 0 +#define HWIO_REG_578636_IN in_dword_masked(\ + HWIO_REG_578636_ADDR, HWIO_REG_578636_RMSK) +#define HWIO_REG_578636_INM(m) \ + in_dword_masked(HWIO_REG_578636_ADDR, m) +#define HWIO_REG_578636_OUT(v) \ + out_dword(HWIO_REG_578636_ADDR, v) +#define HWIO_REG_578636_OUTM(m, v) \ + out_dword_masked_ns(HWIO_REG_578636_ADDR, m, v,\ + HWIO_REG_578636_IN); +#define HWIO_REG_578636_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_578636_BASE_ADDR_SHFT 0 + +#define HWIO_REG_888116_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000006fc) +#define HWIO_REG_888116_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000006fc) +#define HWIO_REG_888116_RMSK 0x1ffff +#define HWIO_REG_888116_SHFT 0 +#define HWIO_REG_888116_IN in_dword_masked(\ + HWIO_REG_888116_ADDR, HWIO_REG_888116_RMSK) +#define HWIO_REG_888116_INM(m) \ + in_dword_masked(HWIO_REG_888116_ADDR, m) +#define HWIO_REG_888116_OUT(v) \ + out_dword(HWIO_REG_888116_ADDR, v) +#define HWIO_REG_888116_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_888116_ADDR, m, v,\ + HWIO_REG_888116_IN); +#define HWIO_REG_888116_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_888116_BASE_ADDR_SHFT 0 + +#define HWIO_REG_759068_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000700) +#define HWIO_REG_759068_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000700) +#define HWIO_REG_759068_RMSK 0x1ffff +#define HWIO_REG_759068_SHFT 0 +#define HWIO_REG_759068_IN in_dword_masked(\ + HWIO_REG_759068_ADDR, HWIO_REG_759068_RMSK) +#define HWIO_REG_759068_INM(m) \ + in_dword_masked(HWIO_REG_759068_ADDR, m) +#define HWIO_REG_759068_OUT(v) \ + out_dword(HWIO_REG_759068_ADDR, v) +#define HWIO_REG_759068_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_759068_ADDR, m, v,\ + HWIO_REG_759068_IN); +#define HWIO_REG_759068_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_759068_BASE_ADDR_SHFT 0 + +#define HWIO_REG_68356_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000704) +#define HWIO_REG_68356_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000704) +#define HWIO_REG_68356_RMSK 0x1ffff +#define HWIO_REG_68356_SHFT 0 +#define HWIO_REG_68356_IN in_dword_masked(\ + HWIO_REG_68356_ADDR, HWIO_REG_68356_RMSK) +#define HWIO_REG_68356_INM(m) \ + in_dword_masked(HWIO_REG_68356_ADDR, m) +#define HWIO_REG_68356_OUT(v) \ + out_dword(HWIO_REG_68356_ADDR, v) +#define HWIO_REG_68356_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_68356_ADDR, m, v,\ + HWIO_REG_68356_IN); +#define HWIO_REG_68356_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_68356_BASE_ADDR_SHFT 0 + +#define HWIO_REG_833502_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000708) +#define HWIO_REG_833502_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000708) +#define HWIO_REG_833502_RMSK 0x1ffff +#define HWIO_REG_833502_SHFT 0 +#define HWIO_REG_833502_IN in_dword_masked(\ + HWIO_REG_833502_ADDR, HWIO_REG_833502_RMSK) +#define HWIO_REG_833502_INM(m) \ + in_dword_masked(HWIO_REG_833502_ADDR, m) +#define HWIO_REG_833502_OUT(v) \ + out_dword(HWIO_REG_833502_ADDR, v) +#define HWIO_REG_833502_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_833502_ADDR, m, v,\ + HWIO_REG_833502_IN); +#define HWIO_REG_833502_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_833502_BASE_ADDR_SHFT 0 + +#define HWIO_REG_127855_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000070c) +#define HWIO_REG_127855_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000070c) +#define HWIO_REG_127855_RMSK 0x1ffff +#define HWIO_REG_127855_SHFT 0 +#define HWIO_REG_127855_IN in_dword_masked(\ + HWIO_REG_127855_ADDR, HWIO_REG_127855_RMSK) +#define HWIO_REG_127855_INM(m) \ + in_dword_masked(HWIO_REG_127855_ADDR, m) +#define HWIO_REG_127855_OUT(v) \ + out_dword(HWIO_REG_127855_ADDR, v) +#define HWIO_REG_127855_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_127855_ADDR, m, v,\ + HWIO_REG_127855_IN); +#define HWIO_REG_127855_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_127855_BASE_ADDR_SHFT 0 + +#define HWIO_REG_616802_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000710) +#define HWIO_REG_616802_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000710) +#define HWIO_REG_616802_RMSK 0x1ffff +#define HWIO_REG_616802_SHFT 0 +#define HWIO_REG_616802_IN in_dword_masked(\ + HWIO_REG_616802_ADDR, HWIO_REG_616802_RMSK) +#define HWIO_REG_616802_INM(m) \ + in_dword_masked(HWIO_REG_616802_ADDR, m) +#define HWIO_REG_616802_OUT(v) \ + out_dword(HWIO_REG_616802_ADDR, v) +#define HWIO_REG_616802_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_616802_ADDR, m, v,\ + HWIO_REG_616802_IN); +#define HWIO_REG_616802_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_616802_BASE_ADDR_SHFT 0 + +#define HWIO_REG_23318_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000714) +#define HWIO_REG_23318_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000714) +#define HWIO_REG_23318_RMSK 0x1ffff +#define HWIO_REG_23318_SHFT 0 +#define HWIO_REG_23318_IN in_dword_masked(\ + HWIO_REG_23318_ADDR, HWIO_REG_23318_RMSK) +#define HWIO_REG_23318_INM(m) \ + in_dword_masked(HWIO_REG_23318_ADDR, m) +#define HWIO_REG_23318_OUT(v) \ + out_dword(HWIO_REG_23318_ADDR, v) +#define HWIO_REG_23318_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_23318_ADDR, m, v,\ + HWIO_REG_23318_IN); +#define HWIO_REG_23318_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_23318_BASE_ADDR_SHFT 0 + +#define HWIO_REG_317106_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000718) +#define HWIO_REG_317106_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000718) +#define HWIO_REG_317106_RMSK 0x1ffff +#define HWIO_REG_317106_SHFT 0 +#define HWIO_REG_317106_IN in_dword_masked(\ + HWIO_REG_317106_ADDR, HWIO_REG_317106_RMSK) +#define HWIO_REG_317106_INM(m) \ + in_dword_masked(HWIO_REG_317106_ADDR, m) +#define HWIO_REG_317106_OUT(v) \ + out_dword(HWIO_REG_317106_ADDR, v) +#define HWIO_REG_317106_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_317106_ADDR, m, v,\ + HWIO_REG_317106_IN); +#define HWIO_REG_317106_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_317106_BASE_ADDR_SHFT 0 + +#define HWIO_REG_603772_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000071c) +#define HWIO_REG_603772_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000071c) +#define HWIO_REG_603772_RMSK 0x1ffff +#define HWIO_REG_603772_SHFT 0 +#define HWIO_REG_603772_IN in_dword_masked(\ + HWIO_REG_603772_ADDR, HWIO_REG_603772_RMSK) +#define HWIO_REG_603772_INM(m) \ + in_dword_masked(HWIO_REG_603772_ADDR, m) +#define HWIO_REG_603772_OUT(v) \ + out_dword(HWIO_REG_603772_ADDR, v) +#define HWIO_REG_603772_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_603772_ADDR, m, v,\ + HWIO_REG_603772_IN); +#define HWIO_REG_603772_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_603772_BASE_ADDR_SHFT 0 + +#define HWIO_REG_175929_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000720) +#define HWIO_REG_175929_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000720) +#define HWIO_REG_175929_RMSK 0x1ffff +#define HWIO_REG_175929_SHFT 0 +#define HWIO_REG_175929_IN in_dword_masked(\ + HWIO_REG_175929_ADDR, HWIO_REG_175929_RMSK) +#define HWIO_REG_175929_INM(m) \ + in_dword_masked(HWIO_REG_175929_ADDR, m) +#define HWIO_REG_175929_OUT(v) \ + out_dword(HWIO_REG_175929_ADDR, v) +#define HWIO_REG_175929_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_175929_ADDR, m, v,\ + HWIO_REG_175929_IN); +#define HWIO_REG_175929_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_175929_BASE_ADDR_SHFT 0 + +#define HWIO_REG_11928_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000724) +#define HWIO_REG_11928_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000724) +#define HWIO_REG_11928_RMSK 0x1ffff +#define HWIO_REG_11928_SHFT 0 +#define HWIO_REG_11928_IN in_dword_masked(\ + HWIO_REG_11928_ADDR, HWIO_REG_11928_RMSK) +#define HWIO_REG_11928_INM(m) \ + in_dword_masked(HWIO_REG_11928_ADDR, m) +#define HWIO_REG_11928_OUT(v) \ + out_dword(HWIO_REG_11928_ADDR, v) +#define HWIO_REG_11928_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_11928_ADDR, m, v,\ + HWIO_REG_11928_IN); +#define HWIO_REG_11928_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_11928_BASE_ADDR_SHFT 0 + +#define HWIO_REG_772678_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000728) +#define HWIO_REG_772678_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000728) +#define HWIO_REG_772678_RMSK 0x1ffff +#define HWIO_REG_772678_SHFT 0 +#define HWIO_REG_772678_IN in_dword_masked(\ + HWIO_REG_772678_ADDR, HWIO_REG_772678_RMSK) +#define HWIO_REG_772678_INM(m) \ + in_dword_masked(HWIO_REG_772678_ADDR, m) +#define HWIO_REG_772678_OUT(v) \ + out_dword(HWIO_REG_772678_ADDR, v) +#define HWIO_REG_772678_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_772678_ADDR, m, v,\ + HWIO_REG_772678_IN); +#define HWIO_REG_772678_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_772678_BASE_ADDR_SHFT 0 + +#define HWIO_REG_603389_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000072c) +#define HWIO_REG_603389_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000072c) +#define HWIO_REG_603389_RMSK 0x1ffff +#define HWIO_REG_603389_SHFT 0 +#define HWIO_REG_603389_IN in_dword_masked(\ + HWIO_REG_603389_ADDR, HWIO_REG_603389_RMSK) +#define HWIO_REG_603389_INM(m) \ + in_dword_masked(HWIO_REG_603389_ADDR, m) +#define HWIO_REG_603389_OUT(v) \ + out_dword(HWIO_REG_603389_ADDR, v) +#define HWIO_REG_603389_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_603389_ADDR, m, v,\ + HWIO_REG_603389_IN); +#define HWIO_REG_603389_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_603389_BASE_ADDR_SHFT 0 + +#define HWIO_REG_989918_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000730) +#define HWIO_REG_989918_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000730) +#define HWIO_REG_989918_RMSK 0x1ffff +#define HWIO_REG_989918_SHFT 0 +#define HWIO_REG_989918_IN in_dword_masked(\ + HWIO_REG_989918_ADDR, HWIO_REG_989918_RMSK) +#define HWIO_REG_989918_INM(m) \ + in_dword_masked(HWIO_REG_989918_ADDR, m) +#define HWIO_REG_989918_OUT(v) \ + out_dword(HWIO_REG_989918_ADDR, v) +#define HWIO_REG_989918_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_989918_ADDR, m, v,\ + HWIO_REG_989918_IN); +#define HWIO_REG_989918_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_989918_BASE_ADDR_SHFT 0 + +#define HWIO_REG_5460_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000734) +#define HWIO_REG_5460_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000734) +#define HWIO_REG_5460_RMSK 0x1ffff +#define HWIO_REG_5460_SHFT 0 +#define HWIO_REG_5460_IN in_dword_masked(\ + HWIO_REG_5460_ADDR, HWIO_REG_5460_RMSK) +#define HWIO_REG_5460_INM(m) \ + in_dword_masked(HWIO_REG_5460_ADDR, m) +#define HWIO_REG_5460_OUT(v) \ + out_dword(HWIO_REG_5460_ADDR, v) +#define HWIO_REG_5460_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_5460_ADDR, m, v,\ + HWIO_REG_5460_IN); +#define HWIO_REG_5460_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_5460_BASE_ADDR_SHFT 0 + +#define HWIO_REG_734724_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000738) +#define HWIO_REG_734724_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000738) +#define HWIO_REG_734724_RMSK 0x1ffff +#define HWIO_REG_734724_SHFT 0 +#define HWIO_REG_734724_IN in_dword_masked(\ + HWIO_REG_734724_ADDR, HWIO_REG_734724_RMSK) +#define HWIO_REG_734724_INM(m) \ + in_dword_masked(HWIO_REG_734724_ADDR, m) +#define HWIO_REG_734724_OUT(v) \ + out_dword(HWIO_REG_734724_ADDR, v) +#define HWIO_REG_734724_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_734724_ADDR, m, v,\ + HWIO_REG_734724_IN); +#define HWIO_REG_734724_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_734724_BASE_ADDR_SHFT 0 + +#define HWIO_REG_451742_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000073c) +#define HWIO_REG_451742_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000073c) +#define HWIO_REG_451742_RMSK 0x1ffff +#define HWIO_REG_451742_SHFT 0 +#define HWIO_REG_451742_IN in_dword_masked(\ + HWIO_REG_451742_ADDR, HWIO_REG_451742_RMSK) +#define HWIO_REG_451742_INM(m) \ + in_dword_masked(HWIO_REG_451742_ADDR, m) +#define HWIO_REG_451742_OUT(v) \ + out_dword(HWIO_REG_451742_ADDR, v) +#define HWIO_REG_451742_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_451742_ADDR, m, v,\ + HWIO_REG_451742_IN); +#define HWIO_REG_451742_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_451742_BASE_ADDR_SHFT 0 + +#define HWIO_REG_475648_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000740) +#define HWIO_REG_475648_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000740) +#define HWIO_REG_475648_RMSK 0x1ffff +#define HWIO_REG_475648_SHFT 0 +#define HWIO_REG_475648_IN in_dword_masked(\ + HWIO_REG_475648_ADDR, HWIO_REG_475648_RMSK) +#define HWIO_REG_475648_INM(m) \ + in_dword_masked(HWIO_REG_475648_ADDR, m) +#define HWIO_REG_475648_OUT(v) \ + out_dword(HWIO_REG_475648_ADDR, v) +#define HWIO_REG_475648_OUTM(m, v) \ + out_dword_masked_ns(HWIO_REG_475648_ADDR, m, v,\ + HWIO_REG_475648_IN); +#define HWIO_REG_475648_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_475648_BASE_ADDR_SHFT 0 + +#define HWIO_REG_284758_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000744) +#define HWIO_REG_284758_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000744) +#define HWIO_REG_284758_RMSK 0x1ffff +#define HWIO_REG_284758_SHFT 0 +#define HWIO_REG_284758_IN in_dword_masked(\ + HWIO_REG_284758_ADDR, HWIO_REG_284758_RMSK) +#define HWIO_REG_284758_INM(m) \ + in_dword_masked(HWIO_REG_284758_ADDR, m) +#define HWIO_REG_284758_OUT(v) \ + out_dword(HWIO_REG_284758_ADDR, v) +#define HWIO_REG_284758_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_284758_ADDR, m, v,\ + HWIO_REG_284758_IN); +#define HWIO_REG_284758_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_284758_BASE_ADDR_SHFT 0 + +#define HWIO_REG_523659_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000748) +#define HWIO_REG_523659_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000748) +#define HWIO_REG_523659_RMSK 0x1ffff +#define HWIO_REG_523659_SHFT 0 +#define HWIO_REG_523659_IN in_dword_masked(\ + HWIO_REG_523659_ADDR, HWIO_REG_523659_RMSK) +#define HWIO_REG_523659_INM(m) \ + in_dword_masked(HWIO_REG_523659_ADDR, m) +#define HWIO_REG_523659_OUT(v) \ + out_dword(HWIO_REG_523659_ADDR, v) +#define HWIO_REG_523659_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_523659_ADDR, m, v,\ + HWIO_REG_523659_IN); +#define HWIO_REG_523659_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_523659_BASE_ADDR_SHFT 0 + +#define HWIO_REG_815580_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000074c) +#define HWIO_REG_815580_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000074c) +#define HWIO_REG_815580_RMSK 0x1ffff +#define HWIO_REG_815580_SHFT 0 +#define HWIO_REG_815580_IN in_dword_masked(\ + HWIO_REG_815580_ADDR, HWIO_REG_815580_RMSK) +#define HWIO_REG_815580_INM(m) \ + in_dword_masked(HWIO_REG_815580_ADDR, m) +#define HWIO_REG_815580_OUT(v) \ + out_dword(HWIO_REG_815580_ADDR, v) +#define HWIO_REG_815580_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_815580_ADDR, m, v,\ + HWIO_REG_815580_IN); +#define HWIO_REG_815580_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_815580_BASE_ADDR_SHFT 0 + +#define HWIO_REG_546551_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000750) +#define HWIO_REG_546551_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000750) +#define HWIO_REG_546551_RMSK 0x1ffff +#define HWIO_REG_546551_SHFT 0 +#define HWIO_REG_546551_IN in_dword_masked(\ + HWIO_REG_546551_ADDR, HWIO_REG_546551_RMSK) +#define HWIO_REG_546551_INM(m) \ + in_dword_masked(HWIO_REG_546551_ADDR, m) +#define HWIO_REG_546551_OUT(v) \ + out_dword(HWIO_REG_546551_ADDR, v) +#define HWIO_REG_546551_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_546551_ADDR, m, v,\ + HWIO_REG_546551_IN); +#define HWIO_REG_546551_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_546551_BASE_ADDR_SHFT 0 + +#define HWIO_REG_769851_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000754) +#define HWIO_REG_769851_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000754) +#define HWIO_REG_769851_RMSK 0x1ffff +#define HWIO_REG_769851_SHFT 0 +#define HWIO_REG_769851_IN in_dword_masked(\ + HWIO_REG_769851_ADDR, HWIO_REG_769851_RMSK) +#define HWIO_REG_769851_INM(m) \ + in_dword_masked(HWIO_REG_769851_ADDR, m) +#define HWIO_REG_769851_OUT(v) \ + out_dword(HWIO_REG_769851_ADDR, v) +#define HWIO_REG_769851_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_769851_ADDR, m, v,\ + HWIO_REG_769851_IN); +#define HWIO_REG_769851_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_769851_BASE_ADDR_SHFT 0 + +#define HWIO_REG_205028_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000758) +#define HWIO_REG_205028_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000758) +#define HWIO_REG_205028_RMSK 0x1ffff +#define HWIO_REG_205028_SHFT 0 +#define HWIO_REG_205028_IN in_dword_masked(\ + HWIO_REG_205028_ADDR, HWIO_REG_205028_RMSK) +#define HWIO_REG_205028_INM(m) \ + in_dword_masked(HWIO_REG_205028_ADDR, m) +#define HWIO_REG_205028_OUT(v) \ + out_dword(HWIO_REG_205028_ADDR, v) +#define HWIO_REG_205028_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_205028_ADDR, m, v,\ + HWIO_REG_205028_IN); +#define HWIO_REG_205028_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_205028_BASE_ADDR_SHFT 0 + +#define HWIO_REG_206835_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000075c) +#define HWIO_REG_206835_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000075c) +#define HWIO_REG_206835_RMSK 0x1ffff +#define HWIO_REG_206835_SHFT 0 +#define HWIO_REG_206835_IN in_dword_masked(\ + HWIO_REG_206835_ADDR, HWIO_REG_206835_RMSK) +#define HWIO_REG_206835_INM(m) \ + in_dword_masked(HWIO_REG_206835_ADDR, m) +#define HWIO_REG_206835_OUT(v) \ + out_dword(HWIO_REG_206835_ADDR, v) +#define HWIO_REG_206835_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_206835_ADDR, m, v,\ + HWIO_REG_206835_IN); +#define HWIO_REG_206835_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_206835_BASE_ADDR_SHFT 0 + +#define HWIO_REG_582575_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000760) +#define HWIO_REG_582575_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000760) +#define HWIO_REG_582575_RMSK 0x1ffff +#define HWIO_REG_582575_SHFT 0 +#define HWIO_REG_582575_IN in_dword_masked(\ + HWIO_REG_582575_ADDR, HWIO_REG_582575_RMSK) +#define HWIO_REG_582575_INM(m) \ + in_dword_masked(HWIO_REG_582575_ADDR, m) +#define HWIO_REG_582575_OUT(v) \ + out_dword(HWIO_REG_582575_ADDR, v) +#define HWIO_REG_582575_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_582575_ADDR, m, v,\ + HWIO_REG_582575_IN); +#define HWIO_REG_582575_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_582575_BASE_ADDR_SHFT 0 + +#define HWIO_REG_120885_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000764) +#define HWIO_REG_120885_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000764) +#define HWIO_REG_120885_RMSK 0x1ffff +#define HWIO_REG_120885_SHFT 0 +#define HWIO_REG_120885_IN in_dword_masked(\ + HWIO_REG_120885_ADDR, HWIO_REG_120885_RMSK) +#define HWIO_REG_120885_INM(m) \ + in_dword_masked(HWIO_REG_120885_ADDR, m) +#define HWIO_REG_120885_OUT(v) \ + out_dword(HWIO_REG_120885_ADDR, v) +#define HWIO_REG_120885_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_120885_ADDR, m, v,\ + HWIO_REG_120885_IN); +#define HWIO_REG_120885_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_120885_BASE_ADDR_SHFT 0 + +#define HWIO_REG_496067_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000768) +#define HWIO_REG_496067_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000768) +#define HWIO_REG_496067_RMSK 0x1ffff +#define HWIO_REG_496067_SHFT 0 +#define HWIO_REG_496067_IN in_dword_masked(\ + HWIO_REG_496067_ADDR, HWIO_REG_496067_RMSK) +#define HWIO_REG_496067_INM(m) \ + in_dword_masked(HWIO_REG_496067_ADDR, m) +#define HWIO_REG_496067_OUT(v) \ + out_dword(HWIO_REG_496067_ADDR, v) +#define HWIO_REG_496067_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_496067_ADDR, m, v,\ + HWIO_REG_496067_IN); +#define HWIO_REG_496067_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_496067_BASE_ADDR_SHFT 0 + +#define HWIO_REG_472919_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000076c) +#define HWIO_REG_472919_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000076c) +#define HWIO_REG_472919_RMSK 0x1ffff +#define HWIO_REG_472919_SHFT 0 +#define HWIO_REG_472919_IN in_dword_masked(\ + HWIO_REG_472919_ADDR, HWIO_REG_472919_RMSK) +#define HWIO_REG_472919_INM(m) \ + in_dword_masked(HWIO_REG_472919_ADDR, m) +#define HWIO_REG_472919_OUT(v) \ + out_dword(HWIO_REG_472919_ADDR, v) +#define HWIO_REG_472919_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_472919_ADDR, m, v,\ + HWIO_REG_472919_IN); +#define HWIO_REG_472919_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_472919_BASE_ADDR_SHFT 0 + +#define HWIO_REG_486985_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000770) +#define HWIO_REG_486985_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000770) +#define HWIO_REG_486985_RMSK 0x1ffff +#define HWIO_REG_486985_SHFT 0 +#define HWIO_REG_486985_IN in_dword_masked(\ + HWIO_REG_486985_ADDR, HWIO_REG_486985_RMSK) +#define HWIO_REG_486985_INM(m) \ + in_dword_masked(HWIO_REG_486985_ADDR, m) +#define HWIO_REG_486985_OUT(v) \ + out_dword(HWIO_REG_486985_ADDR, v) +#define HWIO_REG_486985_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_486985_ADDR, m, v,\ + HWIO_REG_486985_IN); +#define HWIO_REG_486985_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_486985_BASE_ADDR_SHFT 0 + +#define HWIO_REG_964692_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000774) +#define HWIO_REG_964692_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000774) +#define HWIO_REG_964692_RMSK 0x1ffff +#define HWIO_REG_964692_SHFT 0 +#define HWIO_REG_964692_IN in_dword_masked(\ + HWIO_REG_964692_ADDR, HWIO_REG_964692_RMSK) +#define HWIO_REG_964692_INM(m) \ + in_dword_masked(HWIO_REG_964692_ADDR, m) +#define HWIO_REG_964692_OUT(v) \ + out_dword(HWIO_REG_964692_ADDR, v) +#define HWIO_REG_964692_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_964692_ADDR, m, v,\ + HWIO_REG_964692_IN); +#define HWIO_REG_964692_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_964692_BASE_ADDR_SHFT 0 + +#define HWIO_REG_941116_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000778) +#define HWIO_REG_941116_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000778) +#define HWIO_REG_941116_RMSK 0x1ffff +#define HWIO_REG_941116_SHFT 0 +#define HWIO_REG_941116_IN in_dword_masked(\ + HWIO_REG_941116_ADDR, HWIO_REG_941116_RMSK) +#define HWIO_REG_941116_INM(m) \ + in_dword_masked(HWIO_REG_941116_ADDR, m) +#define HWIO_REG_941116_OUT(v) \ + out_dword(HWIO_REG_941116_ADDR, v) +#define HWIO_REG_941116_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_941116_ADDR, m, v,\ + HWIO_REG_941116_IN); +#define HWIO_REG_941116_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_941116_BASE_ADDR_SHFT 0 + +#define HWIO_REG_122567_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000077c) +#define HWIO_REG_122567_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000077c) +#define HWIO_REG_122567_RMSK 0x1ffff +#define HWIO_REG_122567_SHFT 0 +#define HWIO_REG_122567_IN in_dword_masked(\ + HWIO_REG_122567_ADDR, HWIO_REG_122567_RMSK) +#define HWIO_REG_122567_INM(m) \ + in_dword_masked(HWIO_REG_122567_ADDR, m) +#define HWIO_REG_122567_OUT(v) \ + out_dword(HWIO_REG_122567_ADDR, v) +#define HWIO_REG_122567_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_122567_ADDR, m, v,\ + HWIO_REG_122567_IN); +#define HWIO_REG_122567_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_122567_BASE_ADDR_SHFT 0 + +#define HWIO_REG_466192_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000780) +#define HWIO_REG_466192_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000780) +#define HWIO_REG_466192_RMSK 0x1ffff +#define HWIO_REG_466192_SHFT 0 +#define HWIO_REG_466192_IN in_dword_masked(\ + HWIO_REG_466192_ADDR, HWIO_REG_466192_RMSK) +#define HWIO_REG_466192_INM(m) \ + in_dword_masked(HWIO_REG_466192_ADDR, m) +#define HWIO_REG_466192_OUT(v) \ + out_dword(HWIO_REG_466192_ADDR, v) +#define HWIO_REG_466192_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_466192_ADDR, m, v,\ + HWIO_REG_466192_IN); +#define HWIO_REG_466192_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_466192_BASE_ADDR_SHFT 0 + +#define HWIO_REG_554890_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000784) +#define HWIO_REG_554890_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000784) +#define HWIO_REG_554890_RMSK 0x1ffff +#define HWIO_REG_554890_SHFT 0 +#define HWIO_REG_554890_IN in_dword_masked(\ + HWIO_REG_554890_ADDR, HWIO_REG_554890_RMSK) +#define HWIO_REG_554890_INM(m) \ + in_dword_masked(HWIO_REG_554890_ADDR, m) +#define HWIO_REG_554890_OUT(v) \ + out_dword(HWIO_REG_554890_ADDR, v) +#define HWIO_REG_554890_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_554890_ADDR, m, v,\ + HWIO_REG_554890_IN); +#define HWIO_REG_554890_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_554890_BASE_ADDR_SHFT 0 + +#define HWIO_REG_295616_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000788) +#define HWIO_REG_295616_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000788) +#define HWIO_REG_295616_RMSK 0x1ffff +#define HWIO_REG_295616_SHFT 0 +#define HWIO_REG_295616_IN in_dword_masked(\ + HWIO_REG_295616_ADDR, HWIO_REG_295616_RMSK) +#define HWIO_REG_295616_INM(m) \ + in_dword_masked(HWIO_REG_295616_ADDR, m) +#define HWIO_REG_295616_OUT(v) \ + out_dword(HWIO_REG_295616_ADDR, v) +#define HWIO_REG_295616_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_295616_ADDR, m, v,\ + HWIO_REG_295616_IN); +#define HWIO_REG_295616_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_295616_BASE_ADDR_SHFT 0 + +#define HWIO_REG_440836_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000078c) +#define HWIO_REG_440836_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000078c) +#define HWIO_REG_440836_RMSK 0x1ffff +#define HWIO_REG_440836_SHFT 0 +#define HWIO_REG_440836_IN in_dword_masked(\ + HWIO_REG_440836_ADDR, HWIO_REG_440836_RMSK) +#define HWIO_REG_440836_INM(m) \ + in_dword_masked(HWIO_REG_440836_ADDR, m) +#define HWIO_REG_440836_OUT(v) \ + out_dword(HWIO_REG_440836_ADDR, v) +#define HWIO_REG_440836_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_440836_ADDR, m, v,\ + HWIO_REG_440836_IN); +#define HWIO_REG_440836_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_440836_BASE_ADDR_SHFT 0 + +#define HWIO_REG_741154_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000790) +#define HWIO_REG_741154_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000790) +#define HWIO_REG_741154_RMSK 0x1ffff +#define HWIO_REG_741154_SHFT 0 +#define HWIO_REG_741154_IN in_dword_masked(\ + HWIO_REG_741154_ADDR,\ + HWIO_REG_741154_RMSK) +#define HWIO_REG_741154_INM(m) \ + in_dword_masked(HWIO_REG_741154_ADDR, m) +#define HWIO_REG_741154_OUT(v) \ + out_dword(HWIO_REG_741154_ADDR, v) +#define HWIO_REG_741154_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_741154_ADDR, m, v,\ + HWIO_REG_741154_IN); +#define HWIO_REG_741154_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_741154_BASE_ADDR_SHFT 0 + +#define HWIO_REG_753139_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000794) +#define HWIO_REG_753139_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000794) +#define HWIO_REG_753139_RMSK 0x1ffff +#define HWIO_REG_753139_SHFT 0 +#define HWIO_REG_753139_IN in_dword_masked(\ + HWIO_REG_753139_ADDR,\ + HWIO_REG_753139_RMSK) +#define HWIO_REG_753139_INM(m) \ + in_dword_masked(HWIO_REG_753139_ADDR, m) +#define HWIO_REG_753139_OUT(v) \ + out_dword(HWIO_REG_753139_ADDR, v) +#define HWIO_REG_753139_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_753139_ADDR, m, v,\ + HWIO_REG_753139_IN); +#define HWIO_REG_753139_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_753139_BASE_ADDR_SHFT 0 + +#define HWIO_REG_409994_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x00000798) +#define HWIO_REG_409994_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000798) +#define HWIO_REG_409994_RMSK 0x1ffff +#define HWIO_REG_409994_SHFT 0 +#define HWIO_REG_409994_IN in_dword_masked(\ + HWIO_REG_409994_ADDR,\ + HWIO_REG_409994_RMSK) +#define HWIO_REG_409994_INM(m) \ + in_dword_masked(HWIO_REG_409994_ADDR, m) +#define HWIO_REG_409994_OUT(v) \ + out_dword(HWIO_REG_409994_ADDR, v) +#define HWIO_REG_409994_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_409994_ADDR, m, v,\ + HWIO_REG_409994_IN); +#define HWIO_REG_409994_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_409994_BASE_ADDR_SHFT 0 + +#define HWIO_REG_492611_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000079c) +#define HWIO_REG_492611_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000079c) +#define HWIO_REG_492611_RMSK 0x1ffff +#define HWIO_REG_492611_SHFT 0 +#define HWIO_REG_492611_IN in_dword_masked(\ + HWIO_REG_492611_ADDR,\ + HWIO_REG_492611_RMSK) +#define HWIO_REG_492611_INM(m) \ + in_dword_masked(HWIO_REG_492611_ADDR, m) +#define HWIO_REG_492611_OUT(v) \ + out_dword(HWIO_REG_492611_ADDR, v) +#define HWIO_REG_492611_OUTM(m, v) \ + out_dword_masked_ns(HWIO_REG_492611_ADDR, m, v,\ + HWIO_REG_492611_IN); +#define HWIO_REG_492611_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_492611_BASE_ADDR_SHFT 0 + +#define HWIO_REG_91427_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007a0) +#define HWIO_REG_91427_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007a0) +#define HWIO_REG_91427_RMSK 0x1ffff +#define HWIO_REG_91427_SHFT 0 +#define HWIO_REG_91427_IN in_dword_masked(\ + HWIO_REG_91427_ADDR,\ + HWIO_REG_91427_RMSK) +#define HWIO_REG_91427_INM(m) \ + in_dword_masked(HWIO_REG_91427_ADDR, m) +#define HWIO_REG_91427_OUT(v) \ + out_dword(HWIO_REG_91427_ADDR, v) +#define HWIO_REG_91427_OUTM(m, v) \ + out_dword_masked_ns(HWIO_REG_91427_ADDR, m, v,\ + HWIO_REG_91427_IN); +#define HWIO_REG_91427_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_91427_BASE_ADDR_SHFT 0 + +#define HWIO_REG_617696_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007a4) +#define HWIO_REG_617696_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007a4) +#define HWIO_REG_617696_RMSK 0x1ffff +#define HWIO_REG_617696_SHFT 0 +#define HWIO_REG_617696_IN in_dword_masked(\ + HWIO_REG_617696_ADDR,\ + HWIO_REG_617696_RMSK) +#define HWIO_REG_617696_INM(m) \ + in_dword_masked(HWIO_REG_617696_ADDR, m) +#define HWIO_REG_617696_OUT(v) \ + out_dword(HWIO_REG_617696_ADDR, v) +#define HWIO_REG_617696_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_617696_ADDR, m, v,\ + HWIO_REG_617696_IN); +#define HWIO_REG_617696_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_617696_BASE_ADDR_SHFT 0 + +#define HWIO_REG_459602_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007a8) +#define HWIO_REG_459602_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007a8) +#define HWIO_REG_459602_RMSK 0x1ffff +#define HWIO_REG_459602_SHFT 0 +#define HWIO_REG_459602_IN in_dword_masked(\ + HWIO_REG_459602_ADDR,\ + HWIO_REG_459602_RMSK) +#define HWIO_REG_459602_INM(m) \ + in_dword_masked(HWIO_REG_459602_ADDR, m) +#define HWIO_REG_459602_OUT(v) \ + out_dword(HWIO_REG_459602_ADDR, v) +#define HWIO_REG_459602_OUTM(m, v) \ + out_dword_masked_ns(HWIO_REG_459602_ADDR, m, v,\ + HWIO_REG_459602_IN); +#define HWIO_REG_459602_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_459602_BASE_ADDR_SHFT 0 + +#define HWIO_REG_758_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007ac) +#define HWIO_REG_758_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007ac) +#define HWIO_REG_758_RMSK 0x1ffff +#define HWIO_REG_758_SHFT 0 +#define HWIO_REG_758_IN in_dword_masked(\ + HWIO_REG_758_ADDR,\ + HWIO_REG_758_RMSK) +#define HWIO_REG_758_INM(m) \ + in_dword_masked(HWIO_REG_758_ADDR, m) +#define HWIO_REG_758_OUT(v) \ + out_dword(HWIO_REG_758_ADDR, v) +#define HWIO_REG_758_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_758_ADDR, m, v,\ + HWIO_REG_758_IN); +#define HWIO_REG_758_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_758_BASE_ADDR_SHFT 0 + +#define HWIO_REG_710606_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007b0) +#define HWIO_REG_710606_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007b0) +#define HWIO_REG_710606_RMSK 0x1ffff +#define HWIO_REG_710606_SHFT 0 +#define HWIO_REG_710606_IN in_dword_masked(\ + HWIO_REG_710606_ADDR,\ + HWIO_REG_710606_RMSK) +#define HWIO_REG_710606_INM(m) \ + in_dword_masked(HWIO_REG_710606_ADDR, m) +#define HWIO_REG_710606_OUT(v) \ + out_dword(HWIO_REG_710606_ADDR, v) +#define HWIO_REG_710606_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_710606_ADDR, m, v,\ + HWIO_REG_710606_IN); +#define HWIO_REG_710606_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_710606_BASE_ADDR_SHFT 0 + +#define HWIO_REG_122975_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007b4) +#define HWIO_REG_122975_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007b4) +#define HWIO_REG_122975_RMSK 0x1ffff +#define HWIO_REG_122975_SHFT 0 +#define HWIO_REG_122975_IN in_dword_masked(\ + HWIO_REG_122975_ADDR,\ + HWIO_REG_122975_RMSK) +#define HWIO_REG_122975_INM(m)\ + in_dword_masked(HWIO_REG_122975_ADDR, m) +#define HWIO_REG_122975_OUT(v)\ + out_dword(HWIO_REG_122975_ADDR, v) +#define HWIO_REG_122975_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_122975_ADDR, m, v,\ + HWIO_REG_122975_IN); +#define HWIO_REG_122975_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_122975_BASE_ADDR_SHFT 0 + +#define HWIO_REG_860205_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007b8) +#define HWIO_REG_860205_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007b8) +#define HWIO_REG_860205_RMSK 0x1ffff +#define HWIO_REG_860205_SHFT 0 +#define HWIO_REG_860205_IN in_dword_masked(\ + HWIO_REG_860205_ADDR,\ + HWIO_REG_860205_RMSK) +#define HWIO_REG_860205_INM(m) \ + in_dword_masked(HWIO_REG_860205_ADDR, m) +#define HWIO_REG_860205_OUT(v) \ + out_dword(HWIO_REG_860205_ADDR, v) +#define HWIO_REG_860205_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_860205_ADDR, m, v,\ + HWIO_REG_860205_IN); +#define HWIO_REG_860205_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_860205_BASE_ADDR_SHFT 0 + +#define HWIO_REG_366154_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007bc) +#define HWIO_REG_366154_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007bc) +#define HWIO_REG_366154_RMSK 0x1ffff +#define HWIO_REG_366154_SHFT 0 +#define HWIO_REG_366154_IN in_dword_masked(\ + HWIO_REG_366154_ADDR,\ + HWIO_REG_366154_RMSK) +#define HWIO_REG_366154_INM(m) \ + in_dword_masked(HWIO_REG_366154_ADDR, m) +#define HWIO_REG_366154_OUT(v) \ + out_dword(HWIO_REG_366154_ADDR, v) +#define HWIO_REG_366154_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_366154_ADDR, m, v,\ + HWIO_REG_366154_IN); +#define HWIO_REG_366154_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_366154_BASE_ADDR_SHFT 0 + +#define HWIO_REG_632247_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007c0) +#define HWIO_REG_632247_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007c0) +#define HWIO_REG_632247_RMSK 0x1ffff +#define HWIO_REG_632247_SHFT 0 +#define HWIO_REG_632247_IN in_dword_masked(\ + HWIO_REG_632247_ADDR,\ + HWIO_REG_632247_RMSK) +#define HWIO_REG_632247_INM(m) \ + in_dword_masked(HWIO_REG_632247_ADDR, m) +#define HWIO_REG_632247_OUT(v) \ + out_dword(HWIO_REG_632247_ADDR, v) +#define HWIO_REG_632247_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_632247_ADDR, m, v,\ + HWIO_REG_632247_IN); +#define HWIO_REG_632247_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_632247_BASE_ADDR_SHFT 0 + +#define HWIO_REG_709312_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007c4) +#define HWIO_REG_709312_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007c4) +#define HWIO_REG_709312_RMSK 0x1ffff +#define HWIO_REG_709312_SHFT 0 +#define HWIO_REG_709312_IN in_dword_masked(\ + HWIO_REG_709312_ADDR,\ + HWIO_REG_709312_RMSK) +#define HWIO_REG_709312_INM(m) \ + in_dword_masked(HWIO_REG_709312_ADDR, m) +#define HWIO_REG_709312_OUT(v) \ + out_dword(HWIO_REG_709312_ADDR, v) +#define HWIO_REG_709312_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_709312_ADDR, m, v,\ + HWIO_REG_709312_IN); +#define HWIO_REG_709312_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_709312_BASE_ADDR_SHFT 0 + +#define HWIO_REG_891367_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007c8) +#define HWIO_REG_891367_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007c8) +#define HWIO_REG_891367_RMSK 0x1ffff +#define HWIO_REG_891367_SHFT 0 +#define HWIO_REG_891367_IN in_dword_masked(\ + HWIO_REG_891367_ADDR,\ + HWIO_REG_891367_RMSK) +#define HWIO_REG_891367_INM(m) \ + in_dword_masked(HWIO_REG_891367_ADDR, m) +#define HWIO_REG_891367_OUT(v) \ + out_dword(HWIO_REG_891367_ADDR, v) +#define HWIO_REG_891367_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_891367_ADDR, m, v,\ + HWIO_REG_891367_IN); +#define HWIO_REG_891367_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_891367_BASE_ADDR_SHFT 0 + +#define HWIO_REG_628746_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007cc) +#define HWIO_REG_628746_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007cc) +#define HWIO_REG_628746_RMSK 0x1ffff +#define HWIO_REG_628746_SHFT 0 +#define HWIO_REG_628746_IN in_dword_masked(\ + HWIO_REG_628746_ADDR,\ + HWIO_REG_628746_RMSK) +#define HWIO_REG_628746_INM(m) \ + in_dword_masked(HWIO_REG_628746_ADDR, m) +#define HWIO_REG_628746_OUT(v) \ + out_dword(HWIO_REG_628746_ADDR, v) +#define HWIO_REG_628746_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_628746_ADDR, m, v,\ + HWIO_REG_628746_IN); +#define HWIO_REG_628746_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_628746_BASE_ADDR_SHFT 0 + +#define HWIO_REG_821010_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007d0) +#define HWIO_REG_821010_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007d0) +#define HWIO_REG_821010_RMSK 0x1ffff +#define HWIO_REG_821010_SHFT 0 +#define HWIO_REG_821010_IN in_dword_masked(\ + HWIO_REG_821010_ADDR,\ + HWIO_REG_821010_RMSK) +#define HWIO_REG_821010_INM(m) \ + in_dword_masked(HWIO_REG_821010_ADDR, m) +#define HWIO_REG_821010_OUT(v) \ + out_dword(HWIO_REG_821010_ADDR, v) +#define HWIO_REG_821010_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_821010_ADDR, m, v,\ + HWIO_REG_821010_IN); +#define HWIO_REG_821010_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_821010_BASE_ADDR_SHFT 0 + +#define HWIO_REG_902098_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007d4) +#define HWIO_REG_902098_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007d4) +#define HWIO_REG_902098_RMSK 0x1ffff +#define HWIO_REG_902098_SHFT 0 +#define HWIO_REG_902098_IN in_dword_masked(\ + HWIO_REG_902098_ADDR,\ + HWIO_REG_902098_RMSK) +#define HWIO_REG_902098_INM(m) \ + in_dword_masked(HWIO_REG_902098_ADDR, m) +#define HWIO_REG_902098_OUT(v) \ + out_dword(HWIO_REG_902098_ADDR, v) +#define HWIO_REG_902098_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_902098_ADDR, m, v,\ + HWIO_REG_902098_IN); +#define HWIO_REG_902098_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_902098_BASE_ADDR_SHFT 0 + +#define HWIO_REG_939091_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007d8) +#define HWIO_REG_939091_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007d8) +#define HWIO_REG_939091_RMSK 0x1ffff +#define HWIO_REG_939091_SHFT 0 +#define HWIO_REG_939091_IN in_dword_masked(\ + HWIO_REG_939091_ADDR,\ + HWIO_REG_939091_RMSK) +#define HWIO_REG_939091_INM(m) \ + in_dword_masked(HWIO_REG_939091_ADDR, m) +#define HWIO_REG_939091_OUT(v) \ + out_dword(HWIO_REG_939091_ADDR, v) +#define HWIO_REG_939091_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_939091_ADDR, m, v,\ + HWIO_REG_939091_IN); +#define HWIO_REG_939091_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_939091_BASE_ADDR_SHFT 0 + +#define HWIO_REG_261074_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007dc) +#define HWIO_REG_261074_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007dc) +#define HWIO_REG_261074_RMSK 0x1ffff +#define HWIO_REG_261074_SHFT 0 +#define HWIO_REG_261074_IN in_dword_masked(\ + HWIO_REG_261074_ADDR,\ + HWIO_REG_261074_RMSK) +#define HWIO_REG_261074_INM(m) \ + in_dword_masked(HWIO_REG_261074_ADDR, m) +#define HWIO_REG_261074_OUT(v) \ + out_dword(HWIO_REG_261074_ADDR, v) +#define HWIO_REG_261074_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_261074_ADDR, m, v,\ + HWIO_REG_261074_IN); +#define HWIO_REG_261074_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_261074_BASE_ADDR_SHFT 0 + +#define HWIO_REG_157718_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007e0) +#define HWIO_REG_157718_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007e0) +#define HWIO_REG_157718_RMSK 0x1ffff +#define HWIO_REG_157718_SHFT 0 +#define HWIO_REG_157718_IN in_dword_masked(\ + HWIO_REG_157718_ADDR,\ + HWIO_REG_157718_RMSK) +#define HWIO_REG_157718_INM(m) \ + in_dword_masked(HWIO_REG_157718_ADDR, m) +#define HWIO_REG_157718_OUT(v) \ + out_dword(HWIO_REG_157718_ADDR, v) +#define HWIO_REG_157718_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_157718_ADDR, m, v,\ + HWIO_REG_157718_IN); +#define HWIO_REG_5552391_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_5552391_BASE_ADDR_SHFT 0 + +#define HWIO_REG_148889_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007e8) +#define HWIO_REG_148889_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007e8) +#define HWIO_REG_148889_RMSK 0x1ffff +#define HWIO_REG_148889_SHFT 0 +#define HWIO_REG_148889_IN in_dword_masked(\ + HWIO_REG_148889_ADDR,\ + HWIO_REG_148889_RMSK) +#define HWIO_REG_148889_INM(m) \ + in_dword_masked(HWIO_REG_148889_ADDR, m) +#define HWIO_REG_148889_OUT(v) \ + out_dword(HWIO_REG_148889_ADDR, v) +#define HWIO_REG_148889_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_148889_ADDR, m, v,\ + HWIO_REG_148889_IN); +#define HWIO_REG_148889_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_148889_BASE_ADDR_SHFT 0 + +#define HWIO_REG_396380_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007ec) +#define HWIO_REG_396380_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007ec) +#define HWIO_REG_396380_RMSK 0x1ffff +#define HWIO_REG_396380_SHFT 0 +#define HWIO_REG_396380_IN in_dword_masked(\ + HWIO_REG_396380_ADDR,\ + HWIO_REG_396380_RMSK) +#define HWIO_REG_396380_INM(m) \ + in_dword_masked(HWIO_REG_396380_ADDR, m) +#define HWIO_REG_396380_OUT(v) \ + out_dword(HWIO_REG_396380_ADDR, v) +#define HWIO_REG_396380_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_396380_ADDR, m, v,\ + HWIO_REG_396380_IN); +#define HWIO_REG_396380_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_396380_BASE_ADDR_SHFT 0 + +#define HWIO_REG_351005_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007f0) +#define HWIO_REG_351005_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007f0) +#define HWIO_REG_351005_RMSK 0x1ffff +#define HWIO_REG_351005_SHFT 0 +#define HWIO_REG_351005_IN in_dword_masked(\ + HWIO_REG_351005_ADDR,\ + HWIO_REG_351005_RMSK) +#define HWIO_REG_351005_INM(m) \ + in_dword_masked(HWIO_REG_351005_ADDR, m) +#define HWIO_REG_351005_OUT(v) \ + out_dword(HWIO_REG_351005_ADDR, v) +#define HWIO_REG_351005_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_351005_ADDR, m, v,\ + HWIO_REG_351005_IN); +#define HWIO_REG_351005_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_351005_BASE_ADDR_SHFT 0 + +#define HWIO_REG_863263_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007f4) +#define HWIO_REG_863263_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007f4) +#define HWIO_REG_863263_RMSK 0x1ffff +#define HWIO_REG_863263_SHFT 0 +#define HWIO_REG_863263_IN in_dword_masked(\ + HWIO_REG_863263_ADDR,\ + HWIO_REG_863263_RMSK) +#define HWIO_REG_863263_INM(m) \ + in_dword_masked(HWIO_REG_863263_ADDR, m) +#define HWIO_REG_863263_OUT(v) \ + out_dword(HWIO_REG_863263_ADDR, v) +#define HWIO_REG_863263_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_863263_ADDR, m, v,\ + HWIO_REG_863263_IN); +#define HWIO_REG_863263_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_863263_BASE_ADDR_SHFT 0 + +#define HWIO_REG_135009_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007f8) +#define HWIO_REG_135009_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007f8) +#define HWIO_REG_135009_RMSK 0x1ffff +#define HWIO_REG_135009_SHFT 0 +#define HWIO_REG_135009_IN in_dword_masked(\ + HWIO_REG_135009_ADDR,\ + HWIO_REG_135009_RMSK) +#define HWIO_REG_135009_INM(m) \ + in_dword_masked(HWIO_REG_135009_ADDR, m) +#define HWIO_REG_135009_OUT(v) \ + out_dword(HWIO_REG_135009_ADDR, v) +#define HWIO_REG_135009_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_135009_ADDR, m, v,\ + HWIO_REG_135009_IN); +#define HWIO_REG_135009_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_135009_BASE_ADDR_SHFT 0 + +#define HWIO_REG_923883_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x000007fc) +#define HWIO_REG_923883_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000007fc) +#define HWIO_REG_923883_RMSK 0x1ffff +#define HWIO_REG_923883_SHFT 0 +#define HWIO_REG_923883_IN in_dword_masked(\ + HWIO_REG_923883_ADDR,\ + HWIO_REG_923883_RMSK) +#define HWIO_REG_923883_INM(m) \ + in_dword_masked(HWIO_REG_923883_ADDR, m) +#define HWIO_REG_923883_OUT(v) \ + out_dword(HWIO_REG_923883_ADDR, v) +#define HWIO_REG_923883_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_923883_ADDR, m, v,\ + HWIO_REG_923883_IN); +#define HWIO_REG_923883_BASE_ADDR_BMSK 0x1ffff +#define HWIO_REG_923883_BASE_ADDR_SHFT 0 + +#define HWIO_REG_934655_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000818) +#define HWIO_REG_934655_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000818) +#define HWIO_REG_934655_RMSK 0x1fff +#define HWIO_REG_934655_SHFT 0 +#define HWIO_REG_934655_IN \ + in_dword_masked(HWIO_REG_934655_ADDR, HWIO_REG_934655_RMSK) +#define HWIO_REG_934655_INM(m) \ + in_dword_masked(HWIO_REG_934655_ADDR, m) +#define HWIO_REG_934655_OUT(v) \ + out_dword(HWIO_REG_934655_ADDR, v) +#define HWIO_REG_934655_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_934655_ADDR, m, v, HWIO_REG_934655_IN); +#define HWIO_REG_934655_FRAME_WIDTH_BMSK 0x1fff +#define HWIO_REG_934655_FRAME_WIDTH_SHFT 0 + +#define HWIO_REG_179070_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000081c) +#define HWIO_REG_179070_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000081c) +#define HWIO_REG_179070_RMSK 0x1fff +#define HWIO_REG_179070_SHFT 0 +#define HWIO_REG_179070_IN in_dword_masked(\ + HWIO_REG_179070_ADDR, HWIO_REG_179070_RMSK) +#define HWIO_REG_179070_INM(m) \ + in_dword_masked(HWIO_REG_179070_ADDR, m) +#define HWIO_REG_179070_OUT(v) \ + out_dword(HWIO_REG_179070_ADDR, v) +#define HWIO_REG_179070_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_179070_ADDR, m, v, HWIO_REG_179070_IN); +#define HWIO_REG_179070_FRAME_HEIGHT_BMSK 0x1fff +#define HWIO_REG_179070_FRAME_HEIGHT_SHFT 0 + +#define HWIO_REG_63643_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000830) +#define HWIO_REG_63643_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000830) +#define HWIO_REG_63643_RMSK 0xff3f +#define HWIO_REG_63643_SHFT 0 +#define HWIO_REG_63643_IN in_dword_masked(\ + HWIO_REG_63643_ADDR, HWIO_REG_63643_RMSK) +#define HWIO_REG_63643_INM(m) \ + in_dword_masked(HWIO_REG_63643_ADDR, m) +#define HWIO_REG_63643_OUT(v) \ + out_dword(HWIO_REG_63643_ADDR, v) +#define HWIO_REG_63643_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_63643_ADDR, m, v, HWIO_REG_63643_IN); +#define HWIO_REG_63643_LEVEL_BMSK 0xff00 +#define HWIO_REG_63643_LEVEL_SHFT 0x8 +#define HWIO_REG_63643_PROFILE_BMSK 0x3f +#define HWIO_REG_63643_PROFILE_SHFT 0 + +#define HWIO_REG_786024_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000083c) +#define HWIO_REG_786024_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000083c) +#define HWIO_REG_786024_RMSK 0x1 +#define HWIO_REG_786024_SHFT 0 +#define HWIO_REG_786024_IN in_dword_masked(\ + HWIO_REG_786024_ADDR, HWIO_REG_786024_RMSK) +#define HWIO_REG_786024_INM(m) \ + in_dword_masked(HWIO_REG_786024_ADDR, m) +#define HWIO_REG_786024_OUT(v) \ + out_dword(HWIO_REG_786024_ADDR, v) +#define HWIO_REG_786024_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_786024_ADDR, m, v, HWIO_REG_786024_IN); +#define HWIO_REG_786024_FIELD_BMSK 0x1 +#define HWIO_REG_786024_FIELD_SHFT 0 + +#define HWIO_REG_152500_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000848) +#define HWIO_REG_152500_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000848) +#define HWIO_REG_152500_RMSK 0x3 +#define HWIO_REG_152500_SHFT 0 +#define HWIO_REG_152500_IN in_dword_masked(\ + HWIO_REG_152500_ADDR, HWIO_REG_152500_RMSK) +#define HWIO_REG_152500_INM(m) \ + in_dword_masked(HWIO_REG_152500_ADDR, m) +#define HWIO_REG_152500_OUT(v) \ + out_dword(HWIO_REG_152500_ADDR, v) +#define HWIO_REG_152500_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_152500_ADDR, m, v, HWIO_REG_152500_IN); +#define HWIO_REG_152500_LF_CONTROL_BMSK 0x3 +#define HWIO_REG_152500_LF_CONTROL_SHFT 0 + +#define HWIO_REG_266285_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000084c) +#define HWIO_REG_266285_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000084c) +#define HWIO_REG_266285_RMSK 0x1f +#define HWIO_REG_266285_SHFT 0 +#define HWIO_REG_266285_IN in_dword_masked(\ + HWIO_REG_266285_ADDR, HWIO_REG_266285_RMSK) +#define HWIO_REG_266285_INM(m) \ + in_dword_masked(HWIO_REG_266285_ADDR, m) +#define HWIO_REG_266285_OUT(v) \ + out_dword(HWIO_REG_266285_ADDR, v) +#define HWIO_REG_266285_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_266285_ADDR, m, v, HWIO_REG_266285_IN); +#define HWIO_REG_266285_LF_ALPHAS_OFF_BMSK 0x1f +#define HWIO_REG_266285_LF_ALPHAS_OFF_SHFT 0 + +#define HWIO_REG_964731_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000850) +#define HWIO_REG_964731_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000850) +#define HWIO_REG_964731_RMSK 0x1f +#define HWIO_REG_964731_SHFT 0 +#define HWIO_REG_964731_IN in_dword_masked(\ + HWIO_REG_964731_ADDR, HWIO_REG_964731_RMSK) +#define HWIO_REG_964731_INM(m) \ + in_dword_masked(HWIO_REG_964731_ADDR, m) +#define HWIO_REG_964731_OUT(v) \ + out_dword(HWIO_REG_964731_ADDR, v) +#define HWIO_REG_964731_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_964731_ADDR, m, v, HWIO_REG_964731_IN); +#define HWIO_REG_964731_LF_BETA_OFF_BMSK 0x1f +#define HWIO_REG_964731_LF_BETA_OFF_SHFT 0 + +#define HWIO_REG_919924_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000c30) +#define HWIO_REG_919924_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000c30) +#define HWIO_REG_919924_RMSK 0xffffffff +#define HWIO_REG_919924_SHFT 0 +#define HWIO_REG_919924_IN in_dword_masked(\ + HWIO_REG_919924_ADDR, HWIO_REG_919924_RMSK) +#define HWIO_REG_919924_INM(m) \ + in_dword_masked(HWIO_REG_919924_ADDR, m) +#define HWIO_REG_919924_OUT(v) \ + out_dword(HWIO_REG_919924_ADDR, v) +#define HWIO_REG_919924_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_919924_ADDR, m, v, HWIO_REG_919924_IN); +#define HWIO_REG_919924_VIDC_QP_OFFSET_BMSK 0xffffffff +#define HWIO_REG_919924_VIDC_QP_OFFSET_SHFT 0 + +#define HWIO_REG_143629_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00000c34) +#define HWIO_REG_143629_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00000c34) +#define HWIO_REG_143629_RMSK 0x1 +#define HWIO_REG_143629_SHFT 0 +#define HWIO_REG_143629_IN in_dword_masked(\ + HWIO_REG_143629_ADDR, HWIO_REG_143629_RMSK) +#define HWIO_REG_143629_INM(m) \ + in_dword_masked(HWIO_REG_143629_ADDR, m) +#define HWIO_REG_143629_OUT(v) \ + out_dword(HWIO_REG_143629_ADDR, v) +#define HWIO_REG_143629_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_143629_ADDR, m, v, HWIO_REG_143629_IN); +#define HWIO_REG_143629_REG_143629_BMSK 0x1 +#define HWIO_REG_143629_REG_143629_SHFT 0 + +#define HWIO_REG_607589_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002000) +#define HWIO_REG_607589_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002000) +#define HWIO_REG_607589_RMSK 0xffffffff +#define HWIO_REG_607589_SHFT 0 +#define HWIO_REG_607589_IN in_dword_masked(\ + HWIO_REG_607589_ADDR, HWIO_REG_607589_RMSK) +#define HWIO_REG_607589_INM(m) \ + in_dword_masked(HWIO_REG_607589_ADDR, m) +#define HWIO_REG_607589_OUT(v) \ + out_dword(HWIO_REG_607589_ADDR, v) +#define HWIO_REG_607589_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_607589_ADDR, m, v, HWIO_REG_607589_IN); +#define HWIO_REG_607589_RTN_CHID_BMSK 0xffffffff +#define HWIO_REG_607589_RTN_CHID_SHFT 0 + +#define HWIO_REG_845544_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002004) +#define HWIO_REG_845544_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002004) +#define HWIO_REG_845544_RMSK 0xffffffff +#define HWIO_REG_845544_SHFT 0 +#define HWIO_REG_845544_IN in_dword_masked(\ + HWIO_REG_845544_ADDR, HWIO_REG_845544_RMSK) +#define HWIO_REG_845544_INM(m) \ + in_dword_masked(HWIO_REG_845544_ADDR, m) +#define HWIO_REG_845544_OUT(v) \ + out_dword(HWIO_REG_845544_ADDR, v) +#define HWIO_REG_845544_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_845544_ADDR, m, v, HWIO_REG_845544_IN); +#define HWIO_REG_845544_REG_845544_BMSK 0xffffffff +#define HWIO_REG_845544_REG_845544_SHFT 0 + +#define HWIO_REG_859906_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002008) +#define HWIO_REG_859906_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002008) +#define HWIO_REG_859906_RMSK 0xffffffff +#define HWIO_REG_859906_SHFT 0 +#define HWIO_REG_859906_IN in_dword_masked(\ + HWIO_REG_859906_ADDR, HWIO_REG_859906_RMSK) +#define HWIO_REG_859906_INM(m) \ + in_dword_masked(HWIO_REG_859906_ADDR, m) +#define HWIO_REG_859906_OUT(v) \ + out_dword(HWIO_REG_859906_ADDR, v) +#define HWIO_REG_859906_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_859906_ADDR, m, v, HWIO_REG_859906_IN); +#define HWIO_REG_859906_REG_859906_BMSK 0xffffffff +#define HWIO_REG_859906_REG_859906_SHFT 0 + +#define HWIO_REG_490078_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000200c) +#define HWIO_REG_490078_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000200c) +#define HWIO_REG_490078_RMSK 0xffffffff +#define HWIO_REG_490078_SHFT 0 +#define HWIO_REG_490078_IN in_dword_masked(\ + HWIO_REG_490078_ADDR, HWIO_REG_490078_RMSK) +#define HWIO_REG_490078_INM(m) \ + in_dword_masked(HWIO_REG_490078_ADDR, m) +#define HWIO_REG_490078_OUT(v) \ + out_dword(HWIO_REG_490078_ADDR, v) +#define HWIO_REG_490078_OUTM(m, v) \ + out_dword_masked_ns(HWIO_REG_490078_ADDR, m, v,\ + HWIO_REG_490078_IN); +#define HWIO_REG_490078_REG_490078_BMSK 0xffffffff +#define HWIO_REG_490078_REG_490078_SHFT 0 + +#define HWIO_REG_640904_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002010) +#define HWIO_REG_640904_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002010) +#define HWIO_REG_640904_RMSK 0xffffffff +#define HWIO_REG_640904_SHFT 0 +#define HWIO_REG_640904_IN in_dword_masked(\ + HWIO_REG_640904_ADDR, HWIO_REG_640904_RMSK) +#define HWIO_REG_640904_INM(m) \ + in_dword_masked(HWIO_REG_640904_ADDR, m) +#define HWIO_REG_640904_OUT(v) \ + out_dword(HWIO_REG_640904_ADDR, v) +#define HWIO_REG_640904_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_640904_ADDR, m, v, HWIO_REG_640904_IN); +#define HWIO_REG_640904_REG_640904_BMSK 0xffffffff +#define HWIO_REG_640904_REG_640904_SHFT 0 + +#define HWIO_REG_60114_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002014) +#define HWIO_REG_60114_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002014) +#define HWIO_REG_60114_RMSK 0xffffffff +#define HWIO_REG_60114_SHFT 0 +#define HWIO_REG_60114_IN in_dword_masked(\ + HWIO_REG_60114_ADDR, HWIO_REG_60114_RMSK) +#define HWIO_REG_60114_INM(m) \ + in_dword_masked(HWIO_REG_60114_ADDR, m) +#define HWIO_REG_60114_OUT(v) \ + out_dword(HWIO_REG_60114_ADDR, v) +#define HWIO_REG_60114_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_60114_ADDR, m, v, HWIO_REG_60114_IN); +#define HWIO_REG_60114_REG_60114_BMSK 0xffffffff +#define HWIO_REG_60114_REG_60114_SHFT 0 + +#define HWIO_REG_489688_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002018) +#define HWIO_REG_489688_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002018) +#define HWIO_REG_489688_RMSK 0xffffffff +#define HWIO_REG_489688_SHFT 0 +#define HWIO_REG_489688_IN in_dword_masked(\ + HWIO_REG_489688_ADDR, HWIO_REG_489688_RMSK) +#define HWIO_REG_489688_INM(m) \ + in_dword_masked(HWIO_REG_489688_ADDR, m) +#define HWIO_REG_489688_OUT(v) \ + out_dword(HWIO_REG_489688_ADDR, v) +#define HWIO_REG_489688_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_489688_ADDR, m, v, HWIO_REG_489688_IN); +#define HWIO_REG_489688_REG_489688_BMSK 0xffffffff +#define HWIO_REG_489688_REG_489688_SHFT 0 + +#define HWIO_REG_853667_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000201c) +#define HWIO_REG_853667_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000201c) +#define HWIO_REG_853667_RMSK 0xffffffff +#define HWIO_REG_853667_SHFT 0 +#define HWIO_REG_853667_IN in_dword_masked(\ + HWIO_REG_853667_ADDR, HWIO_REG_853667_RMSK) +#define HWIO_REG_853667_INM(m) \ + in_dword_masked(HWIO_REG_853667_ADDR, m) +#define HWIO_REG_853667_OUT(v) \ + out_dword(HWIO_REG_853667_ADDR, v) +#define HWIO_REG_853667_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_853667_ADDR, m, v, HWIO_REG_853667_IN); +#define HWIO_REG_853667_REG_853667_BMSK 0xffffffff +#define HWIO_REG_853667_REG_853667_SHFT 0 + +#define HWIO_REG_760102_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002020) +#define HWIO_REG_760102_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002020) +#define HWIO_REG_760102_RMSK 0xffffffff +#define HWIO_REG_760102_SHFT 0 +#define HWIO_REG_760102_IN in_dword_masked(\ + HWIO_REG_760102_ADDR, HWIO_REG_760102_RMSK) +#define HWIO_REG_760102_INM(m) \ + in_dword_masked(HWIO_REG_760102_ADDR, m) +#define HWIO_REG_760102_OUT(v) \ + out_dword(HWIO_REG_760102_ADDR, v) +#define HWIO_REG_760102_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_760102_ADDR, m, v, HWIO_REG_760102_IN); +#define HWIO_REG_760102_REG_760102_BMSK 0xffffffff +#define HWIO_REG_760102_REG_760102_SHFT 0 + +#define HWIO_REG_378318_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002024) +#define HWIO_REG_378318_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002024) +#define HWIO_REG_378318_RMSK 0xffffffff +#define HWIO_REG_378318_SHFT 0 +#define HWIO_REG_378318_IN in_dword_masked(\ + HWIO_REG_378318_ADDR, HWIO_REG_378318_RMSK) +#define HWIO_REG_378318_INM(m) \ + in_dword_masked(HWIO_REG_378318_ADDR, m) +#define HWIO_REG_378318_OUT(v) \ + out_dword(HWIO_REG_378318_ADDR, v) +#define HWIO_REG_378318_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_378318_ADDR, m, v, HWIO_REG_378318_IN); +#define HWIO_REG_378318_REG_378318_BMSK 0xffffffff +#define HWIO_REG_378318_REG_378318_SHFT 0 + +#define HWIO_REG_203487_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002028) +#define HWIO_REG_203487_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002028) +#define HWIO_REG_203487_RMSK 0xffffffff +#define HWIO_REG_203487_SHFT 0 +#define HWIO_REG_203487_IN in_dword_masked(\ + HWIO_REG_203487_ADDR, HWIO_REG_203487_RMSK) +#define HWIO_REG_203487_INM(m) \ + in_dword_masked(HWIO_REG_203487_ADDR, m) +#define HWIO_REG_203487_OUT(v) \ + out_dword(HWIO_REG_203487_ADDR, v) +#define HWIO_REG_203487_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_203487_ADDR, m, v, HWIO_REG_203487_IN); +#define HWIO_REG_203487_REG_203487_BMSK 0xffffffff +#define HWIO_REG_203487_REG_203487_SHFT 0 + +#define HWIO_REG_692991_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000202c) +#define HWIO_REG_692991_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000202c) +#define HWIO_REG_692991_RMSK 0xffffffff +#define HWIO_REG_692991_SHFT 0 +#define HWIO_REG_692991_IN in_dword_masked(\ + HWIO_REG_692991_ADDR, HWIO_REG_692991_RMSK) +#define HWIO_REG_692991_INM(m) \ + in_dword_masked(HWIO_REG_692991_ADDR, m) +#define HWIO_REG_692991_OUT(v) \ + out_dword(HWIO_REG_692991_ADDR, v) +#define HWIO_REG_692991_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_692991_ADDR, m, v, HWIO_REG_692991_IN); +#define HWIO_REG_692991_REG_692991_BMSK 0xffffffff +#define HWIO_REG_692991_REG_692991_SHFT 0 + +#define HWIO_REG_161740_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002030) +#define HWIO_REG_161740_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002030) +#define HWIO_REG_161740_RMSK 0xffffffff +#define HWIO_REG_161740_SHFT 0 +#define HWIO_REG_161740_IN in_dword_masked(\ + HWIO_REG_161740_ADDR, HWIO_REG_161740_RMSK) +#define HWIO_REG_161740_INM(m) \ + in_dword_masked(HWIO_REG_161740_ADDR, m) +#define HWIO_REG_161740_OUT(v) \ + out_dword(HWIO_REG_161740_ADDR, v) +#define HWIO_REG_161740_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_161740_ADDR, m, v, HWIO_REG_161740_IN); +#define HWIO_REG_161740_REG_161740_BMSK 0xffffffff +#define HWIO_REG_161740_REG_161740_SHFT 0 + +#define HWIO_REG_930239_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002034) +#define HWIO_REG_930239_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002034) +#define HWIO_REG_930239_RMSK 0xffffffff +#define HWIO_REG_930239_SHFT 0 +#define HWIO_REG_930239_IN in_dword_masked(\ + HWIO_REG_930239_ADDR, HWIO_REG_930239_RMSK) +#define HWIO_REG_930239_INM(m) \ + in_dword_masked(HWIO_REG_930239_ADDR, m) +#define HWIO_REG_930239_OUT(v) \ + out_dword(HWIO_REG_930239_ADDR, v) +#define HWIO_REG_930239_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_930239_ADDR, m, v, HWIO_REG_930239_IN); +#define HWIO_REG_930239_REG_930239_BMSK 0xffffffff +#define HWIO_REG_930239_REG_930239_SHFT 0 + +#define HWIO_REG_567827_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002038) +#define HWIO_REG_567827_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002038) +#define HWIO_REG_567827_RMSK 0xffffffff +#define HWIO_REG_567827_SHFT 0 +#define HWIO_REG_567827_IN in_dword_masked(\ + HWIO_REG_567827_ADDR, HWIO_REG_567827_RMSK) +#define HWIO_REG_567827_INM(m) \ + in_dword_masked(HWIO_REG_567827_ADDR, m) +#define HWIO_REG_567827_OUT(v) \ + out_dword(HWIO_REG_567827_ADDR, v) +#define HWIO_REG_567827_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_567827_ADDR, m, v, HWIO_REG_567827_IN); +#define HWIO_REG_567827_REG_567827_BMSK 0xffffffff +#define HWIO_REG_567827_REG_567827_SHFT 0 + +#define HWIO_REG_542997_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000203c) +#define HWIO_REG_542997_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000203c) +#define HWIO_REG_542997_RMSK 0xffffffff +#define HWIO_REG_542997_SHFT 0 +#define HWIO_REG_542997_IN in_dword_masked(\ + HWIO_REG_542997_ADDR, HWIO_REG_542997_RMSK) +#define HWIO_REG_542997_INM(m) \ + in_dword_masked(HWIO_REG_542997_ADDR, m) +#define HWIO_REG_542997_OUT(v) \ + out_dword(HWIO_REG_542997_ADDR, v) +#define HWIO_REG_542997_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_542997_ADDR, m, v, HWIO_REG_542997_IN); +#define HWIO_REG_542997_REG_542997_BMSK 0xffffffff +#define HWIO_REG_542997_REG_542997_SHFT 0 + +#define HWIO_REG_666957_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002040) +#define HWIO_REG_666957_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002040) +#define HWIO_REG_666957_RMSK 0x7ffff +#define HWIO_REG_666957_SHFT 0 +#define HWIO_REG_666957_IN in_dword_masked(\ + HWIO_REG_666957_ADDR, HWIO_REG_666957_RMSK) +#define HWIO_REG_666957_INM(m) \ + in_dword_masked(HWIO_REG_666957_ADDR, m) +#define HWIO_REG_666957_OUT(v) \ + out_dword(HWIO_REG_666957_ADDR, v) +#define HWIO_REG_666957_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_666957_ADDR, m, v, HWIO_REG_666957_IN); +#define HWIO_REG_666957_CH_DEC_TYPE_BMSK 0x70000 +#define HWIO_REG_666957_CH_DEC_TYPE_SHFT 0x10 +#define HWIO_REG_666957_CH_INST_ID_BMSK 0xffff +#define HWIO_REG_666957_CH_INST_ID_SHFT 0 + +#define HWIO_REG_117192_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002044) +#define HWIO_REG_117192_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002044) +#define HWIO_REG_117192_RMSK 0xffffffff +#define HWIO_REG_117192_SHFT 0 +#define HWIO_REG_117192_IN in_dword_masked(\ + HWIO_REG_117192_ADDR, HWIO_REG_117192_RMSK) +#define HWIO_REG_117192_INM(m) \ + in_dword_masked(HWIO_REG_117192_ADDR, m) +#define HWIO_REG_117192_OUT(v) \ + out_dword(HWIO_REG_117192_ADDR, v) +#define HWIO_REG_117192_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_117192_ADDR, m, v, HWIO_REG_117192_IN); +#define HWIO_REG_117192_REG_117192_BMSK 0xffffffff +#define HWIO_REG_117192_REG_117192_SHFT 0 + +#define HWIO_REG_145068_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002048) +#define HWIO_REG_145068_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002048) +#define HWIO_REG_145068_RMSK 0xffffffff +#define HWIO_REG_145068_SHFT 0 +#define HWIO_REG_145068_IN in_dword_masked(\ + HWIO_REG_145068_ADDR, HWIO_REG_145068_RMSK) +#define HWIO_REG_145068_INM(m) \ + in_dword_masked(HWIO_REG_145068_ADDR, m) +#define HWIO_REG_145068_OUT(v) \ + out_dword(HWIO_REG_145068_ADDR, v) +#define HWIO_REG_145068_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_145068_ADDR, m, v, HWIO_REG_145068_IN); +#define HWIO_REG_145068_REG_145068_BMSK 0xffffffff +#define HWIO_REG_145068_REG_145068_SHFT 0 + +#define HWIO_REG_921356_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000204c) +#define HWIO_REG_921356_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000204c) +#define HWIO_REG_921356_RMSK 0xffffffff +#define HWIO_REG_921356_SHFT 0 +#define HWIO_REG_921356_IN in_dword_masked(\ + HWIO_REG_921356_ADDR, HWIO_REG_921356_RMSK) +#define HWIO_REG_921356_INM(m) \ + in_dword_masked(HWIO_REG_921356_ADDR, m) +#define HWIO_REG_921356_OUT(v) \ + out_dword(HWIO_REG_921356_ADDR, v) +#define HWIO_REG_921356_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_921356_ADDR, m, v, HWIO_REG_921356_IN); +#define HWIO_REG_921356_REG_921356_BMSK 0xffffffff +#define HWIO_REG_921356_REG_921356_SHFT 0 + +#define HWIO_REG_612810_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002050) +#define HWIO_REG_612810_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002050) +#define HWIO_REG_612810_RMSK 0xffffffff +#define HWIO_REG_612810_SHFT 0 +#define HWIO_REG_612810_IN in_dword_masked(\ + HWIO_REG_612810_ADDR, HWIO_REG_612810_RMSK) +#define HWIO_REG_612810_INM(m) \ + in_dword_masked(HWIO_REG_612810_ADDR, m) +#define HWIO_REG_612810_OUT(v) \ + out_dword(HWIO_REG_612810_ADDR, v) +#define HWIO_REG_612810_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_612810_ADDR, m, v, HWIO_REG_612810_IN); +#define HWIO_REG_612810_REG_612810_BMSK 0xffffffff +#define HWIO_REG_612810_REG_612810_SHFT 0 + +#define HWIO_REG_175608_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002054) +#define HWIO_REG_175608_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002054) +#define HWIO_REG_175608_RMSK 0xffffffff +#define HWIO_REG_175608_SHFT 0 +#define HWIO_REG_175608_IN in_dword_masked(\ + HWIO_REG_175608_ADDR, HWIO_REG_175608_RMSK) +#define HWIO_REG_175608_INM(m) \ + in_dword_masked(HWIO_REG_175608_ADDR, m) +#define HWIO_REG_175608_OUT(v) \ + out_dword(HWIO_REG_175608_ADDR, v) +#define HWIO_REG_175608_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_175608_ADDR, m, v, HWIO_REG_175608_IN); +#define HWIO_REG_175608_REG_175608_BMSK 0xffffffff +#define HWIO_REG_175608_REG_175608_SHFT 0 + +#define HWIO_REG_190381_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002058) +#define HWIO_REG_190381_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002058) +#define HWIO_REG_190381_RMSK 0xffffffff +#define HWIO_REG_190381_SHFT 0 +#define HWIO_REG_190381_IN in_dword_masked(\ + HWIO_REG_190381_ADDR, HWIO_REG_190381_RMSK) +#define HWIO_REG_190381_INM(m) \ + in_dword_masked(HWIO_REG_190381_ADDR, m) +#define HWIO_REG_190381_OUT(v) \ + out_dword(HWIO_REG_190381_ADDR, v) +#define HWIO_REG_190381_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_190381_ADDR, m, v, HWIO_REG_190381_IN); +#define HWIO_REG_190381_REG_190381_BMSK 0xffffffff +#define HWIO_REG_190381_REG_190381_SHFT 0 + +#define HWIO_REG_85655_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000205c) +#define HWIO_REG_85655_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000205c) +#define HWIO_REG_85655_RMSK 0xffffffff +#define HWIO_REG_85655_SHFT 0 +#define HWIO_REG_85655_IN in_dword_masked(\ + HWIO_REG_85655_ADDR, HWIO_REG_85655_RMSK) +#define HWIO_REG_85655_INM(m) \ + in_dword_masked(HWIO_REG_85655_ADDR, m) +#define HWIO_REG_85655_OUT(v) \ + out_dword(HWIO_REG_85655_ADDR, v) +#define HWIO_REG_85655_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_85655_ADDR, m, v, HWIO_REG_85655_IN); +#define HWIO_REG_85655_REG_85655_BMSK 0xffffffff +#define HWIO_REG_85655_REG_85655_SHFT 0 + +#define HWIO_REG_86830_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002060) +#define HWIO_REG_86830_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002060) +#define HWIO_REG_86830_RMSK 0xffffffff +#define HWIO_REG_86830_SHFT 0 +#define HWIO_REG_86830_IN in_dword_masked(\ + HWIO_REG_86830_ADDR, HWIO_REG_86830_RMSK) +#define HWIO_REG_86830_INM(m) \ + in_dword_masked(HWIO_REG_86830_ADDR, m) +#define HWIO_REG_86830_OUT(v) \ + out_dword(HWIO_REG_86830_ADDR, v) +#define HWIO_REG_86830_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_86830_ADDR, m, v, HWIO_REG_86830_IN); +#define HWIO_REG_86830_REG_86830_BMSK 0xffffffff +#define HWIO_REG_86830_REG_86830_SHFT 0 + +#define HWIO_REG_889944_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002064) +#define HWIO_REG_889944_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002064) +#define HWIO_REG_889944_RMSK 0xffffffff +#define HWIO_REG_889944_SHFT 0 +#define HWIO_REG_889944_IN in_dword_masked(\ + HWIO_REG_889944_ADDR, HWIO_REG_889944_RMSK) +#define HWIO_REG_889944_INM(m) \ + in_dword_masked(HWIO_REG_889944_ADDR, m) +#define HWIO_REG_889944_OUT(v) \ + out_dword(HWIO_REG_889944_ADDR, v) +#define HWIO_REG_889944_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_889944_ADDR, m, v, HWIO_REG_889944_IN); +#define HWIO_REG_889944_HOST_WR_ADDR_BMSK 0xffffffff +#define HWIO_REG_889944_HOST_WR_ADSR_SHFT 0 + +#define HWIO_REG_404623_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002068) +#define HWIO_REG_404623_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002068) +#define HWIO_REG_404623_RMSK 0xffffffff +#define HWIO_REG_404623_SHFT 0 +#define HWIO_REG_404623_IN in_dword_masked(\ + HWIO_REG_404623_ADDR, HWIO_REG_404623_RMSK) +#define HWIO_REG_404623_INM(m) \ + in_dword_masked(HWIO_REG_404623_ADDR, m) +#define HWIO_REG_404623_OUT(v) \ + out_dword(HWIO_REG_404623_ADDR, v) +#define HWIO_REG_404623_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_404623_ADDR, m, v, HWIO_REG_404623_IN); +#define HWIO_REG_404623_REG_404623_BMSK 0xffffffff +#define HWIO_REG_404623_REG_404623_SHFT 0 + +#define HWIO_REG_397087_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000206c) +#define HWIO_REG_397087_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000206c) +#define HWIO_REG_397087_RMSK 0xffffffff +#define HWIO_REG_397087_SHFT 0 +#define HWIO_REG_397087_IN in_dword_masked(\ + HWIO_REG_397087_ADDR, HWIO_REG_397087_RMSK) +#define HWIO_REG_397087_INM(m) \ + in_dword_masked(HWIO_REG_397087_ADDR, m) +#define HWIO_REG_397087_OUT(v) \ + out_dword(HWIO_REG_397087_ADDR, v) +#define HWIO_REG_397087_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_397087_ADDR, m, v, HWIO_REG_397087_IN); +#define HWIO_REG_397087_CMD_SEQ_NUM_BMSK 0xffffffff +#define HWIO_REG_397087_CMD_SEQ_NUM_SHFT 0 + +#define HWIO_REG_212613_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002070) +#define HWIO_REG_212613_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002070) +#define HWIO_REG_212613_RMSK 0xffffffff +#define HWIO_REG_212613_SHFT 0 +#define HWIO_REG_212613_IN in_dword_masked(\ + HWIO_REG_212613_ADDR, HWIO_REG_212613_RMSK) +#define HWIO_REG_212613_INM(m) \ + in_dword_masked(HWIO_REG_212613_ADDR, m) +#define HWIO_REG_212613_OUT(v) \ + out_dword(HWIO_REG_212613_ADDR, v) +#define HWIO_REG_212613_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_212613_ADDR, m, v, HWIO_REG_212613_IN); +#define HWIO_REG_212613_REG_212613_BMSK 0xffffffff +#define HWIO_REG_212613_REG_212613_SHFT 0 + +#define HWIO_REG_840123_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002074) +#define HWIO_REG_840123_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002074) +#define HWIO_REG_840123_RMSK 0xffffffff +#define HWIO_REG_840123_SHFT 0 +#define HWIO_REG_840123_IN in_dword_masked(\ + HWIO_REG_840123_ADDR, HWIO_REG_840123_RMSK) +#define HWIO_REG_840123_INM(m) \ + in_dword_masked(HWIO_REG_840123_ADDR, m) +#define HWIO_REG_840123_OUT(v) \ + out_dword(HWIO_REG_840123_ADDR, v) +#define HWIO_REG_840123_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_840123_ADDR, m, v, HWIO_REG_840123_IN); +#define HWIO_REG_840123_REG_840123_BMSK 0xffffffff +#define HWIO_REG_840123_REG_840123_SHFT 0 + +#define HWIO_REG_520335_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002078) +#define HWIO_REG_520335_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002078) +#define HWIO_REG_520335_RMSK 0xffffffff +#define HWIO_REG_520335_SHFT 0 +#define HWIO_REG_520335_IN in_dword_masked(\ + HWIO_REG_520335_ADDR, HWIO_REG_520335_RMSK) +#define HWIO_REG_520335_INM(m) \ + in_dword_masked(HWIO_REG_520335_ADDR, m) +#define HWIO_REG_520335_OUT(v) \ + out_dword(HWIO_REG_520335_ADDR, v) +#define HWIO_REG_520335_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_520335_ADDR, m, v, HWIO_REG_520335_IN); +#define HWIO_REG_520335_REG_196943_BMSK 0xffffffff +#define HWIO_REG_520335_REG_196943_SHFT 0 + +#define HWIO_REG_196943_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000207c) +#define HWIO_REG_196943_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000207c) +#define HWIO_REG_196943_RMSK 0xffffffff +#define HWIO_REG_196943_SHFT 0 +#define HWIO_REG_196943_IN in_dword_masked(\ + HWIO_REG_196943_ADDR, HWIO_REG_196943_RMSK) +#define HWIO_REG_196943_INM(m) \ + in_dword_masked(HWIO_REG_196943_ADDR, m) +#define HWIO_REG_196943_OUT(v) \ + out_dword(HWIO_REG_196943_ADDR, v) +#define HWIO_REG_196943_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_196943_ADDR, m, v, HWIO_REG_196943_IN); +#define HWIO_REG_196943_REG_196943_BMSK 0xffffffff +#define HWIO_REG_196943_REG_196943_SHFT 0 + +#define HWIO_REG_313350_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002080) +#define HWIO_REG_313350_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002080) +#define HWIO_REG_313350_RMSK 0x7ffff +#define HWIO_REG_313350_SHFT 0 +#define HWIO_REG_313350_IN in_dword_masked(\ + HWIO_REG_313350_ADDR, HWIO_REG_313350_RMSK) +#define HWIO_REG_313350_INM(m) \ + in_dword_masked(HWIO_REG_313350_ADDR, m) +#define HWIO_REG_313350_OUT(v) \ + out_dword(HWIO_REG_313350_ADDR, v) +#define HWIO_REG_313350_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_313350_ADDR, m, v, HWIO_REG_313350_IN); +#define HWIO_REG_313350_CH_DEC_TYPE_BMSK 0x70000 +#define HWIO_REG_313350_CH_DEC_TYPE_SHFT 0x10 +#define HWIO_REG_313350_CH_INST_ID_BMSK 0xffff +#define HWIO_REG_313350_CH_INST_ID_SHFT 0 + +#define HWIO_REG_980194_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002084) +#define HWIO_REG_980194_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002084) +#define HWIO_REG_980194_RMSK 0xffffffff +#define HWIO_REG_980194_SHFT 0 +#define HWIO_REG_980194_IN in_dword_masked(\ + HWIO_REG_980194_ADDR, HWIO_REG_980194_RMSK) +#define HWIO_REG_980194_INM(m) \ + in_dword_masked(HWIO_REG_980194_ADDR, m) +#define HWIO_REG_980194_OUT(v) \ + out_dword(HWIO_REG_980194_ADDR, v) +#define HWIO_REG_980194_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_980194_ADDR, m, v, HWIO_REG_980194_IN); +#define HWIO_REG_980194_REG_980194_BMSK 0xffffffff +#define HWIO_REG_980194_REG_980194_SHFT 0 + +#define HWIO_REG_936704_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002088) +#define HWIO_REG_936704_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002088) +#define HWIO_REG_936704_RMSK 0xffffffff +#define HWIO_REG_936704_SHFT 0 +#define HWIO_REG_936704_IN in_dword_masked(\ + HWIO_REG_936704_ADDR, HWIO_REG_936704_RMSK) +#define HWIO_REG_936704_INM(m) \ + in_dword_masked(HWIO_REG_936704_ADDR, m) +#define HWIO_REG_936704_OUT(v) \ + out_dword(HWIO_REG_936704_ADDR, v) +#define HWIO_REG_936704_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_936704_ADDR, m, v, HWIO_REG_936704_IN); +#define HWIO_REG_936704_REG_936704_BMSK 0xffffffff +#define HWIO_REG_936704_REG_936704_SHFT 0 + +#define HWIO_REG_821977_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000208c) +#define HWIO_REG_821977_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000208c) +#define HWIO_REG_821977_RMSK 0xffffffff +#define HWIO_REG_821977_SHFT 0 +#define HWIO_REG_821977_IN in_dword_masked(\ + HWIO_REG_821977_ADDR, HWIO_REG_821977_RMSK) +#define HWIO_REG_821977_INM(m) \ + in_dword_masked(HWIO_REG_821977_ADDR, m) +#define HWIO_REG_821977_OUT(v) \ + out_dword(HWIO_REG_821977_ADDR, v) +#define HWIO_REG_821977_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_821977_ADDR, m, v, HWIO_REG_821977_IN); +#define HWIO_REG_821977_REG_821977_BMSK 0xffffffff +#define HWIO_REG_821977_REG_821977_SHFT 0 + +#define HWIO_REG_655721_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002090) +#define HWIO_REG_655721_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002090) +#define HWIO_REG_655721_RMSK 0xffffffff +#define HWIO_REG_655721_SHFT 0 +#define HWIO_REG_655721_IN in_dword_masked(\ + HWIO_REG_655721_ADDR, HWIO_REG_655721_RMSK) +#define HWIO_REG_655721_INM(m) \ + in_dword_masked(HWIO_REG_655721_ADDR, m) +#define HWIO_REG_655721_OUT(v) \ + out_dword(HWIO_REG_655721_ADDR, v) +#define HWIO_REG_655721_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_655721_ADDR, m, v, HWIO_REG_655721_IN); +#define HWIO_REG_655721_REG_655721_BMSK 0xffffffff +#define HWIO_REG_655721_REG_655721_SHFT 0 + +#define HWIO_REG_548308_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002094) +#define HWIO_REG_548308_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002094) +#define HWIO_REG_548308_RMSK 0xffffffff +#define HWIO_REG_548308_SHFT 0 +#define HWIO_REG_548308_IN in_dword_masked(\ + HWIO_REG_548308_ADDR, HWIO_REG_548308_RMSK) +#define HWIO_REG_548308_INM(m) \ + in_dword_masked(HWIO_REG_548308_ADDR, m) +#define HWIO_REG_548308_OUT(v) \ + out_dword(HWIO_REG_548308_ADDR, v) +#define HWIO_REG_548308_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_548308_ADDR, m, v, HWIO_REG_548308_IN); +#define HWIO_REG_548308_REG_548308_BMSK 0xffffffff +#define HWIO_REG_548308_REG_548308_SHFT 0 + +#define HWIO_REG_887095_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x00002098) +#define HWIO_REG_887095_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x00002098) +#define HWIO_REG_887095_RMSK 0xffffffff +#define HWIO_REG_887095_SHFT 0 +#define HWIO_REG_887095_IN in_dword_masked(\ + HWIO_REG_887095_ADDR, HWIO_REG_887095_RMSK) +#define HWIO_REG_887095_INM(m) \ + in_dword_masked(HWIO_REG_887095_ADDR, m) +#define HWIO_REG_887095_OUT(v) \ + out_dword(HWIO_REG_887095_ADDR, v) +#define HWIO_REG_887095_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_887095_ADDR, m, v, HWIO_REG_887095_IN); +#define HWIO_REG_887095_REG_887095_BMSK 0xffffffff +#define HWIO_REG_887095_REG_887095_SHFT 0 + +#define HWIO_REG_576987_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000209c) +#define HWIO_REG_576987_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000209c) +#define HWIO_REG_576987_RMSK 0xffffffff +#define HWIO_REG_576987_SHFT 0 +#define HWIO_REG_576987_IN in_dword_masked(\ + HWIO_REG_576987_ADDR, HWIO_REG_576987_RMSK) +#define HWIO_REG_576987_INM(m) \ + in_dword_masked(HWIO_REG_576987_ADDR, m) +#define HWIO_REG_576987_OUT(v) \ + out_dword(HWIO_REG_576987_ADDR, v) +#define HWIO_REG_576987_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_576987_ADDR, m, v, HWIO_REG_576987_IN); +#define HWIO_REG_576987_REG_576987_BMSK 0xffffffff +#define HWIO_REG_576987_REG_576987_SHFT 0 + +#define HWIO_REG_70448_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x000020a0) +#define HWIO_REG_70448_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000020a0) +#define HWIO_REG_70448_RMSK 0xffffffff +#define HWIO_REG_70448_SHFT 0 +#define HWIO_REG_70448_IN in_dword_masked(\ + HWIO_REG_70448_ADDR, HWIO_REG_70448_RMSK) +#define HWIO_REG_70448_INM(m) \ + in_dword_masked(HWIO_REG_70448_ADDR, m) +#define HWIO_REG_70448_OUT(v) \ + out_dword(HWIO_REG_70448_ADDR, v) +#define HWIO_REG_70448_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_70448_ADDR, m, v, HWIO_REG_70448_IN); +#define HWIO_REG_70448_REG_70448_BMSK 0xffffffff +#define HWIO_REG_70448_REG_70448_SHFT 0 + +#define HWIO_REG_652528_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x000020a4) +#define HWIO_REG_652528_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000020a4) +#define HWIO_REG_652528_RMSK 0xffffffff +#define HWIO_REG_652528_SHFT 0 +#define HWIO_REG_652528_IN in_dword_masked(\ + HWIO_REG_652528_ADDR, HWIO_REG_652528_RMSK) +#define HWIO_REG_652528_INM(m) \ + in_dword_masked(HWIO_REG_652528_ADDR, m) +#define HWIO_REG_652528_OUT(v) \ + out_dword(HWIO_REG_652528_ADDR, v) +#define HWIO_REG_652528_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_652528_ADDR, m, v , HWIO_REG_652528_IN); +#define HWIO_REG_652528_REG_652528_BMSK 0xffffffff +#define HWIO_REG_652528_REG_652528_SHFT 0 + +#define HWIO_REG_220637_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x000020a8) +#define HWIO_REG_220637_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000020a8) +#define HWIO_REG_220637_RMSK 0xffffffff +#define HWIO_REG_220637_SHFT 0 +#define HWIO_REG_220637_IN in_dword_masked(\ + HWIO_REG_220637_ADDR, HWIO_REG_220637_RMSK) +#define HWIO_REG_220637_INM(m) \ + in_dword_masked(HWIO_REG_220637_ADDR, m) +#define HWIO_REG_220637_OUT(v) \ + out_dword(HWIO_REG_220637_ADDR, v) +#define HWIO_REG_220637_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_220637_ADDR, m, v, HWIO_REG_220637_IN); +#define HWIO_REG_220637_REG_220637_BMSK 0xffffffff +#define HWIO_REG_220637_REG_220637_SHFT 0 + +#define HWIO_REG_254093_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x000020ac) +#define HWIO_REG_254093_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000020ac) +#define HWIO_REG_254093_RMSK 0xffffffff +#define HWIO_REG_254093_SHFT 0 +#define HWIO_REG_254093_IN in_dword_masked(\ + HWIO_REG_254093_ADDR, HWIO_REG_254093_RMSK) +#define HWIO_REG_254093_INM(m) \ + in_dword_masked(HWIO_REG_254093_ADDR, m) +#define HWIO_REG_254093_OUT(v) \ + out_dword(HWIO_REG_254093_ADDR, v) +#define HWIO_REG_254093_OUTM(m, v) out_dword_masked_ns\ + (HWIO_REG_254093_ADDR, m, v, HWIO_REG_254093_IN); +#define HWIO_REG_254093_REG_254093_BMSK 0xffffffff +#define HWIO_REG_254093_REG_254093_SHFT 0 + +#define HWIO_REG_160474_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x000020b0) +#define HWIO_REG_160474_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000020b0) +#define HWIO_REG_160474_RMSK 0xffffffff +#define HWIO_REG_160474_SHFT 0 +#define HWIO_REG_160474_IN in_dword_masked(\ + HWIO_REG_160474_ADDR, HWIO_REG_160474_RMSK) +#define HWIO_REG_160474_INM(m) \ + in_dword_masked(HWIO_REG_160474_ADDR, m) +#define HWIO_REG_160474_OUT(v) \ + out_dword(HWIO_REG_160474_ADDR, v) +#define HWIO_REG_160474_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_160474_ADDR, m, v, HWIO_REG_160474_IN); +#define HWIO_REG_160474_REG_160474_BMSK 0xffffffff +#define HWIO_REG_160474_REG_160474_SHFT 0 + +#define HWIO_REG_39027_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x000020b4) +#define HWIO_REG_39027_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000020b4) +#define HWIO_REG_39027_RMSK 0xffffffff +#define HWIO_REG_39027_SHFT 0 +#define HWIO_REG_39027_IN in_dword_masked(\ + HWIO_REG_39027_ADDR, HWIO_REG_39027_RMSK) +#define HWIO_REG_39027_INM(m) \ + in_dword_masked(HWIO_REG_39027_ADDR, m) +#define HWIO_REG_39027_OUT(v) \ + out_dword(HWIO_REG_39027_ADDR, v) +#define HWIO_REG_39027_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_39027_ADDR, m, v, HWIO_REG_39027_IN); +#define HWIO_REG_39027_REG_39027_BMSK 0xffffffff +#define HWIO_REG_39027_REG_39027_SHFT 0 + +#define HWIO_REG_74049_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x000020b8) +#define HWIO_REG_74049_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000020b8) +#define HWIO_REG_74049_RMSK 0xffffffff +#define HWIO_REG_74049_SHFT 0 +#define HWIO_REG_74049_IN in_dword_masked(\ + HWIO_REG_74049_ADDR, HWIO_REG_74049_RMSK) +#define HWIO_REG_74049_INM(m) \ + in_dword_masked(HWIO_REG_74049_ADDR, m) +#define HWIO_REG_74049_OUT(v) \ + out_dword(HWIO_REG_74049_ADDR, v) +#define HWIO_REG_74049_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_74049_ADDR, m, v, HWIO_REG_74049_IN); +#define HWIO_REG_74049_REG_74049_BMSK 0xffffffff +#define HWIO_REG_74049_REG_74049_SHFT 0 + +#define HWIO_REG_697870_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x000020bc) +#define HWIO_REG_697870_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x000020bc) +#define HWIO_REG_697870_RMSK 0xffffffff +#define HWIO_REG_697870_SHFT 0 +#define HWIO_REG_697870_IN in_dword_masked(\ + HWIO_REG_697870_ADDR, HWIO_REG_697870_RMSK) +#define HWIO_REG_697870_INM(m) \ + in_dword_masked(HWIO_REG_697870_ADDR, m) +#define HWIO_REG_697870_OUT(v) \ + out_dword(HWIO_REG_697870_ADDR, v) +#define HWIO_REG_697870_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_697870_ADDR, m, v, HWIO_REG_697870_IN); +#define HWIO_REG_697870_REG_697870_BMSK 0xffffffff +#define HWIO_REG_697870_REG_697870_SHFT 0 + +#define HWIO_REG_783891_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c504) +#define HWIO_REG_783891_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c504) +#define HWIO_REG_783891_RMSK 0x7ffff +#define HWIO_REG_783891_SHFT 0 +#define HWIO_REG_783891_IN in_dword_masked(\ + HWIO_REG_783891_ADDR, HWIO_REG_783891_RMSK) +#define HWIO_REG_783891_INM(m) \ + in_dword_masked(HWIO_REG_783891_ADDR, m) +#define HWIO_REG_783891_OUT(v) \ + out_dword(HWIO_REG_783891_ADDR, v) +#define HWIO_REG_783891_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_783891_ADDR, m, v, HWIO_REG_783891_IN); +#define HWIO_REG_783891_ENC_PIC_TYPE_USE_BMSK 0x40000 +#define HWIO_REG_783891_ENC_PIC_TYPE_USE_SHFT 0x12 +#define HWIO_REG_783891_B_FRM_CTRL_BMSK 0x30000 +#define HWIO_REG_783891_B_FRM_CTRL_SHFT 0x10 +#define HWIO_REG_783891_I_FRM_CTRL_BMSK 0xffff +#define HWIO_REG_783891_I_FRM_CTRL_SHFT 0 + +#define HWIO_REG_226332_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c50c) +#define HWIO_REG_226332_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c50c) +#define HWIO_REG_226332_RMSK 0x7 +#define HWIO_REG_226332_SHFT 0 +#define HWIO_REG_226332_IN in_dword_masked(\ + HWIO_REG_226332_ADDR, HWIO_REG_226332_RMSK) +#define HWIO_REG_226332_INM(m) in_dword_masked(HWIO_REG_226332_ADDR, m) +#define HWIO_REG_226332_OUT(v) out_dword(HWIO_REG_226332_ADDR, v) +#define HWIO_REG_226332_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_226332_ADDR, m, v, HWIO_REG_226332_IN); +#define HWIO_REG_226332_MSLICE_MODE_BMSK 0x6 +#define HWIO_REG_226332_MSLICE_MODE_SHFT 0x1 +#define HWIO_REG_226332_MSLICE_ENA_BMSK 0x1 +#define HWIO_REG_226332_MSLICE_ENA_SHFT 0 + +#define HWIO_REG_696136_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c510) +#define HWIO_REG_696136_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c510) +#define HWIO_REG_696136_RMSK 0xffff +#define HWIO_REG_696136_SHFT 0 +#define HWIO_REG_696136_IN in_dword_masked(\ + HWIO_REG_696136_ADDR, HWIO_REG_696136_RMSK) +#define HWIO_REG_696136_INM(m) in_dword_masked(HWIO_REG_696136_ADDR, m) +#define HWIO_REG_696136_OUT(v) out_dword(HWIO_REG_696136_ADDR, v) +#define HWIO_REG_696136_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_696136_ADDR, m, v, HWIO_REG_696136_IN); +#define HWIO_REG_696136_MSLICE_MB_BMSK 0xffff +#define HWIO_REG_696136_MSLICE_MB_SHFT 0 + +#define HWIO_REG_515564_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c514) +#define HWIO_REG_515564_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c514) +#define HWIO_REG_515564_RMSK 0xffffffff +#define HWIO_REG_515564_SHFT 0 +#define HWIO_REG_515564_IN in_dword_masked(\ + HWIO_REG_515564_ADDR, HWIO_REG_515564_RMSK) +#define HWIO_REG_515564_INM(m) \ + in_dword_masked(HWIO_REG_515564_ADDR, m) +#define HWIO_REG_515564_OUT(v) out_dword(HWIO_REG_515564_ADDR, v) +#define HWIO_REG_515564_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_515564_ADDR, m, v, HWIO_REG_515564_IN); +#define HWIO_REG_515564_MSLICE_BIT_BMSK 0xffffffff +#define HWIO_REG_515564_MSLICE_BIT_SHFT 0 + +#define HWIO_REG_886210_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c518) +#define HWIO_REG_886210_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c518) +#define HWIO_REG_886210_RMSK 0xffff +#define HWIO_REG_886210_SHFT 0 +#define HWIO_REG_886210_IN in_dword_masked(\ + HWIO_REG_886210_ADDR, HWIO_REG_886210_RMSK) +#define HWIO_REG_886210_INM(m) in_dword_masked(HWIO_REG_886210_ADDR, m) +#define HWIO_REG_886210_OUT(v) out_dword(HWIO_REG_886210_ADDR, v) +#define HWIO_REG_886210_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_886210_ADDR, m, v, HWIO_REG_886210_IN); +#define HWIO_REG_886210_CIR_NUM_BMSK 0xffff +#define HWIO_REG_886210_CIR_NUM_SHFT 0 + +#define HWIO_REG_645603_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c51c) +#define HWIO_REG_645603_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c51c) +#define HWIO_REG_645603_RMSK 0x3 +#define HWIO_REG_645603_SHFT 0 +#define HWIO_REG_645603_IN in_dword_masked(\ + HWIO_REG_645603_ADDR, HWIO_REG_645603_RMSK) +#define HWIO_REG_645603_INM(m) \ + in_dword_masked(HWIO_REG_645603_ADDR, m) +#define HWIO_REG_645603_OUT(v) out_dword(HWIO_REG_645603_ADDR, v) +#define HWIO_REG_645603_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_645603_ADDR, m, v, HWIO_REG_645603_IN); +#define HWIO_REG_645603_REG_645603_BMSK 0x3 +#define HWIO_REG_645603_REG_645603_SHFT 0 + +#define HWIO_REG_811733_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c520) +#define HWIO_REG_811733_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c520) +#define HWIO_REG_811733_RMSK 0x80ffffff +#define HWIO_REG_811733_SHFT 0 +#define HWIO_REG_811733_IN in_dword_masked(\ + HWIO_REG_811733_ADDR, HWIO_REG_811733_RMSK) +#define HWIO_REG_811733_INM(m) \ + in_dword_masked(HWIO_REG_811733_ADDR, m) +#define HWIO_REG_811733_OUT(v) out_dword(HWIO_REG_811733_ADDR, v) +#define HWIO_REG_811733_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_811733_ADDR, m, v, HWIO_REG_811733_IN); +#define HWIO_REG_811733_PAD_CTRL_ON_BMSK 0x80000000 +#define HWIO_REG_811733_PAD_CTRL_ON_SHFT 0x1f +#define HWIO_REG_811733_CR_PAD_VIDC_BMSK 0xff0000 +#define HWIO_REG_811733_CR_PAD_VIDC_SHFT 0x10 +#define HWIO_REG_811733_CB_PAD_VIDC_BMSK 0xff00 +#define HWIO_REG_811733_CB_PAD_VIDC_SHFT 0x8 +#define HWIO_REG_811733_LUMA_PAD_VIDC_BMSK 0xff +#define HWIO_REG_811733_LUMA_PAD_VIDC_SHFT 0 + +#define HWIO_REG_676866_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c588) +#define HWIO_REG_676866_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c588) +#define HWIO_REG_676866_RMSK 0xffff +#define HWIO_REG_676866_SHFT 0 +#define HWIO_REG_676866_IN in_dword_masked(\ + HWIO_REG_676866_ADDR, HWIO_REG_676866_RMSK) +#define HWIO_REG_676866_INM(m) \ + in_dword_masked(HWIO_REG_676866_ADDR, m) +#define HWIO_REG_676866_OUT(v) \ + out_dword(HWIO_REG_676866_ADDR, v) +#define HWIO_REG_676866_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_676866_ADDR, m, v, HWIO_REG_676866_IN); +#define HWIO_REG_676866_REG_676866_BMSK 0xffff +#define HWIO_REG_676866_REG_676866_SHFT 0 + +#define HWIO_REG_54267_ADDR \ + (VIDC_BLACKBIRD_REG_BASE + 0x0000c58c) +#define HWIO_REG_54267_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c58c) +#define HWIO_REG_54267_RMSK 0xffff +#define HWIO_REG_54267_SHFT 0 +#define HWIO_REG_54267_IN in_dword_masked(\ + HWIO_REG_54267_ADDR,\ + HWIO_REG_54267_RMSK) +#define HWIO_REG_54267_INM(m) \ + in_dword_masked(HWIO_REG_54267_ADDR, m) +#define HWIO_REG_54267_OUT(v) \ + out_dword(HWIO_REG_54267_ADDR, v) +#define HWIO_REG_54267_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_54267_ADDR, m, v,\ + HWIO_REG_54267_IN); +#define HWIO_REG_54267_REG_54267_BMSK 0xffff +#define HWIO_REG_54267_REG_54267_SHFT 0 + +#define HWIO_REG_559908_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c5a0) +#define HWIO_REG_559908_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c5a0) +#define HWIO_REG_559908_RMSK 0x33f +#define HWIO_REG_559908_SHFT 0 +#define HWIO_REG_559908_IN in_dword_masked(\ + HWIO_REG_559908_ADDR, HWIO_REG_559908_RMSK) +#define HWIO_REG_559908_INM(m) in_dword_masked(HWIO_REG_559908_ADDR, m) +#define HWIO_REG_559908_OUT(v) out_dword(HWIO_REG_559908_ADDR, v) +#define HWIO_REG_559908_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_559908_ADDR, m, v, HWIO_REG_559908_IN); +#define HWIO_REG_559908_FR_RC_EN_BMSK 0x200 +#define HWIO_REG_559908_FR_RC_EN_SHFT 0x9 +#define HWIO_REG_559908_MB_RC_EN_BMSK 0x100 +#define HWIO_REG_559908_MB_RC_EN_SHFT 0x8 +#define HWIO_REG_559908_FRAME_QP_BMSK 0x3f +#define HWIO_REG_559908_FRAME_QP_SHFT 0 + +#define HWIO_REG_977937_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000d0d0) +#define HWIO_REG_977937_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000d0d0) +#define HWIO_REG_977937_RMSK 0xff +#define HWIO_REG_977937_SHFT 0 +#define HWIO_REG_977937_IN in_dword_masked(\ + HWIO_REG_977937_ADDR, HWIO_REG_977937_RMSK) +#define HWIO_REG_977937_INM(m) in_dword_masked(HWIO_REG_977937_ADDR, m) +#define HWIO_REG_977937_OUT(v) out_dword(HWIO_REG_977937_ADDR, v) +#define HWIO_REG_977937_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_977937_ADDR, m, v, HWIO_REG_977937_IN); +#define HWIO_REG_977937_FRAME_RATE_BMSK 0xff +#define HWIO_REG_977937_FRAME_RATE_SHFT 0 + +#define HWIO_REG_166135_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c5a8) +#define HWIO_REG_166135_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c5a8) +#define HWIO_REG_166135_RMSK 0xffffffff +#define HWIO_REG_166135_SHFT 0 +#define HWIO_REG_166135_IN in_dword_masked(\ + HWIO_REG_166135_ADDR, HWIO_REG_166135_RMSK) +#define HWIO_REG_166135_INM(m) in_dword_masked(HWIO_REG_166135_ADDR, m) +#define HWIO_REG_166135_OUT(v) out_dword(HWIO_REG_166135_ADDR, v) +#define HWIO_REG_166135_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_166135_ADDR, m, v, HWIO_REG_166135_IN); +#define HWIO_REG_166135_BIT_RATE_BMSK 0xffffffff +#define HWIO_REG_166135_BIT_RATE_SHFT 0 + +#define HWIO_REG_109072_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c5ac) +#define HWIO_REG_109072_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c5ac) +#define HWIO_REG_109072_RMSK 0x3fff +#define HWIO_REG_109072_SHFT 0 +#define HWIO_REG_109072_IN in_dword_masked(\ + HWIO_REG_109072_ADDR, HWIO_REG_109072_RMSK) +#define HWIO_REG_109072_INM(m) in_dword_masked(HWIO_REG_109072_ADDR, m) +#define HWIO_REG_109072_OUT(v) out_dword(HWIO_REG_109072_ADDR, v) +#define HWIO_REG_109072_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_109072_ADDR, m, v, HWIO_REG_109072_IN); +#define HWIO_REG_109072_MAX_QP_BMSK 0x3f00 +#define HWIO_REG_109072_MAX_QP_SHFT 0x8 +#define HWIO_REG_109072_MIN_QP_BMSK 0x3f +#define HWIO_REG_109072_MIN_QP_SHFT 0 + +#define HWIO_REG_550322_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c5b0) +#define HWIO_REG_550322_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c5b0) +#define HWIO_REG_550322_RMSK 0xffff +#define HWIO_REG_550322_SHFT 0 +#define HWIO_REG_550322_IN in_dword_masked(\ + HWIO_REG_550322_ADDR, HWIO_REG_550322_RMSK) +#define HWIO_REG_550322_INM(m) in_dword_masked(HWIO_REG_550322_ADDR, m) +#define HWIO_REG_550322_OUT(v) out_dword(HWIO_REG_550322_ADDR, v) +#define HWIO_REG_550322_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_550322_ADDR, m, v, HWIO_REG_550322_IN); +#define HWIO_REG_550322_REACT_PARA_BMSK 0xffff +#define HWIO_REG_550322_REACT_PARA_SHFT 0 + +#define HWIO_REG_949086_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000c5b4) +#define HWIO_REG_949086_PHYS (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000c5b4) +#define HWIO_REG_949086_RMSK 0xf +#define HWIO_REG_949086_SHFT 0 +#define HWIO_REG_949086_IN in_dword_masked(\ + HWIO_REG_949086_ADDR, HWIO_REG_949086_RMSK) +#define HWIO_REG_949086_INM(m) in_dword_masked(HWIO_REG_949086_ADDR, m) +#define HWIO_REG_949086_OUT(v) out_dword(HWIO_REG_949086_ADDR, v) +#define HWIO_REG_949086_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_949086_ADDR, m, v, HWIO_REG_949086_IN); +#define HWIO_REG_949086_DARK_DISABLE_BMSK 0x8 +#define HWIO_REG_949086_DARK_DISABLE_SHFT 0x3 +#define HWIO_REG_949086_SMOOTH_DISABLE_BMSK 0x4 +#define HWIO_REG_949086_SMOOTH_DISABLE_SHFT 0x2 +#define HWIO_REG_949086_STATIC_DISABLE_BMSK 0x2 +#define HWIO_REG_949086_STATIC_DISABLE_SHFT 0x1 +#define HWIO_REG_949086_ACT_DISABLE_BMSK 0x1 +#define HWIO_REG_949086_ACT_DISABLE_SHFT 0 + +#define HWIO_REG_447796_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000d004) +#define HWIO_REG_447796_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000d004) +#define HWIO_REG_447796_RMSK 0x1 +#define HWIO_REG_447796_SHFT 0 +#define HWIO_REG_447796_IN in_dword_masked(\ + HWIO_REG_447796_ADDR, HWIO_REG_447796_RMSK) +#define HWIO_REG_447796_INM(m) \ + in_dword_masked(HWIO_REG_447796_ADDR, m) +#define HWIO_REG_447796_OUT(v) \ + out_dword(HWIO_REG_447796_ADDR, v) +#define HWIO_REG_447796_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_447796_ADDR, m, v, HWIO_REG_447796_IN); +#define HWIO_REG_447796_REG_447796_BMSK 0x1 +#define HWIO_REG_447796_REG_447796_SHFT 0 + +#define HWIO_REG_744348_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000d010) +#define HWIO_REG_744348_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000d010) +#define HWIO_REG_744348_RMSK 0x7f +#define HWIO_REG_744348_SHFT 0 +#define HWIO_REG_744348_IN in_dword_masked(\ + HWIO_REG_744348_ADDR, HWIO_REG_744348_RMSK) +#define HWIO_REG_744348_INM(m) \ + in_dword_masked(HWIO_REG_744348_ADDR, m) +#define HWIO_REG_744348_OUT(v) \ + out_dword(HWIO_REG_744348_ADDR, v) +#define HWIO_REG_744348_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_744348_ADDR, m, v, HWIO_REG_744348_IN); +#define HWIO_REG_744348_P_BMSK 0x60 +#define HWIO_REG_744348_P_SHFT 0x5 +#define HWIO_REG_744348_BMSK 0x1f +#define HWIO_REG_744348_SHFT 0 + +#define HWIO_REG_672163_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000d034) +#define HWIO_REG_672163_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000d034) +#define HWIO_REG_672163_RMSK 0x1 +#define HWIO_REG_672163_SHFT 0 +#define HWIO_REG_672163_IN in_dword_masked(\ + HWIO_REG_672163_ADDR, HWIO_REG_672163_RMSK) +#define HWIO_REG_672163_INM(m) \ + in_dword_masked(HWIO_REG_672163_ADDR, m) +#define HWIO_REG_672163_OUT(v) \ + out_dword(HWIO_REG_672163_ADDR, v) +#define HWIO_REG_672163_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_672163_ADDR, m, v,\ + HWIO_REG_672163_IN); +#define HWIO_REG_672163_ENC_TRANS_8X8_FLAG_BMSK 0x1 +#define HWIO_REG_672163_ENC_TRANS_8X8_FLAG_SHFT 0 + +#define HWIO_REG_780908_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000d140) +#define HWIO_REG_780908_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000d140) +#define HWIO_REG_780908_RMSK 0x1 +#define HWIO_REG_780908_SHFT 0 +#define HWIO_REG_780908_IN in_dword_masked(\ + HWIO_REG_780908_ADDR, HWIO_REG_780908_RMSK) +#define HWIO_REG_780908_INM(m) in_dword_masked(\ + HWIO_REG_780908_ADDR, m) +#define HWIO_REG_780908_OUT(v) out_dword(\ + HWIO_REG_780908_ADDR, v) +#define HWIO_REG_780908_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_780908_ADDR, m, v,\ + HWIO_REG_780908_IN) +#define HWIO_REG_780908_REG_780908_BMSK 0x1 +#define HWIO_REG_780908_REG_780908_SHFT 0 + +#define HWIO_REG_330132_ADDR (VIDC_BLACKBIRD_REG_BASE + 0x0000e008) +#define HWIO_REG_330132_PHYS \ + (VIDC_BLACKBIRD_REG_BASE_PHYS + 0x0000e008) +#define HWIO_REG_330132_RMSK 0x1 +#define HWIO_REG_330132_SHFT 0 +#define HWIO_REG_330132_IN in_dword_masked(\ + HWIO_REG_330132_ADDR, HWIO_REG_330132_RMSK) +#define HWIO_REG_330132_INM(m) \ + in_dword_masked(HWIO_REG_330132_ADDR, m) +#define HWIO_REG_330132_OUT(v) \ + out_dword(HWIO_REG_330132_ADDR, v) +#define HWIO_REG_330132_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_330132_ADDR, m, v, HWIO_REG_330132_IN); +#define HWIO_REG_330132_MPEG4_QUART_PXL_BMSK 0x1 +#define HWIO_REG_330132_MPEG4_QUART_PXL_SHFT 0 + + +#define VIDC_MGEN2MAXI_REG_BASE (VIDC_BASE + 0x00080000) +#define VIDC_MGEN2MAXI_REG_BASE_PHYS 0x04480000 + +#define HWIO_REG_916352_ADDR (VIDC_MGEN2MAXI_REG_BASE + 00000000) +#define HWIO_REG_916352_PHYS (VIDC_MGEN2MAXI_REG_BASE_PHYS + 00000000) +#define HWIO_REG_916352_RMSK 0xff +#define HWIO_REG_916352_SHFT 0 +#define HWIO_REG_916352_IN in_dword_masked(\ + HWIO_REG_916352_ADDR, HWIO_REG_916352_RMSK) +#define HWIO_REG_916352_INM(m) \ + in_dword_masked(HWIO_REG_916352_ADDR, m) +#define HWIO_REG_916352_VERSION_BMSK 0xff +#define HWIO_REG_916352_VERSION_SHFT 0 + +#define HWIO_REG_5519_ADDR (VIDC_MGEN2MAXI_REG_BASE + 0x00000004) +#define HWIO_REG_5519_PHYS \ + (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000004) +#define HWIO_REG_5519_RMSK 0x1 +#define HWIO_REG_5519_SHFT 0 +#define HWIO_REG_5519_IN in_dword_masked(\ + HWIO_REG_5519_ADDR, HWIO_REG_5519_RMSK) +#define HWIO_REG_5519_INM(m) \ + in_dword_masked(HWIO_REG_5519_ADDR, m) +#define HWIO_REG_5519_OUT(v) \ + out_dword(HWIO_REG_5519_ADDR, v) +#define HWIO_REG_5519_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_5519_ADDR, m, v, HWIO_REG_5519_IN); +#define HWIO_REG_5519_AXI_AOOORD_BMSK 0x1 +#define HWIO_REG_5519_AXI_AOOORD_SHFT 0 + +#define HWIO_REG_606364_ADDR (VIDC_MGEN2MAXI_REG_BASE + 0x00000008) +#define HWIO_REG_606364_PHYS \ + (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000008) +#define HWIO_REG_606364_RMSK 0x1 +#define HWIO_REG_606364_SHFT 0 +#define HWIO_REG_606364_IN in_dword_masked(\ + HWIO_REG_606364_ADDR, HWIO_REG_606364_RMSK) +#define HWIO_REG_606364_INM(m) \ + in_dword_masked(HWIO_REG_606364_ADDR, m) +#define HWIO_REG_606364_OUT(v) \ + out_dword(HWIO_REG_606364_ADDR, v) +#define HWIO_REG_606364_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_606364_ADDR, m, v, HWIO_REG_606364_IN); +#define HWIO_REG_606364_AXI_AOOOWR_BMSK 0x1 +#define HWIO_REG_606364_AXI_AOOOWR_SHFT 0 + +#define HWIO_REG_821472_ADDR (VIDC_MGEN2MAXI_REG_BASE + 0x0000000c) +#define HWIO_REG_821472_PHYS \ + (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x0000000c) +#define HWIO_REG_821472_RMSK 0xf +#define HWIO_REG_821472_SHFT 0 +#define HWIO_REG_821472_IN in_dword_masked(\ + HWIO_REG_821472_ADDR, HWIO_REG_821472_RMSK) +#define HWIO_REG_821472_INM(m) \ + in_dword_masked(HWIO_REG_821472_ADDR, m) +#define HWIO_REG_821472_OUT(v) \ + out_dword(HWIO_REG_821472_ADDR, v) +#define HWIO_REG_821472_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_821472_ADDR, m, v, HWIO_REG_821472_IN); +#define HWIO_REG_821472_AXI_TYPE_BMSK 0xf +#define HWIO_REG_821472_AXI_TYPE_SHFT 0 + +#define HWIO_REG_988424_ADDR \ + (VIDC_MGEN2MAXI_REG_BASE + 0x00000010) +#define HWIO_REG_988424_PHYS \ + (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000010) +#define HWIO_REG_988424_RMSK 0x3 +#define HWIO_REG_988424_SHFT 0 +#define HWIO_REG_988424_IN in_dword_masked(\ + HWIO_REG_988424_ADDR,\ + HWIO_REG_988424_RMSK) +#define HWIO_REG_988424_INM(m) \ + in_dword_masked(HWIO_REG_988424_ADDR, m) +#define HWIO_REG_988424_OUT(v) \ + out_dword(HWIO_REG_988424_ADDR, v) +#define HWIO_REG_988424_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_988424_ADDR, m, v,\ + HWIO_REG_988424_IN); +#define HWIO_REG_988424_AXI_AREQPRIORITY_BMSK 0x3 +#define HWIO_REG_988424_AXI_AREQPRIORITY_SHFT 0 + +#define HWIO_REG_471159_ADDR (VIDC_MGEN2MAXI_REG_BASE + 0x00000014) +#define HWIO_REG_471159_PHYS (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000014) +#define HWIO_REG_471159_RMSK 0x801f1111 +#define HWIO_REG_471159_SHFT 0 +#define HWIO_REG_471159_IN in_dword_masked(\ + HWIO_REG_471159_ADDR, HWIO_REG_471159_RMSK) +#define HWIO_REG_471159_INM(m) \ + in_dword_masked(HWIO_REG_471159_ADDR, m) +#define HWIO_REG_471159_OUT(v) \ + out_dword(HWIO_REG_471159_ADDR, v) +#define HWIO_REG_471159_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_471159_ADDR, m, v, HWIO_REG_471159_IN); +#define HWIO_REG_471159_AXI_INTR_CLR_BMSK 0x80000000 +#define HWIO_REG_471159_AXI_INTR_CLR_SHFT 0x1f +#define HWIO_REG_471159_AXI_WDTIMEOUT_LOG2_BMSK 0x1e0000 +#define HWIO_REG_471159_AXI_WDTIMEOUT_LOG2_SHFT 0x11 +#define HWIO_REG_471159_AXI_HALT_ON_WDTIMEOUT_BMSK 0x10000 +#define HWIO_REG_471159_AXI_HALT_ON_WDTIMEOUT_SHFT 0x10 +#define HWIO_REG_471159_AXI_HALT_ON_WR_ERR_BMSK 0x1000 +#define HWIO_REG_471159_AXI_HALT_ON_WR_ERR_SHFT 0xc +#define HWIO_REG_471159_AXI_HALT_ON_RD_ERR_BMSK 0x100 +#define HWIO_REG_471159_AXI_HALT_ON_RD_ERR_SHFT 0x8 +#define HWIO_REG_471159_AXI_RESET_BMSK 0x10 +#define HWIO_REG_471159_AXI_RESET_SHFT 0x4 +#define HWIO_REG_471159_AXI_HALT_REQ_BMSK 0x1 +#define HWIO_REG_471159_AXI_HALT_REQ_SHFT 0 + +#define HWIO_REG_437878_ADDR (VIDC_MGEN2MAXI_REG_BASE + 0x00000018) +#define HWIO_REG_437878_PHYS \ + (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000018) +#define HWIO_REG_437878_RMSK 0x3333 +#define HWIO_REG_437878_SHFT 0 +#define HWIO_REG_437878_IN in_dword_masked(\ + HWIO_REG_437878_ADDR, HWIO_REG_437878_RMSK) +#define HWIO_REG_437878_INM(m) \ + in_dword_masked(HWIO_REG_437878_ADDR, m) +#define HWIO_REG_437878_AXI_WDTIMEOUT_INTR_BMSK 0x3000 +#define HWIO_REG_437878_AXI_WDTIMEOUT_INTR_SHFT 0xc +#define HWIO_REG_437878_AXI_ERR_INTR_BMSK 0x300 +#define HWIO_REG_437878_AXI_ERR_INTR_SHFT 0x8 +#define HWIO_REG_437878_AXI_IDLE_BMSK 0x30 +#define HWIO_REG_437878_AXI_IDLE_SHFT 0x4 +#define HWIO_REG_437878_AXI_HALT_ACK_BMSK 0x3 +#define HWIO_REG_437878_AXI_HALT_ACK_SHFT 0 + +#define HWIO_REG_736158_ADDR \ + (VIDC_MGEN2MAXI_REG_BASE + 0x0000001c) +#define HWIO_REG_736158_PHYS \ + (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x0000001c) +#define HWIO_REG_736158_RMSK 0x10fff +#define HWIO_REG_736158_SHFT 0 +#define HWIO_REG_736158_IN in_dword_masked(\ + HWIO_REG_736158_ADDR,\ + HWIO_REG_736158_RMSK) +#define HWIO_REG_736158_INM(m) \ + in_dword_masked(HWIO_REG_736158_ADDR, m) +#define HWIO_REG_736158_AXI_WDTIMEOUT_BMSK 0x10000 +#define HWIO_REG_736158_AXI_WDTIMEOUT_SHFT 0x10 +#define HWIO_REG_736158_AXI_ERR_BMSK 0x800 +#define HWIO_REG_736158_AXI_ERR_SHFT 0xb +#define HWIO_REG_736158_AXI_ERR_TYPE_BMSK 0x400 +#define HWIO_REG_736158_AXI_ERR_TYPE_SHFT 0xa +#define HWIO_REG_736158_AXI_RESP_BMSK 0x300 +#define HWIO_REG_736158_AXI_RESP_SHFT 0x8 +#define HWIO_REG_736158_AXI_MID_BMSK 0xf0 +#define HWIO_REG_736158_AXI_MID_SHFT 0x4 +#define HWIO_REG_736158_AXI_TID_BMSK 0xf +#define HWIO_REG_736158_AXI_TID_SHFT 0 + +#define HWIO_REG_598415_ADDR \ + (VIDC_MGEN2MAXI_REG_BASE + 0x00000020) +#define HWIO_REG_598415_PHYS \ + (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000020) +#define HWIO_REG_598415_RMSK 0x10fff +#define HWIO_REG_598415_SHFT 0 +#define HWIO_REG_598415_IN in_dword_masked(\ + HWIO_REG_598415_ADDR,\ + HWIO_REG_598415_RMSK) +#define HWIO_REG_598415_INM(m) \ + in_dword_masked(HWIO_REG_598415_ADDR, m) +#define HWIO_REG_598415_AXI_WDTIMEOUT_BMSK 0x10000 +#define HWIO_REG_598415_AXI_WDTIMEOUT_SHFT 0x10 +#define HWIO_REG_598415_AXI_ERR_BMSK 0x800 +#define HWIO_REG_598415_AXI_ERR_SHFT 0xb +#define HWIO_REG_598415_AXI_ERR_TYPE_BMSK 0x400 +#define HWIO_REG_598415_AXI_ERR_TYPE_SHFT 0xa +#define HWIO_REG_598415_AXI_RESP_BMSK 0x300 +#define HWIO_REG_598415_AXI_RESP_SHFT 0x8 +#define HWIO_REG_598415_AXI_MID_BMSK 0xf0 +#define HWIO_REG_598415_AXI_MID_SHFT 0x4 +#define HWIO_REG_598415_AXI_TID_BMSK 0xf +#define HWIO_REG_598415_AXI_TID_SHFT 0 + +#define HWIO_REG_439061_ADDR (VIDC_MGEN2MAXI_REG_BASE + 0x00000024) +#define HWIO_REG_439061_PHYS \ + (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000024) +#define HWIO_REG_439061_RMSK 0x11111ff +#define HWIO_REG_439061_SHFT 0 +#define HWIO_REG_439061_IN in_dword_masked(\ + HWIO_REG_439061_ADDR, HWIO_REG_439061_RMSK) +#define HWIO_REG_439061_INM(m) \ + in_dword_masked(HWIO_REG_439061_ADDR, m) +#define HWIO_REG_439061_OUT(v) \ + out_dword(HWIO_REG_439061_ADDR, v) +#define HWIO_REG_439061_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_439061_ADDR, m, v, HWIO_REG_439061_IN); +#define HWIO_REG_439061_AXI_RD_LAT_REP_EN_BMSK 0x1000000 +#define HWIO_REG_439061_AXI_RD_LAT_REP_EN_SHFT 0x18 +#define HWIO_REG_439061_AXI_LSFR_EN_BMSK 0x100000 +#define HWIO_REG_439061_AXI_LSFR_EN_SHFT 0x14 +#define HWIO_REG_439061_AXI_MISR_RES_BMSK 0x10000 +#define HWIO_REG_439061_AXI_MISR_RES_SHFT 0x10 +#define HWIO_REG_439061_AXI_MISR_EN_BMSK 0x1000 +#define HWIO_REG_439061_AXI_MISR_EN_SHFT 0xc +#define HWIO_REG_439061_AXI_MISR_WD_BMSK 0x100 +#define HWIO_REG_439061_AXI_MISR_WD_SHFT 0x8 +#define HWIO_REG_439061_AXI_CTR_EN_BMSK 0x80 +#define HWIO_REG_439061_AXI_CTR_EN_SHFT 0x7 +#define HWIO_REG_439061_AXI_CTR_RES_BMSK 0x40 +#define HWIO_REG_439061_AXI_CTR_RES_SHFT 0x6 +#define HWIO_REG_439061_AXI_TEST_ARB_SEL_BMSK 0x30 +#define HWIO_REG_439061_AXI_TEST_ARB_SEL_SHFT 0x4 +#define HWIO_REG_439061_AXI_TEST_OUT_SEL_BMSK 0xf +#define HWIO_REG_439061_AXI_TEST_OUT_SEL_SHFT 0 + +#define HWIO_REG_573121_ADDR \ + (VIDC_MGEN2MAXI_REG_BASE + 0x00000028) +#define HWIO_REG_573121_PHYS \ + (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000028) +#define HWIO_REG_573121_RMSK 0xffffffff +#define HWIO_REG_573121_SHFT 0 +#define HWIO_REG_573121_IN in_dword_masked(\ + HWIO_REG_573121_ADDR,\ + HWIO_REG_573121_RMSK) +#define HWIO_REG_573121_INM(m) \ + in_dword_masked(HWIO_REG_573121_ADDR, m) +#define HWIO_REG_573121_AXI_TEST_OUT_BMSK 0xffffffff +#define HWIO_REG_573121_AXI_TEST_OUT_SHFT 0 + +#define HWIO_REG_806413_ADDR \ + (VIDC_MGEN2MAXI_REG_BASE + 0x0000002c) +#define HWIO_REG_806413_PHYS \ + (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x0000002c) +#define HWIO_REG_806413_RMSK 0xffffffff +#define HWIO_REG_806413_SHFT 0 +#define HWIO_REG_806413_IN in_dword_masked(\ + HWIO_REG_806413_ADDR,\ + HWIO_REG_806413_RMSK) +#define HWIO_REG_806413_INM(m) \ + in_dword_masked(HWIO_REG_806413_ADDR, m) +#define HWIO_REG_806413_AXI_TEST_OUT_BMSK 0xffffffff +#define HWIO_REG_806413_AXI_TEST_OUT_SHFT 0 + +#define HWIO_REG_804110_ADDR (VIDC_MGEN2MAXI_REG_BASE + 0x00000030) +#define HWIO_REG_804110_PHYS (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000030) +#define HWIO_REG_804110_RMSK 0xc00fffff +#define HWIO_REG_804110_SHFT 0 +#define HWIO_REG_804110_IN in_dword_masked(\ + HWIO_REG_804110_ADDR, HWIO_REG_804110_RMSK) +#define HWIO_REG_804110_INM(m) \ + in_dword_masked(HWIO_REG_804110_ADDR, m) +#define HWIO_REG_804110_OUT(v) out_dword(HWIO_REG_804110_ADDR, v) +#define HWIO_REG_804110_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_804110_ADDR, m, v, HWIO_REG_804110_IN); +#define HWIO_REG_804110_ENABLE_BMSK 0x80000000 +#define HWIO_REG_804110_ENABLE_SHFT 0x1f +#define HWIO_REG_804110_CONST_VIDC_BMSK 0x40000000 +#define HWIO_REG_804110_CONST_VIDC_SHFT 0x1e +#define HWIO_REG_804110_VIDCV_1080P_VERSION_BMSK 0xff000 +#define HWIO_REG_804110_VIDCV_1080P_VERSION_SHFT 0xc +#define HWIO_REG_804110_MGEN2MAXI_DATA_SEL_BMSK 0xf00 +#define HWIO_REG_804110_MGEN2MAXI_DATA_SEL_SHFT 0x8 +#define HWIO_REG_804110_MGEN2MAXI_XIN_SEL_BMSK 0x80 +#define HWIO_REG_804110_MGEN2MAXI_XIN_SEL_SHFT 0x7 +#define HWIO_REG_804110_MGEN2MAXI_ARB_SEL_BMSK 0x40 +#define HWIO_REG_804110_MGEN2MAXI_ARB_SEL_SHFT 0x6 +#define HWIO_REG_804110_MGEN2MAXI_TESTBUS_SEL_BMSK 0x30 +#define HWIO_REG_804110_MGEN2MAXI_TESTBUS_SEL_SHFT 0x4 +#define HWIO_REG_804110_AHB2AHB_TESTBUS_SEL_BMSK 0x8 +#define HWIO_REG_804110_AHB2AHB_TESTBUS_SEL_SHFT 0x3 +#define HWIO_REG_804110_MGEN2MAXI_AXI_SEL_BMSK 0x4 +#define HWIO_REG_804110_MGEN2MAXI_AXI_SEL_SHFT 0x2 +#define HWIO_REG_804110_SELECT_BMSK 0x3 +#define HWIO_REG_804110_SELECT_SHFT 0 + +#define HWIO_REG_616440_ADDR \ + (VIDC_MGEN2MAXI_REG_BASE + 0x00000034) +#define HWIO_REG_616440_PHYS \ + (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000034) +#define HWIO_REG_616440_RMSK 0xffff +#define HWIO_REG_616440_SHFT 0 +#define HWIO_REG_616440_IN in_dword_masked(\ + HWIO_REG_616440_ADDR,\ + HWIO_REG_616440_RMSK) +#define HWIO_REG_616440_INM(m) \ + in_dword_masked(HWIO_REG_616440_ADDR, m) +#define HWIO_REG_616440_OUT(v) \ + out_dword(HWIO_REG_616440_ADDR, v) +#define HWIO_REG_616440_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_616440_ADDR, m, v,\ + HWIO_REG_616440_IN); +#define HWIO_REG_616440_XBAR_IN_RD_LIM_BMSK 0xff00 +#define HWIO_REG_616440_XBAR_IN_RD_LIM_SHFT 0x8 +#define HWIO_REG_616440_XBAR_IN_WR_LIM_BMSK 0xff +#define HWIO_REG_616440_XBAR_IN_WR_LIM_SHFT 0 + +#define HWIO_REG_527219_ADDR \ + (VIDC_MGEN2MAXI_REG_BASE + 0x00000038) +#define HWIO_REG_527219_PHYS \ + (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x00000038) +#define HWIO_REG_527219_RMSK 0xffff +#define HWIO_REG_527219_SHFT 0 +#define HWIO_REG_527219_IN in_dword_masked(\ + HWIO_REG_527219_ADDR,\ + HWIO_REG_527219_RMSK) +#define HWIO_REG_527219_INM(m) \ + in_dword_masked(HWIO_REG_527219_ADDR, m) +#define HWIO_REG_527219_OUT(v) \ + out_dword(HWIO_REG_527219_ADDR, v) +#define HWIO_REG_527219_OUTM(m, v) \out_dword_masked_ns(\ + HWIO_REG_527219_ADDR, m, v,\ + HWIO_REG_527219_IN); +#define HWIO_REG_527219_XBAR_OUT_RD_LIM_BMSK 0xff00 +#define HWIO_REG_527219_XBAR_OUT_RD_LIM_SHFT 0x8 +#define HWIO_REG_527219_XBAR_OUT_WR_LIM_BMSK 0xff +#define HWIO_REG_527219_XBAR_OUT_WR_LIM_SHFT 0 + +#define HWIO_REG_922106_ADDR \ + (VIDC_MGEN2MAXI_REG_BASE + 0x0000003c) +#define HWIO_REG_922106_PHYS \ + (VIDC_MGEN2MAXI_REG_BASE_PHYS + 0x0000003c) +#define HWIO_REG_922106_RMSK 0xffff +#define HWIO_REG_922106_SHFT 0 +#define HWIO_REG_922106_IN in_dword_masked(\ + HWIO_REG_922106_ADDR,\ + HWIO_REG_922106_RMSK) +#define HWIO_REG_922106_INM(m) \ + in_dword_masked(HWIO_REG_922106_ADDR, m) +#define HWIO_REG_922106_OUT(v) \ + out_dword(HWIO_REG_922106_ADDR, v) +#define HWIO_REG_922106_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_922106_ADDR, m, v,\ + HWIO_REG_922106_IN); +#define HWIO_REG_922106_XBAR_OUT_MAX_RD_BURST_BMSK 0xff00 +#define HWIO_REG_922106_XBAR_OUT_MAX_RD_BURST_SHFT 0x8 +#define HWIO_REG_922106_XBAR_OUT_MAX_WR_BURST_BMSK 0xff +#define HWIO_REG_922106_XBAR_OUT_MAX_WR_BURST_SHFT 0 + +#define VIDC_ENHANCE_REG_BASE (VIDC_BASE + 0x000c0000) +#define VIDC_ENHANCE_REG_BASE_PHYS 0x044c0000 + +#define HWIO_REG_261029_ADDR (VIDC_ENHANCE_REG_BASE + 00000000) +#define HWIO_REG_261029_PHYS (VIDC_ENHANCE_REG_BASE_PHYS + 00000000) +#define HWIO_REG_261029_RMSK 0x10f +#define HWIO_REG_261029_SHFT 0 +#define HWIO_REG_261029_IN in_dword_masked(\ + HWIO_REG_261029_ADDR, HWIO_REG_261029_RMSK) +#define HWIO_REG_261029_INM(m) \ + in_dword_masked(HWIO_REG_261029_ADDR, m) +#define HWIO_REG_261029_OUT(v) \ + out_dword(HWIO_REG_261029_ADDR, v) +#define HWIO_REG_261029_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_261029_ADDR, m, v, HWIO_REG_261029_IN); +#define HWIO_REG_261029_AUTO_INC_EN_BMSK 0x100 +#define HWIO_REG_261029_AUTO_INC_EN_SHFT 0x8 +#define HWIO_REG_261029_DMI_RAM_SEL_BMSK 0xf +#define HWIO_REG_261029_DMI_RAM_SEL_SHFT 0 + +#define HWIO_REG_576200_ADDR (VIDC_ENHANCE_REG_BASE + 0x00000004) +#define HWIO_REG_576200_PHYS (VIDC_ENHANCE_REG_BASE_PHYS + 0x00000004) +#define HWIO_REG_576200_RMSK 0x7ff +#define HWIO_REG_576200_SHFT 0 +#define HWIO_REG_576200_IN in_dword_masked(\ + HWIO_REG_576200_ADDR, HWIO_REG_576200_RMSK) +#define HWIO_REG_576200_INM(m) \ + in_dword_masked(HWIO_REG_576200_ADDR, m) +#define HWIO_REG_576200_OUT(v) \ + out_dword(HWIO_REG_576200_ADDR, v) +#define HWIO_REG_576200_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_576200_ADDR, m, v, HWIO_REG_576200_IN); +#define HWIO_REG_576200_DMI_ADDR_BMSK 0x7ff +#define HWIO_REG_576200_DMI_ADDR_SHFT 0 + +#define HWIO_REG_917583_ADDR (VIDC_ENHANCE_REG_BASE + 0x00000008) +#define HWIO_REG_917583_PHYS (VIDC_ENHANCE_REG_BASE_PHYS + 0x00000008) +#define HWIO_REG_917583_RMSK 0xffffffff +#define HWIO_REG_917583_SHFT 0 +#define HWIO_REG_917583_IN in_dword_masked(\ + HWIO_REG_917583_ADDR, HWIO_REG_917583_RMSK) +#define HWIO_REG_917583_INM(m) \ + in_dword_masked(HWIO_REG_917583_ADDR, m) +#define HWIO_REG_917583_OUT(v) \ + out_dword(HWIO_REG_917583_ADDR, v) +#define HWIO_REG_917583_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_917583_ADDR, m, v, HWIO_REG_917583_IN); +#define HWIO_REG_917583_DMI_DATA_HI_BMSK 0xffffffff +#define HWIO_REG_917583_DMI_DATA_HI_SHFT 0 + +#define HWIO_REG_556274_ADDR (VIDC_ENHANCE_REG_BASE + 0x0000000c) +#define HWIO_REG_556274_PHYS (VIDC_ENHANCE_REG_BASE_PHYS + 0x0000000c) +#define HWIO_REG_556274_RMSK 0xffffffff +#define HWIO_REG_556274_SHFT 0 +#define HWIO_REG_556274_IN in_dword_masked(\ + HWIO_REG_556274_ADDR, HWIO_REG_556274_RMSK) +#define HWIO_REG_556274_INM(m) \ + in_dword_masked(HWIO_REG_556274_ADDR, m) +#define HWIO_REG_556274_OUT(v) \ + out_dword(HWIO_REG_556274_ADDR, v) +#define HWIO_REG_556274_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_556274_ADDR, m, v, HWIO_REG_556274_IN); +#define HWIO_REG_556274_DMI_DATA_LO_BMSK 0xffffffff +#define HWIO_REG_556274_DMI_DATA_LO_SHFT 0 + +#define HWIO_REG_39703_ADDR (VIDC_ENHANCE_REG_BASE + 0x00000010) +#define HWIO_REG_39703_PHYS \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x00000010) +#define HWIO_REG_39703_RMSK 0x1f +#define HWIO_REG_39703_SHFT 0 +#define HWIO_REG_39703_IN in_dword_masked(\ + HWIO_REG_39703_ADDR, HWIO_REG_39703_RMSK) +#define HWIO_REG_39703_INM(m) \ + in_dword_masked(HWIO_REG_39703_ADDR, m) +#define HWIO_REG_39703_OUT(v) \ + out_dword(HWIO_REG_39703_ADDR, v) +#define HWIO_REG_39703_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_39703_ADDR, m, v, HWIO_REG_39703_IN); +#define HWIO_REG_39703_PIX_CACHE_TB_SEL_BMSK 0x1f +#define HWIO_REG_39703_PIX_CACHE_TB_SEL_SHFT 0 + +#define HWIO_REG_169013_ADDR (VIDC_ENHANCE_REG_BASE + 0x00000014) +#define HWIO_REG_169013_PHYS (VIDC_ENHANCE_REG_BASE_PHYS + 0x00000014) +#define HWIO_REG_169013_RMSK 0x3 +#define HWIO_REG_169013_SHFT 0 +#define HWIO_REG_169013_IN in_dword_masked(\ + HWIO_REG_169013_ADDR, HWIO_REG_169013_RMSK) +#define HWIO_REG_169013_INM(m) \ + in_dword_masked(HWIO_REG_169013_ADDR, m) +#define HWIO_REG_169013_OUT(v) \ + out_dword(HWIO_REG_169013_ADDR, v) +#define HWIO_REG_169013_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_169013_ADDR, m, v, HWIO_REG_169013_IN); +#define HWIO_REG_169013_PIX_CACHE_SW_RESET_BMSK 0x2 +#define HWIO_REG_169013_PIX_CACHE_SW_RESET_SHFT 0x1 +#define HWIO_REG_169013_CRIF_RESET_BMSK 0x1 +#define HWIO_REG_169013_CRIF_RESET_SHFT 0 + +#define HWIO_REG_22756_ADDR (VIDC_ENHANCE_REG_BASE + 0x00000018) +#define HWIO_REG_22756_PHYS \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x00000018) +#define HWIO_REG_22756_RMSK 0x133f +#define HWIO_REG_22756_SHFT 0 +#define HWIO_REG_22756_IN in_dword_masked(\ + HWIO_REG_22756_ADDR, HWIO_REG_22756_RMSK) +#define HWIO_REG_22756_INM(m) \ + in_dword_masked(HWIO_REG_22756_ADDR, m) +#define HWIO_REG_22756_OUT(v) \ + out_dword(HWIO_REG_22756_ADDR, v) +#define HWIO_REG_22756_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_22756_ADDR, m, v, HWIO_REG_22756_IN); +#define HWIO_REG_22756_CACHE_HALT_BMSK 0x1000 +#define HWIO_REG_22756_CACHE_HALT_SHFT 0xc +#define HWIO_REG_22756_PAGE_SIZE_BMSK 0x300 +#define HWIO_REG_22756_PAGE_SIZE_SHFT 0x8 +#define HWIO_REG_22756_STATISTICS_OFF_BMSK 0x20 +#define HWIO_REG_22756_STATISTICS_OFF_SHFT 0x5 +#define HWIO_REG_22756_CACHE_PORT_SELECT_BMSK 0x10 +#define HWIO_REG_22756_CACHE_PORT_SELECT_SHFT 0x4 +#define HWIO_REG_22756_PREFETCH_EN_BMSK 0x8 +#define HWIO_REG_22756_PREFETCH_EN_SHFT 0x3 +#define HWIO_REG_22756_SS_TILE_FORMAT_BMSK 0x4 +#define HWIO_REG_22756_SS_TILE_FORMAT_SHFT 0x2 +#define HWIO_REG_22756_CACHE_EN_BMSK 0x2 +#define HWIO_REG_22756_CACHE_EN_SHFT 0x1 +#define HWIO_REG_22756_CACHE_TAG_CLEAR_BMSK 0x1 +#define HWIO_REG_22756_CACHE_TAG_CLEAR_SHFT 0 + +#define HWIO_REG_951731_ADDR \ + (VIDC_ENHANCE_REG_BASE + 0x0000001c) +#define HWIO_REG_951731_PHYS \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x0000001c) +#define HWIO_REG_951731_RMSK 0x7ff07ff +#define HWIO_REG_951731_SHFT 0 +#define HWIO_REG_951731_IN in_dword_masked(\ + HWIO_REG_951731_ADDR,\ + HWIO_REG_951731_RMSK) +#define HWIO_REG_951731_INM(m) \ + in_dword_masked(HWIO_REG_951731_ADDR, m) +#define HWIO_REG_951731_OUT(v) \ + out_dword(HWIO_REG_951731_ADDR, v) +#define HWIO_REG_951731_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_951731_ADDR, m, v,\ + HWIO_REG_951731_IN); +#define HWIO_REG_951731_FRAME_HEIGHT_BMSK 0x7ff0000 +#define HWIO_REG_951731_FRAME_HEIGHT_SHFT 0x10 +#define HWIO_REG_951731_FRAME_WIDTH_BMSK 0x7ff +#define HWIO_REG_951731_FRAME_WIDTH_SHFT 0 + +#define HWIO_REG_905239_ADDR \ + (VIDC_ENHANCE_REG_BASE + 0x00000020) +#define HWIO_REG_905239_PHYS \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x00000020) +#define HWIO_REG_905239_RMSK 0x3ffff +#define HWIO_REG_905239_SHFT 0 +#define HWIO_REG_905239_IN in_dword_masked(\ + HWIO_REG_905239_ADDR,\ + HWIO_REG_905239_RMSK) +#define HWIO_REG_905239_INM(m) \ + in_dword_masked(HWIO_REG_905239_ADDR, m) +#define HWIO_REG_905239_OUT(v) \ + out_dword(HWIO_REG_905239_ADDR, v) +#define HWIO_REG_905239_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_905239_ADDR, m, v,\ + HWIO_REG_905239_IN); +#define HWIO_REG_905239_LINEAR_LUMA_BMSK 0x3ffff +#define HWIO_REG_905239_LINEAR_LUMA_SHFT 0 +#define HWIO_REG_905239_TILE_LUMA_BMSK 0xff00 +#define HWIO_REG_905239_TILE_LUMA_SHFT 0x8 +#define HWIO_REG_905239_TILE_CHROMA_BMSK 0xff +#define HWIO_REG_905239_TILE_CHROMA_SHFT 0 + +#define HWIO_REG_804925_ADDR(n) \ + (VIDC_ENHANCE_REG_BASE + 0x00000024 + 4 * (n)) +#define HWIO_REG_804925_PHYS(n) \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x00000024 + 4 * (n)) +#define HWIO_REG_804925_RMSK 0xfffffff8 +#define HWIO_REG_804925_SHFT 0 +#define HWIO_REG_804925_MAXn 0x12 +#define HWIO_REG_804925_INI(n) \ + in_dword(HWIO_REG_804925_ADDR(n)) +#define HWIO_REG_804925_INMI(n, mask) \ + in_dword_masked(HWIO_REG_804925_ADDR(n), mask) +#define HWIO_REG_804925_OUTI(n, val) \ + out_dword(HWIO_REG_804925_ADDR(n), val) +#define HWIO_REG_804925_OUTMI(n, mask, val) \ + out_dword_masked_ns(HWIO_REG_804925_ADDR(n),\ + mask, val, HWIO_REG_804925_INI(n)); +#define HWIO_REG_804925_ADDR_BMSK 0xfffffff8 +#define HWIO_REG_804925_ADDR_SHFT 0x3 + +#define HWIO_REG_41909_ADDR(n) \ + (VIDC_ENHANCE_REG_BASE + 0x00000070 + 4 * (n)) +#define HWIO_REG_41909_PHYS(n) \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x00000070 + 4 * (n)) +#define HWIO_REG_41909_RMSK 0xfffffff8 +#define HWIO_REG_41909_SHFT 0 +#define HWIO_REG_41909_MAXn 0x12 +#define HWIO_REG_41909_INI(n) \ + in_dword(HWIO_REG_41909_ADDR(n)) +#define HWIO_REG_41909_INMI(n, mask) \ + in_dword_masked(HWIO_REG_41909_ADDR(n), mask) +#define HWIO_REG_41909_OUTI(n, val) \ + out_dword(HWIO_REG_41909_ADDR(n), val) +#define HWIO_REG_41909_OUTMI(n, mask, val) \ + out_dword_masked_ns(HWIO_REG_41909_ADDR(n),\ + mask, val, HWIO_REG_41909_INI(n)); +#define HWIO_REG_41909_ADDR_BMSK 0xfffffff8 +#define HWIO_REG_41909_ADDR_SHFT 0x3 + +#define HWIO_REG_919904_ADDR (VIDC_ENHANCE_REG_BASE + 0x000000bc) +#define HWIO_REG_919904_PHYS \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x000000bc) +#define HWIO_REG_919904_RMSK 0x1 +#define HWIO_REG_919904_SHFT 0 +#define HWIO_REG_919904_IN in_dword_masked(\ + HWIO_REG_919904_ADDR,\ + HWIO_REG_919904_RMSK) +#define HWIO_REG_919904_INM(m) \ + in_dword_masked(HWIO_REG_919904_ADDR, m) +#define HWIO_REG_919904_IDLE_BMSK 0x1 +#define HWIO_REG_919904_IDLE_SHFT 0 + +#define HWIO_REG_278310_ADDR \ + (VIDC_ENHANCE_REG_BASE + 0x000000c0) +#define HWIO_REG_278310_PHYS \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x000000c0) +#define HWIO_REG_278310_RMSK 0xffffffff +#define HWIO_REG_278310_SHFT 0 +#define HWIO_REG_278310_IN in_dword_masked(\ + HWIO_REG_278310_ADDR,\ + HWIO_REG_278310_RMSK) +#define HWIO_REG_278310_INM(m) \ + in_dword_masked(HWIO_REG_278310_ADDR, m) +#define HWIO_REG_278310_MISS_COUNT_BMSK 0xffffffff +#define HWIO_REG_278310_MISS_COUNT_SHFT 0 + +#define HWIO_REG_421222_ADDR \ + (VIDC_ENHANCE_REG_BASE + 0x000000c4) +#define HWIO_REG_421222_PHYS \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x000000c4) +#define HWIO_REG_421222_RMSK 0xffffffff +#define HWIO_REG_421222_SHFT 0 +#define HWIO_REG_421222_IN in_dword_masked(\ + HWIO_REG_421222_ADDR,\ + HWIO_REG_421222_RMSK) +#define HWIO_REG_421222_INM(m) \ + in_dword_masked(HWIO_REG_421222_ADDR, m) +#define HWIO_REG_421222_HIT_COUNT_BMSK 0xffffffff +#define HWIO_REG_421222_HIT_COUNT_SHFT 0 + +#define HWIO_REG_609607_ADDR \ + (VIDC_ENHANCE_REG_BASE + 0x000000c8) +#define HWIO_REG_609607_PHYS \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x000000c8) +#define HWIO_REG_609607_RMSK 0xffffffff +#define HWIO_REG_609607_SHFT 0 +#define HWIO_REG_609607_IN in_dword_masked(\ + HWIO_REG_609607_ADDR,\ + HWIO_REG_609607_RMSK) +#define HWIO_REG_609607_INM(m) \ + in_dword_masked(HWIO_REG_609607_ADDR, m) +#define HWIO_REG_609607_AXI_REQUEST_COUNT_BMSK 0xffffffff +#define HWIO_REG_609607_AXI_REQUEST_COUNT_SHFT 0 + +#define HWIO_REG_395232_ADDR \ + (VIDC_ENHANCE_REG_BASE + 0x000000cc) +#define HWIO_REG_395232_PHYS \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x000000cc) +#define HWIO_REG_395232_RMSK 0xffffffff +#define HWIO_REG_395232_SHFT 0 +#define HWIO_REG_395232_IN in_dword_masked(\ + HWIO_REG_395232_ADDR,\ + HWIO_REG_395232_RMSK) +#define HWIO_REG_395232_INM(m) \ + in_dword_masked(HWIO_REG_395232_ADDR, m) +#define HWIO_REG_395232_CORE_REQUEST_COUNT_BMSK \ + 0xffffffff +#define HWIO_REG_395232_CORE_REQUEST_COUNT_SHFT 0 + +#define HWIO_REG_450146_ADDR \ + (VIDC_ENHANCE_REG_BASE + 0x000000d0) +#define HWIO_REG_450146_PHYS \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x000000d0) +#define HWIO_REG_450146_RMSK 0xffffffff +#define HWIO_REG_450146_SHFT 0 +#define HWIO_REG_450146_IN in_dword_masked(\ + HWIO_REG_450146_ADDR,\ + HWIO_REG_450146_RMSK) +#define HWIO_REG_450146_INM(m) \ + in_dword_masked(HWIO_REG_450146_ADDR, m) +#define HWIO_REG_450146_AXI_BEAT_COUNT_BMSK 0xffffffff +#define HWIO_REG_450146_AXI_BEAT_COUNT_SHFT 0 + +#define HWIO_REG_610651_ADDR \ + (VIDC_ENHANCE_REG_BASE + 0x000000d4) +#define HWIO_REG_610651_PHYS \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x000000d4) +#define HWIO_REG_610651_RMSK 0xffffffff +#define HWIO_REG_610651_SHFT 0 +#define HWIO_REG_610651_IN in_dword_masked(\ + HWIO_REG_610651_ADDR,\ + HWIO_REG_610651_RMSK) +#define HWIO_REG_610651_INM(m) \ + in_dword_masked(HWIO_REG_610651_ADDR, m) +#define HWIO_REG_610651_CORE_BEAT_COUNT_BMSK 0xffffffff +#define HWIO_REG_610651_CORE_BEAT_COUNT_SHFT 0 + +#define HWIO_REG_883784_ADDR \ + (VIDC_ENHANCE_REG_BASE + 0x000000d8) +#define HWIO_REG_883784_PHYS \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x000000d8) +#define HWIO_REG_883784_RMSK 0xffffffff +#define HWIO_REG_883784_SHFT 0 +#define HWIO_REG_883784_IN in_dword_masked(\ + HWIO_REG_883784_ADDR,\ + HWIO_REG_883784_RMSK) +#define HWIO_REG_883784_INM(m) \ + in_dword_masked(HWIO_REG_883784_ADDR, m) +#define HWIO_REG_883784_OUT(v) \ + out_dword(HWIO_REG_883784_ADDR, v) +#define HWIO_REG_883784_OUTM(m, v) out_dword_masked_ns(\ + HWIO_REG_883784_ADDR, m, v,\ + HWIO_REG_883784_IN); +#define HWIO_REG_883784_COUNTER_BMSK 0xffffff00 +#define HWIO_REG_883784_COUNTER_SHFT 0x8 +#define HWIO_REG_883784_ID_BMSK 0xf0 +#define HWIO_REG_883784_ID_SHFT 0x4 +#define HWIO_REG_883784_IGNORE_ID_BMSK 0x8 +#define HWIO_REG_883784_IGNORE_ID_SHFT 0x3 +#define HWIO_REG_883784_INPUT_SEL_BMSK 0x6 +#define HWIO_REG_883784_INPUT_SEL_SHFT 0x1 +#define HWIO_REG_883784_MISR_EN_BMSK 0x1 +#define HWIO_REG_883784_MISR_EN_SHFT 0 + +#define HWIO_REG_651391_ADDR(n) \ + (VIDC_ENHANCE_REG_BASE + 0x000000dc + 4 * (n)) +#define HWIO_REG_651391_PHYS(n) \ + (VIDC_ENHANCE_REG_BASE_PHYS + 0x000000dc + 4 * (n)) +#define HWIO_REG_651391_RMSK 0xffffffff +#define HWIO_REG_651391_SHFT 0 +#define HWIO_REG_651391_MAXn 0x1 +#define HWIO_REG_651391_INI(n) \ + in_dword(HWIO_REG_651391_ADDR(n)) +#define HWIO_REG_651391_INMI(n, mask) \ + in_dword_masked(HWIO_REG_651391_ADDR(n), mask) +#define HWIO_REG_651391_OUTI(n, val) \ + out_dword(HWIO_REG_651391_ADDR(n), val) +#define HWIO_REG_651391_SIGNATURE_BMSK 0xffffffff +#define HWIO_REG_651391_SIGNATURE_SHFT 0 + +#endif + diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.c b/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.c new file mode 100644 index 000000000000..de294fd423e9 --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.c @@ -0,0 +1,349 @@ +/* Copyright (c) 2010, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#include "vidc_hwio_reg.h" +#include "vidc_hwio.h" +#include "vidc_pix_cache.h" + + +#define VIDC_1080P_MAX_DEC_DPB 19 +#define VIDC_TILE_MULTIPLY_FACTOR 8192 + +void vidc_pix_cache_sw_reset(void) +{ + u32 sw_reset_value = 0; + + VIDC_HWIO_IN(REG_169013, &sw_reset_value); + sw_reset_value |= HWIO_REG_169013_PIX_CACHE_SW_RESET_BMSK; + VIDC_HWIO_OUT(REG_169013, sw_reset_value); + VIDC_HWIO_IN(REG_169013, &sw_reset_value); + sw_reset_value &= (~HWIO_REG_169013_PIX_CACHE_SW_RESET_BMSK); + VIDC_HWIO_OUT(REG_169013, sw_reset_value); +} + +void vidc_pix_cache_init_luma_chroma_base_addr(u32 dpb, + u32 *pn_dpb_luma_offset, u32 *pn_dpb_chroma_offset) +{ + u32 count, num_dpb_used = dpb; + u32 dpb_reset_value = VIDC_1080P_DEC_DPB_RESET_VALUE; + + if (num_dpb_used > VIDC_1080P_MAX_DEC_DPB) + num_dpb_used = VIDC_1080P_MAX_DEC_DPB; + for (count = 0; count < VIDC_1080P_MAX_DEC_DPB; count++) { + if (count < num_dpb_used) { + if (pn_dpb_luma_offset) { + VIDC_HWIO_OUTI( + REG_804925, + count, pn_dpb_luma_offset[count]); + } else { + VIDC_HWIO_OUTI( + REG_804925, + count, dpb_reset_value); + } + if (pn_dpb_chroma_offset) { + VIDC_HWIO_OUTI( + REG_41909, + count, pn_dpb_chroma_offset[count]); + } else { + VIDC_HWIO_OUTI( + REG_41909, + count, dpb_reset_value); + } + } else { + VIDC_HWIO_OUTI(REG_804925, + count, dpb_reset_value); + VIDC_HWIO_OUTI(REG_41909, + count, dpb_reset_value); + } + } +} + +void vidc_pix_cache_set_frame_range(u32 luma_size, u32 chroma_size) +{ + u32 frame_range; + + frame_range = + (((luma_size / VIDC_TILE_MULTIPLY_FACTOR) & 0xFF) << 8)| + ((chroma_size / VIDC_TILE_MULTIPLY_FACTOR) & 0xFF); + VIDC_HWIO_OUT(REG_905239, frame_range); +} +void vidc_pix_cache_set_frame_size(u32 frame_width, u32 frame_height) +{ + u32 frame_size; + frame_size = (((u32) (frame_height << HWIO_REG_951731_FRAME_HEIGHT_SHFT) & + HWIO_REG_951731_FRAME_HEIGHT_BMSK) | + ((u32) (frame_width << HWIO_REG_951731_FRAME_WIDTH_SHFT) & + HWIO_REG_951731_FRAME_WIDTH_BMSK)); + VIDC_HWIO_OUT(REG_951731, frame_size); +} + +void vidc_pix_cache_init_config( + struct vidc_1080P_pix_cache_config *config) +{ + u32 cfg_reg = 0; + + if (config->cache_enable) + cfg_reg |= HWIO_REG_22756_CACHE_EN_BMSK; + else + cfg_reg &= (~HWIO_REG_22756_CACHE_EN_BMSK); + if (config->port_select == VIDC_1080P_PIX_CACHE_PORT_A) + cfg_reg &= + (~HWIO_REG_22756_CACHE_PORT_SELECT_BMSK); + else + cfg_reg |= HWIO_REG_22756_CACHE_PORT_SELECT_BMSK; + if (!config->statistics_off) + cfg_reg |= HWIO_REG_22756_STATISTICS_OFF_BMSK; + else + cfg_reg &= (~HWIO_REG_22756_STATISTICS_OFF_BMSK); + if (config->prefetch_en) + cfg_reg |= HWIO_REG_22756_PREFETCH_EN_BMSK; + else + cfg_reg &= (~HWIO_REG_22756_PREFETCH_EN_BMSK); + cfg_reg &= (~HWIO_REG_22756_PAGE_SIZE_BMSK); + cfg_reg |= VIDC_SETFIELD(config->page_size, + HWIO_REG_22756_PAGE_SIZE_SHFT, + HWIO_REG_22756_PAGE_SIZE_BMSK); + VIDC_HWIO_OUT(REG_22756, cfg_reg); +} + +void vidc_pix_cache_set_prefetch_page_limit(u32 page_size_limit) +{ + u32 cfg_reg = 0; + + VIDC_HWIO_IN(REG_22756, &cfg_reg); + cfg_reg &= (~HWIO_REG_22756_PAGE_SIZE_BMSK); + cfg_reg |= VIDC_SETFIELD(page_size_limit, + HWIO_REG_22756_PAGE_SIZE_SHFT, + HWIO_REG_22756_PAGE_SIZE_BMSK); + VIDC_HWIO_OUT(REG_22756, cfg_reg); +} + +void vidc_pix_cache_enable_prefetch(u32 prefetch_enable) +{ + u32 cfg_reg = 0; + + VIDC_HWIO_IN(REG_22756, &cfg_reg); + if (prefetch_enable) + cfg_reg |= HWIO_REG_22756_PREFETCH_EN_BMSK; + else + cfg_reg &= (~HWIO_REG_22756_PREFETCH_EN_BMSK); + VIDC_HWIO_OUT(REG_22756, cfg_reg); +} + +void vidc_pix_cache_disable_statistics(u32 statistics_off) +{ + u32 cfg_reg = 0; + + VIDC_HWIO_IN(REG_22756, &cfg_reg); + if (!statistics_off) + cfg_reg |= HWIO_REG_22756_STATISTICS_OFF_BMSK; + else + cfg_reg &= (~HWIO_REG_22756_STATISTICS_OFF_BMSK); + VIDC_HWIO_OUT(REG_22756, cfg_reg); +} + +void vidc_pix_cache_set_port( + enum vidc_1080P_pix_cache_port_sel port_select) +{ + u32 cfg_reg = 0; + + VIDC_HWIO_IN(REG_22756, &cfg_reg); + if (port_select == VIDC_1080P_PIX_CACHE_PORT_A) + cfg_reg &= + (~HWIO_REG_22756_CACHE_PORT_SELECT_BMSK); + else + cfg_reg |= HWIO_REG_22756_CACHE_PORT_SELECT_BMSK; + VIDC_HWIO_OUT(REG_22756, cfg_reg); +} + +void vidc_pix_cache_enable_cache(u32 cache_enable) +{ + u32 cfg_reg = 0; + + VIDC_HWIO_IN(REG_22756, &cfg_reg); + if (cache_enable) + cfg_reg |= HWIO_REG_22756_CACHE_EN_BMSK; + else + cfg_reg &= (~HWIO_REG_22756_CACHE_EN_BMSK); + VIDC_HWIO_OUT(REG_22756, cfg_reg); +} + +void vidc_pix_cache_clear_cache_tags(void) +{ + u32 cfg_reg = 0; + + VIDC_HWIO_IN(REG_22756, &cfg_reg); + cfg_reg |= HWIO_REG_22756_CACHE_TAG_CLEAR_BMSK; + VIDC_HWIO_OUT(REG_22756, cfg_reg); + VIDC_HWIO_IN(REG_22756, &cfg_reg); + cfg_reg &= (~HWIO_REG_22756_CACHE_TAG_CLEAR_BMSK); + VIDC_HWIO_OUT(REG_22756, cfg_reg); +} + +void vidc_pix_cache_set_halt(u32 halt_enable) +{ + u32 cfg_reg = 0; + + VIDC_HWIO_IN(REG_22756, &cfg_reg); + if (halt_enable) + cfg_reg |= HWIO_REG_22756_CACHE_HALT_BMSK; + else + cfg_reg &= (~HWIO_REG_22756_CACHE_HALT_BMSK); + VIDC_HWIO_OUT(REG_22756, cfg_reg); +} + +void vidc_pix_cache_get_status_idle(u32 *idle_status) +{ + VIDC_HWIO_IN(REG_919904, idle_status); +} + +void vidc_pix_cache_set_ram(u32 ram_select) +{ + u32 dmi_cfg_reg = 0; + + VIDC_HWIO_IN(REG_261029, &dmi_cfg_reg); + dmi_cfg_reg &= (~HWIO_REG_261029_DMI_RAM_SEL_BMSK); + dmi_cfg_reg |= VIDC_SETFIELD(ram_select, + HWIO_REG_261029_AUTO_INC_EN_SHFT, + HWIO_REG_261029_DMI_RAM_SEL_BMSK); + VIDC_HWIO_OUT(REG_261029, dmi_cfg_reg); +} + +void vidc_pix_cache_set_auto_inc_ram_addr(u32 auto_inc_enable) +{ + u32 dmi_cfg_reg = 0; + + VIDC_HWIO_IN(REG_261029, &dmi_cfg_reg); + if (auto_inc_enable) + dmi_cfg_reg |= HWIO_REG_261029_AUTO_INC_EN_BMSK; + else + dmi_cfg_reg &= (~HWIO_REG_261029_AUTO_INC_EN_BMSK); + VIDC_HWIO_OUT(REG_261029, dmi_cfg_reg); +} + + +void vidc_pix_cache_read_ram_data(u32 src_ram_address, + u32 ram_size, u32 *dest_address) +{ + u32 count, dmi_cfg_reg = 0; + + VIDC_HWIO_IN(REG_261029, &dmi_cfg_reg); + VIDC_HWIO_OUT(REG_576200, src_ram_address); + vidc_pix_cache_set_auto_inc_ram_addr(1); + for (count = 0; count < ram_size; count++) { + VIDC_HWIO_IN(REG_556274, dest_address); + dest_address++; + VIDC_HWIO_IN(REG_917583, dest_address); + dest_address++; + } + VIDC_HWIO_OUT(REG_261029, dmi_cfg_reg); +} + +void vidc_pix_cache_write_ram_data(u32 *src_address, + u32 ram_size, u32 dest_ram_address) +{ + u32 count, dmi_cfg_reg = 0; + + VIDC_HWIO_IN(REG_261029, &dmi_cfg_reg); + VIDC_HWIO_OUT(REG_576200, dest_ram_address); + vidc_pix_cache_set_auto_inc_ram_addr(1); + for (count = 0; count < ram_size; count++) { + VIDC_HWIO_OUT(REG_917583, *src_address); + src_address++; + VIDC_HWIO_OUT(REG_556274, *src_address); + src_address++; + } + VIDC_HWIO_OUT(REG_261029, dmi_cfg_reg); +} + +void vidc_pix_cache_get_statistics( + struct vidc_1080P_pix_cache_statistics *statistics) +{ + VIDC_HWIO_IN(REG_278310, + &statistics->access_miss); + VIDC_HWIO_IN(REG_421222, + &statistics->access_hit); + VIDC_HWIO_IN(REG_609607, + &statistics->axi_req); + VIDC_HWIO_IN(REG_395232, + &statistics->core_req); + VIDC_HWIO_IN(REG_450146, + &statistics->axi_bus); + VIDC_HWIO_IN(REG_610651, + &statistics->core_bus); +} + +void vidc_pix_cache_enable_misr(u32 misr_enable) +{ + u32 misr_cfg_reg = 0; + + VIDC_HWIO_IN(REG_883784, &misr_cfg_reg); + if (misr_enable) + misr_cfg_reg |= HWIO_REG_883784_MISR_EN_BMSK; + else + misr_cfg_reg &= + (~HWIO_REG_883784_MISR_EN_BMSK); + VIDC_HWIO_OUT(REG_261029, misr_cfg_reg); +} + +void vidc_pix_cache_set_misr_interface(u32 input_select) +{ + u32 misr_cfg_reg = 0; + + VIDC_HWIO_IN(REG_883784, &misr_cfg_reg); + misr_cfg_reg &= (~HWIO_REG_883784_INPUT_SEL_BMSK); + misr_cfg_reg |= VIDC_SETFIELD(input_select, + HWIO_REG_883784_INPUT_SEL_SHFT, + HWIO_REG_883784_INPUT_SEL_BMSK); + VIDC_HWIO_OUT(REG_261029, misr_cfg_reg); +} + +void vidc_pix_cache_set_misr_id_filtering( + struct vidc_1080P_pix_cache_misr_id_filtering *filter_id) +{ + u32 misr_cfg_reg = 0; + + VIDC_HWIO_IN(REG_883784, &misr_cfg_reg); + if (filter_id->ignore_id) + misr_cfg_reg |= + HWIO_REG_883784_IGNORE_ID_BMSK; + else + misr_cfg_reg &= + (~HWIO_REG_883784_IGNORE_ID_BMSK); + misr_cfg_reg &= (~HWIO_REG_883784_ID_BMSK); + misr_cfg_reg |= VIDC_SETFIELD(filter_id->id, + HWIO_REG_883784_ID_SHFT, + HWIO_REG_883784_ID_BMSK); + VIDC_HWIO_OUT(REG_261029, misr_cfg_reg); +} + +void vidc_pix_cache_set_misr_filter_trans(u32 no_of_trans) +{ + u32 misr_cfg_reg = 0; + + VIDC_HWIO_IN(REG_883784, &misr_cfg_reg); + misr_cfg_reg &= (~HWIO_REG_883784_COUNTER_BMSK); + misr_cfg_reg |= VIDC_SETFIELD(no_of_trans, + HWIO_REG_883784_COUNTER_SHFT, + HWIO_REG_883784_COUNTER_BMSK); + VIDC_HWIO_OUT(REG_261029, misr_cfg_reg); +} + +void vidc_pix_cache_get_misr_signatures( + struct vidc_1080P_pix_cache_misr_signature *signatures) +{ + VIDC_HWIO_INI(REG_651391, 0, + &signatures->signature0); + VIDC_HWIO_INI(REG_651391, 1, + &signatures->signature1); +} diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.h b/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.h new file mode 100644 index 000000000000..c70b1131d5d5 --- /dev/null +++ b/drivers/video/msm/vidc/1080p/ddl/vidc_pix_cache.h @@ -0,0 +1,87 @@ +/* Copyright (c) 2010, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#ifndef _VIDEO_CORE_PIXCACHE_ +#define _VIDEO_CORE_PIXCACHE_ + + +#include "vidc.h" + +#define VIDC_1080P_DEC_DPB_RESET_VALUE 0xFFFFFFF8 + +enum vidc_1080P_pix_cache_port_sel{ + VIDC_1080P_PIX_CACHE_PORT_A = 0, + VIDC_1080P_PIX_CACHE_PORT_B = 1, + VIDC_1080P_PIX_CACHE_PORT_32BIT = 0x7FFFFFFF +}; +enum vidc_1080P_pix_cache_page_size{ + VIDC_1080P_PIX_CACHE_PAGE_SIZE_1K = 0, + VIDC_1080P_PIX_CACHE_PAGE_SIZE_2K = 1, + VIDC_1080P_PIX_CACHE_PAGE_SIZE_4K = 2 +}; +struct vidc_1080P_pix_cache_config{ + u32 cache_enable; + u32 prefetch_en; + enum vidc_1080P_pix_cache_port_sel port_select; + u32 statistics_off; + enum vidc_1080P_pix_cache_page_size page_size; +}; +struct vidc_1080P_pix_cache_statistics{ + u32 access_miss; + u32 access_hit; + u32 axi_req; + u32 core_req; + u32 axi_bus; + u32 core_bus; +}; +struct vidc_1080P_pix_cache_misr_id_filtering{ + u32 ignore_id; + u32 id; +}; +struct vidc_1080P_pix_cache_misr_signature{ + u32 signature0; + u32 signature1; +}; + +void vidc_pix_cache_sw_reset(void); +void vidc_pix_cache_init_luma_chroma_base_addr(u32 dpb, + u32 *pn_dpb_luma_offset, u32 *pn_dpb_chroma_offset); +void vidc_pix_cache_set_frame_range(u32 luma_size, u32 chroma_size); +void vidc_pix_cache_set_frame_size(u32 frame_width, u32 frame_height); +void vidc_pix_cache_init_config( + struct vidc_1080P_pix_cache_config *config); +void vidc_pix_cache_set_prefetch_page_limit(u32 page_size_limit); +void vidc_pix_cache_enable_prefetch(u32 prefetch_enable); +void vidc_pix_cache_disable_statistics(u32 statistics_off); +void vidc_pix_cache_set_port( + enum vidc_1080P_pix_cache_port_sel port_select); +void vidc_pix_cache_enable_cache(u32 cache_enable); +void vidc_pix_cache_clear_cache_tags(void); +void vidc_pix_cache_set_halt(u32 halt_enable); +void vidc_pix_cache_get_status_idle(u32 *idle_status); +void vidc_pix_cache_set_ram(u32 ram_select); +void vidc_pix_cache_set_auto_inc_ram_addr(u32 auto_inc_enable); +void vidc_pix_cache_read_ram_data(u32 src_ram_address, u32 ram_size, + u32 *dest_address); +void vidc_pix_cache_write_ram_data(u32 *src_address, u32 ram_size, + u32 dest_ram_address); +void vidc_pix_cache_get_statistics( + struct vidc_1080P_pix_cache_statistics *statistics); +void vidc_pix_cache_enable_misr(u32 misr_enable); +void vidc_pix_cache_set_misr_interface(u32 input_select); +void vidc_pix_cache_set_misr_id_filtering( + struct vidc_1080P_pix_cache_misr_id_filtering *filter_id); +void vidc_pix_cache_set_misr_filter_trans(u32 no_of_trans); +void vidc_pix_cache_get_misr_signatures( + struct vidc_1080P_pix_cache_misr_signature *signatures); +#endif diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c new file mode 100644 index 000000000000..36059520edf8 --- /dev/null +++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c @@ -0,0 +1,1023 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "vidc.h" +#include "vcd_res_tracker.h" + +#define PIL_FW_BASE_ADDR 0x9fe00000 +#define PIL_FW_SIZE 0x200000 + +static unsigned int vidc_clk_table[4] = { + 48000000, 133330000, 200000000, 228570000, +}; +static unsigned int restrk_mmu_subsystem[] = { + MSM_SUBSYSTEM_VIDEO, MSM_SUBSYSTEM_VIDEO_FWARE}; +static struct res_trk_context resource_context; + +#define VIDC_FW "vidc_1080p.fw" +#define VIDC_FW_SIZE SZ_1M + +struct res_trk_vidc_mmu_clk { + char *mmu_clk_name; + struct clk *mmu_clk; +}; + +static struct res_trk_vidc_mmu_clk vidc_mmu_clks[] = { + {"mdp_iommu_clk"}, {"rot_iommu_clk"}, + {"vcodec_iommu0_clk"}, {"vcodec_iommu1_clk"}, + {"smmu_iface_clk"} +}; + +unsigned char *vidc_video_codec_fw; +u32 vidc_video_codec_fw_size; +static u32 res_trk_get_clk(void); +static void res_trk_put_clk(void); + +static void *res_trk_pmem_map + (struct ddl_buf_addr *addr, size_t sz, u32 alignment) +{ + u32 offset = 0, flags = 0; + u32 index = 0; + struct ddl_context *ddl_context; + struct msm_mapped_buffer *mapped_buffer = NULL; + int ret = 0; + unsigned long iova = 0; + unsigned long buffer_size = 0; + unsigned long *kernel_vaddr = NULL; + + ddl_context = ddl_get_context(); + if (res_trk_get_enable_ion() && addr->alloc_handle) { + kernel_vaddr = (unsigned long *) ion_map_kernel( + ddl_context->video_ion_client, + addr->alloc_handle, UNCACHED); + if (IS_ERR_OR_NULL(kernel_vaddr)) { + DDL_MSG_ERROR("%s():DDL ION client map failed\n", + __func__); + goto ion_bail_out; + } + addr->virtual_base_addr = (u8 *) kernel_vaddr; + ret = ion_map_iommu(ddl_context->video_ion_client, + addr->alloc_handle, + VIDEO_DOMAIN, + VIDEO_FIRMWARE_POOL, + SZ_4K, + 0, + &iova, + &buffer_size, + UNCACHED, 0); + if (ret) { + DDL_MSG_ERROR("%s():DDL ION client iommu map failed\n", + __func__); + goto ion_unmap_bail_out; + } + addr->mapped_buffer = NULL; + addr->physical_base_addr = (u8 *)iova; + addr->align_physical_addr = (u8 *) DDL_ALIGN((u32) + addr->physical_base_addr, alignment); + offset = (u32)(addr->align_physical_addr - + addr->physical_base_addr); + addr->align_virtual_addr = addr->virtual_base_addr + offset; + addr->buffer_size = buffer_size; + } else { + if (!res_trk_check_for_sec_session()) { + if (!addr->alloced_phys_addr) { + pr_err(" %s() alloced addres NULL", __func__); + goto bail_out; + } + flags = MSM_SUBSYSTEM_MAP_IOVA | + MSM_SUBSYSTEM_MAP_KADDR; + if (alignment == DDL_KILO_BYTE(128)) + index = 1; + else if (alignment > SZ_4K) + flags |= MSM_SUBSYSTEM_ALIGN_IOVA_8K; + addr->mapped_buffer = + msm_subsystem_map_buffer( + (unsigned long)addr->alloced_phys_addr, + sz, flags, &restrk_mmu_subsystem[index], + sizeof(restrk_mmu_subsystem[index])/ + sizeof(unsigned int)); + if (IS_ERR(addr->mapped_buffer)) { + pr_err(" %s() buffer map failed", __func__); + goto bail_out; + } + mapped_buffer = addr->mapped_buffer; + if (!mapped_buffer->vaddr || !mapped_buffer->iova[0]) { + pr_err("%s() map buffers failed\n", __func__); + goto bail_out; + } + addr->physical_base_addr = + (u8 *)mapped_buffer->iova[0]; + addr->virtual_base_addr = + mapped_buffer->vaddr; + } else { + addr->physical_base_addr = + (u8 *) addr->alloced_phys_addr; + addr->virtual_base_addr = + (u8 *)addr->alloced_phys_addr; + } + addr->align_physical_addr = (u8 *) DDL_ALIGN((u32) + addr->physical_base_addr, alignment); + offset = (u32)(addr->align_physical_addr - + addr->physical_base_addr); + addr->align_virtual_addr = addr->virtual_base_addr + offset; + addr->buffer_size = sz; + } + return addr->virtual_base_addr; +bail_out: + if (IS_ERR(addr->mapped_buffer)) + msm_subsystem_unmap_buffer(addr->mapped_buffer); + return NULL; +ion_unmap_bail_out: + if (!IS_ERR_OR_NULL(addr->alloc_handle)) { + ion_unmap_kernel(resource_context. + res_ion_client, addr->alloc_handle); + } +ion_bail_out: + return NULL; +} + +static void res_trk_pmem_free(struct ddl_buf_addr *addr) +{ + struct ddl_context *ddl_context; + ddl_context = ddl_get_context(); + if (ddl_context->video_ion_client) { + if (addr && addr->alloc_handle) { + ion_free(ddl_context->video_ion_client, + addr->alloc_handle); + addr->alloc_handle = NULL; + } + } else { + if (addr->mapped_buffer) + msm_subsystem_unmap_buffer(addr->mapped_buffer); + if (addr->alloced_phys_addr) + free_contiguous_memory_by_paddr( + (unsigned long)addr->alloced_phys_addr); + } + memset(addr, 0 , sizeof(struct ddl_buf_addr)); +} +static int res_trk_pmem_alloc + (struct ddl_buf_addr *addr, size_t sz, u32 alignment) +{ + u32 alloc_size; + struct ddl_context *ddl_context; + int rc = 0; + DBG_PMEM("\n%s() IN: Requested alloc size(%u)", __func__, (u32)sz); + if (!addr) { + DDL_MSG_ERROR("\n%s() Invalid Parameters", __func__); + rc = -EINVAL; + goto bail_out; + } + ddl_context = ddl_get_context(); + res_trk_set_mem_type(addr->mem_type); + alloc_size = (sz + alignment); + if (res_trk_get_enable_ion()) { + if (!res_trk_is_cp_enabled() || + !res_trk_check_for_sec_session()) { + if (!ddl_context->video_ion_client) + ddl_context->video_ion_client = + res_trk_get_ion_client(); + if (!ddl_context->video_ion_client) { + DDL_MSG_ERROR( + "%s() :DDL ION Client Invalid handle\n", + __func__); + rc = -ENOMEM; + goto bail_out; + } + alloc_size = (alloc_size+4095) & ~4095; + addr->alloc_handle = ion_alloc( + ddl_context->video_ion_client, + alloc_size, SZ_4K, + res_trk_get_mem_type()); + if (IS_ERR_OR_NULL(addr->alloc_handle)) { + DDL_MSG_ERROR("%s() :DDL ION alloc failed\n", + __func__); + rc = -ENOMEM; + goto bail_out; + } + } else { + addr->alloc_handle = NULL; + addr->alloced_phys_addr = PIL_FW_BASE_ADDR; + addr->buffer_size = sz; + } + } else { + addr->alloced_phys_addr = (phys_addr_t) + allocate_contiguous_memory_nomap(alloc_size, + res_trk_get_mem_type(), SZ_4K); + if (!addr->alloced_phys_addr) { + DDL_MSG_ERROR("%s() : acm alloc failed (%d)\n", + __func__, alloc_size); + rc = -ENOMEM; + goto bail_out; + } + addr->buffer_size = sz; + return rc; + } +bail_out: + return rc; +} + +static void res_trk_pmem_unmap(struct ddl_buf_addr *addr) +{ + if (!addr) { + pr_err("%s() invalid args\n", __func__); + return; + } + if (!IS_ERR_OR_NULL(addr->alloc_handle)) { + if (addr->physical_base_addr) { + ion_unmap_kernel(resource_context.res_ion_client, + addr->alloc_handle); + if (!res_trk_check_for_sec_session()) { + ion_unmap_iommu(resource_context.res_ion_client, + addr->alloc_handle, + VIDEO_DOMAIN, + VIDEO_FIRMWARE_POOL); + } + addr->virtual_base_addr = NULL; + addr->physical_base_addr = NULL; + } + } else if (addr->mapped_buffer) + msm_subsystem_unmap_buffer(addr->mapped_buffer); + addr->mapped_buffer = NULL; +} + +static u32 res_trk_get_clk() +{ + if (resource_context.vcodec_clk || + resource_context.vcodec_pclk) { + VCDRES_MSG_ERROR("%s() Clock reference exists\n", + __func__); + goto bail_out; + } + resource_context.vcodec_clk = clk_get(resource_context.device, + "core_clk"); + if (IS_ERR(resource_context.vcodec_clk)) { + VCDRES_MSG_ERROR("%s(): core_clk get failed\n", + __func__); + goto bail_out; + } + resource_context.vcodec_pclk = clk_get(resource_context.device, + "iface_clk"); + if (IS_ERR(resource_context.vcodec_pclk)) { + VCDRES_MSG_ERROR("%s(): iface_clk get failed\n", + __func__); + goto release_vcodec_clk; + } + if (clk_set_rate(resource_context.vcodec_clk, + vidc_clk_table[0])) { + VCDRES_MSG_ERROR("%s(): set rate failed in power up\n", + __func__); + goto release_vcodec_pclk; + } + return true; +release_vcodec_pclk: + clk_put(resource_context.vcodec_pclk); + resource_context.vcodec_pclk = NULL; +release_vcodec_clk: + clk_put(resource_context.vcodec_clk); + resource_context.vcodec_clk = NULL; +bail_out: + return false; +} + +static void res_trk_put_clk() +{ + if (resource_context.vcodec_clk) + clk_put(resource_context.vcodec_clk); + if (resource_context.vcodec_pclk) + clk_put(resource_context.vcodec_pclk); + resource_context.vcodec_clk = NULL; + resource_context.vcodec_pclk = NULL; +} + +static u32 res_trk_shutdown_vidc(void) +{ + mutex_lock(&resource_context.lock); + if (resource_context.clock_enabled) { + mutex_unlock(&resource_context.lock); + VCDRES_MSG_LOW("\n Calling CLK disable in Power Down\n"); + res_trk_disable_clocks(); + mutex_lock(&resource_context.lock); + } + res_trk_put_clk(); + if (resource_context.footswitch) { + if (regulator_disable(resource_context.footswitch)) + VCDRES_MSG_ERROR("Regulator disable failed\n"); + regulator_put(resource_context.footswitch); + resource_context.footswitch = NULL; + } + if (pm_runtime_put(resource_context.device) < 0) + VCDRES_MSG_ERROR("Error : pm_runtime_put failed"); + mutex_unlock(&resource_context.lock); + return true; +} + +u32 res_trk_enable_clocks(void) +{ + VCDRES_MSG_LOW("\n in res_trk_enable_clocks()"); + mutex_lock(&resource_context.lock); + if (!resource_context.clock_enabled) { + VCDRES_MSG_LOW("Enabling IRQ in %s()\n", __func__); + enable_irq(resource_context.irq_num); + VCDRES_MSG_LOW("%s(): Enabling the clocks\n", __func__); + if (resource_context.vcodec_clk && + resource_context.vcodec_pclk) { + if (clk_prepare_enable(resource_context.vcodec_pclk)) { + VCDRES_MSG_ERROR("vidc pclk Enable fail\n"); + goto bail_out; + } + if (clk_prepare_enable(resource_context.vcodec_clk)) { + VCDRES_MSG_ERROR("vidc core clk Enable fail\n"); + goto vidc_disable_pclk; + } + + VCDRES_MSG_LOW("%s(): Clocks enabled!\n", __func__); + } else { + VCDRES_MSG_ERROR("%s(): Clocks enable failed!\n", + __func__); + goto bail_out; + } + } + resource_context.clock_enabled = 1; + mutex_unlock(&resource_context.lock); + return true; +vidc_disable_pclk: + clk_disable_unprepare(resource_context.vcodec_pclk); +bail_out: + mutex_unlock(&resource_context.lock); + return false; +} + +static u32 res_trk_sel_clk_rate(unsigned long hclk_rate) +{ + u32 status = true; + mutex_lock(&resource_context.lock); + if (clk_set_rate(resource_context.vcodec_clk, + hclk_rate)) { + VCDRES_MSG_ERROR("vidc hclk set rate failed\n"); + status = false; + } else + resource_context.vcodec_clk_rate = hclk_rate; + mutex_unlock(&resource_context.lock); + return status; +} + +u32 res_trk_get_clk_rate(unsigned long *phclk_rate) +{ + u32 status = true; + mutex_lock(&resource_context.lock); + if (phclk_rate) { + *phclk_rate = clk_get_rate(resource_context.vcodec_clk); + if (!(*phclk_rate)) { + VCDRES_MSG_ERROR("vidc hclk get rate failed\n"); + status = false; + } + } else + status = false; + mutex_unlock(&resource_context.lock); + return status; +} + +u32 res_trk_disable_clocks(void) +{ + u32 status = false; + VCDRES_MSG_LOW("in res_trk_disable_clocks()\n"); + mutex_lock(&resource_context.lock); + if (resource_context.clock_enabled) { + VCDRES_MSG_LOW("Disabling IRQ in %s()\n", __func__); + disable_irq_nosync(resource_context.irq_num); + VCDRES_MSG_LOW("%s(): Disabling the clocks ...\n", __func__); + resource_context.clock_enabled = 0; + if (resource_context.vcodec_clk) + clk_disable_unprepare(resource_context.vcodec_clk); + if (resource_context.vcodec_pclk) + clk_disable_unprepare(resource_context.vcodec_pclk); + status = true; + } + mutex_unlock(&resource_context.lock); + return status; +} + +static u32 res_trk_vidc_pwr_up(void) +{ + mutex_lock(&resource_context.lock); + + if (pm_runtime_get(resource_context.device) < 0) { + VCDRES_MSG_ERROR("Error : pm_runtime_get failed\n"); + goto bail_out; + } + if (!resource_context.footswitch) + resource_context.footswitch = + regulator_get(resource_context.device, "vdd"); + if (IS_ERR(resource_context.footswitch)) { + VCDRES_MSG_ERROR("foot switch get failed\n"); + resource_context.footswitch = NULL; + } else + regulator_enable(resource_context.footswitch); + if (!res_trk_get_clk()) + goto rel_vidc_pm_runtime; + mutex_unlock(&resource_context.lock); + return true; + +rel_vidc_pm_runtime: + if (pm_runtime_put(resource_context.device) < 0) + VCDRES_MSG_ERROR("Error : pm_runtime_put failed"); +bail_out: + mutex_unlock(&resource_context.lock); + return false; +} + +static struct ion_client *res_trk_create_ion_client(void){ + struct ion_client *video_client; + video_client = msm_ion_client_create(-1, "video_client"); + return video_client; +} + +int res_trk_enable_footswitch(void) +{ + int rc = 0; + mutex_lock(&resource_context.lock); + if (!resource_context.footswitch) + resource_context.footswitch = regulator_get(NULL, "fs_ved"); + if (IS_ERR(resource_context.footswitch)) { + VCDRES_MSG_ERROR("foot switch get failed\n"); + resource_context.footswitch = NULL; + rc = -EINVAL; + } else + rc = regulator_enable(resource_context.footswitch); + mutex_unlock(&resource_context.lock); + return rc; +} + +int res_trk_disable_footswitch(void) +{ + mutex_lock(&resource_context.lock); + if (resource_context.footswitch) { + if (regulator_disable(resource_context.footswitch)) + VCDRES_MSG_ERROR("Regulator disable failed\n"); + regulator_put(resource_context.footswitch); + resource_context.footswitch = NULL; + } + mutex_unlock(&resource_context.lock); + return 0; +} + +u32 res_trk_power_up(void) +{ + VCDRES_MSG_LOW("clk_regime_rail_enable"); + VCDRES_MSG_LOW("clk_regime_sel_rail_control"); +#ifdef CONFIG_MSM_BUS_SCALING + resource_context.pcl = 0; + if (resource_context.vidc_bus_client_pdata) { + resource_context.pcl = msm_bus_scale_register_client( + resource_context.vidc_bus_client_pdata); + VCDRES_MSG_LOW("%s(), resource_context.pcl = %x", __func__, + resource_context.pcl); + } + if (resource_context.pcl == 0) { + dev_err(resource_context.device, + "register bus client returned NULL\n"); + return false; + } +#endif + return res_trk_vidc_pwr_up(); +} + +u32 res_trk_power_down(void) +{ + VCDRES_MSG_LOW("clk_regime_rail_disable"); + res_trk_pmem_unmap(&resource_context.firmware_addr); + res_trk_pmem_free(&resource_context.firmware_addr); +#ifdef CONFIG_MSM_BUS_SCALING + msm_bus_scale_client_update_request(resource_context.pcl, 0); + msm_bus_scale_unregister_client(resource_context.pcl); +#endif + VCDRES_MSG_MED("res_trk_power_down():: Calling " + "res_trk_shutdown_vidc()\n"); + return res_trk_shutdown_vidc(); +} + +u32 res_trk_get_max_perf_level(u32 *pn_max_perf_lvl) +{ + if (!pn_max_perf_lvl) { + VCDRES_MSG_ERROR("%s(): pn_max_perf_lvl is NULL\n", + __func__); + return false; + } + *pn_max_perf_lvl = RESTRK_1080P_MAX_PERF_LEVEL; + return true; +} + +#ifdef CONFIG_MSM_BUS_SCALING +int res_trk_update_bus_perf_level(struct vcd_dev_ctxt *dev_ctxt, u32 perf_level) +{ + struct vcd_clnt_ctxt *cctxt_itr = NULL; + u32 enc_perf_level = 0, dec_perf_level = 0; + u32 bus_clk_index, client_type = 0; + int rc = 0; + + cctxt_itr = dev_ctxt->cctxt_list_head; + while (cctxt_itr) { + if (cctxt_itr->decoding) + dec_perf_level += cctxt_itr->reqd_perf_lvl; + else + enc_perf_level += cctxt_itr->reqd_perf_lvl; + cctxt_itr = cctxt_itr->next; + } + + if (!enc_perf_level) + client_type = 1; + if (perf_level <= RESTRK_1080P_VGA_PERF_LEVEL) + bus_clk_index = 0; + else if (perf_level <= RESTRK_1080P_720P_PERF_LEVEL) + bus_clk_index = 1; + else if (perf_level <= RESTRK_1080P_MAX_PERF_LEVEL) + bus_clk_index = 2; + else + bus_clk_index = 3; + + if (dev_ctxt->reqd_perf_lvl + dev_ctxt->curr_perf_lvl == 0) + bus_clk_index = 2; + else if (resource_context.vidc_platform_data->disable_turbo + && bus_clk_index == 3) { + VCDRES_MSG_ERROR("Warning: Turbo mode not supported " + " falling back to 1080p bus\n"); + bus_clk_index = 2; + } + + bus_clk_index = (bus_clk_index << 1) + (client_type + 1); + VCDRES_MSG_LOW("%s(), bus_clk_index = %d", __func__, bus_clk_index); + VCDRES_MSG_LOW("%s(),context.pcl = %x", __func__, resource_context.pcl); + VCDRES_MSG_LOW("%s(), bus_perf_level = %x", __func__, perf_level); + rc = msm_bus_scale_client_update_request(resource_context.pcl, + bus_clk_index); + return rc; +} +#endif + +u32 res_trk_set_perf_level(u32 req_perf_lvl, u32 *pn_set_perf_lvl, + struct vcd_dev_ctxt *dev_ctxt) +{ + u32 vidc_freq = 0; + if (!pn_set_perf_lvl || !dev_ctxt) { + VCDRES_MSG_ERROR("%s(): NULL pointer! dev_ctxt(%p)\n", + __func__, dev_ctxt); + return false; + } + VCDRES_MSG_LOW("%s(), req_perf_lvl = %d", __func__, req_perf_lvl); + + if (resource_context.vidc_platform_data->disable_turbo + && req_perf_lvl > RESTRK_1080P_MAX_PERF_LEVEL) { + VCDRES_MSG_ERROR("%s(): Turbo not supported! dev_ctxt(%p)\n", + __func__, dev_ctxt); + } + +#ifdef CONFIG_MSM_BUS_SCALING + if (!res_trk_update_bus_perf_level(dev_ctxt, req_perf_lvl) < 0) { + VCDRES_MSG_ERROR("%s(): update buf perf level failed\n", + __func__); + return false; + } + +#endif + if (dev_ctxt->reqd_perf_lvl + dev_ctxt->curr_perf_lvl == 0) + req_perf_lvl = RESTRK_1080P_MAX_PERF_LEVEL; + + if (req_perf_lvl <= RESTRK_1080P_VGA_PERF_LEVEL) { + vidc_freq = vidc_clk_table[0]; + *pn_set_perf_lvl = RESTRK_1080P_VGA_PERF_LEVEL; + } else if (req_perf_lvl <= RESTRK_1080P_720P_PERF_LEVEL) { + vidc_freq = vidc_clk_table[1]; + *pn_set_perf_lvl = RESTRK_1080P_720P_PERF_LEVEL; + } else if (req_perf_lvl <= RESTRK_1080P_MAX_PERF_LEVEL) { + vidc_freq = vidc_clk_table[2]; + *pn_set_perf_lvl = RESTRK_1080P_MAX_PERF_LEVEL; + } else { + vidc_freq = vidc_clk_table[3]; + *pn_set_perf_lvl = RESTRK_1080P_TURBO_PERF_LEVEL; + } + + if (resource_context.vidc_platform_data->disable_turbo && + *pn_set_perf_lvl == RESTRK_1080P_TURBO_PERF_LEVEL) { + VCDRES_MSG_ERROR("Warning: Turbo mode not supported " + " falling back to 1080p clocks\n"); + vidc_freq = vidc_clk_table[2]; + *pn_set_perf_lvl = RESTRK_1080P_MAX_PERF_LEVEL; + } + + resource_context.perf_level = *pn_set_perf_lvl; + VCDRES_MSG_MED("VIDC: vidc_freq = %u, req_perf_lvl = %u\n", + vidc_freq, req_perf_lvl); +#ifdef USE_RES_TRACKER + if (req_perf_lvl != RESTRK_1080P_MIN_PERF_LEVEL) { + VCDRES_MSG_MED("%s(): Setting vidc freq to %u\n", + __func__, vidc_freq); + if (!res_trk_sel_clk_rate(vidc_freq)) { + VCDRES_MSG_ERROR("%s(): res_trk_sel_clk_rate FAILED\n", + __func__); + *pn_set_perf_lvl = 0; + return false; + } + } +#endif + VCDRES_MSG_MED("%s() set perl level : %d", __func__, *pn_set_perf_lvl); + return true; +} + +u32 res_trk_get_curr_perf_level(u32 *pn_perf_lvl) +{ + unsigned long freq; + + if (!pn_perf_lvl) { + VCDRES_MSG_ERROR("%s(): pn_perf_lvl is NULL\n", + __func__); + return false; + } + VCDRES_MSG_LOW("clk_regime_msm_get_clk_freq_hz"); + if (!res_trk_get_clk_rate(&freq)) { + VCDRES_MSG_ERROR("%s(): res_trk_get_clk_rate FAILED\n", + __func__); + *pn_perf_lvl = 0; + return false; + } + *pn_perf_lvl = resource_context.perf_level; + VCDRES_MSG_MED("%s(): freq = %lu, *pn_perf_lvl = %u", __func__, + freq, *pn_perf_lvl); + return true; +} + +u32 res_trk_download_firmware(void) +{ + const struct firmware *fw_video = NULL; + int rc = 0; + u32 status = true; + + VCDRES_MSG_HIGH("%s(): Request firmware download\n", + __func__); + mutex_lock(&resource_context.lock); + rc = request_firmware(&fw_video, VIDC_FW, + resource_context.device); + if (rc) { + VCDRES_MSG_ERROR("request_firmware for %s error %d\n", + VIDC_FW, rc); + status = false; + goto bail_out; + } + vidc_video_codec_fw = (unsigned char *)fw_video->data; + vidc_video_codec_fw_size = (u32) fw_video->size; +bail_out: + mutex_unlock(&resource_context.lock); + return status; +} + +void res_trk_init(struct device *device, u32 irq) +{ + if (resource_context.device || resource_context.irq_num || + !device) { + VCDRES_MSG_ERROR("%s() Resource Tracker Init error\n", + __func__); + } else { + memset(&resource_context, 0, sizeof(resource_context)); + mutex_init(&resource_context.lock); + mutex_init(&resource_context.secure_lock); + resource_context.device = device; + resource_context.irq_num = irq; + resource_context.vidc_platform_data = + (struct msm_vidc_platform_data *) device->platform_data; + if (resource_context.vidc_platform_data) { + resource_context.memtype = + resource_context.vidc_platform_data->memtype; + resource_context.fw_mem_type = + resource_context.vidc_platform_data->memtype; + resource_context.cmd_mem_type = + resource_context.vidc_platform_data->memtype; + if (resource_context.vidc_platform_data->enable_ion) { + resource_context.res_ion_client = + res_trk_create_ion_client(); + if (!(resource_context.res_ion_client)) { + VCDRES_MSG_ERROR("%s()ION createfail\n", + __func__); + return; + } + resource_context.fw_mem_type = + ION_MM_FIRMWARE_HEAP_ID; + resource_context.cmd_mem_type = + ION_CP_MFC_HEAP_ID; + } + resource_context.disable_dmx = + resource_context.vidc_platform_data->disable_dmx; + resource_context.disable_fullhd = + resource_context.vidc_platform_data->disable_fullhd; +#ifdef CONFIG_MSM_BUS_SCALING + resource_context.vidc_bus_client_pdata = + resource_context.vidc_platform_data-> + vidc_bus_client_pdata; +#endif + } else { + resource_context.memtype = -1; + resource_context.disable_dmx = 0; + } + resource_context.core_type = VCD_CORE_1080P; + resource_context.firmware_addr.mem_type = DDL_FW_MEM; + } +} + +u32 res_trk_get_core_type(void){ + return resource_context.core_type; +} + +u32 res_trk_get_firmware_addr(struct ddl_buf_addr *firm_addr) +{ + int rc = 0; + size_t size = 0; + if (!firm_addr || resource_context.firmware_addr.mapped_buffer) { + pr_err("%s() invalid params", __func__); + return -EINVAL; + } + if (res_trk_is_cp_enabled() && res_trk_check_for_sec_session()) + size = PIL_FW_SIZE; + else + size = VIDC_FW_SIZE; + + if (res_trk_pmem_alloc(&resource_context.firmware_addr, + size, DDL_KILO_BYTE(128))) { + pr_err("%s() Firmware buffer allocation failed", + __func__); + memset(&resource_context.firmware_addr, 0, + sizeof(resource_context.firmware_addr)); + rc = -ENOMEM; + goto fail_alloc; + } + if (!res_trk_pmem_map(&resource_context.firmware_addr, + resource_context.firmware_addr.buffer_size, + DDL_KILO_BYTE(128))) { + pr_err("%s() Firmware buffer mapping failed", + __func__); + rc = -ENOMEM; + goto fail_map; + } + memcpy(firm_addr, &resource_context.firmware_addr, + sizeof(struct ddl_buf_addr)); + return 0; +fail_map: + res_trk_pmem_free(&resource_context.firmware_addr); +fail_alloc: + return rc; +} + +void res_trk_release_fw_addr(void) +{ + res_trk_pmem_unmap(&resource_context.firmware_addr); + res_trk_pmem_free(&resource_context.firmware_addr); +} + +int res_trk_check_for_sec_session(void) +{ + int rc; + mutex_lock(&resource_context.secure_lock); + rc = resource_context.secure_session; + mutex_unlock(&resource_context.secure_lock); + return rc; +} + +int res_trk_get_mem_type(void) +{ + int mem_type = -1; + switch (resource_context.res_mem_type) { + case DDL_FW_MEM: + mem_type = ION_HEAP(resource_context.fw_mem_type); + return mem_type; + case DDL_MM_MEM: + mem_type = resource_context.memtype; + break; + case DDL_CMD_MEM: + if (res_trk_check_for_sec_session()) + mem_type = resource_context.cmd_mem_type; + else + mem_type = resource_context.memtype; + break; + default: + return mem_type; + } + if (resource_context.vidc_platform_data->enable_ion) { + if (res_trk_check_for_sec_session()) { + mem_type = ION_HEAP(mem_type); + if (resource_context.res_mem_type != DDL_FW_MEM) + mem_type |= ION_SECURE; + else if (res_trk_is_cp_enabled()) + mem_type |= ION_SECURE; + } else + mem_type = (ION_HEAP(mem_type) | + ION_HEAP(ION_IOMMU_HEAP_ID)); + } + return mem_type; +} + +u32 res_trk_is_cp_enabled(void) +{ + if (resource_context.vidc_platform_data->cp_enabled) + return 1; + else + return 0; +} + +u32 res_trk_get_enable_ion(void) +{ + if (resource_context.vidc_platform_data->enable_ion) + return 1; + else + return 0; +} + +struct ion_client *res_trk_get_ion_client(void) +{ + return resource_context.res_ion_client; +} + +u32 res_trk_get_disable_dmx(void){ + return resource_context.disable_dmx; +} + +u32 res_trk_get_min_dpb_count(void){ + return resource_context.vidc_platform_data->cont_mode_dpb_count; +} + +void res_trk_set_mem_type(enum ddl_mem_area mem_type) +{ + resource_context.res_mem_type = mem_type; + return; +} + +u32 res_trk_get_disable_fullhd(void) +{ + return resource_context.disable_fullhd; +} + +int res_trk_enable_iommu_clocks(void) +{ + int ret = 0, i; + if (resource_context.mmu_clks_on) { + pr_err(" %s: Clocks are already on", __func__); + return -EINVAL; + } + resource_context.mmu_clks_on = 1; + for (i = 0; i < ARRAY_SIZE(vidc_mmu_clks); i++) { + vidc_mmu_clks[i].mmu_clk = clk_get(resource_context.device, + vidc_mmu_clks[i].mmu_clk_name); + if (IS_ERR(vidc_mmu_clks[i].mmu_clk)) { + pr_err(" %s: Get failed for clk %s", __func__, + vidc_mmu_clks[i].mmu_clk_name); + ret = PTR_ERR(vidc_mmu_clks[i].mmu_clk); + } + if (!ret) { + ret = clk_prepare_enable(vidc_mmu_clks[i].mmu_clk); + if (ret) { + clk_put(vidc_mmu_clks[i].mmu_clk); + vidc_mmu_clks[i].mmu_clk = NULL; + } + } + if (ret) { + for (i--; i >= 0; i--) { + clk_disable_unprepare(vidc_mmu_clks[i].mmu_clk); + clk_put(vidc_mmu_clks[i].mmu_clk); + vidc_mmu_clks[i].mmu_clk = NULL; + } + resource_context.mmu_clks_on = 0; + pr_err("%s() clocks enable failed", __func__); + break; + } + } + return ret; +} + +int res_trk_disable_iommu_clocks(void) +{ + int i; + if (!resource_context.mmu_clks_on) { + pr_err(" %s: clks are already off", __func__); + return -EINVAL; + } + resource_context.mmu_clks_on = 0; + for (i = 0; i < ARRAY_SIZE(vidc_mmu_clks); i++) { + clk_disable_unprepare(vidc_mmu_clks[i].mmu_clk); + clk_put(vidc_mmu_clks[i].mmu_clk); + vidc_mmu_clks[i].mmu_clk = NULL; + } + return 0; +} + +void res_trk_secure_unset(void) +{ + mutex_lock(&resource_context.secure_lock); + resource_context.secure_session--; + mutex_unlock(&resource_context.secure_lock); +} + +void res_trk_secure_set(void) +{ + mutex_lock(&resource_context.secure_lock); + resource_context.secure_session++; + mutex_unlock(&resource_context.secure_lock); +} + +int res_trk_open_secure_session() +{ + int rc; + + if (res_trk_check_for_sec_session() == 1) { + mutex_lock(&resource_context.secure_lock); + pr_err("Securing...\n"); + rc = res_trk_enable_iommu_clocks(); + if (rc) { + pr_err("IOMMU clock enabled failed while open"); + goto error_open; + } + msm_ion_secure_heap(ION_HEAP(resource_context.memtype)); + msm_ion_secure_heap(ION_HEAP(resource_context.cmd_mem_type)); + res_trk_disable_iommu_clocks(); + mutex_unlock(&resource_context.secure_lock); + } + return 0; +error_open: + mutex_unlock(&resource_context.secure_lock); + return rc; +} + +int res_trk_close_secure_session() +{ + int rc; + if (res_trk_check_for_sec_session() == 1) { + pr_err("Unsecuring....\n"); + mutex_lock(&resource_context.secure_lock); + rc = res_trk_enable_iommu_clocks(); + if (rc) { + pr_err("IOMMU clock enabled failed while close"); + goto error_close; + } + msm_ion_unsecure_heap(ION_HEAP(resource_context.cmd_mem_type)); + msm_ion_unsecure_heap(ION_HEAP(resource_context.memtype)); + res_trk_disable_iommu_clocks(); + mutex_unlock(&resource_context.secure_lock); + } + return 0; +error_close: + mutex_unlock(&resource_context.secure_lock); + return rc; +} + +u32 get_res_trk_perf_level(enum vcd_perf_level perf_level) +{ + u32 res_trk_perf_level; + switch (perf_level) { + case VCD_PERF_LEVEL0: + res_trk_perf_level = RESTRK_1080P_VGA_PERF_LEVEL; + break; + case VCD_PERF_LEVEL1: + res_trk_perf_level = RESTRK_1080P_720P_PERF_LEVEL; + break; + case VCD_PERF_LEVEL2: + res_trk_perf_level = RESTRK_1080P_MAX_PERF_LEVEL; + break; + case VCD_PERF_LEVEL_TURBO: + res_trk_perf_level = RESTRK_1080P_TURBO_PERF_LEVEL; + break; + default: + VCD_MSG_ERROR("Invalid perf level: %d\n", perf_level); + res_trk_perf_level = -EINVAL; + } + return res_trk_perf_level; +} + +u32 res_trk_estimate_perf_level(u32 pn_perf_lvl) +{ + VCDRES_MSG_MED("%s(), req_perf_lvl = %d", __func__, pn_perf_lvl); + if ((pn_perf_lvl >= RESTRK_1080P_VGA_PERF_LEVEL) && + (pn_perf_lvl < RESTRK_1080P_720P_PERF_LEVEL)) { + return RESTRK_1080P_720P_PERF_LEVEL; + } else if ((pn_perf_lvl >= RESTRK_1080P_720P_PERF_LEVEL) && + (pn_perf_lvl < RESTRK_1080P_MAX_PERF_LEVEL)) { + return RESTRK_1080P_MAX_PERF_LEVEL; + } else { + return pn_perf_lvl; + } +} diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h new file mode 100644 index 000000000000..ff0411a1da7f --- /dev/null +++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h @@ -0,0 +1,78 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#ifndef _VIDEO_720P_RESOURCE_TRACKER_H_ +#define _VIDEO_720P_RESOURCE_TRACKER_H_ + +#include +#include +#include "vcd_res_tracker_api.h" +#ifdef CONFIG_MSM_BUS_SCALING +#include +#include +#endif +#include + +#define RESTRK_1080P_VGA_PERF_LEVEL VCD_MIN_PERF_LEVEL +#define RESTRK_1080P_720P_PERF_LEVEL 108000 +#define RESTRK_1080P_1080P_PERF_LEVEL 244800 + +#define RESTRK_1080P_MIN_PERF_LEVEL RESTRK_1080P_VGA_PERF_LEVEL +#define RESTRK_1080P_MAX_PERF_LEVEL RESTRK_1080P_1080P_PERF_LEVEL +#define RESTRK_1080P_TURBO_PERF_LEVEL (RESTRK_1080P_MAX_PERF_LEVEL + 1) + +struct res_trk_context { + struct device *device; + u32 irq_num; + struct mutex lock; + struct clk *vcodec_clk; + struct clk *vcodec_pclk; + unsigned long vcodec_clk_rate; + unsigned int clock_enabled; + unsigned int perf_level; + struct regulator *footswitch; + struct msm_vidc_platform_data *vidc_platform_data; + int memtype; + int fw_mem_type; + int cmd_mem_type; +#ifdef CONFIG_MSM_BUS_SCALING + struct msm_bus_scale_pdata *vidc_bus_client_pdata; + uint32_t pcl; +#endif + u32 core_type; + struct ddl_buf_addr firmware_addr; + struct ion_client *res_ion_client; + u32 disable_dmx; + u32 disable_fullhd; + enum ddl_mem_area res_mem_type; + u32 mmu_clks_on; + u32 secure_session; + struct mutex secure_lock; +}; + +#if DEBUG + +#define VCDRES_MSG_LOW(xx_fmt...) printk(KERN_INFO "\n\t* " xx_fmt) +#define VCDRES_MSG_MED(xx_fmt...) printk(KERN_INFO "\n * " xx_fmt) + +#else + +#define VCDRES_MSG_LOW(xx_fmt...) +#define VCDRES_MSG_MED(xx_fmt...) + +#endif + +#define VCDRES_MSG_HIGH(xx_fmt...) printk(KERN_WARNING "\n" xx_fmt) +#define VCDRES_MSG_ERROR(xx_fmt...) printk(KERN_ERR "\n err: " xx_fmt) +#define VCDRES_MSG_FATAL(xx_fmt...) printk(KERN_ERR "\n " xx_fmt) + +#endif diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h new file mode 100644 index 000000000000..26c20c502615 --- /dev/null +++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h @@ -0,0 +1,53 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#ifndef _VIDEO_720P_RESOURCE_TRACKER_API_H_ +#define _VIDEO_720P_RESOURCE_TRACKER_API_H_ + +#include "vcd_core.h" +#include "vcd_ddl.h" +#include "vcd_ddl_utils.h" + +void res_trk_init(struct device *device, u32 irq); +u32 res_trk_power_up(void); +u32 res_trk_power_down(void); +u32 res_trk_enable_clocks(void); +u32 res_trk_disable_clocks(void); +u32 res_trk_get_max_perf_level(u32 *pn_max_perf_lvl); +u32 res_trk_set_perf_level(u32 req_perf_lvl, u32 *pn_set_perf_lvl, + struct vcd_dev_ctxt *dev_ctxt); +u32 res_trk_get_curr_perf_level(u32 *pn_perf_lvl); +u32 res_trk_download_firmware(void); +u32 res_trk_get_core_type(void); +u32 res_trk_get_firmware_addr(struct ddl_buf_addr *firm_addr); +int res_trk_get_mem_type(void); +u32 res_trk_get_enable_ion(void); +u32 res_trk_is_cp_enabled(void); +u32 res_trk_get_disable_fullhd(void); +struct ion_client *res_trk_get_ion_client(void); +u32 res_trk_get_disable_dmx(void); +u32 res_trk_get_min_dpb_count(void); +void res_trk_set_mem_type(enum ddl_mem_area mem_type); +int res_trk_enable_iommu_clocks(void); +int res_trk_disable_iommu_clocks(void); +int res_trk_check_for_sec_session(void); +int res_trk_open_secure_session(void); +int res_trk_close_secure_session(void); +void res_trk_secure_set(void); +void res_trk_secure_unset(void); +u32 get_res_trk_perf_level(enum vcd_perf_level); +int res_trk_enable_footswitch(void); +int res_trk_disable_footswitch(void); +void res_trk_release_fw_addr(void); +u32 res_trk_estimate_perf_level(u32 pn_perf_lvl); +u32 res_trk_get_clk_rate(unsigned long *phclk_rate); +#endif diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.c new file mode 100644 index 000000000000..f8be339912db --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.c @@ -0,0 +1,628 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#include +#include "vcd_ddl_utils.h" +#include "vcd_ddl_metadata.h" +#include "vcd_res_tracker_api.h" + +u32 ddl_device_init(struct ddl_init_config *ddl_init_config, + void *client_data) +{ + struct ddl_context *ddl_context; + u32 status = VCD_S_SUCCESS; + + if ((!ddl_init_config) || + (!ddl_init_config->ddl_callback) || + (!ddl_init_config->core_virtual_base_addr) + ) { + VIDC_LOGERR_STRING("ddl_dev_init:Bad_argument"); + return VCD_ERR_ILLEGAL_PARM; + } + + ddl_context = ddl_get_context(); + + if (DDL_IS_INITIALIZED(ddl_context)) { + VIDC_LOGERR_STRING("ddl_dev_init:Multiple_init"); + return VCD_ERR_ILLEGAL_OP; + } + if (DDL_IS_BUSY(ddl_context)) { + VIDC_LOGERR_STRING("ddl_dev_init:Ddl_busy"); + return VCD_ERR_BUSY; + } + + DDL_MEMSET(ddl_context, 0, sizeof(struct ddl_context)); + + DDL_BUSY(ddl_context); + ddl_context->memtype = res_trk_get_mem_type(); + if (ddl_context->memtype == -1) { + VIDC_LOGERR_STRING("ddl_dev_init:Invalid Memtype"); + return VCD_ERR_ILLEGAL_PARM; + } + ddl_context->ddl_callback = ddl_init_config->ddl_callback; + ddl_context->interrupt_clr = ddl_init_config->interrupt_clr; + ddl_context->core_virtual_base_addr = + ddl_init_config->core_virtual_base_addr; + ddl_context->client_data = client_data; + + vidc_720p_set_device_virtual_base(ddl_context-> + core_virtual_base_addr); + + ddl_context->current_ddl = NULL; + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + + ddl_client_transact(DDL_INIT_CLIENTS, NULL); + + ddl_pmem_alloc(&ddl_context->context_buf_addr, + DDL_CONTEXT_MEMORY, DDL_LINEAR_BUFFER_ALIGN_BYTES); + if (!ddl_context->context_buf_addr.virtual_base_addr) { + VIDC_LOGERR_STRING("ddl_dev_init:Context_alloc_fail"); + status = VCD_ERR_ALLOC_FAIL; + } + if (!status) { + ddl_pmem_alloc(&ddl_context->db_line_buffer, + DDL_DB_LINE_BUF_SIZE, + DDL_TILE_BUFFER_ALIGN_BYTES); + if (!ddl_context->db_line_buffer.virtual_base_addr) { + VIDC_LOGERR_STRING("ddl_dev_init:Line_buf_alloc_fail"); + status = VCD_ERR_ALLOC_FAIL; + } + } + + if (!status) { + ddl_pmem_alloc(&ddl_context->data_partition_tempbuf, + DDL_MPEG4_DATA_PARTITION_BUF_SIZE, + DDL_TILE_BUFFER_ALIGN_BYTES); + if (ddl_context->data_partition_tempbuf.virtual_base_addr \ + == NULL) { + VIDC_LOGERR_STRING + ("ddl_dev_init:Data_partition_buf_alloc_fail"); + status = VCD_ERR_ALLOC_FAIL; + } + } + + if (!status) { + + ddl_pmem_alloc(&ddl_context->metadata_shared_input, + DDL_METADATA_TOTAL_INPUTBUFSIZE, + DDL_LINEAR_BUFFER_ALIGN_BYTES); + if (!ddl_context->metadata_shared_input.virtual_base_addr) { + VIDC_LOGERR_STRING + ("ddl_dev_init:metadata_shared_input_alloc_fail"); + status = VCD_ERR_ALLOC_FAIL; + } + } + + if (!status) { + ddl_pmem_alloc(&ddl_context->dbg_core_dump, \ + DDL_DBG_CORE_DUMP_SIZE, \ + DDL_LINEAR_BUFFER_ALIGN_BYTES); + if (!ddl_context->dbg_core_dump.virtual_base_addr) { + VIDC_LOGERR_STRING + ("ddl_dev_init:dbg_core_dump_alloc_failed"); + status = VCD_ERR_ALLOC_FAIL; + } + ddl_context->enable_dbg_core_dump = 0; + } + + if (!status && !vcd_fw_init()) { + VIDC_LOGERR_STRING("ddl_dev_init:fw_init_failed"); + status = VCD_ERR_ALLOC_FAIL; + } + if (status) { + ddl_release_context_buffers(ddl_context); + DDL_IDLE(ddl_context); + return status; + } + + ddl_move_command_state(ddl_context, DDL_CMD_DMA_INIT); + + ddl_core_init(ddl_context); + + return status; +} + +u32 ddl_device_release(void *client_data) +{ + struct ddl_context *ddl_context; + + ddl_context = ddl_get_context(); + + if (DDL_IS_BUSY(ddl_context)) { + VIDC_LOGERR_STRING("ddl_dev_rel:Ddl_busy"); + return VCD_ERR_BUSY; + } + + if (!DDL_IS_INITIALIZED(ddl_context)) { + VIDC_LOGERR_STRING("ddl_dev_rel:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + + if (!ddl_client_transact(DDL_ACTIVE_CLIENT, NULL)) { + VIDC_LOGERR_STRING("ddl_dev_rel:Client_present_err"); + return VCD_ERR_CLIENT_PRESENT; + } + DDL_BUSY(ddl_context); + + ddl_context->device_state = DDL_DEVICE_NOTINIT; + ddl_context->client_data = client_data; + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + vidc_720p_stop_fw(); + + VIDC_LOG_STRING("FW_ENDDONE"); + ddl_release_context_buffers(ddl_context); + + DDL_IDLE(ddl_context); + + return VCD_S_SUCCESS; +} + +u32 ddl_open(u32 **ddl_handle, u32 decoding) +{ + struct ddl_context *ddl_context; + struct ddl_client_context *ddl; + u32 status; + + if (!ddl_handle) { + VIDC_LOGERR_STRING("ddl_open:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + + ddl_context = ddl_get_context(); + + if (!DDL_IS_INITIALIZED(ddl_context)) { + VIDC_LOGERR_STRING("ddl_open:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + + status = ddl_client_transact(DDL_GET_CLIENT, &ddl); + + if (status) { + VIDC_LOGERR_STRING("ddl_open:Client_trasac_failed"); + return status; + } + + ddl_move_client_state(ddl, DDL_CLIENT_OPEN); + + ddl->codec_data.hdr.decoding = decoding; + ddl->decoding = decoding; + + ddl_set_default_meta_data_hdr(ddl); + + ddl_set_initial_default_values(ddl); + + *ddl_handle = (u32 *) ddl; + return VCD_S_SUCCESS; +} + +u32 ddl_close(u32 **ddl_handle) +{ + struct ddl_context *ddl_context; + struct ddl_client_context **ddl = + (struct ddl_client_context **)ddl_handle; + + if (!ddl || !*ddl) { + VIDC_LOGERR_STRING("ddl_close:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + + ddl_context = ddl_get_context(); + + if (!DDL_IS_INITIALIZED(ddl_context)) { + VIDC_LOGERR_STRING("ddl_close:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + + if (!DDLCLIENT_STATE_IS(*ddl, DDL_CLIENT_OPEN)) { + VIDC_LOGERR_STRING("ddl_close:Not_in_open_state"); + return VCD_ERR_ILLEGAL_OP; + } + + ddl_move_client_state(*ddl, DDL_CLIENT_INVALID); + if ((*ddl)->decoding) { + vcd_fw_transact(false, true, + (*ddl)->codec_data.decoder.codec.codec); + } else { + vcd_fw_transact(false, false, + (*ddl)->codec_data.encoder.codec.codec); + } + ddl_client_transact(DDL_FREE_CLIENT, ddl); + + return VCD_S_SUCCESS; +} + +u32 ddl_encode_start(u32 *ddl_handle, void *client_data) +{ + struct ddl_client_context *ddl = + (struct ddl_client_context *)ddl_handle; + struct ddl_context *ddl_context; + struct ddl_encoder_data *encoder; + u32 dpb_size; + + ddl_context = ddl_get_context(); + + if (!DDL_IS_INITIALIZED(ddl_context)) { + VIDC_LOGERR_STRING("ddl_enc_start:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (DDL_IS_BUSY(ddl_context)) { + VIDC_LOGERR_STRING("ddl_enc_start:Ddl_busy"); + return VCD_ERR_BUSY; + } + if (!ddl || ddl->decoding) { + VIDC_LOGERR_STRING("ddl_enc_start:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) { + VIDC_LOGERR_STRING("ddl_enc_start:Not_opened"); + return VCD_ERR_ILLEGAL_OP; + } + + if (!ddl_encoder_ready_to_start(ddl)) { + VIDC_LOGERR_STRING("ddl_enc_start:Err_param_settings"); + return VCD_ERR_ILLEGAL_OP; + } + + encoder = &ddl->codec_data.encoder; + + dpb_size = ddl_get_yuv_buffer_size(&encoder->frame_size, + &encoder->re_con_buf_format, false, + encoder->codec.codec); + + dpb_size *= DDL_ENC_NUM_DPB_BUFFERS; + ddl_pmem_alloc(&encoder->enc_dpb_addr, + dpb_size, DDL_TILE_BUFFER_ALIGN_BYTES); + if (!encoder->enc_dpb_addr.virtual_base_addr) { + VIDC_LOGERR_STRING("ddl_enc_start:Dpb_alloc_failed"); + return VCD_ERR_ALLOC_FAIL; + } + + if ((encoder->codec.codec == VCD_CODEC_MPEG4 && + !encoder->short_header.short_header) || + encoder->codec.codec == VCD_CODEC_H264) { + ddl_pmem_alloc(&encoder->seq_header, + DDL_ENC_SEQHEADER_SIZE, + DDL_LINEAR_BUFFER_ALIGN_BYTES); + if (!encoder->seq_header.virtual_base_addr) { + ddl_pmem_free(&encoder->enc_dpb_addr); + VIDC_LOGERR_STRING + ("ddl_enc_start:Seq_hdr_alloc_failed"); + return VCD_ERR_ALLOC_FAIL; + } + } else { + encoder->seq_header.buffer_size = 0; + encoder->seq_header.virtual_base_addr = 0; + } + + DDL_BUSY(ddl_context); + + ddl_context->current_ddl = ddl; + ddl_context->client_data = client_data; + ddl_channel_set(ddl); + return VCD_S_SUCCESS; +} + +u32 ddl_decode_start(u32 *ddl_handle, + struct vcd_sequence_hdr *header, void *client_data) +{ + struct ddl_client_context *ddl = + (struct ddl_client_context *)ddl_handle; + struct ddl_context *ddl_context; + struct ddl_decoder_data *decoder; + + ddl_context = ddl_get_context(); + + if (!DDL_IS_INITIALIZED(ddl_context)) { + VIDC_LOGERR_STRING("ddl_dec_start:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (DDL_IS_BUSY(ddl_context)) { + VIDC_LOGERR_STRING("ddl_dec_start:Ddl_busy"); + return VCD_ERR_BUSY; + } + if (!ddl || !ddl->decoding) { + VIDC_LOGERR_STRING("ddl_dec_start:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) { + VIDC_LOGERR_STRING("ddl_dec_start:Not_in_opened_state"); + return VCD_ERR_ILLEGAL_OP; + } + + if ((header) && + ((!header->sequence_header_len) || + (!header->sequence_header) + ) + ) { + VIDC_LOGERR_STRING("ddl_dec_start:Bad_param_seq_header"); + return VCD_ERR_ILLEGAL_PARM; + } + + if (!ddl_decoder_ready_to_start(ddl, header)) { + VIDC_LOGERR_STRING("ddl_dec_start:Err_param_settings"); + return VCD_ERR_ILLEGAL_OP; + } + + DDL_BUSY(ddl_context); + + decoder = &ddl->codec_data.decoder; + if (header) { + decoder->header_in_start = true; + decoder->decode_config = *header; + } else { + decoder->header_in_start = false; + decoder->decode_config.sequence_header_len = 0; + } + + if (decoder->codec.codec == VCD_CODEC_H264) { + ddl_pmem_alloc(&decoder->h264Vsp_temp_buffer, + DDL_DECODE_H264_VSPTEMP_BUFSIZE, + DDL_LINEAR_BUFFER_ALIGN_BYTES); + if (!decoder->h264Vsp_temp_buffer.virtual_base_addr) { + DDL_IDLE(ddl_context); + VIDC_LOGERR_STRING + ("ddl_dec_start:H264Sps_alloc_failed"); + return VCD_ERR_ALLOC_FAIL; + } + } + + ddl_context->current_ddl = ddl; + ddl_context->client_data = client_data; + + ddl_channel_set(ddl); + return VCD_S_SUCCESS; +} + +u32 ddl_decode_frame(u32 *ddl_handle, + struct ddl_frame_data_tag *input_bits, void *client_data) +{ + u32 vcd_status = VCD_S_SUCCESS; + struct ddl_client_context *ddl = + (struct ddl_client_context *)ddl_handle; + struct ddl_context *ddl_context = ddl_get_context(); + + if (!DDL_IS_INITIALIZED(ddl_context)) { + VIDC_LOGERR_STRING("ddl_dec_frame:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (DDL_IS_BUSY(ddl_context)) { + VIDC_LOGERR_STRING("ddl_dec_frame:Ddl_busy"); + return VCD_ERR_BUSY; + } + if (!ddl || !ddl->decoding) { + VIDC_LOGERR_STRING("ddl_dec_frame:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + if (!input_bits || + ((!input_bits->vcd_frm.physical || + !input_bits->vcd_frm.data_len) && + (!(VCD_FRAME_FLAG_EOS & input_bits->vcd_frm.flags)) + ) + ) { + VIDC_LOGERR_STRING("ddl_dec_frame:Bad_input_param"); + return VCD_ERR_ILLEGAL_PARM; + } + + DDL_BUSY(ddl_context); + + ddl_context->current_ddl = ddl; + ddl_context->client_data = client_data; + + ddl->input_frame = *input_bits; + + if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME)) { + ddl_decode_frame_run(ddl); + } else { + if (!ddl->codec_data.decoder.dp_buf.no_of_dec_pic_buf) { + VIDC_LOGERR_STRING("ddl_dec_frame:Dpbs_requied"); + vcd_status = VCD_ERR_ILLEGAL_OP; + } else if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB)) { + vcd_status = ddl_decode_set_buffers(ddl); + } else + if (DDLCLIENT_STATE_IS + (ddl, DDL_CLIENT_WAIT_FOR_INITCODEC)) { + ddl->codec_data.decoder.decode_config. + sequence_header = + ddl->input_frame.vcd_frm.physical; + ddl->codec_data.decoder.decode_config. + sequence_header_len = + ddl->input_frame.vcd_frm.data_len; + ddl_decode_init_codec(ddl); + } else { + VIDC_LOGERR_STRING("Dec_frame:Wrong_state"); + vcd_status = VCD_ERR_ILLEGAL_OP; + } + if (vcd_status) + DDL_IDLE(ddl_context); + } + return vcd_status; +} + +u32 ddl_encode_frame(u32 *ddl_handle, + struct ddl_frame_data_tag *input_frame, + struct ddl_frame_data_tag *output_bit, void *client_data) +{ + struct ddl_client_context *ddl = + (struct ddl_client_context *)ddl_handle; + struct ddl_context *ddl_context = ddl_get_context(); + + if (vidc_msg_timing) + ddl_set_core_start_time(__func__, ENC_OP_TIME); + + if (!DDL_IS_INITIALIZED(ddl_context)) { + VIDC_LOGERR_STRING("ddl_enc_frame:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (DDL_IS_BUSY(ddl_context)) { + VIDC_LOGERR_STRING("ddl_enc_frame:Ddl_busy"); + return VCD_ERR_BUSY; + } + if (!ddl || ddl->decoding) { + VIDC_LOGERR_STRING("ddl_enc_frame:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + if (!input_frame || + !input_frame->vcd_frm.physical || + !input_frame->vcd_frm.data_len) { + VIDC_LOGERR_STRING("ddl_enc_frame:Bad_input_params"); + return VCD_ERR_ILLEGAL_PARM; + } + if ((((u32) input_frame->vcd_frm.physical + + input_frame->vcd_frm.offset) & + (DDL_STREAMBUF_ALIGN_GUARD_BYTES) + ) + ) { + VIDC_LOGERR_STRING + ("ddl_enc_frame:Un_aligned_yuv_start_address"); + return VCD_ERR_ILLEGAL_PARM; + } + if (!output_bit || + !output_bit->vcd_frm.physical || + !output_bit->vcd_frm.alloc_len) { + VIDC_LOGERR_STRING("ddl_enc_frame:Bad_output_params"); + return VCD_ERR_ILLEGAL_PARM; + } + if ((ddl->codec_data.encoder.output_buf_req.sz + + output_bit->vcd_frm.offset) > + output_bit->vcd_frm.alloc_len) { + VIDC_LOGERR_STRING + ("ddl_enc_frame:offset_large, Exceeds_min_buf_size"); + } + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME)) { + VIDC_LOGERR_STRING("ddl_enc_frame:Wrong_state"); + return VCD_ERR_ILLEGAL_OP; + } + + DDL_BUSY(ddl_context); + + ddl_context->current_ddl = ddl; + ddl_context->client_data = client_data; + + ddl->input_frame = *input_frame; + ddl->output_frame = *output_bit; + + ddl_encode_frame_run(ddl); + return VCD_S_SUCCESS; +} + +u32 ddl_decode_end(u32 *ddl_handle, void *client_data) +{ + struct ddl_client_context *ddl = + (struct ddl_client_context *)ddl_handle; + struct ddl_context *ddl_context; + + ddl_context = ddl_get_context(); + + if (vidc_msg_timing) { + ddl_reset_core_time_variables(DEC_OP_TIME); + ddl_reset_core_time_variables(DEC_IP_TIME); + } + + if (!DDL_IS_INITIALIZED(ddl_context)) { + VIDC_LOGERR_STRING("ddl_dec_end:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (DDL_IS_BUSY(ddl_context)) { + VIDC_LOGERR_STRING("ddl_dec_end:Ddl_busy"); + return VCD_ERR_BUSY; + } + if (!ddl || !ddl->decoding) { + VIDC_LOGERR_STRING("ddl_dec_end:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME) && + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODEC) && + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB) && + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_FATAL_ERROR) + ) { + VIDC_LOGERR_STRING("ddl_dec_end:Wrong_state"); + return VCD_ERR_ILLEGAL_OP; + } + DDL_BUSY(ddl_context); + + ddl_context->current_ddl = ddl; + ddl_context->client_data = client_data; + + ddl_channel_end(ddl); + return VCD_S_SUCCESS; +} + +u32 ddl_encode_end(u32 *ddl_handle, void *client_data) +{ + struct ddl_client_context *ddl = + (struct ddl_client_context *)ddl_handle; + struct ddl_context *ddl_context; + + ddl_context = ddl_get_context(); + + if (vidc_msg_timing) + ddl_reset_core_time_variables(ENC_OP_TIME); + + if (!DDL_IS_INITIALIZED(ddl_context)) { + VIDC_LOGERR_STRING("ddl_enc_end:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + if (DDL_IS_BUSY(ddl_context)) { + VIDC_LOGERR_STRING("ddl_enc_end:Ddl_busy"); + return VCD_ERR_BUSY; + } + if (!ddl || ddl->decoding) { + VIDC_LOGERR_STRING("ddl_enc_end:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME) && + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODEC) && + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_FATAL_ERROR)) { + VIDC_LOGERR_STRING("ddl_enc_end:Wrong_state"); + return VCD_ERR_ILLEGAL_OP; + } + DDL_BUSY(ddl_context); + + ddl_context->current_ddl = ddl; + ddl_context->client_data = client_data; + + ddl_channel_end(ddl); + return VCD_S_SUCCESS; +} + +u32 ddl_reset_hw(u32 mode) +{ + struct ddl_context *ddl_context; + struct ddl_client_context *ddl; + int i_client_num; + + VIDC_LOG_STRING("ddl_reset_hw:called"); + ddl_context = ddl_get_context(); + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + DDL_BUSY(ddl_context); + + if (ddl_context->core_virtual_base_addr) + vidc_720p_do_sw_reset(); + + ddl_context->device_state = DDL_DEVICE_NOTINIT; + for (i_client_num = 0; i_client_num < VCD_MAX_NO_CLIENT; + ++i_client_num) { + ddl = ddl_context->ddl_clients[i_client_num]; + ddl_context->ddl_clients[i_client_num] = NULL; + if (ddl) { + ddl_release_client_internal_buffers(ddl); + ddl_client_transact(DDL_FREE_CLIENT, &ddl); + } + } + + ddl_release_context_buffers(ddl_context); + DDL_MEMSET(ddl_context, 0, sizeof(struct ddl_context)); + + return true; +} diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h new file mode 100644 index 000000000000..44d5b0dd927a --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl.h @@ -0,0 +1,292 @@ +/* Copyright (c) 2010, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#ifndef _VCD_DDL_H_ +#define _VCD_DDL_H_ +#include +#include "vcd_ddl_api.h" +#include "vcd_ddl_utils.h" +#include "vcd_ddl_firmware.h" +#include "vidc.h" + +#undef DDL_INLINE +#define DDL_INLINE + +#define DDL_BUSY_STATE 1 +#define DDL_IDLE_STATE 0 +#define DDL_ERROR_STATE 2 +#define DDL_IS_BUSY(ddl_context) \ + (((ddl_context)->ddl_busy != DDL_IDLE_STATE)) +#define DDL_BUSY(ddl_context) \ + ((ddl_context)->ddl_busy = DDL_BUSY_STATE) +#define DDL_IDLE(ddl_context) \ + ((ddl_context)->ddl_busy = DDL_IDLE_STATE) +#define DDL_ERROR(ddl_context) \ + ((ddl_context)->ddl_busy = DDL_ERROR_STATE) + +#define DDL_DEVICE_NOTINIT 0 +#define DDL_DEVICE_INITED 1 +#define DDL_DEVICE_HWFATAL 2 +#define DDL_IS_INITIALIZED(ddl_context) \ +(ddl_context->device_state == DDL_DEVICE_INITED) + +#define DDLCOMMAND_STATE_IS(ddl_context, command_state) \ +(command_state == (ddl_context)->cmd_state) + +#define DDLCLIENT_STATE_IS(ddl, current_state) \ +(current_state == (ddl)->client_state) + +#define DDL_DPB_OP_INIT 1 +#define DDL_DPB_OP_MARK_FREE 2 +#define DDL_DPB_OP_MARK_BUSY 3 +#define DDL_DPB_OP_SET_MASK 4 +#define DDL_DPB_OP_RETRIEVE 5 + +#define DDL_INIT_CLIENTS 0 +#define DDL_GET_CLIENT 1 +#define DDL_FREE_CLIENT 2 +#define DDL_ACTIVE_CLIENT 3 + +#define DDL_INVALID_CHANNEL_ID ((u32)~0) +#define DDL_INVALID_CODEC_TYPE ((u32)~0) + +#define DDL_ENC_REQ_IFRAME 0x01 +#define DDL_ENC_CHANGE_IPERIOD 0x02 +#define DDL_ENC_CHANGE_BITRATE 0x04 +#define DDL_ENC_CHANGE_FRAMERATE 0x08 +#define DDL_ENC_CHANGE_CIR 0x10 + +#define DDL_DEC_REQ_OUTPUT_FLUSH 0x1 + +enum ddl_mem_area { + DDL_MM_MEM = 0x0 +}; + +struct ddl_buf_addr { + u32 *physical_base_addr; + u32 *virtual_base_addr; + u32 *align_physical_addr; + u32 *align_virtual_addr; + struct msm_mapped_buffer *mapped_buffer; + u32 buffer_size; + enum ddl_mem_area mem_type; +}; + +enum ddl_cmd_state { + DDL_CMD_INVALID = 0x0, + DDL_CMD_DMA_INIT = 0x1, + DDL_CMD_CPU_RESET = 0x2, + DDL_CMD_CHANNEL_SET = 0x3, + DDL_CMD_INIT_CODEC = 0x4, + DDL_CMD_HEADER_PARSE = 0x5, + DDL_CMD_DECODE_SET_DPB = 0x6, + DDL_CMD_DECODE_FRAME = 0x7, + DDL_CMD_ENCODE_FRAME = 0x8, + DDL_CMD_EOS = 0x9, + DDL_CMD_CHANNEL_END = 0xA, + DDL_CMD_32BIT = 0x7FFFFFFF +}; + +enum ddl_client_state { + DDL_CLIENT_INVALID = 0x0, + DDL_CLIENT_OPEN = 0x1, + DDL_CLIENT_WAIT_FOR_CHDONE = 0x2, + DDL_CLIENT_WAIT_FOR_INITCODEC = 0x3, + DDL_CLIENT_WAIT_FOR_INITCODECDONE = 0x4, + DDL_CLIENT_WAIT_FOR_DPB = 0x5, + DDL_CLIENT_WAIT_FOR_DPBDONE = 0x6, + DDL_CLIENT_WAIT_FOR_FRAME = 0x7, + DDL_CLIENT_WAIT_FOR_FRAME_DONE = 0x8, + DDL_CLIENT_WAIT_FOR_EOS_DONE = 0x9, + DDL_CLIENT_WAIT_FOR_CHEND = 0xA, + DDL_CLIENT_FATAL_ERROR = 0xB, + DDL_CLIENT_32BIT = 0x7FFFFFFF +}; + +struct ddl_mask { + u32 client_mask; + u32 hw_mask; +}; + +struct ddl_context; + +struct ddl_client_context; + +struct ddl_codec_data_hdr { + u32 decoding; +}; + +struct ddl_encoder_data { + struct ddl_codec_data_hdr hdr; + struct vcd_property_codec codec; + struct vcd_property_frame_size frame_size; + struct vcd_property_frame_rate frame_rate; + struct vcd_property_target_bitrate target_bit_rate; + struct vcd_property_profile profile; + struct vcd_property_level level; + struct vcd_property_rate_control rc; + struct vcd_property_multi_slice multi_slice; + u32 meta_data_enable_flag; + u32 suffix; + struct ddl_buf_addr meta_data_input; + u32 meta_data_offset; + struct vcd_property_short_header short_header; + struct vcd_property_vop_timing vop_timing; + u32 hdr_ext_control; + struct vcd_property_db_config db_control; + struct vcd_property_entropy_control entropy_control; + struct vcd_property_i_period i_period; + struct vcd_property_session_qp session_qp; + struct vcd_property_qp_range qp_range; + struct vcd_property_rc_level rc_level; + u32 r_cframe_skip; + u32 vb_vbuffer_size; + struct vcd_property_frame_level_rc_params frame_level_rc; + struct vcd_property_adaptive_rc_params adaptive_rc; + struct vcd_property_intra_refresh_mb_number intra_refresh; + struct vcd_property_buffer_format buf_format; + struct vcd_property_buffer_format re_con_buf_format; + u32 dynamic_prop_change; + u32 dynmic_prop_change_req; + u32 ext_enc_control_val; + struct vidc_720p_enc_frame_info enc_frame_info; + struct ddl_buf_addr enc_dpb_addr; + struct ddl_buf_addr seq_header; + struct vcd_buffer_requirement input_buf_req; + struct vcd_buffer_requirement output_buf_req; + struct vcd_buffer_requirement client_input_buf_req; + struct vcd_buffer_requirement client_output_buf_req; +}; + +struct ddl_decoder_data { + struct ddl_codec_data_hdr hdr; + struct vcd_property_codec codec; + struct vcd_property_buffer_format buf_format; + struct vcd_property_frame_size frame_size; + struct vcd_property_frame_size client_frame_size; + struct vcd_property_profile profile; + struct vcd_property_level level; + u32 progressive_only; + u32 output_order; + u32 meta_data_enable_flag; + u32 suffix; + struct ddl_buf_addr meta_data_input; + struct ddl_buf_addr ref_buffer; + u32 meta_data_offset; + struct vcd_property_post_filter post_filter; + struct vcd_sequence_hdr decode_config; + u32 header_in_start; + u32 min_dpb_num; + u32 y_cb_cr_size; + struct ddl_property_dec_pic_buffers dp_buf; + struct ddl_mask dpb_mask; + u32 dynamic_prop_change; + u32 dynmic_prop_change_req; + struct vidc_720p_dec_disp_info dec_disp_info; + struct ddl_buf_addr dpb_comv_buffer; + struct ddl_buf_addr h264Vsp_temp_buffer; + struct vcd_buffer_requirement actual_input_buf_req; + struct vcd_buffer_requirement min_input_buf_req; + struct vcd_buffer_requirement client_input_buf_req; + struct vcd_buffer_requirement actual_output_buf_req; + struct vcd_buffer_requirement min_output_buf_req; + struct vcd_buffer_requirement client_output_buf_req; + u32 idr_only_decoding; +}; + +union ddl_codec_data { + struct ddl_codec_data_hdr hdr; + struct ddl_decoder_data decoder; + struct ddl_encoder_data encoder; +}; + +struct ddl_context { + int memtype; + u8 *core_virtual_base_addr; + void (*ddl_callback) (u32 event, u32 status, void *payload, size_t sz, + u32 *ddl_handle, void *const client_data); + void *client_data; + void (*interrupt_clr) (void); + enum ddl_cmd_state cmd_state; + struct ddl_client_context *current_ddl; + struct ddl_buf_addr context_buf_addr; + struct ddl_buf_addr db_line_buffer; + struct ddl_buf_addr data_partition_tempbuf; + struct ddl_buf_addr metadata_shared_input; + struct ddl_buf_addr dbg_core_dump; + u32 enable_dbg_core_dump; + struct ddl_client_context *ddl_clients[VCD_MAX_NO_CLIENT]; + u32 device_state; + u32 ddl_busy; + u32 intr_status; + u32 cmd_err_status; + u32 disp_pic_err_status; + u32 op_failed; +}; + +struct ddl_client_context { + struct ddl_context *ddl_context; + enum ddl_client_state client_state; + u32 decoding; + u32 channel_id; + struct ddl_frame_data_tag input_frame; + struct ddl_frame_data_tag output_frame; + union ddl_codec_data codec_data; +}; + +DDL_INLINE struct ddl_context *ddl_get_context(void); +DDL_INLINE void ddl_move_command_state(struct ddl_context *ddl_context, + enum ddl_cmd_state command_state); +DDL_INLINE void ddl_move_client_state(struct ddl_client_context *ddl, + enum ddl_client_state client_state); +void ddl_core_init(struct ddl_context *); +void ddl_core_start_cpu(struct ddl_context *); +void ddl_channel_set(struct ddl_client_context *); +void ddl_channel_end(struct ddl_client_context *); +void ddl_encode_init_codec(struct ddl_client_context *); +void ddl_decode_init_codec(struct ddl_client_context *); +void ddl_encode_frame_run(struct ddl_client_context *); +void ddl_decode_frame_run(struct ddl_client_context *); +void ddl_decode_eos_run(struct ddl_client_context *); +void ddl_release_context_buffers(struct ddl_context *); +void ddl_release_client_internal_buffers(struct ddl_client_context *ddl); +u32 ddl_decode_set_buffers(struct ddl_client_context *); +u32 ddl_decoder_dpb_transact(struct ddl_decoder_data *decoder, + struct ddl_frame_data_tag *in_out_frame, + u32 operation); +u32 ddl_client_transact(u32, struct ddl_client_context **); +void ddl_set_default_decoder_buffer_req + (struct ddl_decoder_data *decoder, u32 estimate); +void ddl_set_default_encoder_buffer_req + (struct ddl_encoder_data *encoder); +void ddl_set_default_dec_property(struct ddl_client_context *); +u32 ddl_encoder_ready_to_start(struct ddl_client_context *); +u32 ddl_decoder_ready_to_start(struct ddl_client_context *, + struct vcd_sequence_hdr *); +u32 ddl_get_yuv_buffer_size + (struct vcd_property_frame_size *frame_size, + struct vcd_property_buffer_format *buf_format, u32 inter_lace, + enum vcd_codec codec); +void ddl_calculate_stride(struct vcd_property_frame_size *frame_size, + u32 inter_lace, enum vcd_codec codec); +void ddl_encode_dynamic_property(struct ddl_client_context *ddl, + u32 enable); +void ddl_decode_dynamic_property(struct ddl_client_context *ddl, + u32 enable); +void ddl_set_initial_default_values(struct ddl_client_context *ddl); +u32 ddl_handle_core_errors(struct ddl_context *ddl_context); +void ddl_client_fatal_cb(struct ddl_context *ddl_context); +void ddl_hw_fatal_cb(struct ddl_context *ddl_context); +u32 ddl_hal_engine_reset(struct ddl_context *ddl_context); +void ddl_pmem_alloc(struct ddl_buf_addr *addr, size_t sz, u32 alignment); +void ddl_pmem_free(struct ddl_buf_addr *addr); +#endif diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_api.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_api.h new file mode 100644 index 000000000000..3796e8f7ab5b --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_api.h @@ -0,0 +1,53 @@ +/* Copyright (c) 2010, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#ifndef _VCD_DDL_API_H_ +#define _VCD_DDL_API_H_ +#include "vcd_ddl_internal_property.h" + +struct ddl_init_config { + int memtype; + u8 *core_virtual_base_addr; + void (*interrupt_clr) (void); + void (*ddl_callback) (u32 event, u32 status, void *payload, size_t sz, + u32 *ddl_handle, void *const client_data); +}; + +struct ddl_frame_data_tag { + struct vcd_frame_data vcd_frm; + u32 frm_trans_end; + u32 frm_delta; +}; + +u32 ddl_device_init(struct ddl_init_config *ddl_init_config, + void *client_data); +u32 ddl_device_release(void *client_data); +u32 ddl_open(u32 **ddl_handle, u32 decoding); +u32 ddl_close(u32 **ddl_handle); +u32 ddl_encode_start(u32 *ddl_handle, void *client_data); +u32 ddl_encode_frame(u32 *ddl_handle, + struct ddl_frame_data_tag *input_frame, + struct ddl_frame_data_tag *output_bit, void *client_data); +u32 ddl_encode_end(u32 *ddl_handle, void *client_data); +u32 ddl_decode_start(u32 *ddl_handle, struct vcd_sequence_hdr *header, + void *client_data); +u32 ddl_decode_frame(u32 *ddl_handle, + struct ddl_frame_data_tag *input_bits, void *client_data); +u32 ddl_decode_end(u32 *ddl_handle, void *client_data); +u32 ddl_set_property(u32 *ddl_handle, + struct vcd_property_hdr *property_hdr, void *property_value); +u32 ddl_get_property(u32 *ddl_handle, + struct vcd_property_hdr *property_hdr, void *property_value); +void ddl_read_and_clear_interrupt(void); +u32 ddl_process_core_response(void); +u32 ddl_reset_hw(u32 mode); +#endif diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_core.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_core.h new file mode 100644 index 000000000000..78b05ec1d04b --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_core.h @@ -0,0 +1,99 @@ +/* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#ifndef _VCD_DDL_CORE_H_ +#define _VCD_DDL_CORE_H_ + +#define DDL_LINEAR_BUF_ALIGN_MASK 0xFFFFFFF8U +#define DDL_LINEAR_BUF_ALIGN_GUARD_BYTES 0x7 +#define DDL_LINEAR_BUFFER_ALIGN_BYTES 8 + +#define DDL_TILE_BUF_ALIGN_MASK 0xFFFFE000U +#define DDL_TILE_BUF_ALIGN_GUARD_BYTES 0x1FFF +#define DDL_TILE_BUFFER_ALIGN_BYTES 8192 + +#define DDL_MAX_FRAME_WIDTH (1280) +#define DDL_MAX_FRAME_HEIGHT (720) + +#define DDL_MAX_DP_FRAME_WIDTH 352 +#define DDL_MAX_DP_FRAME_HEIGHT 288 + +#define DDL_MAX_BIT_RATE (14*1000*1000) + +#define DDL_SW_RESET_SLEEP 10 + +#define VCD_MAX_NO_CLIENT 4 +#define VCD_FRAME_COMMAND_DEPTH 1 +#define VCD_GENERAL_COMMAND_DEPTH 1 +#define VCD_COMMAND_EXCLUSIVE true + +#define DDL_HW_TIMEOUT_IN_MS 1000 + +#define DDL_STREAMBUF_ALIGN_GUARD_BYTES 0x7 + +#define DDL_CONTEXT_MEMORY (1024 * 15 * (VCD_MAX_NO_CLIENT + 1)) +#define DDL_DB_LINE_BUF_SIZE \ +(((((DDL_MAX_FRAME_WIDTH * 4) - 1) / 256) + 1) * 8 * 1024) +#define DDL_MPEG4_DATA_PARTITION_BUF_SIZE (64 * 1024) +#define DDL_DECODE_H264_VSPTEMP_BUFSIZE 0x59c00 +#define DDL_ENC_NUM_DPB_BUFFERS 2 + +#define DDL_DBG_CORE_DUMP_SIZE (10 * 1024) + +#define DDL_BUFEND_PAD 256 +#define DDL_ENC_SEQHEADER_SIZE (256+DDL_BUFEND_PAD) +#define DDL_MAX_BUFFER_COUNT 32 + +#define DDL_MPEG_REFBUF_COUNT 2 + +#define DDL_MPEG_COMV_BUF_NO 2 +#define DDL_H263_COMV_BUF_NO 2 +#define DDL_COMV_BUFLINE_NO 128 +#define DDL_VC1_COMV_BUFLINE_NO 32 +#define DDL_MINIMUM_BYTE_PER_SLICE 1920 + +#define DDL_MAX_H264_QP 51 +#define DDL_MAX_MPEG4_QP 31 + +#define DDL_PADDING_HACK(addr) \ + (addr) = (u32)((((u32)(addr) + DDL_STREAMBUF_ALIGN_GUARD_BYTES) & \ + ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES)) + DDL_BUFEND_PAD) + +#define DDL_QCIF_MBS 99 +#define DDL_CIF_MBS 396 +#define DDL_QVGA_MBS 300 +#define DDL_VGA_MBS 1200 +#define DDL_WVGA_MBS 1500 +#define DDL_720P_MBS 3600 + +#define DDL_FRAMESIZE_DIV_FACTOR (0xF) + +#define DDL_NO_OF_MB(width, height) \ + (((width + 15) >> 4) * ((height + 15) >> 4)) + +#define DDL_ALLOW_ENC_FRAMESIZE(width, height) \ +((DDL_NO_OF_MB(width, height) <= DDL_720P_MBS) \ + && (((width) <= DDL_MAX_FRAME_WIDTH) && \ + ((height) <= DDL_MAX_FRAME_WIDTH)) \ + && ((width) >= 32 && (height) >= 32)) + +#define DDL_VALIDATE_ENC_FRAMESIZE(width, height) \ + (!((width) & DDL_FRAMESIZE_DIV_FACTOR) && \ + !((height) & DDL_FRAMESIZE_DIV_FACTOR)) + +#define DDL_TILE_ALIGN_WIDTH 128 +#define DDL_TILE_ALIGN_HEIGHT 32 +#define DDL_TILE_MULTIPLY_FACTOR 8192 +#define DDL_TILE_ALIGN(val, grid) \ + (((val) + (grid) - 1) / (grid) * (grid)) + +#endif diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c new file mode 100644 index 000000000000..17416fb47e32 --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_errors.c @@ -0,0 +1,609 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#include +#include "vcd_ddl_utils.h" +#include "vcd_ddl.h" + +#if DEBUG +#define DBG(x...) printk(KERN_DEBUG x) +#else +#define DBG(x...) +#endif + +#define ERR(x...) printk(KERN_ERR x) + +#define INVALID_CHANNEL_NUMBER 1 +#define INVALID_COMMAND_ID 2 +#define CHANNEL_ALREADY_IN_USE 3 +#define CHANNEL_NOT_SET_BEFORE_CHANNEL_CLOSE 4 +#define CHANNEL_SET_ERROR_INIT_CODEC 5 +#define INIT_CODEC_ALREADY_CALLED 6 +#define CHANNEL_SET_ERROR_INIT_BUFFERS 7 +#define INIT_CODEC_ERROR_INIT_BUFFERS 8 +#define INIT_BUFFER_ALREADY_CALLED 9 +#define CHANNEL_SET_ERROR_FRAME_RUN 10 +#define INIT_CODEC_ERROR_FRAME_RUN 11 +#define INIT_BUFFERS_ERROR_FRAME_RUN 12 +#define CODEC_LIMIT_EXCEEDED 13 +#define FIRMWARE_SIZE_ZERO 14 +#define FIRMWARE_ADDRESS_EXT_ZERO 15 +#define CONTEXT_DMA_IN_ERROR 16 +#define CONTEXT_DMA_OUT_ERROR 17 +#define PROGRAM_DMA_ERROR 18 +#define CONTEXT_STORE_EXT_ADD_ZERO 19 +#define MEM_ALLOCATION_FAILED 20 + + +#define UNSUPPORTED_FEATURE_IN_PROFILE 27 +#define RESOLUTION_NOT_SUPPORTED 28 +#define HEADER_NOT_FOUND 52 +#define MB_NUM_INVALID 61 +#define FRAME_RATE_NOT_SUPPORTED 62 +#define INVALID_QP_VALUE 63 +#define INVALID_RC_REACTION_COEFFICIENT 64 +#define INVALID_CPB_SIZE_AT_GIVEN_LEVEL 65 + +#define ALLOC_DPB_SIZE_NOT_SUFFICIENT 71 +#define ALLOC_DB_SIZE_NOT_SUFFICIENT 72 +#define ALLOC_COMV_SIZE_NOT_SUFFICIENT 73 +#define NUM_BUF_OUT_OF_RANGE 74 +#define NULL_CONTEXT_POINTER 75 +#define NULL_COMAMND_CONTROL_COMM_POINTER 76 +#define NULL_METADATA_INPUT_POINTER 77 +#define NULL_DPB_POINTER 78 +#define NULL_DB_POINTER 79 +#define NULL_COMV_POINTER 80 + +#define DIVIDE_BY_ZERO 81 +#define BIT_STREAM_BUF_EXHAUST 82 +#define DMA_NOT_STOPPED 83 +#define DMA_TX_NOT_COMPLETE 84 + +#define MB_HEADER_NOT_DONE 85 +#define MB_COEFF_NOT_DONE 86 +#define CODEC_SLICE_NOT_DONE 87 +#define VME_NOT_READY 88 +#define VC1_BITPLANE_DECODE_ERR 89 + + +#define VSP_NOT_READY 90 +#define BUFFER_FULL_STATE 91 + +#define RESOLUTION_MISMATCH 112 +#define NV_QUANT_ERR 113 +#define SYNC_MARKER_ERR 114 +#define FEATURE_NOT_SUPPORTED 115 +#define MEM_CORRUPTION 116 +#define INVALID_REFERENCE_FRAME 117 +#define PICTURE_CODING_TYPE_ERR 118 +#define MV_RANGE_ERR 119 +#define PICTURE_STRUCTURE_ERR 120 +#define SLICE_ADDR_INVALID 121 +#define NON_PAIRED_FIELD_NOT_SUPPORTED 122 +#define NON_FRAME_DATA_RECEIVED 123 +#define INCOMPLETE_FRAME 124 +#define NO_BUFFER_RELEASED_FROM_HOST 125 +#define PICTURE_MANAGEMENT_ERROR 128 +#define INVALID_MMCO 129 +#define INVALID_PIC_REORDERING 130 +#define INVALID_POC_TYPE 131 +#define ACTIVE_SPS_NOT_PRESENT 132 +#define ACTIVE_PPS_NOT_PRESENT 133 +#define INVALID_SPS_ID 134 +#define INVALID_PPS_ID 135 + + +#define METADATA_NO_SPACE_QP 151 +#define METADATA_NO_SAPCE_CONCEAL_MB 152 +#define METADATA_NO_SPACE_VC1_PARAM 153 +#define METADATA_NO_SPACE_SEI 154 +#define METADATA_NO_SPACE_VUI 155 +#define METADATA_NO_SPACE_EXTRA 156 +#define METADATA_NO_SPACE_DATA_NONE 157 +#define FRAME_RATE_UNKNOWN 158 +#define ASPECT_RATIO_UNKOWN 159 +#define COLOR_PRIMARIES_UNKNOWN 160 +#define TRANSFER_CHAR_UNKWON 161 +#define MATRIX_COEFF_UNKNOWN 162 +#define NON_SEQ_SLICE_ADDR 163 +#define BROKEN_LINK 164 +#define FRAME_CONCEALED 165 +#define PROFILE_UNKOWN 166 +#define LEVEL_UNKOWN 167 +#define BIT_RATE_NOT_SUPPORTED 168 +#define COLOR_DIFF_FORMAT_NOT_SUPPORTED 169 +#define NULL_EXTRA_METADATA_POINTER 170 +#define SYNC_POINT_NOT_RECEIVED_STARTED_DECODING 171 +#define NULL_FW_DEBUG_INFO_POINTER 172 +#define ALLOC_DEBUG_INFO_SIZE_INSUFFICIENT 173 +#define MAX_STAGE_COUNTER_EXCEEDED 174 + +#define METADATA_NO_SPACE_MB_INFO 180 +#define METADATA_NO_SPACE_SLICE_SIZE 181 +#define RESOLUTION_WARNING 182 + +static void ddl_handle_npf_decoding_error( + struct ddl_context *ddl_context); + +static u32 ddl_handle_seqhdr_fail_error( + struct ddl_context *ddl_context); + +void ddl_hw_fatal_cb(struct ddl_context *ddl_context) +{ + /* Invalidate the command state */ + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + ddl_context->device_state = DDL_DEVICE_HWFATAL; + + /* callback to the client to indicate hw fatal error */ + ddl_context->ddl_callback(VCD_EVT_IND_HWERRFATAL, + VCD_ERR_HW_FATAL, NULL, 0, + (void *)ddl_context->current_ddl, + ddl_context->client_data); + + DDL_IDLE(ddl_context); +} + +static u32 ddl_handle_hw_fatal_errors(struct ddl_context + *ddl_context) +{ + u32 status = false; + + switch (ddl_context->cmd_err_status) { + + case INVALID_CHANNEL_NUMBER: + case INVALID_COMMAND_ID: + case CHANNEL_ALREADY_IN_USE: + case CHANNEL_NOT_SET_BEFORE_CHANNEL_CLOSE: + case CHANNEL_SET_ERROR_INIT_CODEC: + case INIT_CODEC_ALREADY_CALLED: + case CHANNEL_SET_ERROR_INIT_BUFFERS: + case INIT_CODEC_ERROR_INIT_BUFFERS: + case INIT_BUFFER_ALREADY_CALLED: + case CHANNEL_SET_ERROR_FRAME_RUN: + case INIT_CODEC_ERROR_FRAME_RUN: + case INIT_BUFFERS_ERROR_FRAME_RUN: + case CODEC_LIMIT_EXCEEDED: + case FIRMWARE_SIZE_ZERO: + case FIRMWARE_ADDRESS_EXT_ZERO: + + case CONTEXT_DMA_IN_ERROR: + case CONTEXT_DMA_OUT_ERROR: + case PROGRAM_DMA_ERROR: + case CONTEXT_STORE_EXT_ADD_ZERO: + case MEM_ALLOCATION_FAILED: + + case DIVIDE_BY_ZERO: + case DMA_NOT_STOPPED: + case DMA_TX_NOT_COMPLETE: + + case VSP_NOT_READY: + case BUFFER_FULL_STATE: + case NULL_DB_POINTER: + ERR("HW FATAL ERROR"); + ddl_hw_fatal_cb(ddl_context); + status = true; + break; + } + return status; +} + +void ddl_client_fatal_cb(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl = + ddl_context->current_ddl; + + if (ddl_context->cmd_state == DDL_CMD_DECODE_FRAME) + ddl_decode_dynamic_property(ddl, false); + else if (ddl_context->cmd_state == DDL_CMD_ENCODE_FRAME) + ddl_encode_dynamic_property(ddl, false); + + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + + ddl_move_client_state(ddl, DDL_CLIENT_FATAL_ERROR); + + ddl_context->ddl_callback + ( + VCD_EVT_IND_HWERRFATAL, + VCD_ERR_CLIENT_FATAL, + NULL, + 0, + (void *)ddl, + ddl_context->client_data + ); + + DDL_IDLE(ddl_context); +} + +static u32 ddl_handle_client_fatal_errors(struct ddl_context + *ddl_context) +{ + u32 status = false; + + switch (ddl_context->cmd_err_status) { + case MB_NUM_INVALID: + case FRAME_RATE_NOT_SUPPORTED: + case INVALID_QP_VALUE: + case INVALID_RC_REACTION_COEFFICIENT: + case INVALID_CPB_SIZE_AT_GIVEN_LEVEL: + + case ALLOC_DPB_SIZE_NOT_SUFFICIENT: + case ALLOC_DB_SIZE_NOT_SUFFICIENT: + case ALLOC_COMV_SIZE_NOT_SUFFICIENT: + case NUM_BUF_OUT_OF_RANGE: + case NULL_CONTEXT_POINTER: + case NULL_COMAMND_CONTROL_COMM_POINTER: + case NULL_METADATA_INPUT_POINTER: + case NULL_DPB_POINTER: + case NULL_COMV_POINTER: + { + status = true; + break; + } + } + + if (!status) + ERR("UNKNOWN-OP-FAILED"); + + ddl_client_fatal_cb(ddl_context); + + return true; +} + +static void ddl_input_failed_cb(struct ddl_context *ddl_context, + u32 vcd_event, u32 vcd_status) +{ + struct ddl_client_context *ddl = ddl_context->current_ddl; + + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + + if (ddl->decoding) + ddl_decode_dynamic_property(ddl, false); + else + ddl_encode_dynamic_property(ddl, false); + + ddl_context->ddl_callback(vcd_event, + vcd_status, &ddl->input_frame, + sizeof(struct ddl_frame_data_tag), + (void *)ddl, ddl_context->client_data); + + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_FRAME); +} + +static u32 ddl_handle_core_recoverable_errors(struct ddl_context \ + *ddl_context) +{ + struct ddl_client_context *ddl = ddl_context->current_ddl; + u32 vcd_status = VCD_S_SUCCESS; + u32 vcd_event = VCD_EVT_RESP_INPUT_DONE; + u32 eos = false, pending_display = 0, release_mask = 0; + + if (ddl->decoding) + if (ddl_handle_seqhdr_fail_error(ddl_context)) + return true; + + if (ddl_context->cmd_state != DDL_CMD_DECODE_FRAME && + ddl_context->cmd_state != DDL_CMD_ENCODE_FRAME) { + return false; + } + switch (ddl_context->cmd_err_status) { + case NON_PAIRED_FIELD_NOT_SUPPORTED: + { + ddl_handle_npf_decoding_error(ddl_context); + return true; + } + case NO_BUFFER_RELEASED_FROM_HOST: + { + /* lets check sanity of this error */ + release_mask = + ddl->codec_data.decoder.dpb_mask.hw_mask; + while (release_mask > 0) { + if ((release_mask & 0x1)) + pending_display += 1; + release_mask >>= 1; + } + + if (pending_display >= + ddl->codec_data.decoder.min_dpb_num) { + DBG("FWISSUE-REQBUF!!"); + /* callback to client for client fatal error */ + ddl_client_fatal_cb(ddl_context); + return true ; + } + vcd_event = VCD_EVT_RESP_OUTPUT_REQ; + break; + } + case BIT_STREAM_BUF_EXHAUST: + case MB_HEADER_NOT_DONE: + case MB_COEFF_NOT_DONE: + case CODEC_SLICE_NOT_DONE: + case VME_NOT_READY: + case VC1_BITPLANE_DECODE_ERR: + { + u32 reset_core; + /* need to reset the internal core hw engine */ + reset_core = ddl_hal_engine_reset(ddl_context); + if (!reset_core) + return true; + /* fall through to process bitstream error handling */ + } + case RESOLUTION_MISMATCH: + case NV_QUANT_ERR: + case SYNC_MARKER_ERR: + case FEATURE_NOT_SUPPORTED: + case MEM_CORRUPTION: + case INVALID_REFERENCE_FRAME: + case PICTURE_CODING_TYPE_ERR: + case MV_RANGE_ERR: + case PICTURE_STRUCTURE_ERR: + case SLICE_ADDR_INVALID: + case NON_FRAME_DATA_RECEIVED: + case INCOMPLETE_FRAME: + case PICTURE_MANAGEMENT_ERROR: + case INVALID_MMCO: + case INVALID_PIC_REORDERING: + case INVALID_POC_TYPE: + { + vcd_status = VCD_ERR_BITSTREAM_ERR; + break; + } + case ACTIVE_SPS_NOT_PRESENT: + case ACTIVE_PPS_NOT_PRESENT: + { + if (ddl->codec_data.decoder.idr_only_decoding) { + DBG("Consider warnings as errors in idr mode"); + ddl_client_fatal_cb(ddl_context); + return true; + } + vcd_status = VCD_ERR_BITSTREAM_ERR; + break; + } + case PROFILE_UNKOWN: + if (ddl->decoding) + vcd_status = VCD_ERR_BITSTREAM_ERR; + break; + } + + if (!vcd_status && vcd_event == VCD_EVT_RESP_INPUT_DONE) + return false; + + ddl->input_frame.frm_trans_end = true; + + eos = ((vcd_event == VCD_EVT_RESP_INPUT_DONE) && + ((VCD_FRAME_FLAG_EOS & ddl->input_frame. + vcd_frm.flags))); + + if ((ddl->decoding && eos) || + (!ddl->decoding)) + ddl->input_frame.frm_trans_end = false; + + if (vcd_event == VCD_EVT_RESP_INPUT_DONE && + ddl->decoding && + !ddl->codec_data.decoder.header_in_start && + !ddl->codec_data.decoder.dec_disp_info.img_size_x && + !ddl->codec_data.decoder.dec_disp_info.img_size_y + ) { + /* this is first frame seq. header only case */ + vcd_status = VCD_S_SUCCESS; + ddl->input_frame.vcd_frm.flags |= + VCD_FRAME_FLAG_CODECCONFIG; + ddl->input_frame.frm_trans_end = !eos; + /* put just some non - zero value */ + ddl->codec_data.decoder.dec_disp_info.img_size_x = 0xff; + } + /* inform client about input failed */ + ddl_input_failed_cb(ddl_context, vcd_event, vcd_status); + + /* for Encoder case, we need to send output done also */ + if (!ddl->decoding) { + /* transaction is complete after this callback */ + ddl->output_frame.frm_trans_end = !eos; + /* error case: NO data present */ + ddl->output_frame.vcd_frm.data_len = 0; + /* call back to client for output frame done */ + ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE, + VCD_ERR_FAIL, &(ddl->output_frame), + sizeof(struct ddl_frame_data_tag), + (void *)ddl, ddl_context->client_data); + + if (eos) { + DBG("ENC-EOS_DONE"); + /* send client EOS DONE callback */ + ddl_context->ddl_callback(VCD_EVT_RESP_EOS_DONE, + VCD_S_SUCCESS, NULL, 0, (void *)ddl, + ddl_context->client_data); + } + } + + /* if it is decoder EOS case */ + if (ddl->decoding && eos) + ddl_decode_eos_run(ddl); + else + DDL_IDLE(ddl_context); + + return true; +} + +static u32 ddl_handle_core_warnings(u32 err_status) +{ + u32 status = false; + + switch (err_status) { + case FRAME_RATE_UNKNOWN: + case ASPECT_RATIO_UNKOWN: + case COLOR_PRIMARIES_UNKNOWN: + case TRANSFER_CHAR_UNKWON: + case MATRIX_COEFF_UNKNOWN: + case NON_SEQ_SLICE_ADDR: + case BROKEN_LINK: + case FRAME_CONCEALED: + case PROFILE_UNKOWN: + case LEVEL_UNKOWN: + case BIT_RATE_NOT_SUPPORTED: + case COLOR_DIFF_FORMAT_NOT_SUPPORTED: + case NULL_EXTRA_METADATA_POINTER: + case SYNC_POINT_NOT_RECEIVED_STARTED_DECODING: + + case NULL_FW_DEBUG_INFO_POINTER: + case ALLOC_DEBUG_INFO_SIZE_INSUFFICIENT: + case MAX_STAGE_COUNTER_EXCEEDED: + + case METADATA_NO_SPACE_MB_INFO: + case METADATA_NO_SPACE_SLICE_SIZE: + case RESOLUTION_WARNING: + + /* decoder warnings */ + case METADATA_NO_SPACE_QP: + case METADATA_NO_SAPCE_CONCEAL_MB: + case METADATA_NO_SPACE_VC1_PARAM: + case METADATA_NO_SPACE_SEI: + case METADATA_NO_SPACE_VUI: + case METADATA_NO_SPACE_EXTRA: + case METADATA_NO_SPACE_DATA_NONE: + { + status = true; + DBG("CMD-WARNING-IGNORED!!"); + break; + } + } + return status; +} + +u32 ddl_handle_core_errors(struct ddl_context *ddl_context) +{ + u32 status = false; + + if (!ddl_context->cmd_err_status && + !ddl_context->disp_pic_err_status && + !ddl_context->op_failed) + return false; + + if (ddl_context->cmd_state == DDL_CMD_INVALID) { + DBG("SPURIOUS_INTERRUPT_ERROR"); + return true; + } + + if (!ddl_context->op_failed) { + u32 disp_status; + status = ddl_handle_core_warnings(ddl_context-> + cmd_err_status); + disp_status = ddl_handle_core_warnings( + ddl_context->disp_pic_err_status); + if (!status && !disp_status) + DBG("ddl_warning:Unknown"); + + return false; + } + + ERR("\n %s(): OPFAILED!!", __func__); + ERR("\n CMD_ERROR_STATUS = %u, DISP_ERR_STATUS = %u", + ddl_context->cmd_err_status, + ddl_context->disp_pic_err_status); + + status = ddl_handle_hw_fatal_errors(ddl_context); + + if (!status) + status = ddl_handle_core_recoverable_errors(ddl_context); + + if (!status) + status = ddl_handle_client_fatal_errors(ddl_context); + + return status; +} + +void ddl_handle_npf_decoding_error(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl = ddl_context->current_ddl; + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + if (!ddl->decoding) { + ERR("FWISSUE-ENC-NPF!!!"); + ddl_client_fatal_cb(ddl_context); + return; + } + vidc_720p_decode_display_info(&decoder->dec_disp_info); + ddl_decode_dynamic_property(ddl, false); + ddl->output_frame.vcd_frm.ip_frm_tag = + decoder->dec_disp_info.tag_top; + ddl->output_frame.vcd_frm.physical = NULL; + ddl->output_frame.frm_trans_end = false; + ddl->ddl_context->ddl_callback( + VCD_EVT_RESP_OUTPUT_DONE, + VCD_ERR_INTRLCD_FIELD_DROP, + &ddl->output_frame, + sizeof(struct ddl_frame_data_tag), + (void *)ddl, + ddl->ddl_context->client_data); + ddl_decode_frame_run(ddl); +} + +u32 ddl_handle_seqhdr_fail_error(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl = ddl_context->current_ddl; + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + u32 status = false; + if (ddl_context->cmd_state == DDL_CMD_HEADER_PARSE && + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE)) { + switch (ddl_context->cmd_err_status) { + case UNSUPPORTED_FEATURE_IN_PROFILE: + case HEADER_NOT_FOUND: + case INVALID_SPS_ID: + case INVALID_PPS_ID: + case RESOLUTION_NOT_SUPPORTED: + case PROFILE_UNKOWN: + ERR("SEQ-HDR-FAILED!!!"); + if ((ddl_context->cmd_err_status == + RESOLUTION_NOT_SUPPORTED) && + (decoder->codec.codec == VCD_CODEC_H264 || + decoder->codec.codec == VCD_CODEC_H263 || + decoder->codec.codec == VCD_CODEC_MPEG4 || + decoder->codec.codec == VCD_CODEC_VC1_RCV || + decoder->codec.codec == VCD_CODEC_VC1)) { + ddl_client_fatal_cb(ddl_context); + status = true; + break; + } + if (decoder->header_in_start) { + decoder->header_in_start = false; + ddl_context->ddl_callback(VCD_EVT_RESP_START, + VCD_ERR_SEQHDR_PARSE_FAIL, + NULL, 0, (void *)ddl, + ddl_context->client_data); + } else { + if (ddl->input_frame.vcd_frm.flags & + VCD_FRAME_FLAG_EOS) + ddl->input_frame.frm_trans_end = false; + else + ddl->input_frame.frm_trans_end = true; + ddl_decode_dynamic_property(ddl, false); + ddl_context->ddl_callback( + VCD_EVT_RESP_INPUT_DONE, + VCD_ERR_SEQHDR_PARSE_FAIL, + &ddl->input_frame, + sizeof(struct ddl_frame_data_tag), + (void *)ddl, ddl_context->client_data); + if (ddl->input_frame.vcd_frm.flags & + VCD_FRAME_FLAG_EOS) + ddl_context->ddl_callback( + VCD_EVT_RESP_EOS_DONE, + VCD_S_SUCCESS, NULL, + 0, (void *)ddl, + ddl_context->client_data); + } + ddl_move_client_state(ddl, + DDL_CLIENT_WAIT_FOR_INITCODEC); + DDL_IDLE(ddl_context); + status = true; + } + } + return status; +} diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.c new file mode 100644 index 000000000000..23948d4e8f54 --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.c @@ -0,0 +1,352 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#include +#include "vcd_ddl_firmware.h" +#include "vcd_ddl_utils.h" + +#define VCDFW_TOTALNUM_IMAGE 7 +#define VCDFW_MAX_NO_IMAGE 2 + +struct vcd_firmware { + u32 active_fw_img[VCDFW_TOTALNUM_IMAGE]; + struct ddl_buf_addr boot_code; + + struct ddl_buf_addr enc_mpeg4; + struct ddl_buf_addr encH264; + + struct ddl_buf_addr dec_mpeg4; + struct ddl_buf_addr decH264; + struct ddl_buf_addr decH263; + struct ddl_buf_addr dec_mpeg2; + struct ddl_buf_addr dec_vc1; +}; + +static struct vcd_firmware vcd_firmware; + + +static void vcd_fw_change_endian(unsigned char *fw, u32 fw_size) +{ + u32 i = 0; + unsigned char temp; + for (i = 0; i < fw_size; i = i + 4) { + temp = fw[i]; + fw[i] = fw[i + 3]; + fw[i + 3] = temp; + + temp = fw[i + 1]; + fw[i + 1] = fw[i + 2]; + fw[i + 2] = temp; + } + return; +} + +static u32 vcd_fw_prepare(struct ddl_buf_addr *fw_details, + const unsigned char fw_array[], + const unsigned int fw_array_size, u32 change_endian) +{ + u32 *buffer; + + ddl_pmem_alloc(fw_details, fw_array_size, + DDL_LINEAR_BUFFER_ALIGN_BYTES); + if (!fw_details->virtual_base_addr) + return false; + + fw_details->buffer_size = fw_array_size / 4; + + buffer = fw_details->align_virtual_addr; + + memcpy(buffer, fw_array, fw_array_size); + if (change_endian) + vcd_fw_change_endian((unsigned char *)buffer, fw_array_size); + return true; +} + +u32 vcd_fw_init(void) +{ + u32 status = false; + + status = vcd_fw_prepare(&vcd_firmware.boot_code, + vidc_command_control_fw, + vidc_command_control_fw_size, false); + + if (status) { + status = vcd_fw_prepare(&vcd_firmware.dec_mpeg4, + vidc_mpg4_dec_fw, + vidc_mpg4_dec_fw_size, true); + } + + if (status) { + status = vcd_fw_prepare(&vcd_firmware.decH264, + vidc_h264_dec_fw, + vidc_h264_dec_fw_size, true); + } + + if (status) { + status = vcd_fw_prepare(&vcd_firmware.decH263, + vidc_h263_dec_fw, + vidc_h263_dec_fw_size, true); + } + + if (status) { + status = vcd_fw_prepare(&vcd_firmware.enc_mpeg4, + vidc_mpg4_enc_fw, + vidc_mpg4_enc_fw_size, true); + } + + if (status) { + status = vcd_fw_prepare(&vcd_firmware.encH264, + vidc_h264_enc_fw, + vidc_h264_enc_fw_size, true); + } + + if (status) { + status = vcd_fw_prepare(&vcd_firmware.dec_vc1, + vidc_vc1_dec_fw, + vidc_vc1_dec_fw_size, true); + } + return status; +} + + +static u32 get_dec_fw_image(struct vcd_fw_details *fw_details) +{ + u32 status = true; + switch (fw_details->codec) { + case VCD_CODEC_DIVX_4: + case VCD_CODEC_DIVX_5: + case VCD_CODEC_DIVX_6: + case VCD_CODEC_XVID: + case VCD_CODEC_MPEG4: + { + fw_details->fw_buffer_addr = + vcd_firmware.dec_mpeg4.align_physical_addr; + fw_details->fw_size = + vcd_firmware.dec_mpeg4.buffer_size; + break; + } + case VCD_CODEC_H264: + { + fw_details->fw_buffer_addr = + vcd_firmware.decH264.align_physical_addr; + fw_details->fw_size = + vcd_firmware.decH264.buffer_size; + break; + } + case VCD_CODEC_VC1: + case VCD_CODEC_VC1_RCV: + { + fw_details->fw_buffer_addr = + vcd_firmware.dec_vc1.align_physical_addr; + fw_details->fw_size = + vcd_firmware.dec_vc1.buffer_size; + break; + } + case VCD_CODEC_MPEG2: + { + fw_details->fw_buffer_addr = + vcd_firmware.dec_mpeg2.align_physical_addr; + fw_details->fw_size = + vcd_firmware.dec_mpeg2.buffer_size; + break; + } + case VCD_CODEC_H263: + { + fw_details->fw_buffer_addr = + vcd_firmware.decH263.align_physical_addr; + fw_details->fw_size = + vcd_firmware.decH263.buffer_size; + break; + } + default: + { + status = false; + break; + } + } + return status; +} + +static u32 get_enc_fw_image(struct vcd_fw_details *fw_details) +{ + u32 status = true; + switch (fw_details->codec) { + case VCD_CODEC_H263: + case VCD_CODEC_MPEG4: + { + fw_details->fw_buffer_addr = + vcd_firmware.enc_mpeg4.align_physical_addr; + fw_details->fw_size = + vcd_firmware.enc_mpeg4.buffer_size; + break; + } + case VCD_CODEC_H264: + { + fw_details->fw_buffer_addr = + vcd_firmware.encH264.align_physical_addr; + fw_details->fw_size = + vcd_firmware.encH264.buffer_size; + break; + } + default: + { + status = false; + break; + } + } + return status; +} + +u32 vcd_get_fw_property(u32 prop_id, void *prop_details) +{ + u32 status = true; + struct vcd_fw_details *fw_details; + switch (prop_id) { + case VCD_FW_ENDIAN: + { + *(u32 *) prop_details = VCD_FW_BIG_ENDIAN; + break; + } + case VCD_FW_BOOTCODE: + { + fw_details = + (struct vcd_fw_details *)prop_details; + fw_details->fw_buffer_addr = + vcd_firmware.boot_code.align_physical_addr; + fw_details->fw_size = + vcd_firmware.boot_code.buffer_size; + break; + } + case VCD_FW_DECODE: + { + fw_details = + (struct vcd_fw_details *)prop_details; + status = get_dec_fw_image(fw_details); + break; + } + case VCD_FW_ENCODE: + { + fw_details = + (struct vcd_fw_details *)prop_details; + status = get_enc_fw_image(fw_details); + break; + } + default: + { + status = false; + break; + } + } + return status; +} + +u32 vcd_fw_transact(u32 add, u32 decoding, enum vcd_codec codec) +{ + u32 status = true; + u32 index = 0, active_fw = 0, loop_count; + + if (decoding) { + switch (codec) { + case VCD_CODEC_DIVX_4: + case VCD_CODEC_DIVX_5: + case VCD_CODEC_DIVX_6: + case VCD_CODEC_XVID: + case VCD_CODEC_MPEG4: + { + index = 0; + break; + } + case VCD_CODEC_H264: + { + index = 1; + break; + } + case VCD_CODEC_H263: + { + index = 2; + break; + } + case VCD_CODEC_MPEG2: + { + index = 3; + break; + } + case VCD_CODEC_VC1: + case VCD_CODEC_VC1_RCV: + { + index = 4; + break; + } + default: + { + status = false; + break; + } + } + } else { + switch (codec) { + case VCD_CODEC_H263: + case VCD_CODEC_MPEG4: + { + index = 5; + break; + } + case VCD_CODEC_H264: + { + index = 6; + break; + } + default: + { + status = false; + break; + } + } + } + + if (!status) + return status; + + if (!add && + vcd_firmware.active_fw_img[index] + ) { + --vcd_firmware.active_fw_img[index]; + return status; + } + + for (loop_count = 0; loop_count < VCDFW_TOTALNUM_IMAGE; + ++loop_count) { + if (vcd_firmware.active_fw_img[loop_count]) + ++active_fw; + } + + if (active_fw < VCDFW_MAX_NO_IMAGE || + vcd_firmware.active_fw_img[index] > 0) { + ++vcd_firmware.active_fw_img[index]; + } else { + status = false; + } + return status; +} + +void vcd_fw_release(void) +{ + ddl_pmem_free(&vcd_firmware.boot_code); + ddl_pmem_free(&vcd_firmware.enc_mpeg4); + ddl_pmem_free(&vcd_firmware.encH264); + ddl_pmem_free(&vcd_firmware.dec_mpeg4); + ddl_pmem_free(&vcd_firmware.decH264); + ddl_pmem_free(&vcd_firmware.decH263); + ddl_pmem_free(&vcd_firmware.dec_mpeg2); + ddl_pmem_free(&vcd_firmware.dec_vc1); +} diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.h new file mode 100644 index 000000000000..ba8dbcbfcce4 --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_firmware.h @@ -0,0 +1,53 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#ifndef _VCD_DDL_FIRMWARE_H_ +#define _VCD_DDL_FIRMWARE_H_ +#include + +#define VCD_FW_BIG_ENDIAN 0x0 +#define VCD_FW_LITTLE_ENDIAN 0x1 + +struct vcd_fw_details { + enum vcd_codec codec; + u32 *fw_buffer_addr; + u32 fw_size; +}; + +#define VCD_FW_PROP_BASE 0x0 + +#define VCD_FW_ENDIAN (VCD_FW_PROP_BASE + 0x1) +#define VCD_FW_BOOTCODE (VCD_FW_PROP_BASE + 0x2) +#define VCD_FW_DECODE (VCD_FW_PROP_BASE + 0x3) +#define VCD_FW_ENCODE (VCD_FW_PROP_BASE + 0x4) + +extern unsigned char *vidc_command_control_fw; +extern u32 vidc_command_control_fw_size; +extern unsigned char *vidc_mpg4_dec_fw; +extern u32 vidc_mpg4_dec_fw_size; +extern unsigned char *vidc_h263_dec_fw; +extern u32 vidc_h263_dec_fw_size; +extern unsigned char *vidc_h264_dec_fw; +extern u32 vidc_h264_dec_fw_size; +extern unsigned char *vidc_mpg4_enc_fw; +extern u32 vidc_mpg4_enc_fw_size; +extern unsigned char *vidc_h264_enc_fw; +extern u32 vidc_h264_enc_fw_size; +extern unsigned char *vidc_vc1_dec_fw; +extern u32 vidc_vc1_dec_fw_size; + +u32 vcd_fw_init(void); +u32 vcd_get_fw_property(u32 prop_id, void *prop_details); +u32 vcd_fw_transact(u32 add, u32 decoding, enum vcd_codec codec); +void vcd_fw_release(void); + +#endif diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c new file mode 100644 index 000000000000..4cbd984a47ca --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c @@ -0,0 +1,971 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#include + +#include "vcd_ddl_utils.h" +#include "vcd_ddl_metadata.h" + +#if DEBUG +#define DBG(x...) printk(KERN_DEBUG x) +#else +#define DBG(x...) +#endif + +#define DBG_INFO(x...) pr_info(x) + +void ddl_core_init(struct ddl_context *ddl_context) +{ + char *psz_version; + struct vcd_fw_details fw_details; + u32 fw_endianness; + enum vidc_720p_endian dma_endian; + u32 interrupt_off; + enum vidc_720p_interrupt_level_selection interrupt_sel; + u32 intr_mask = 0x0; + + vcd_get_fw_property(VCD_FW_BOOTCODE, &fw_details); + vcd_get_fw_property(VCD_FW_ENDIAN, &fw_endianness); + if (fw_endianness == VCD_FW_BIG_ENDIAN) + dma_endian = VIDC_720P_BIG_ENDIAN; + else + dma_endian = VIDC_720P_LITTLE_ENDIAN; + + interrupt_off = false; + interrupt_sel = VIDC_720P_INTERRUPT_LEVEL_SEL; + + intr_mask |= VIDC_720P_INTR_BUFFER_FULL; + intr_mask |= VIDC_720P_INTR_FW_DONE; + intr_mask |= VIDC_720P_INTR_DMA_DONE; + intr_mask |= VIDC_720P_INTR_FRAME_DONE; + + vidc_720p_do_sw_reset(); + + DBG_INFO("Loading CONTROL_FW of FW_SIZE %u\n", + fw_details.fw_size*4); + + vidc_720p_init(&psz_version, + fw_details.fw_size, + fw_details.fw_buffer_addr, + dma_endian, + interrupt_off, interrupt_sel, intr_mask); + return; +} + +void ddl_core_start_cpu(struct ddl_context *ddl_context) +{ + u32 fw_endianness; + enum vidc_720p_endian dma_endian; + u32 dbg_core_dump_buf_size = 0; + + vcd_get_fw_property(VCD_FW_ENDIAN, &fw_endianness); + if (fw_endianness == VCD_FW_BIG_ENDIAN) + dma_endian = VIDC_720P_LITTLE_ENDIAN; + else + dma_endian = VIDC_720P_BIG_ENDIAN; + + ddl_move_command_state(ddl_context, DDL_CMD_CPU_RESET); + + DBG("VSP_BUF_ADDR_SIZE %d", + ddl_context->context_buf_addr.buffer_size); + if (ddl_context->enable_dbg_core_dump) { + dbg_core_dump_buf_size = ddl_context->dbg_core_dump. + buffer_size; + } + + vidc_720p_start_cpu(dma_endian, + ddl_context->context_buf_addr.align_physical_addr, + ddl_context->dbg_core_dump.align_physical_addr, + dbg_core_dump_buf_size); + + VIDC_DEBUG_REGISTER_LOG; +} + +void ddl_channel_set(struct ddl_client_context *ddl) +{ + enum vidc_720p_enc_dec_selection enc_dec_sel; + enum vidc_720p_codec codec; + enum vcd_codec *vcd_codec; + u32 fw_property_id; + struct vcd_fw_details fw_details; + + if (ddl->decoding) { + if (vidc_msg_timing) + ddl_set_core_start_time(__func__, DEC_OP_TIME); + enc_dec_sel = VIDC_720P_DECODER; + fw_property_id = VCD_FW_DECODE; + vcd_codec = &(ddl->codec_data.decoder.codec.codec); + } else { + enc_dec_sel = VIDC_720P_ENCODER; + fw_property_id = VCD_FW_ENCODE; + vcd_codec = &(ddl->codec_data.encoder.codec.codec); + } + switch (*vcd_codec) { + default: + case VCD_CODEC_MPEG4: + { + codec = VIDC_720P_MPEG4; + + if (ddl->decoding) { + vidc_720p_decode_set_mpeg4_data_partitionbuffer + (ddl->ddl_context->data_partition_tempbuf. + align_physical_addr); + } + + break; + } + case VCD_CODEC_H264: + { + codec = VIDC_720P_H264; + break; + } + case VCD_CODEC_DIVX_4: + case VCD_CODEC_DIVX_5: + case VCD_CODEC_DIVX_6: + { + codec = VIDC_720P_DIVX; + break; + } + case VCD_CODEC_XVID: + { + codec = VIDC_720P_XVID; + break; + } + case VCD_CODEC_H263: + { + codec = VIDC_720P_H263; + break; + } + case VCD_CODEC_MPEG2: + { + codec = VIDC_720P_MPEG2; + break; + } + case VCD_CODEC_VC1: + case VCD_CODEC_VC1_RCV: + { + codec = VIDC_720P_VC1; + break; + } + } + + fw_details.codec = *vcd_codec; + vcd_get_fw_property(fw_property_id, &fw_details); + VIDC_DEBUG_REGISTER_LOG; + + ddl_move_command_state(ddl->ddl_context, DDL_CMD_CHANNEL_SET); + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_CHDONE); + + DBG_INFO("Loading firmware for CODEC:%u of FW_SIZE:%u\n", + fw_details.codec, fw_details.fw_size*4); + + vidc_720p_set_channel(ddl->channel_id, + enc_dec_sel, + codec, + fw_details.fw_buffer_addr, + fw_details.fw_size); +} + +void ddl_decode_init_codec(struct ddl_client_context *ddl) +{ + u32 seq_h = 0, seq_e = 0, start_byte_num = 0; + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + struct vcd_sequence_hdr *seq_hdr = &decoder->decode_config; + enum vidc_720p_memory_access_method mem_access_method; + if (vidc_msg_timing) + ddl_set_core_start_time(__func__, DEC_OP_TIME); + ddl_metadata_enable(ddl); + + vidc_720p_decode_set_error_control(true); + + vidc_720p_decode_set_mpeg4Post_filter(decoder->post_filter. + post_filter); + + if (decoder->codec.codec == VCD_CODEC_H264) { + vidc_720p_decode_setH264VSPBuffer(decoder-> + h264Vsp_temp_buffer. + align_physical_addr); + VIDC_LOG1("VSP_BUF_ADDR_SIZE", + decoder->h264Vsp_temp_buffer.buffer_size); + } + + if (decoder->codec.codec == VCD_CODEC_VC1_RCV || + decoder->codec.codec == VCD_CODEC_VC1) { + vidc_720p_set_frame_size(decoder->client_frame_size.width, + decoder->client_frame_size.height); + } else { + vidc_720p_set_frame_size(0x0, 0x0); + } + + switch (decoder->buf_format.buffer_format) { + default: + case VCD_BUFFER_FORMAT_NV12: + { + mem_access_method = VIDC_720P_TILE_LINEAR; + break; + } + case VCD_BUFFER_FORMAT_TILE_4x2: + { + mem_access_method = VIDC_720P_TILE_64x32; + break; + } + } + VIDC_LOG_STRING("HEADER-PARSE-START"); + VIDC_DEBUG_REGISTER_LOG; + seq_h = (u32) seq_hdr->sequence_header; + start_byte_num = 8 - (seq_h & DDL_STREAMBUF_ALIGN_GUARD_BYTES); + seq_e = seq_h + seq_hdr->sequence_header_len; + seq_h &= ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES); + DDL_PADDING_HACK(seq_e); + + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE); + ddl_move_command_state(ddl->ddl_context, DDL_CMD_HEADER_PARSE); + + vidc_720p_decode_bitstream_header(ddl->channel_id, + seq_hdr->sequence_header_len, + start_byte_num, + seq_h, + seq_e, + mem_access_method, + decoder->output_order); +} + +void ddl_decode_dynamic_property(struct ddl_client_context *ddl, + u32 enable) +{ + uint8_t *temp = NULL; + u32 extra_datastart = 0; + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + struct vcd_frame_data *bit_stream = + &(ddl->input_frame.vcd_frm); + + if (!enable) { + if (decoder->dynmic_prop_change_req) { + decoder->dynmic_prop_change_req = false; + vidc_720p_decode_dynamic_req_reset(); + } + return; + } + if ((decoder->dynamic_prop_change & + DDL_DEC_REQ_OUTPUT_FLUSH)) { + decoder->dynmic_prop_change_req = true; + decoder->dynamic_prop_change &= ~(DDL_DEC_REQ_OUTPUT_FLUSH); + decoder->dpb_mask.hw_mask = 0; + vidc_720p_decode_dynamic_req_set(VIDC_720P_FLUSH_REQ); + } + if (((decoder->meta_data_enable_flag & VCD_METADATA_PASSTHROUGH)) + && ((VCD_FRAME_FLAG_EXTRADATA & bit_stream->flags)) + ) { + + temp = ((uint8_t *)bit_stream->physical + + bit_stream->offset + + bit_stream->data_len + 3); + + extra_datastart = (u32) ((u32)temp & ~3); + decoder->dynmic_prop_change_req = true; + + vidc_720p_decode_setpassthrough_start(extra_datastart); + + vidc_720p_decode_dynamic_req_set(VIDC_720P_EXTRADATA); + } +} + +void ddl_encode_dynamic_property(struct ddl_client_context *ddl, + u32 enable) +{ + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + u32 enc_param_change = 0; + + if (!enable) { + if (encoder->dynmic_prop_change_req) { + encoder->dynmic_prop_change_req = false; + encoder->ext_enc_control_val &= + ~(VIDC_720P_ENC_IFRAME_REQ); + vidc_720p_encode_set_control_param + (encoder->ext_enc_control_val); + vidc_720p_encoder_set_param_change(enc_param_change); + } + return; + } + if ((encoder->dynamic_prop_change & DDL_ENC_REQ_IFRAME)) { + encoder->dynamic_prop_change &= ~(DDL_ENC_REQ_IFRAME); + encoder->ext_enc_control_val |= VIDC_720P_ENC_IFRAME_REQ; + vidc_720p_encode_set_control_param + (encoder->ext_enc_control_val); + } + if ((encoder->dynamic_prop_change & DDL_ENC_CHANGE_BITRATE)) { + vidc_720p_encode_set_bit_rate( + encoder->target_bit_rate.target_bitrate); + enc_param_change |= VIDC_720P_ENC_BITRATE_CHANGE; + encoder->dynamic_prop_change &= ~(DDL_ENC_CHANGE_BITRATE); + } + if ((encoder->dynamic_prop_change & DDL_ENC_CHANGE_CIR)) { + vidc_720p_encode_set_intra_refresh_mb_number( + encoder->intra_refresh.cir_mb_number); + encoder->dynamic_prop_change &= ~(DDL_ENC_CHANGE_CIR); + } + if ((encoder->dynamic_prop_change & DDL_ENC_CHANGE_IPERIOD)) { + vidc_720p_encode_set_i_period + (encoder->i_period.p_frames); + enc_param_change |= VIDC_720P_ENC_IPERIOD_CHANGE; + encoder->dynamic_prop_change &= ~(DDL_ENC_CHANGE_IPERIOD); + } + if ((encoder->dynamic_prop_change & + DDL_ENC_CHANGE_FRAMERATE)) { + vidc_720p_encode_set_fps + ((encoder->frame_rate.fps_numerator * 1000) / + encoder->frame_rate.fps_denominator); + enc_param_change |= VIDC_720P_ENC_FRAMERATE_CHANGE; + encoder->dynamic_prop_change &= ~(DDL_ENC_CHANGE_FRAMERATE); + } + if (enc_param_change) + vidc_720p_encoder_set_param_change(enc_param_change); +} + +static void ddl_encode_set_profile_level(struct ddl_client_context *ddl) +{ + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + u32 profile; + u32 level; + + switch (encoder->profile.profile) { + default: + case VCD_PROFILE_MPEG4_SP: + { + profile = VIDC_720P_PROFILE_MPEG4_SP; + break; + } + case VCD_PROFILE_MPEG4_ASP: + { + profile = VIDC_720P_PROFILE_MPEG4_ASP; + break; + } + case VCD_PROFILE_H264_BASELINE: + { + profile = VIDC_720P_PROFILE_H264_CPB; + break; + } + case VCD_PROFILE_H264_MAIN: + { + profile = VIDC_720P_PROFILE_H264_MAIN; + break; + } + case VCD_PROFILE_H264_HIGH: + { + profile = VIDC_720P_PROFILE_H264_HIGH; + break; + } + case VCD_PROFILE_H263_BASELINE: + { + profile = VIDC_720P_PROFILE_H263_BASELINE; + break; + } + } + switch (encoder->level.level) { + default: + case VCD_LEVEL_MPEG4_0: + { + level = VIDC_720P_MPEG4_LEVEL0; + break; + } + case VCD_LEVEL_MPEG4_0b: + { + level = VIDC_720P_MPEG4_LEVEL0b; + break; + } + case VCD_LEVEL_MPEG4_1: + { + level = VIDC_720P_MPEG4_LEVEL1; + break; + } + case VCD_LEVEL_MPEG4_2: + { + level = VIDC_720P_MPEG4_LEVEL2; + break; + } + case VCD_LEVEL_MPEG4_3: + { + level = VIDC_720P_MPEG4_LEVEL3; + break; + } + case VCD_LEVEL_MPEG4_3b: + { + level = VIDC_720P_MPEG4_LEVEL3b; + break; + } + + case VCD_LEVEL_MPEG4_4: + case VCD_LEVEL_MPEG4_4a: + { + level = VIDC_720P_MPEG4_LEVEL4a; + break; + } + case VCD_LEVEL_MPEG4_5: + { + level = VIDC_720P_MPEG4_LEVEL5; + break; + } + case VCD_LEVEL_MPEG4_6: + { + level = VIDC_720P_MPEG4_LEVEL6; + break; + } + case VCD_LEVEL_H264_1: + { + level = VIDC_720P_H264_LEVEL1; + break; + } + case VCD_LEVEL_H264_1b: + { + level = VIDC_720P_H264_LEVEL1b; + break; + } + case VCD_LEVEL_H264_1p1: + { + level = VIDC_720P_H264_LEVEL1p1; + break; + } + case VCD_LEVEL_H264_1p2: + { + level = VIDC_720P_H264_LEVEL1p2; + break; + } + case VCD_LEVEL_H264_1p3: + { + level = VIDC_720P_H264_LEVEL1p3; + break; + } + case VCD_LEVEL_H264_2: + { + level = VIDC_720P_H264_LEVEL2; + break; + } + case VCD_LEVEL_H264_2p1: + { + level = VIDC_720P_H264_LEVEL2p1; + break; + } + case VCD_LEVEL_H264_2p2: + { + level = VIDC_720P_H264_LEVEL2p2; + break; + } + case VCD_LEVEL_H264_3: + { + level = VIDC_720P_H264_LEVEL3; + break; + } + case VCD_LEVEL_H264_3p1: + { + level = VIDC_720P_H264_LEVEL3p1; + break; + } + case VCD_LEVEL_H263_10: + { + level = VIDC_720P_H263_LEVEL10; + break; + } + case VCD_LEVEL_H263_20: + { + level = VIDC_720P_H263_LEVEL20; + break; + } + case VCD_LEVEL_H263_30: + { + level = VIDC_720P_H263_LEVEL30; + break; + } + case VCD_LEVEL_H263_40: + { + level = VIDC_720P_H263_LEVEL40; + break; + } + case VCD_LEVEL_H263_45: + { + level = VIDC_720P_H263_LEVEL45; + break; + } + case VCD_LEVEL_H263_50: + { + level = VIDC_720P_H263_LEVEL50; + break; + } + case VCD_LEVEL_H263_60: + { + level = VIDC_720P_H263_LEVEL60; + break; + } + case VCD_LEVEL_H263_70: + { + level = VIDC_720P_H263_LEVEL70; + break; + } + } + vidc_720p_encode_set_profile(profile, level); +} + +void ddl_encode_init_codec(struct ddl_client_context *ddl) +{ + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + enum vidc_720p_memory_access_method mem_access_method; + enum vidc_720p_DBConfig db_config; + enum vidc_720p_MSlice_selection m_slice_sel; + + ddl_encode_set_profile_level(ddl); + + vidc_720p_set_frame_size + (encoder->frame_size.width, encoder->frame_size.height); + vidc_720p_encode_set_qp_params + (encoder->qp_range.max_qp, encoder->qp_range.min_qp); + vidc_720p_encode_set_rc_config + (encoder->rc_level.frame_level_rc, + encoder->rc_level.mb_level_rc, + encoder->session_qp.i_frame_qp, + encoder->session_qp.p_frame_qp); + + if (encoder->r_cframe_skip) { + if (encoder->vb_vbuffer_size) { + encoder->ext_enc_control_val = (0x2 << 0x2) | + (encoder->vb_vbuffer_size << 0x10); + } else + encoder->ext_enc_control_val = (0x1 << 2); + } else + encoder->ext_enc_control_val = 0; + + vidc_720p_encode_set_fps + ((encoder->frame_rate.fps_numerator * 1000) / + encoder->frame_rate.fps_denominator); + + vidc_720p_encode_set_vop_time( + encoder->vop_timing.vop_time_resolution, 0); + + if (encoder->rc_level.frame_level_rc) { + vidc_720p_encode_set_bit_rate + (encoder->target_bit_rate.target_bitrate); + + vidc_720p_encode_set_frame_level_rc_params + (encoder->frame_level_rc.reaction_coeff); + } + if (encoder->rc_level.mb_level_rc) { + vidc_720p_encode_set_mb_level_rc_params + (encoder->adaptive_rc.dark_region_as_flag, + encoder->adaptive_rc.smooth_region_as_flag, + encoder->adaptive_rc.static_region_as_flag, + encoder->adaptive_rc.activity_region_flag); + } + if (encoder->codec.codec == VCD_CODEC_MPEG4) { + vidc_720p_encode_set_short_header + (encoder->short_header.short_header); + + if (encoder->hdr_ext_control) { + vidc_720p_encode_set_hec_period + (encoder->hdr_ext_control); + encoder->ext_enc_control_val |= (0x1 << 0x1); + } + } + /* set extended encoder control settings */ + vidc_720p_encode_set_control_param + (encoder->ext_enc_control_val); + + if (encoder->codec.codec == VCD_CODEC_H264) { + enum vidc_720p_entropy_sel entropy_sel; + enum vidc_720p_cabac_model cabac_model_number; + switch (encoder->entropy_control.entropy_sel) { + default: + case VCD_ENTROPY_SEL_CAVLC: + { + entropy_sel = VIDC_720P_ENTROPY_SEL_CAVLC; + break; + } + case VCD_ENTROPY_SEL_CABAC: + { + entropy_sel = VIDC_720P_ENTROPY_SEL_CABAC; + break; + } + } + switch (encoder->entropy_control.cabac_model) { + default: + case VCD_CABAC_MODEL_NUMBER_0: + { + cabac_model_number = + VIDC_720P_CABAC_MODEL_NUMBER_0; + break; + } + case VCD_CABAC_MODEL_NUMBER_1: + { + cabac_model_number = + VIDC_720P_CABAC_MODEL_NUMBER_1; + break; + } + case VCD_CABAC_MODEL_NUMBER_2: + { + cabac_model_number = + VIDC_720P_CABAC_MODEL_NUMBER_2; + break; + } + } + vidc_720p_encode_set_entropy_control + (entropy_sel, cabac_model_number); + switch (encoder->db_control.db_config) { + default: + case VCD_DB_ALL_BLOCKING_BOUNDARY: + { + db_config = + VIDC_720P_DB_ALL_BLOCKING_BOUNDARY; + break; + } + case VCD_DB_DISABLE: + { + db_config = + VIDC_720P_DB_DISABLE; + break; + } + case VCD_DB_SKIP_SLICE_BOUNDARY: + { + db_config = + VIDC_720P_DB_SKIP_SLICE_BOUNDARY; + break; + } + } + vidc_720p_encode_set_db_filter_control + (db_config, + encoder->db_control.slice_alpha_offset, + encoder->db_control.slice_beta_offset); + } + + vidc_720p_encode_set_intra_refresh_mb_number + (encoder->intra_refresh.cir_mb_number); + + switch (encoder->multi_slice.m_slice_sel) { + default: + case VCD_MSLICE_OFF: + m_slice_sel = VIDC_720P_MSLICE_OFF; + break; + case VCD_MSLICE_BY_MB_COUNT: + { + m_slice_sel = VIDC_720P_MSLICE_BY_MB_COUNT; + break; + } + case VCD_MSLICE_BY_BYTE_COUNT: + { + m_slice_sel = VIDC_720P_MSLICE_BY_BYTE_COUNT; + break; + } + case VCD_MSLICE_BY_GOB: + { + m_slice_sel = VIDC_720P_MSLICE_BY_GOB; + break; + } + } + vidc_720p_encode_set_multi_slice_info + (m_slice_sel, encoder->multi_slice.m_slice_size); + + vidc_720p_encode_set_dpb_buffer + (encoder->enc_dpb_addr.align_physical_addr, + encoder->enc_dpb_addr.buffer_size); + + VIDC_LOG1("ENC_DPB_ADDR_SIZE", encoder->enc_dpb_addr.buffer_size); + + vidc_720p_encode_set_i_period(encoder->i_period.p_frames); + + ddl_metadata_enable(ddl); + + if (encoder->seq_header.virtual_base_addr) { + u32 ext_buffer_start, ext_buffer_end, start_byte_num; + ext_buffer_start = + (u32) encoder->seq_header.align_physical_addr; + ext_buffer_end = + ext_buffer_start + encoder->seq_header.buffer_size; + start_byte_num = + (ext_buffer_start & DDL_STREAMBUF_ALIGN_GUARD_BYTES); + ext_buffer_start &= ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES); + ext_buffer_end &= ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES); + VIDC_LOG1("ENC_SEQHDR_ALLOC_SIZE", + encoder->seq_header.buffer_size); + vidc_720p_encode_set_seq_header_buffer(ext_buffer_start, + ext_buffer_end, + start_byte_num); + } + + if (encoder->re_con_buf_format.buffer_format == + VCD_BUFFER_FORMAT_NV12) + mem_access_method = VIDC_720P_TILE_LINEAR; + else + mem_access_method = VIDC_720P_TILE_16x16; + + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE); + ddl_move_command_state(ddl->ddl_context, DDL_CMD_INIT_CODEC); + + vidc_720p_encode_init_codec(ddl->channel_id, mem_access_method); +} + +void ddl_channel_end(struct ddl_client_context *ddl) +{ + VIDC_DEBUG_REGISTER_LOG; + + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_CHEND); + ddl_move_command_state(ddl->ddl_context, DDL_CMD_CHANNEL_END); + + vidc_720p_submit_command(ddl->channel_id, VIDC_720P_CMD_CHEND); +} + +void ddl_encode_frame_run(struct ddl_client_context *ddl) +{ + u32 ext_buffer_start, ext_buffer_end; + u32 y_addr, c_addr; + u32 start_byte_number = 0; + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + struct vcd_frame_data *stream = &(ddl->output_frame.vcd_frm); + + ext_buffer_start = (u32) stream->physical + stream->offset; + ext_buffer_end = ddl_encode_set_metadata_output_buf(ddl); + start_byte_number = + (ext_buffer_start & DDL_STREAMBUF_ALIGN_GUARD_BYTES); + if (start_byte_number) { + u32 upper_data, lower_data; + u32 *align_virtual_addr; + ext_buffer_start &= ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES); + align_virtual_addr = (u32 *) (((u32) stream->virtual + + stream->offset) - + start_byte_number); + upper_data = *align_virtual_addr; + align_virtual_addr++; + lower_data = *align_virtual_addr; + vidc_720p_encode_unalign_bitstream(upper_data, lower_data); + } + + y_addr = (u32) ddl->input_frame.vcd_frm.physical + + ddl->input_frame.vcd_frm.offset; + c_addr = (y_addr + (encoder->frame_size.scan_lines * + encoder->frame_size.stride)); + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE); + ddl_move_command_state(ddl->ddl_context, DDL_CMD_ENCODE_FRAME); + + if (encoder->dynamic_prop_change) { + encoder->dynmic_prop_change_req = true; + ddl_encode_dynamic_property(ddl, true); + } + vidc_720p_encode_set_vop_time( + encoder->vop_timing.vop_time_resolution, + ddl->input_frame.frm_delta + ); + + vidc_720p_encode_frame(ddl->channel_id, + ext_buffer_start, + ext_buffer_end, + start_byte_number, y_addr, c_addr); +} + +u32 ddl_decode_set_buffers(struct ddl_client_context *ddl) +{ + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + u32 comv_buf_size = DDL_COMV_BUFLINE_NO, comv_buf_no = 0; + u32 ref_buf_no = 0; + struct ddl_context *ddl_ctxt = NULL; + + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB)) { + VIDC_LOG_STRING("STATE-CRITICAL"); + return VCD_ERR_FAIL; + } + if (vidc_msg_timing) + ddl_set_core_start_time(__func__, DEC_OP_TIME); + switch (decoder->codec.codec) { + default: + case VCD_CODEC_DIVX_4: + case VCD_CODEC_DIVX_5: + case VCD_CODEC_DIVX_6: + case VCD_CODEC_XVID: + case VCD_CODEC_MPEG2: + case VCD_CODEC_MPEG4: + { + comv_buf_no = DDL_MPEG_COMV_BUF_NO; + ref_buf_no = DDL_MPEG_REFBUF_COUNT; + break; + } + case VCD_CODEC_H263: + { + comv_buf_no = DDL_H263_COMV_BUF_NO; + break; + } + case VCD_CODEC_VC1: + case VCD_CODEC_VC1_RCV: + { + comv_buf_no = + decoder->client_output_buf_req.actual_count + 1; + comv_buf_size = DDL_VC1_COMV_BUFLINE_NO; + break; + } + case VCD_CODEC_H264: + { + if (decoder->idr_only_decoding) + comv_buf_no = decoder->min_dpb_num; + else + comv_buf_no = + decoder-> + client_output_buf_req. + actual_count; + break; + } + } + + if (comv_buf_no) { + comv_buf_size *= (comv_buf_no * + (decoder->client_frame_size.stride >> 4) * + ((decoder->client_frame_size.scan_lines >> 4) + 1)); + if (decoder->dpb_comv_buffer.virtual_base_addr) + ddl_pmem_free(&decoder->dpb_comv_buffer); + ddl_pmem_alloc(&decoder->dpb_comv_buffer, comv_buf_size, + DDL_LINEAR_BUFFER_ALIGN_BYTES); + if (!decoder->dpb_comv_buffer.virtual_base_addr) { + VIDC_LOGERR_STRING + ("Dec_set_buf:Comv_buf_alloc_failed"); + return VCD_ERR_ALLOC_FAIL; + } + vidc_720p_decode_set_comv_buffer(decoder->dpb_comv_buffer. + align_physical_addr, + decoder->dpb_comv_buffer. + buffer_size); + } + decoder->ref_buffer.align_physical_addr = NULL; + if (ref_buf_no) { + size_t sz, align_bytes, y_sz, frm_sz; + u32 i = 0; + sz = decoder->dp_buf.dec_pic_buffers[0].vcd_frm.alloc_len; + frm_sz = sz; + y_sz = decoder->client_frame_size.height * + decoder->client_frame_size.width; + sz *= ref_buf_no; + align_bytes = decoder->client_output_buf_req.align; + if (decoder->ref_buffer.virtual_base_addr) + ddl_pmem_free(&decoder->ref_buffer); + ddl_pmem_alloc(&decoder->ref_buffer, sz, align_bytes); + if (!decoder->ref_buffer.virtual_base_addr) { + ddl_pmem_free(&decoder->dpb_comv_buffer); + VIDC_LOGERR_STRING + ("Dec_set_buf:mpeg_ref_buf_alloc_failed"); + return VCD_ERR_ALLOC_FAIL; + } + memset((u8 *)decoder->ref_buffer.virtual_base_addr, + 0x80, sz); + for (i = 0; i < ref_buf_no; i++) + memset((u8 *)decoder->ref_buffer.align_virtual_addr + + i*frm_sz, 0x10, y_sz); + } + ddl_decode_set_metadata_output(decoder); + ddl_decoder_dpb_transact(decoder, NULL, DDL_DPB_OP_INIT); + ddl_ctxt = ddl_get_context(); + vidc_720p_set_deblock_line_buffer( + ddl_ctxt->db_line_buffer.align_physical_addr, + ddl_ctxt->db_line_buffer.buffer_size); + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_DPBDONE); + ddl_move_command_state(ddl->ddl_context, DDL_CMD_DECODE_SET_DPB); + + vidc_720p_submit_command(ddl->channel_id, + VIDC_720P_CMD_INITBUFFERS); + return VCD_S_SUCCESS; +} + +void ddl_decode_frame_run(struct ddl_client_context *ddl) +{ + u32 ext_buffer_start = 0, ext_buffer_end = 0; + u32 start_byte_num = 8; + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + struct vcd_frame_data *bit_stream = + &(ddl->input_frame.vcd_frm); + if (vidc_msg_timing) { + ddl_set_core_start_time(__func__, DEC_OP_TIME); + ddl_set_core_start_time(__func__, DEC_IP_TIME); + } + if (!bit_stream->data_len || + !bit_stream->physical) { + ddl_decode_eos_run(ddl); + return; + } + + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE); + + ddl_decode_dynamic_property(ddl, true); + + ddl_decoder_dpb_transact(decoder, NULL, DDL_DPB_OP_SET_MASK); + + ext_buffer_start = (u32)bit_stream->physical + + bit_stream->offset; + start_byte_num = 8 - (ext_buffer_start & + DDL_STREAMBUF_ALIGN_GUARD_BYTES); + ext_buffer_end = ext_buffer_start + bit_stream->data_len; + ext_buffer_start &= ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES); + DDL_PADDING_HACK(ext_buffer_end); + + ddl_move_command_state(ddl->ddl_context, DDL_CMD_DECODE_FRAME); + + vidc_720p_decode_frame(ddl->channel_id, + ext_buffer_start, + ext_buffer_end, + bit_stream->data_len, + start_byte_num, bit_stream->ip_frm_tag); +} + +void ddl_decode_eos_run(struct ddl_client_context *ddl) +{ + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE); + + ddl_decode_dynamic_property(ddl, true); + + ddl_decoder_dpb_transact(decoder, NULL, DDL_DPB_OP_SET_MASK); + + decoder->dynmic_prop_change_req = true; + + ddl_move_command_state(ddl->ddl_context, DDL_CMD_EOS); + + vidc_720p_issue_eos(ddl->channel_id); +} + +u32 ddl_hal_engine_reset(struct ddl_context *ddl_context) +{ + u32 eng_reset; + u32 channel_id = 0; + u32 fw_endianness; + enum vidc_720p_endian dma_endian; + enum vidc_720p_interrupt_level_selection interrupt_sel; + u32 intr_mask = 0x0; + + if (ddl_context->current_ddl) + channel_id = ddl_context->current_ddl->channel_id; + + interrupt_sel = VIDC_720P_INTERRUPT_LEVEL_SEL; + /* Enable all the supported interrupt */ + intr_mask |= VIDC_720P_INTR_BUFFER_FULL; + intr_mask |= VIDC_720P_INTR_FW_DONE; + intr_mask |= VIDC_720P_INTR_DMA_DONE; + intr_mask |= VIDC_720P_INTR_FRAME_DONE; + + vcd_get_fw_property(VCD_FW_ENDIAN, &fw_endianness); + /* Reverse the endianness settings after boot code download */ + if (fw_endianness == VCD_FW_BIG_ENDIAN) + dma_endian = VIDC_720P_LITTLE_ENDIAN; + else + dma_endian = VIDC_720P_BIG_ENDIAN; + + /* Need to reset MFC silently */ + eng_reset = vidc_720p_engine_reset( + channel_id, + dma_endian, interrupt_sel, + intr_mask); + if (!eng_reset) { + /* call the hw fatal callback if engine reset fails */ + ddl_hw_fatal_cb(ddl_context); + } + return eng_reset ; +} diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c new file mode 100644 index 000000000000..b97fae6a32f7 --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_helper.c @@ -0,0 +1,297 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#include +#include "vcd_ddl_utils.h" + +DDL_INLINE struct ddl_context *ddl_get_context(void) +{ + static struct ddl_context ddl_context; + return &ddl_context; +} + +DDL_INLINE void ddl_move_client_state(struct ddl_client_context *ddl, + enum ddl_client_state client_state) +{ + ddl->client_state = client_state; +} + +DDL_INLINE void ddl_move_command_state(struct ddl_context *ddl_context, + enum ddl_cmd_state command_state) +{ + ddl_context->cmd_state = command_state; +} + +u32 ddl_client_transact(u32 operation, + struct ddl_client_context **pddl_client) +{ + u32 ret_status = VCD_ERR_FAIL; + u32 counter; + struct ddl_context *ddl_context; + + ddl_context = ddl_get_context(); + switch (operation) { + case DDL_FREE_CLIENT: + { + if (pddl_client && *pddl_client) { + u32 channel_id; + channel_id = (*pddl_client)->channel_id; + if (channel_id < VCD_MAX_NO_CLIENT) { + ddl_context-> + ddl_clients[channel_id] = NULL; + } else { + VIDC_LOG_STRING("CHID_CORRUPTION"); + } + DDL_FREE(*pddl_client); + ret_status = VCD_S_SUCCESS; + } + break; + } + case DDL_GET_CLIENT: + { + ret_status = VCD_ERR_MAX_CLIENT; + for (counter = 0; counter < VCD_MAX_NO_CLIENT && + ret_status == VCD_ERR_MAX_CLIENT; ++counter) { + if (!ddl_context->ddl_clients[counter]) { + *pddl_client = + (struct ddl_client_context *) + DDL_MALLOC(sizeof + (struct ddl_client_context) + ); + if (!*pddl_client) { + ret_status = VCD_ERR_ALLOC_FAIL; + } else { + DDL_MEMSET(*pddl_client, 0, + sizeof(struct + ddl_client_context)); + ddl_context-> + ddl_clients[counter] = + *pddl_client; + (*pddl_client)->channel_id = + counter; + (*pddl_client)->ddl_context = + ddl_context; + ret_status = VCD_S_SUCCESS; + } + } + } + break; + } + case DDL_INIT_CLIENTS: + { + for (counter = 0; counter < VCD_MAX_NO_CLIENT; + ++counter) { + ddl_context->ddl_clients[counter] = NULL; + } + ret_status = VCD_S_SUCCESS; + break; + } + case DDL_ACTIVE_CLIENT: + { + for (counter = 0; counter < VCD_MAX_NO_CLIENT; + ++counter) { + if (ddl_context->ddl_clients[counter]) { + ret_status = VCD_S_SUCCESS; + break; + } + } + break; + } + default: + { + ret_status = VCD_ERR_ILLEGAL_PARM; + break; + } + } + return ret_status; +} + +u32 ddl_decoder_dpb_transact(struct ddl_decoder_data *decoder, + struct ddl_frame_data_tag *in_out_frame, + u32 operation) +{ + u32 vcd_status = VCD_S_SUCCESS; + u32 loopc; + struct ddl_frame_data_tag *found_frame = NULL; + struct ddl_mask *dpb_mask = &decoder->dpb_mask; + u32 temp_mask; + + switch (operation) { + case DDL_DPB_OP_MARK_BUSY: + case DDL_DPB_OP_MARK_FREE: + { + for (loopc = 0; !found_frame && + loopc < decoder->dp_buf.no_of_dec_pic_buf; + ++loopc) { + if (in_out_frame->vcd_frm.physical == + decoder->dp_buf. + dec_pic_buffers[loopc].vcd_frm. + physical) { + found_frame = + &(decoder->dp_buf. + dec_pic_buffers[loopc]); + break; + } + } + + if (found_frame) { + if (operation == DDL_DPB_OP_MARK_BUSY) { + temp_mask = (~(0x1 << loopc)); + if (decoder->idr_only_decoding) + temp_mask = ~(0xffffffff); + dpb_mask->hw_mask &= temp_mask; + *in_out_frame = *found_frame; + } else if (operation == + DDL_DPB_OP_MARK_FREE) { + temp_mask = (0x1 << loopc); + if (decoder->idr_only_decoding) + temp_mask = 0xffffffff; + dpb_mask->client_mask |= temp_mask; + *found_frame = *in_out_frame; + } + } else { + in_out_frame->vcd_frm.physical = NULL; + in_out_frame->vcd_frm.virtual = NULL; + vcd_status = VCD_ERR_BAD_POINTER; + VIDC_LOG_STRING("BUF_NOT_FOUND"); + } + break; + } + case DDL_DPB_OP_SET_MASK: + { + dpb_mask->hw_mask |= dpb_mask->client_mask; + dpb_mask->client_mask = 0; + vidc_720p_decode_set_dpb_release_buffer_mask + (dpb_mask->hw_mask); + break; + } + case DDL_DPB_OP_INIT: + { + u32 dpb_size, index, num_dpb; + dpb_size = (!decoder->meta_data_offset) ? + decoder->dp_buf.dec_pic_buffers[0].vcd_frm. + alloc_len : decoder->meta_data_offset; + if (decoder->idr_only_decoding) + num_dpb = decoder->min_dpb_num; + else + num_dpb = decoder->dp_buf.no_of_dec_pic_buf; + vidc_720p_decode_set_dpb_details( + num_dpb, + dpb_size, + decoder->ref_buffer. + align_physical_addr); + for (loopc = 0; loopc < num_dpb; ++loopc) { + if (decoder->idr_only_decoding) + index = 0; + else + index = loopc; + vidc_720p_decode_set_dpb_buffers(loopc, + (u32 *) + decoder-> + dp_buf. + dec_pic_buffers + [index]. + vcd_frm. + physical); + VIDC_LOG1("DEC_DPB_BUFn_SIZE=%d", + decoder->dp_buf. + dec_pic_buffers[index].vcd_frm. + alloc_len); + } + break; + } + case DDL_DPB_OP_RETRIEVE: + { + u32 position; + if (dpb_mask->client_mask) { + position = 0x1; + for (loopc = 0; + loopc < + decoder->dp_buf.no_of_dec_pic_buf + && !found_frame; ++loopc) { + if (dpb_mask-> + client_mask & position) { + found_frame = + &decoder->dp_buf. + dec_pic_buffers[loopc]; + dpb_mask->client_mask &= + ~(position); + } + position <<= 1; + } + } else if (dpb_mask->hw_mask) { + position = 0x1; + for (loopc = 0; + loopc < + decoder->dp_buf.no_of_dec_pic_buf + && !found_frame; ++loopc) { + if (dpb_mask->hw_mask + & position) { + found_frame = + &decoder->dp_buf. + dec_pic_buffers[loopc]; + dpb_mask->hw_mask &= + ~(position); + } + position <<= 1; + } + } + if (found_frame) + *in_out_frame = *found_frame; + else { + in_out_frame->vcd_frm.physical = NULL; + in_out_frame->vcd_frm.virtual = NULL; + } + break; + } + } + return vcd_status; +} + +void ddl_release_context_buffers(struct ddl_context *ddl_context) +{ + ddl_pmem_free(&ddl_context->context_buf_addr); + ddl_pmem_free(&ddl_context->db_line_buffer); + ddl_pmem_free(&ddl_context->data_partition_tempbuf); + ddl_pmem_free(&ddl_context->metadata_shared_input); + ddl_pmem_free(&ddl_context->dbg_core_dump); + + vcd_fw_release(); +} + +void ddl_release_client_internal_buffers(struct ddl_client_context *ddl) +{ + if (ddl->decoding) { + struct ddl_decoder_data *decoder = + &(ddl->codec_data.decoder); + ddl_pmem_free(&decoder->h264Vsp_temp_buffer); + ddl_pmem_free(&decoder->dpb_comv_buffer); + ddl_pmem_free(&decoder->ref_buffer); + DDL_FREE(decoder->dp_buf.dec_pic_buffers); + ddl_decode_dynamic_property(ddl, false); + decoder->decode_config.sequence_header_len = 0; + decoder->decode_config.sequence_header = NULL; + decoder->dpb_mask.client_mask = 0; + decoder->dpb_mask.hw_mask = 0; + decoder->dp_buf.no_of_dec_pic_buf = 0; + decoder->dynamic_prop_change = 0; + + } else { + struct ddl_encoder_data *encoder = + &(ddl->codec_data.encoder); + ddl_pmem_free(&encoder->enc_dpb_addr); + ddl_pmem_free(&encoder->seq_header); + ddl_encode_dynamic_property(ddl, false); + encoder->dynamic_prop_change = 0; + } +} diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_internal_property.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_internal_property.h new file mode 100644 index 000000000000..32a40477581d --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_internal_property.h @@ -0,0 +1,81 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#ifndef _VCD_DDL_INTERNAL_PROPERTY_H_ +#define _VCD_DDL_INTERNAL_PROPERTY_H_ +#include + +#define VCD_EVT_RESP_DDL_BASE 0x3000 +#define VCD_EVT_RESP_DEVICE_INIT (VCD_EVT_RESP_DDL_BASE + 0x1) +#define VCD_EVT_RESP_OUTPUT_REQ (VCD_EVT_RESP_DDL_BASE + 0x2) +#define VCD_EVT_RESP_EOS_DONE (VCD_EVT_RESP_DDL_BASE + 0x3) +#define VCD_EVT_RESP_TRANSACTION_PENDING (VCD_EVT_RESP_DDL_BASE + 0x4) + +#define VCD_S_DDL_ERR_BASE 0x90000000 +#define VCD_ERR_MAX_NO_CODEC (VCD_S_DDL_ERR_BASE + 0x1) +#define VCD_ERR_CLIENT_PRESENT (VCD_S_DDL_ERR_BASE + 0x2) +#define VCD_ERR_CLIENT_FATAL (VCD_S_DDL_ERR_BASE + 0x3) + +#define VCD_I_CUSTOM_BASE (VCD_I_RESERVED_BASE) +#define VCD_I_RC_LEVEL_CONFIG (VCD_I_CUSTOM_BASE + 0x1) +#define VCD_I_FRAME_LEVEL_RC (VCD_I_CUSTOM_BASE + 0x2) +#define VCD_I_ADAPTIVE_RC (VCD_I_CUSTOM_BASE + 0x3) +#define VCD_I_CUSTOM_DDL_BASE (VCD_I_RESERVED_BASE + 0x100) +#define DDL_I_INPUT_BUF_REQ (VCD_I_CUSTOM_DDL_BASE + 0x1) +#define DDL_I_OUTPUT_BUF_REQ (VCD_I_CUSTOM_DDL_BASE + 0x2) +#define DDL_I_DPB (VCD_I_CUSTOM_DDL_BASE + 0x3) +#define DDL_I_DPB_RELEASE (VCD_I_CUSTOM_DDL_BASE + 0x4) +#define DDL_I_DPB_RETRIEVE (VCD_I_CUSTOM_DDL_BASE + 0x5) +#define DDL_I_REQ_OUTPUT_FLUSH (VCD_I_CUSTOM_DDL_BASE + 0x6) +#define DDL_I_SEQHDR_ALIGN_BYTES (VCD_I_CUSTOM_DDL_BASE + 0x7) +#define DDL_I_SEQHDR_PRESENT (VCD_I_CUSTOM_DDL_BASE + 0xb) +#define DDL_I_CAPABILITY (VCD_I_CUSTOM_DDL_BASE + 0x8) +#define DDL_I_FRAME_PROC_UNITS (VCD_I_CUSTOM_DDL_BASE + 0x9) + +struct vcd_property_rc_level { + u32 frame_level_rc; + u32 mb_level_rc; +}; + +struct vcd_property_frame_level_rc_params { + u32 reaction_coeff; +}; + +struct vcd_property_adaptive_rc_params { + u32 dark_region_as_flag; + u32 smooth_region_as_flag; + u32 static_region_as_flag; + u32 activity_region_flag; +}; + +struct vcd_property_slice_delivery_info { + u32 enable; + u32 num_slices; + u32 num_slices_enc; +}; + +struct ddl_frame_data_tag; + +struct ddl_property_dec_pic_buffers { + struct ddl_frame_data_tag *dec_pic_buffers; + u32 no_of_dec_pic_buf; +}; + +struct ddl_property_capability { + u32 max_num_client; + u32 general_command_depth; + u32 frame_command_depth; + u32 exclusive; + u32 ddl_time_out_in_ms; +}; + +#endif diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_interrupt_handler.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_interrupt_handler.c new file mode 100644 index 000000000000..eea4c762889c --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_interrupt_handler.c @@ -0,0 +1,1130 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#include +#include "vidc.h" +#include "vcd_ddl_utils.h" +#include "vcd_ddl_metadata.h" + +#if DEBUG +#define DBG(x...) printk(KERN_DEBUG x) +#else +#define DBG(x...) +#endif + +static void ddl_decoder_input_done_callback( + struct ddl_client_context *ddl, u32 frame_transact_end); +static u32 ddl_decoder_output_done_callback( + struct ddl_client_context *ddl, u32 frame_transact_end); + +static u32 ddl_get_frame + (struct vcd_frame_data *frame, u32 frame_type); + +static void ddl_getdec_profilelevel +(struct ddl_decoder_data *decoder, u32 profile, u32 level); + +static void ddl_dma_done_callback(struct ddl_context *ddl_context) +{ + if (!DDLCOMMAND_STATE_IS(ddl_context, DDL_CMD_DMA_INIT)) { + VIDC_LOGERR_STRING("UNKWN_DMADONE"); + return; + } + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + VIDC_LOG_STRING("DMA_DONE"); + ddl_core_start_cpu(ddl_context); +} + +static void ddl_cpu_started_callback(struct ddl_context *ddl_context) +{ + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + VIDC_LOG_STRING("CPU-STARTED"); + + if (!vidc_720p_cpu_start()) { + ddl_hw_fatal_cb(ddl_context); + return; + } + + vidc_720p_set_deblock_line_buffer( + ddl_context->db_line_buffer.align_physical_addr, + ddl_context->db_line_buffer.buffer_size); + ddl_context->device_state = DDL_DEVICE_INITED; + ddl_context->ddl_callback(VCD_EVT_RESP_DEVICE_INIT, VCD_S_SUCCESS, + NULL, 0, NULL, ddl_context->client_data); + DDL_IDLE(ddl_context); +} + + +static u32 ddl_eos_done_callback(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl = ddl_context->current_ddl; + u32 displaystatus, resl_change; + + if (!DDLCOMMAND_STATE_IS(ddl_context, DDL_CMD_EOS)) { + VIDC_LOGERR_STRING("UNKWN_EOSDONE"); + ddl_client_fatal_cb(ddl_context); + return true; + } + + if (!ddl || + !ddl->decoding || + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE) + ) { + VIDC_LOG_STRING("STATE-CRITICAL-EOSDONE"); + ddl_client_fatal_cb(ddl_context); + return true; + } + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + + vidc_720p_eos_info(&displaystatus, &resl_change); + if ((enum vidc_720p_display_status)displaystatus + != VIDC_720P_EMPTY_BUFFER) { + VIDC_LOG_STRING("EOSDONE-EMPTYBUF-ISSUE"); + } + + ddl_decode_dynamic_property(ddl, false); + if (resl_change == 0x1) { + ddl->codec_data.decoder.header_in_start = false; + ddl->codec_data.decoder.decode_config.sequence_header = + ddl->input_frame.vcd_frm.physical; + ddl->codec_data.decoder.decode_config.sequence_header_len = + ddl->input_frame.vcd_frm.data_len; + ddl_decode_init_codec(ddl); + return false; + } + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_FRAME); + VIDC_LOG_STRING("EOS_DONE"); + ddl_context->ddl_callback(VCD_EVT_RESP_EOS_DONE, VCD_S_SUCCESS, + NULL, 0, (u32 *) ddl, ddl_context->client_data); + DDL_IDLE(ddl_context); + + return true; +} + +static u32 ddl_channel_set_callback(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl = ddl_context->current_ddl; + u32 return_status = false; + + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + VIDC_DEBUG_REGISTER_LOG; + + if (!ddl || + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_CHDONE) + ) { + VIDC_LOG_STRING("STATE-CRITICAL-CHSET"); + DDL_IDLE(ddl_context); + return return_status; + } + VIDC_LOG_STRING("Channel-set"); + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_INITCODEC); + + if (ddl->decoding) { + if (vidc_msg_timing) + ddl_calc_core_proc_time(__func__, DEC_OP_TIME); + if (ddl->codec_data.decoder.header_in_start) { + ddl_decode_init_codec(ddl); + } else { + ddl_context->ddl_callback(VCD_EVT_RESP_START, + VCD_S_SUCCESS, NULL, + 0, (u32 *) ddl, + ddl_context->client_data); + + DDL_IDLE(ddl_context); + return_status = true; + } + } else { + ddl_encode_init_codec(ddl); + } + return return_status; +} + +static void ddl_init_codec_done_callback(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl = ddl_context->current_ddl; + struct ddl_encoder_data *encoder; + + if (!ddl || + ddl->decoding || + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE) + ) { + VIDC_LOG_STRING("STATE-CRITICAL-INITCODEC"); + ddl_client_fatal_cb(ddl_context); + return; + } + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_FRAME); + VIDC_LOG_STRING("INIT_CODEC_DONE"); + + encoder = &ddl->codec_data.encoder; + if (encoder->seq_header.virtual_base_addr) { + vidc_720p_encode_get_header(&encoder->seq_header. + buffer_size); + } + + ddl_context->ddl_callback(VCD_EVT_RESP_START, VCD_S_SUCCESS, NULL, + 0, (u32 *) ddl, ddl_context->client_data); + + DDL_IDLE(ddl_context); +} + +static u32 ddl_header_done_callback(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl = ddl_context->current_ddl; + struct ddl_decoder_data *decoder; + struct vidc_720p_seq_hdr_info seq_hdr_info; + + u32 process_further = true; + u32 seq_hdr_only_frame = false; + u32 need_reconfig = true; + struct vcd_frame_data *input_vcd_frm; + struct ddl_frame_data_tag *reconfig_payload = NULL; + u32 reconfig_payload_size = 0; + + if (!ddl || + !ddl->decoding || + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_INITCODECDONE) + ) { + VIDC_LOG_STRING("STATE-CRITICAL-HDDONE"); + ddl_client_fatal_cb(ddl_context); + return true; + } + if (vidc_msg_timing) + ddl_calc_core_proc_time(__func__, DEC_OP_TIME); + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_DPB); + VIDC_LOG_STRING("HEADER_DONE"); + VIDC_DEBUG_REGISTER_LOG; + + vidc_720p_decode_get_seq_hdr_info(&seq_hdr_info); + + decoder = &(ddl->codec_data.decoder); + decoder->frame_size.width = seq_hdr_info.img_size_x; + decoder->frame_size.height = seq_hdr_info.img_size_y; + decoder->min_dpb_num = seq_hdr_info.min_num_dpb; + decoder->y_cb_cr_size = seq_hdr_info.min_dpb_size; + decoder->progressive_only = 1 - seq_hdr_info.progressive; + if (!seq_hdr_info.img_size_x || !seq_hdr_info.img_size_y) { + VIDC_LOGERR_STRING("FATAL: ZeroImageSize"); + ddl_client_fatal_cb(ddl_context); + return process_further; + } + if (seq_hdr_info.data_partitioned == 0x1 && + decoder->codec.codec == VCD_CODEC_MPEG4 && + seq_hdr_info.img_size_x > DDL_MAX_DP_FRAME_WIDTH && + seq_hdr_info.img_size_y > DDL_MAX_DP_FRAME_HEIGHT) { + ddl_client_fatal_cb(ddl_context); + return process_further; + } + ddl_getdec_profilelevel(decoder, seq_hdr_info.profile, + seq_hdr_info.level); + ddl_calculate_stride(&decoder->frame_size, + !decoder->progressive_only, + decoder->codec.codec); + if (decoder->buf_format.buffer_format == VCD_BUFFER_FORMAT_TILE_4x2) { + decoder->frame_size.stride = + DDL_TILE_ALIGN(decoder->frame_size.width, + DDL_TILE_ALIGN_WIDTH); + decoder->frame_size.scan_lines = + DDL_TILE_ALIGN(decoder->frame_size.height, + DDL_TILE_ALIGN_HEIGHT); + } + if (seq_hdr_info.crop_exists) { + decoder->frame_size.width -= + (seq_hdr_info.crop_right_offset + + seq_hdr_info.crop_left_offset); + decoder->frame_size.height -= + (seq_hdr_info.crop_top_offset + + seq_hdr_info.crop_bottom_offset); + } + ddl_set_default_decoder_buffer_req(decoder, false); + + if (decoder->header_in_start) { + decoder->client_frame_size = decoder->frame_size; + decoder->client_output_buf_req = + decoder->actual_output_buf_req; + decoder->client_input_buf_req = + decoder->actual_input_buf_req; + ddl_context->ddl_callback(VCD_EVT_RESP_START, VCD_S_SUCCESS, + NULL, 0, (u32 *) ddl, ddl_context->client_data); + DDL_IDLE(ddl_context); + } else { + DBG("%s(): Client data: WxH(%u x %u) SxSL(%u x %u) Sz(%u)\n", + __func__, decoder->client_frame_size.width, + decoder->client_frame_size.height, + decoder->client_frame_size.stride, + decoder->client_frame_size.scan_lines, + decoder->client_output_buf_req.sz); + DBG("%s(): DDL data: WxH(%u x %u) SxSL(%u x %u) Sz(%u)\n", + __func__, decoder->frame_size.width, + decoder->frame_size.height, + decoder->frame_size.stride, + decoder->frame_size.scan_lines, + decoder->actual_output_buf_req.sz); + DBG("%s(): min_dpb_num = %d actual_count = %d\n", __func__, + decoder->min_dpb_num, + decoder->client_output_buf_req.actual_count); + + input_vcd_frm = &(ddl->input_frame.vcd_frm); + + if (decoder->frame_size.width == + decoder->client_frame_size.width + && decoder->frame_size.height == + decoder->client_frame_size.height + && decoder->frame_size.stride == + decoder->client_frame_size.stride + && decoder->frame_size.scan_lines == + decoder->client_frame_size.scan_lines + && decoder->actual_output_buf_req.sz <= + decoder->client_output_buf_req.sz + && decoder->actual_output_buf_req.actual_count <= + decoder->client_output_buf_req.actual_count + && decoder->progressive_only) + need_reconfig = false; + if (input_vcd_frm->flags & VCD_FRAME_FLAG_EOS) + need_reconfig = false; + if ((input_vcd_frm->data_len <= seq_hdr_info.dec_frm_size || + (input_vcd_frm->flags & VCD_FRAME_FLAG_CODECCONFIG)) && + (!need_reconfig || + !(input_vcd_frm->flags & VCD_FRAME_FLAG_EOS))) { + input_vcd_frm->flags |= + VCD_FRAME_FLAG_CODECCONFIG; + seq_hdr_only_frame = true; + input_vcd_frm->data_len = 0; + ddl->input_frame.frm_trans_end = !need_reconfig; + ddl_context->ddl_callback( + VCD_EVT_RESP_INPUT_DONE, + VCD_S_SUCCESS, &ddl->input_frame, + sizeof(struct ddl_frame_data_tag), + (u32 *) ddl, + ddl->ddl_context->client_data); + } else if (decoder->codec.codec != VCD_CODEC_H263) { + input_vcd_frm->offset += seq_hdr_info.dec_frm_size; + input_vcd_frm->data_len -= seq_hdr_info.dec_frm_size; + } + if (need_reconfig) { + decoder->client_frame_size = decoder->frame_size; + decoder->client_output_buf_req = + decoder->actual_output_buf_req; + decoder->client_input_buf_req = + decoder->actual_input_buf_req; + if (!seq_hdr_only_frame) { + reconfig_payload = &ddl->input_frame; + reconfig_payload_size = + sizeof(struct ddl_frame_data_tag); + } + ddl_context->ddl_callback(VCD_EVT_IND_OUTPUT_RECONFIG, + VCD_S_SUCCESS, reconfig_payload, + reconfig_payload_size, + (u32 *) ddl, + ddl_context->client_data); + } + if (!need_reconfig && !seq_hdr_only_frame) { + if (ddl_decode_set_buffers(ddl) == VCD_S_SUCCESS) + process_further = false; + else + ddl_client_fatal_cb(ddl_context); + } else + DDL_IDLE(ddl_context); + } + return process_further; +} + +static u32 ddl_dpb_buffers_set_done_callback(struct ddl_context + *ddl_context) +{ + struct ddl_client_context *ddl = ddl_context->current_ddl; + + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + if (!ddl || + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPBDONE) + ) { + VIDC_LOG_STRING("STATE-CRITICAL-DPBDONE"); + ddl_client_fatal_cb(ddl_context); + return true; + } + if (vidc_msg_timing) { + ddl_calc_core_proc_time(__func__, DEC_OP_TIME); + ddl_reset_core_time_variables(DEC_OP_TIME); + } + VIDC_LOG_STRING("INTR_DPBDONE"); + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_FRAME); + ddl->codec_data.decoder.dec_disp_info.img_size_x = 0; + ddl->codec_data.decoder.dec_disp_info.img_size_y = 0; + ddl_decode_frame_run(ddl); + return false; +} + +static void ddl_encoder_frame_run_callback(struct ddl_context + *ddl_context) +{ + struct ddl_client_context *ddl = ddl_context->current_ddl; + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + u32 eos_present = false; + + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE) + ) { + VIDC_LOG_STRING("STATE-CRITICAL-ENCFRMRUN"); + ddl_client_fatal_cb(ddl_context); + return; + } + + VIDC_LOG_STRING("ENC_FRM_RUN_DONE"); + + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + vidc_720p_enc_frame_info(&encoder->enc_frame_info); + + ddl->output_frame.vcd_frm.ip_frm_tag = + ddl->input_frame.vcd_frm.ip_frm_tag; + ddl->output_frame.vcd_frm.data_len = + encoder->enc_frame_info.enc_size; + ddl->output_frame.vcd_frm.flags |= VCD_FRAME_FLAG_ENDOFFRAME; + ddl_get_frame + (&(ddl->output_frame.vcd_frm), + encoder->enc_frame_info.frame); + ddl_process_encoder_metadata(ddl); + + ddl_encode_dynamic_property(ddl, false); + + ddl->input_frame.frm_trans_end = false; + ddl_context->ddl_callback(VCD_EVT_RESP_INPUT_DONE, VCD_S_SUCCESS, + &(ddl->input_frame), sizeof(struct ddl_frame_data_tag), + (u32 *) ddl, ddl_context->client_data); + + if (vidc_msg_timing) + ddl_calc_core_proc_time(__func__, ENC_OP_TIME); + + /* check the presence of EOS */ + eos_present = + ((VCD_FRAME_FLAG_EOS & ddl->input_frame.vcd_frm.flags)); + + ddl->output_frame.frm_trans_end = !eos_present; + ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE, VCD_S_SUCCESS, + &(ddl->output_frame), sizeof(struct ddl_frame_data_tag), + (u32 *) ddl, ddl_context->client_data); + + if (eos_present) { + VIDC_LOG_STRING("ENC-EOS_DONE"); + ddl_context->ddl_callback(VCD_EVT_RESP_EOS_DONE, + VCD_S_SUCCESS, NULL, 0, (u32 *)ddl, + ddl_context->client_data); + } + + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_FRAME); + DDL_IDLE(ddl_context); +} + +static u32 ddl_decoder_frame_run_callback(struct ddl_context + *ddl_context) +{ + struct ddl_client_context *ddl = ddl_context->current_ddl; + struct vidc_720p_dec_disp_info *dec_disp_info = + &(ddl->codec_data.decoder.dec_disp_info); + u32 callback_end = false; + u32 status = true, eos_present = false;; + + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE)) { + VIDC_LOG_STRING("STATE-CRITICAL-DECFRMRUN"); + ddl_client_fatal_cb(ddl_context); + return true; + } + + VIDC_LOG_STRING("DEC_FRM_RUN_DONE"); + + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + + vidc_720p_decode_display_info(dec_disp_info); + + ddl_decode_dynamic_property(ddl, false); + + if (dec_disp_info->resl_change) { + VIDC_LOG_STRING + ("DEC_FRM_RUN_DONE: RECONFIG"); + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE); + ddl_move_command_state(ddl_context, DDL_CMD_EOS); + vidc_720p_submit_command(ddl->channel_id, + VIDC_720P_CMD_FRAMERUN_REALLOCATE); + return false; + } + + if ((VCD_FRAME_FLAG_EOS & ddl->input_frame.vcd_frm.flags)) { + callback_end = false; + eos_present = true; + } + + + if (dec_disp_info->disp_status == VIDC_720P_DECODE_ONLY || + dec_disp_info->disp_status + == VIDC_720P_DECODE_AND_DISPLAY) { + if (!eos_present) + callback_end = (dec_disp_info->disp_status + == VIDC_720P_DECODE_ONLY); + + ddl_decoder_input_done_callback(ddl, callback_end); + } + + if (dec_disp_info->disp_status == VIDC_720P_DECODE_AND_DISPLAY + || dec_disp_info->disp_status == VIDC_720P_DISPLAY_ONLY) { + if (!eos_present) + callback_end = + (dec_disp_info->disp_status + == VIDC_720P_DECODE_AND_DISPLAY); + + if (ddl_decoder_output_done_callback(ddl, callback_end) + != VCD_S_SUCCESS) + return true; + } + + if (dec_disp_info->disp_status == VIDC_720P_DISPLAY_ONLY || + dec_disp_info->disp_status == VIDC_720P_EMPTY_BUFFER) { + /* send the same input once again for decoding */ + ddl_decode_frame_run(ddl); + /* client need to ignore the interrupt */ + status = false; + } else if (eos_present) { + /* send EOS command to HW */ + ddl_decode_eos_run(ddl); + /* client need to ignore the interrupt */ + status = false; + } else { + ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_FRAME); + /* move to Idle */ + DDL_IDLE(ddl_context); + } + return status; +} + +static u32 ddl_eos_frame_done_callback(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl = ddl_context->current_ddl; + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + struct vidc_720p_dec_disp_info *dec_disp_info = + &(decoder->dec_disp_info); + + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_EOS_DONE)) { + VIDC_LOGERR_STRING("STATE-CRITICAL-EOSFRMRUN"); + ddl_client_fatal_cb(ddl_context); + return true; + } + VIDC_LOG_STRING("EOS_FRM_RUN_DONE"); + + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + + vidc_720p_decode_display_info(dec_disp_info); + + ddl_decode_dynamic_property(ddl, false); + + if (dec_disp_info->disp_status == VIDC_720P_DISPLAY_ONLY) { + if (ddl_decoder_output_done_callback(ddl, false) + != VCD_S_SUCCESS) + return true; + } else + VIDC_LOG_STRING("STATE-CRITICAL-WRONG-DISP-STATUS"); + + ddl_decoder_dpb_transact(decoder, NULL, DDL_DPB_OP_SET_MASK); + ddl_move_command_state(ddl_context, DDL_CMD_EOS); + vidc_720p_submit_command(ddl->channel_id, + VIDC_720P_CMD_FRAMERUN); + return false; +} + +static void ddl_channel_end_callback(struct ddl_context *ddl_context) +{ + struct ddl_client_context *ddl; + + ddl_move_command_state(ddl_context, DDL_CMD_INVALID); + VIDC_LOG_STRING("CH_END_DONE"); + + ddl = ddl_context->current_ddl; + if (!ddl || + !DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_CHEND) + ) { + VIDC_LOG_STRING("STATE-CRITICAL-CHEND"); + DDL_IDLE(ddl_context); + return; + } + + ddl_release_client_internal_buffers(ddl); + ddl_context->ddl_callback(VCD_EVT_RESP_STOP, VCD_S_SUCCESS, + NULL, 0, (u32 *) ddl, ddl_context->client_data); + ddl_move_client_state(ddl, DDL_CLIENT_OPEN); + DDL_IDLE(ddl_context); +} + +static u32 ddl_operation_done_callback(struct ddl_context *ddl_context) +{ + u32 return_status = true; + + switch (ddl_context->cmd_state) { + case DDL_CMD_DECODE_FRAME: + { + return_status = ddl_decoder_frame_run_callback( + ddl_context); + break; + } + case DDL_CMD_ENCODE_FRAME: + { + ddl_encoder_frame_run_callback(ddl_context); + break; + } + case DDL_CMD_CHANNEL_SET: + { + return_status = ddl_channel_set_callback( + ddl_context); + break; + } + case DDL_CMD_INIT_CODEC: + { + ddl_init_codec_done_callback(ddl_context); + break; + } + case DDL_CMD_HEADER_PARSE: + { + return_status = ddl_header_done_callback( + ddl_context); + break; + } + case DDL_CMD_DECODE_SET_DPB: + { + return_status = ddl_dpb_buffers_set_done_callback( + ddl_context); + break; + } + case DDL_CMD_CHANNEL_END: + { + ddl_channel_end_callback(ddl_context); + break; + } + case DDL_CMD_EOS: + { + return_status = ddl_eos_frame_done_callback( + ddl_context); + break; + } + case DDL_CMD_CPU_RESET: + { + ddl_cpu_started_callback(ddl_context); + break; + } + default: + { + VIDC_LOG_STRING("UNKWN_OPDONE"); + return_status = false; + break; + } + } + return return_status; +} + +static u32 ddl_process_intr_status(struct ddl_context *ddl_context, + u32 int_status) +{ + u32 status = true; + switch (int_status) { + case VIDC_720P_INTR_FRAME_DONE: + { + status = ddl_operation_done_callback(ddl_context); + break; + } + case VIDC_720P_INTR_DMA_DONE: + { + ddl_dma_done_callback(ddl_context); + status = false; + break; + } + case VIDC_720P_INTR_FW_DONE: + { + status = ddl_eos_done_callback(ddl_context); + break; + } + case VIDC_720P_INTR_BUFFER_FULL: + { + VIDC_LOGERR_STRING("BUF_FULL_INTR"); + ddl_hw_fatal_cb(ddl_context); + break; + } + default: + { + VIDC_LOGERR_STRING("UNKWN_INTR"); + break; + } + } + return status; +} + +void ddl_read_and_clear_interrupt(void) +{ + struct ddl_context *ddl_context; + + ddl_context = ddl_get_context(); + if (!ddl_context->core_virtual_base_addr) { + VIDC_LOGERR_STRING("SPURIOUS_INTERRUPT"); + return; + } + vidc_720p_get_interrupt_status(&ddl_context->intr_status, + &ddl_context->cmd_err_status, + &ddl_context->disp_pic_err_status, + &ddl_context->op_failed + ); + + vidc_720p_interrupt_done_clear(); + +} + +u32 ddl_process_core_response(void) +{ + struct ddl_context *ddl_context; + u32 return_status = true; + + ddl_context = ddl_get_context(); + if (!ddl_context->core_virtual_base_addr) { + VIDC_LOGERR_STRING("UNKWN_INTR"); + return false; + } + + if (!ddl_handle_core_errors(ddl_context)) { + return_status = ddl_process_intr_status(ddl_context, + ddl_context->intr_status); + } + + if (ddl_context->interrupt_clr) + (*ddl_context->interrupt_clr)(); + + return return_status; +} + +static void ddl_decoder_input_done_callback( + struct ddl_client_context *ddl, u32 frame_transact_end) +{ + struct vidc_720p_dec_disp_info *dec_disp_info = + &(ddl->codec_data.decoder.dec_disp_info); + struct vcd_frame_data *input_vcd_frm = + &(ddl->input_frame.vcd_frm); + ddl_get_frame(input_vcd_frm, dec_disp_info-> + input_frame); + + input_vcd_frm->interlaced = (dec_disp_info-> + input_is_interlace); + + input_vcd_frm->offset += dec_disp_info->input_bytes_consumed; + input_vcd_frm->data_len -= dec_disp_info->input_bytes_consumed; + + ddl->input_frame.frm_trans_end = frame_transact_end; + if (vidc_msg_timing) + ddl_calc_core_proc_time(__func__, DEC_IP_TIME); + ddl->ddl_context->ddl_callback( + VCD_EVT_RESP_INPUT_DONE, + VCD_S_SUCCESS, + &ddl->input_frame, + sizeof(struct ddl_frame_data_tag), + (void *)ddl, + ddl->ddl_context->client_data); +} + +static u32 ddl_decoder_output_done_callback( + struct ddl_client_context *ddl, + u32 frame_transact_end) +{ + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + struct vidc_720p_dec_disp_info *dec_disp_info = + &(decoder->dec_disp_info); + struct ddl_frame_data_tag *output_frame = + &ddl->output_frame; + struct vcd_frame_data *output_vcd_frm = + &(output_frame->vcd_frm); + u32 vcd_status; + u32 free_luma_dpb = 0; + + output_vcd_frm->physical = (u8 *)dec_disp_info->y_addr; + + if (decoder->codec.codec == VCD_CODEC_MPEG4 || + decoder->codec.codec == VCD_CODEC_VC1 || + decoder->codec.codec == VCD_CODEC_VC1_RCV || + (decoder->codec.codec >= VCD_CODEC_DIVX_3 && + decoder->codec.codec <= VCD_CODEC_XVID)){ + vidc_720p_decode_skip_frm_details(&free_luma_dpb); + if (free_luma_dpb) + output_vcd_frm->physical = (u8 *) free_luma_dpb; + } + + + vcd_status = ddl_decoder_dpb_transact( + decoder, + output_frame, + DDL_DPB_OP_MARK_BUSY); + + if (vcd_status != VCD_S_SUCCESS) { + VIDC_LOGERR_STRING("CorruptedOutputBufferAddress"); + ddl_hw_fatal_cb(ddl->ddl_context); + return vcd_status; + } + + output_vcd_frm->ip_frm_tag = dec_disp_info->tag_top; + if (dec_disp_info->crop_exists == 0x1) { + output_vcd_frm->dec_op_prop.disp_frm.left = + dec_disp_info->crop_left_offset; + output_vcd_frm->dec_op_prop.disp_frm.top = + dec_disp_info->crop_top_offset; + output_vcd_frm->dec_op_prop.disp_frm.right = + dec_disp_info->img_size_x - + dec_disp_info->crop_right_offset; + output_vcd_frm->dec_op_prop.disp_frm.bottom = + dec_disp_info->img_size_y - + dec_disp_info->crop_bottom_offset; + } else { + output_vcd_frm->dec_op_prop.disp_frm.left = 0; + output_vcd_frm->dec_op_prop.disp_frm.top = 0; + output_vcd_frm->dec_op_prop.disp_frm.right = + dec_disp_info->img_size_x; + output_vcd_frm->dec_op_prop.disp_frm.bottom = + dec_disp_info->img_size_y; + } + if (!dec_disp_info->disp_is_interlace) { + output_vcd_frm->interlaced = false; + output_vcd_frm->intrlcd_ip_frm_tag = VCD_FRAMETAG_INVALID; + } else { + output_vcd_frm->interlaced = true; + output_vcd_frm->intrlcd_ip_frm_tag = + dec_disp_info->tag_bottom; + } + + output_vcd_frm->offset = 0; + output_vcd_frm->data_len = decoder->y_cb_cr_size; + if (free_luma_dpb) { + output_vcd_frm->data_len = 0; + output_vcd_frm->flags |= VCD_FRAME_FLAG_DECODEONLY; + } + output_vcd_frm->flags |= VCD_FRAME_FLAG_ENDOFFRAME; + ddl_process_decoder_metadata(ddl); + output_frame->frm_trans_end = frame_transact_end; + + if (vidc_msg_timing) + ddl_calc_core_proc_time(__func__, DEC_OP_TIME); + + ddl->ddl_context->ddl_callback( + VCD_EVT_RESP_OUTPUT_DONE, + vcd_status, + output_frame, + sizeof(struct ddl_frame_data_tag), + (void *)ddl, + ddl->ddl_context->client_data); + return vcd_status; +} + +static u32 ddl_get_frame + (struct vcd_frame_data *frame, u32 frametype) { + enum vidc_720p_frame vidc_frame = + (enum vidc_720p_frame)frametype; + u32 status = true; + + switch (vidc_frame) { + case VIDC_720P_IFRAME: + { + frame->flags |= VCD_FRAME_FLAG_SYNCFRAME; + frame->frame = VCD_FRAME_I; + break; + } + case VIDC_720P_PFRAME: + { + frame->frame = VCD_FRAME_P; + break; + } + case VIDC_720P_BFRAME: + { + frame->frame = VCD_FRAME_B; + break; + } + case VIDC_720P_NOTCODED: + { + frame->frame = VCD_FRAME_NOTCODED; + frame->data_len = 0; + break; + } + case VIDC_720P_IDRFRAME: + { + frame->flags |= VCD_FRAME_FLAG_SYNCFRAME; + frame->frame = VCD_FRAME_IDR; + break; + } + default: + { + VIDC_LOG_STRING("CRITICAL-FRAMETYPE"); + status = false; + break; + } + } + return status; +} + +static void ddl_getmpeg4_declevel(enum vcd_codec_level *codec_level, + u32 level) +{ + switch (level) { + case VIDC_720P_MPEG4_LEVEL0: + { + *codec_level = VCD_LEVEL_MPEG4_0; + break; + } + case VIDC_720P_MPEG4_LEVEL0b: + { + *codec_level = VCD_LEVEL_MPEG4_0b; + break; + } + case VIDC_720P_MPEG4_LEVEL1: + { + *codec_level = VCD_LEVEL_MPEG4_1; + break; + } + case VIDC_720P_MPEG4_LEVEL2: + { + *codec_level = VCD_LEVEL_MPEG4_2; + break; + } + case VIDC_720P_MPEG4_LEVEL3: + { + *codec_level = VCD_LEVEL_MPEG4_3; + break; + } + case VIDC_720P_MPEG4_LEVEL3b: + { + *codec_level = VCD_LEVEL_MPEG4_3b; + break; + } + case VIDC_720P_MPEG4_LEVEL4a: + { + *codec_level = VCD_LEVEL_MPEG4_4a; + break; + } + case VIDC_720P_MPEG4_LEVEL5: + { + *codec_level = VCD_LEVEL_MPEG4_5; + break; + } + case VIDC_720P_MPEG4_LEVEL6: + { + *codec_level = VCD_LEVEL_MPEG4_6; + break; + } + } +} + +static void ddl_geth264_declevel(enum vcd_codec_level *codec_level, + u32 level) +{ + switch (level) { + case VIDC_720P_H264_LEVEL1: + { + *codec_level = VCD_LEVEL_H264_1; + break; + } + case VIDC_720P_H264_LEVEL1b: + { + *codec_level = VCD_LEVEL_H264_1b; + break; + } + case VIDC_720P_H264_LEVEL1p1: + { + *codec_level = VCD_LEVEL_H264_1p1; + break; + } + case VIDC_720P_H264_LEVEL1p2: + { + *codec_level = VCD_LEVEL_H264_1p2; + break; + } + case VIDC_720P_H264_LEVEL1p3: + { + *codec_level = VCD_LEVEL_H264_1p3; + break; + } + case VIDC_720P_H264_LEVEL2: + { + *codec_level = VCD_LEVEL_H264_2; + break; + } + case VIDC_720P_H264_LEVEL2p1: + { + *codec_level = VCD_LEVEL_H264_2p1; + break; + } + case VIDC_720P_H264_LEVEL2p2: + { + *codec_level = VCD_LEVEL_H264_2p2; + break; + } + case VIDC_720P_H264_LEVEL3: + { + *codec_level = VCD_LEVEL_H264_3; + break; + } + case VIDC_720P_H264_LEVEL3p1: + { + *codec_level = VCD_LEVEL_H264_3p1; + break; + } + case VIDC_720P_H264_LEVEL3p2: + { + *codec_level = VCD_LEVEL_H264_3p2; + break; + } + + } +} + +static void ddl_get_vc1_dec_level( + enum vcd_codec_level *codec_level, u32 level, + enum vcd_codec_profile vc1_profile) +{ + if (vc1_profile == VCD_PROFILE_VC1_ADVANCE) { + switch (level) { + case VIDC_720P_VC1_LEVEL0: + { + *codec_level = VCD_LEVEL_VC1_A_0; + break; + } + case VIDC_720P_VC1_LEVEL1: + { + *codec_level = VCD_LEVEL_VC1_A_1; + break; + } + case VIDC_720P_VC1_LEVEL2: + { + *codec_level = VCD_LEVEL_VC1_A_2; + break; + } + case VIDC_720P_VC1_LEVEL3: + { + *codec_level = VCD_LEVEL_VC1_A_3; + break; + } + case VIDC_720P_VC1_LEVEL4: + { + *codec_level = VCD_LEVEL_VC1_A_4; + break; + } + } + return; + } else if (vc1_profile == VCD_PROFILE_VC1_MAIN) { + switch (level) { + case VIDC_720P_VC1_LEVEL_LOW: + { + *codec_level = VCD_LEVEL_VC1_M_LOW; + break; + } + case VIDC_720P_VC1_LEVEL_MED: + { + *codec_level = VCD_LEVEL_VC1_M_MEDIUM; + break; + } + case VIDC_720P_VC1_LEVEL_HIGH: + { + *codec_level = VCD_LEVEL_VC1_M_HIGH; + break; + } + } + } else if (vc1_profile == VCD_PROFILE_VC1_SIMPLE) { + switch (level) { + case VIDC_720P_VC1_LEVEL_LOW: + { + *codec_level = VCD_LEVEL_VC1_S_LOW; + break; + } + case VIDC_720P_VC1_LEVEL_MED: + { + *codec_level = VCD_LEVEL_VC1_S_MEDIUM; + break; + } + } + } +} + +static void ddl_get_mpeg2_dec_level(enum vcd_codec_level *codec_level, + u32 level) +{ + switch (level) { + case VIDCL_720P_MPEG2_LEVEL_LOW: + { + *codec_level = VCD_LEVEL_MPEG2_LOW; + break; + } + case VIDCL_720P_MPEG2_LEVEL_MAIN: + { + *codec_level = VCD_LEVEL_MPEG2_MAIN; + break; + } + case VIDCL_720P_MPEG2_LEVEL_HIGH14: + { + *codec_level = VCD_LEVEL_MPEG2_HIGH_14; + break; + } + } +} + +static void ddl_getdec_profilelevel(struct ddl_decoder_data *decoder, + u32 profile, u32 level) +{ + enum vcd_codec_profile codec_profile = VCD_PROFILE_UNKNOWN; + enum vcd_codec_level codec_level = VCD_LEVEL_UNKNOWN; + + switch (decoder->codec.codec) { + case VCD_CODEC_MPEG4: + { + if (profile == VIDC_720P_PROFILE_MPEG4_SP) + codec_profile = VCD_PROFILE_MPEG4_SP; + else if (profile == VIDC_720P_PROFILE_MPEG4_ASP) + codec_profile = VCD_PROFILE_MPEG4_ASP; + + ddl_getmpeg4_declevel(&codec_level, level); + break; + } + case VCD_CODEC_H264: + { + if (profile == VIDC_720P_PROFILE_H264_BASELINE) + codec_profile = VCD_PROFILE_H264_BASELINE; + else if (profile == VIDC_720P_PROFILE_H264_MAIN) + codec_profile = VCD_PROFILE_H264_MAIN; + else if (profile == VIDC_720P_PROFILE_H264_HIGH) + codec_profile = VCD_PROFILE_H264_HIGH; + ddl_geth264_declevel(&codec_level, level); + break; + } + default: + case VCD_CODEC_H263: + { + break; + } + case VCD_CODEC_VC1: + case VCD_CODEC_VC1_RCV: + { + if (profile == VIDC_720P_PROFILE_VC1_SP) + codec_profile = VCD_PROFILE_VC1_SIMPLE; + else if (profile == VIDC_720P_PROFILE_VC1_MAIN) + codec_profile = VCD_PROFILE_VC1_MAIN; + else if (profile == VIDC_720P_PROFILE_VC1_ADV) + codec_profile = VCD_PROFILE_VC1_ADVANCE; + ddl_get_vc1_dec_level(&codec_level, level, profile); + break; + } + case VCD_CODEC_MPEG2: + { + if (profile == VIDC_720P_PROFILE_MPEG2_MAIN) + codec_profile = VCD_PROFILE_MPEG2_MAIN; + else if (profile == VIDC_720P_PROFILE_MPEG2_SP) + codec_profile = VCD_PROFILE_MPEG2_SIMPLE; + ddl_get_mpeg2_dec_level(&codec_level, level); + break; + } + } + + decoder->profile.profile = codec_profile; + decoder->level.level = codec_level; +} diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.c new file mode 100644 index 000000000000..5d8753324365 --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.c @@ -0,0 +1,580 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#include +#include "vcd_ddl_utils.h" +#include "vcd_ddl_metadata.h" + +static u32 *ddl_metadata_hdr_entry(struct ddl_client_context *ddl, + u32 meta_data) +{ + u32 skip_words = 0; + u32 *buffer; + + if (ddl->decoding) { + buffer = (u32 *) + ddl->codec_data.decoder.meta_data_input. + align_virtual_addr; + skip_words = 32 + 1; + buffer += skip_words; + + switch (meta_data) { + default: + case VCD_METADATA_DATANONE: + { + skip_words = 0; + break; + } + case VCD_METADATA_QPARRAY: + { + skip_words = 3; + break; + } + case VCD_METADATA_CONCEALMB: + { + skip_words = 6; + break; + } + case VCD_METADATA_VC1: + { + skip_words = 9; + break; + } + case VCD_METADATA_SEI: + { + skip_words = 12; + break; + } + case VCD_METADATA_VUI: + { + skip_words = 15; + break; + } + case VCD_METADATA_PASSTHROUGH: + { + skip_words = 18; + break; + } + case VCD_METADATA_QCOMFILLER: + { + skip_words = 21; + break; + } + } + } else { + buffer = (u32 *) + ddl->codec_data.encoder.meta_data_input. + align_virtual_addr; + skip_words = 2; + buffer += skip_words; + + switch (meta_data) { + default: + case VCD_METADATA_DATANONE: + { + skip_words = 0; + break; + } + case VCD_METADATA_ENC_SLICE: + { + skip_words = 3; + break; + } + case VCD_METADATA_QCOMFILLER: + { + skip_words = 6; + break; + } + } + + } + + buffer += skip_words; + return buffer; +} + +void ddl_set_default_meta_data_hdr(struct ddl_client_context *ddl) +{ + struct ddl_buf_addr *main_buffer = + &ddl->ddl_context->metadata_shared_input; + struct ddl_buf_addr *client_buffer; + u32 *hdr_entry; + + if (ddl->decoding) + client_buffer = &(ddl->codec_data.decoder.meta_data_input); + else + client_buffer = &(ddl->codec_data.encoder.meta_data_input); + + DDL_METADATA_CLIENT_INPUTBUF(main_buffer, client_buffer, + ddl->channel_id); + + hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_QCOMFILLER); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_QCOMFILLER; + + hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_DATANONE); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_DATANONE; + + if (ddl->decoding) { + hdr_entry = + ddl_metadata_hdr_entry(ddl, VCD_METADATA_QPARRAY); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_QPARRAY; + + hdr_entry = + ddl_metadata_hdr_entry(ddl, VCD_METADATA_CONCEALMB); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_CONCEALMB; + + hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_SEI); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_SEI; + + hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_VUI); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_VUI; + + hdr_entry = ddl_metadata_hdr_entry(ddl, VCD_METADATA_VC1); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = VCD_METADATA_VC1; + + hdr_entry = + ddl_metadata_hdr_entry(ddl, VCD_METADATA_PASSTHROUGH); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = + VCD_METADATA_PASSTHROUGH; + + } else { + hdr_entry = + ddl_metadata_hdr_entry(ddl, VCD_METADATA_ENC_SLICE); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = 0x00000101; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = 1; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = + VCD_METADATA_ENC_SLICE; + } +} + +static u32 ddl_supported_metadata_flag(struct ddl_client_context *ddl) +{ + u32 flag = 0; + + if (ddl->decoding) { + enum vcd_codec codec = + ddl->codec_data.decoder.codec.codec; + + flag |= (VCD_METADATA_CONCEALMB | + VCD_METADATA_PASSTHROUGH | VCD_METADATA_QPARRAY); + if (codec == VCD_CODEC_H264) { + flag |= (VCD_METADATA_SEI | VCD_METADATA_VUI); + } else if (codec == VCD_CODEC_VC1 || + codec == VCD_CODEC_VC1_RCV) { + flag |= VCD_METADATA_VC1; + } + } else { + flag |= VCD_METADATA_ENC_SLICE; + } + + return flag; +} + +void ddl_set_default_metadata_flag(struct ddl_client_context *ddl) +{ + if (ddl->decoding) + ddl->codec_data.decoder.meta_data_enable_flag = 0; + else + ddl->codec_data.encoder.meta_data_enable_flag = 0; +} + +void ddl_set_default_decoder_metadata_buffer_size( + struct ddl_decoder_data *decoder, + struct vcd_property_frame_size *frame_size, + struct vcd_buffer_requirement *output_buf_req) +{ + u32 flag = decoder->meta_data_enable_flag; + u32 suffix = 0; + size_t sz = 0; + + if (!flag) { + decoder->suffix = 0; + return; + } + + if (flag & VCD_METADATA_QPARRAY) { + u32 num_of_mb = + ((frame_size->width * frame_size->height) >> 8); + sz = DDL_METADATA_HDR_SIZE; + sz += num_of_mb; + DDL_METADATA_ALIGNSIZE(sz); + suffix += sz; + } + if (flag & VCD_METADATA_CONCEALMB) { + u32 num_of_mb = + ((frame_size->width * frame_size->height) >> 8); + sz = DDL_METADATA_HDR_SIZE + (num_of_mb >> 3); + DDL_METADATA_ALIGNSIZE(sz); + suffix += sz; + } + if (flag & VCD_METADATA_VC1) { + sz = DDL_METADATA_HDR_SIZE; + sz += DDL_METADATA_VC1_PAYLOAD_SIZE; + DDL_METADATA_ALIGNSIZE(sz); + suffix += sz; + } + if (flag & VCD_METADATA_SEI) { + sz = DDL_METADATA_HDR_SIZE; + sz += DDL_METADATA_SEI_PAYLOAD_SIZE; + DDL_METADATA_ALIGNSIZE(sz); + suffix += (sz * DDL_METADATA_SEI_MAX); + } + if (flag & VCD_METADATA_VUI) { + sz = DDL_METADATA_HDR_SIZE; + sz += DDL_METADATA_VUI_PAYLOAD_SIZE; + DDL_METADATA_ALIGNSIZE(sz); + suffix += (sz); + } + if (flag & VCD_METADATA_PASSTHROUGH) { + sz = DDL_METADATA_HDR_SIZE; + sz += DDL_METADATA_PASSTHROUGH_PAYLOAD_SIZE; + DDL_METADATA_ALIGNSIZE(sz); + suffix += (sz); + } + sz = DDL_METADATA_EXTRADATANONE_SIZE; + DDL_METADATA_ALIGNSIZE(sz); + suffix += (sz); + + suffix += DDL_METADATA_EXTRAPAD_SIZE; + DDL_METADATA_ALIGNSIZE(suffix); + + decoder->suffix = suffix; + output_buf_req->sz += suffix; + return; +} + +void ddl_set_default_encoder_metadata_buffer_size(struct ddl_encoder_data + *encoder) +{ + u32 flag = encoder->meta_data_enable_flag; + u32 suffix = 0; + size_t sz = 0; + + if (!flag) { + encoder->suffix = 0; + return; + } + + if (flag & VCD_METADATA_ENC_SLICE) { + u32 num_of_mb = (encoder->frame_size.width * + encoder->frame_size.height / 16 / 16); + sz = DDL_METADATA_HDR_SIZE; + + sz += 4; + + sz += (8 * num_of_mb); + DDL_METADATA_ALIGNSIZE(sz); + suffix += sz; + } + + sz = DDL_METADATA_EXTRADATANONE_SIZE; + DDL_METADATA_ALIGNSIZE(sz); + suffix += (sz); + + suffix += DDL_METADATA_EXTRAPAD_SIZE; + DDL_METADATA_ALIGNSIZE(suffix); + + encoder->suffix = suffix; + encoder->output_buf_req.sz += suffix; +} + +u32 ddl_set_metadata_params(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, + void *property_value) +{ + u32 vcd_status = VCD_ERR_ILLEGAL_PARM; + if (property_hdr->prop_id == VCD_I_METADATA_ENABLE) { + struct vcd_property_meta_data_enable *meta_data_enable = + (struct vcd_property_meta_data_enable *) + property_value; + u32 *meta_data_enable_flag; + enum vcd_codec codec; + if (ddl->decoding) { + meta_data_enable_flag = + &(ddl->codec_data.decoder. + meta_data_enable_flag); + codec = ddl->codec_data.decoder.codec.codec; + } else { + meta_data_enable_flag = + &(ddl->codec_data.encoder. + meta_data_enable_flag); + codec = ddl->codec_data.encoder.codec.codec; + } + if (sizeof(struct vcd_property_meta_data_enable) == + property_hdr->sz && + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) && + codec) { + u32 flag = ddl_supported_metadata_flag(ddl); + flag &= (meta_data_enable->meta_data_enable_flag); + if (flag) + flag |= DDL_METADATA_MANDATORY; + if (flag != *meta_data_enable_flag) { + *meta_data_enable_flag = flag; + if (ddl->decoding) { + ddl_set_default_decoder_buffer_req + (&ddl->codec_data.decoder, + true); + } else { + ddl_set_default_encoder_buffer_req + (&ddl->codec_data.encoder); + } + } + vcd_status = VCD_S_SUCCESS; + } + } else if (property_hdr->prop_id == VCD_I_METADATA_HEADER) { + struct vcd_property_metadata_hdr *hdr = + (struct vcd_property_metadata_hdr *)property_value; + if (sizeof(struct vcd_property_metadata_hdr) == + property_hdr->sz) { + u32 flag = ddl_supported_metadata_flag(ddl); + flag |= DDL_METADATA_MANDATORY; + flag &= hdr->meta_data_id; + if (!(flag & (flag - 1))) { + u32 *hdr_entry = + ddl_metadata_hdr_entry(ddl, flag); + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX] = + hdr->version; + hdr_entry[DDL_METADATA_HDR_PORT_INDEX] = + hdr->port_index; + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX] = + hdr->type; + vcd_status = VCD_S_SUCCESS; + } + } + } + return vcd_status; +} + +u32 ddl_get_metadata_params(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, + void *property_value) +{ + u32 vcd_status = VCD_ERR_ILLEGAL_PARM ; + if (property_hdr->prop_id == VCD_I_METADATA_ENABLE && + sizeof(struct vcd_property_meta_data_enable) + == property_hdr->sz) { + struct vcd_property_meta_data_enable *meta_data_enable = + (struct vcd_property_meta_data_enable *) + property_value; + meta_data_enable->meta_data_enable_flag = + ((ddl->decoding) ? + (ddl->codec_data.decoder.meta_data_enable_flag) + : (ddl->codec_data.encoder.meta_data_enable_flag)); + vcd_status = VCD_S_SUCCESS; + } else if (property_hdr->prop_id == VCD_I_METADATA_HEADER && + sizeof(struct vcd_property_metadata_hdr) == + property_hdr->sz) { + struct vcd_property_metadata_hdr *hdr = + (struct vcd_property_metadata_hdr *) + property_value; + u32 flag = ddl_supported_metadata_flag(ddl); + flag |= DDL_METADATA_MANDATORY; + flag &= hdr->meta_data_id; + if (!(flag & (flag - 1))) { + u32 *hdr_entry = ddl_metadata_hdr_entry(ddl, + flag); + hdr->version = + hdr_entry[DDL_METADATA_HDR_VERSION_INDEX]; + hdr->port_index = + hdr_entry[DDL_METADATA_HDR_PORT_INDEX]; + hdr->type = + hdr_entry[DDL_METADATA_HDR_TYPE_INDEX]; + vcd_status = VCD_S_SUCCESS; + } + } + return vcd_status; +} + +void ddl_metadata_enable(struct ddl_client_context *ddl) +{ + u32 flag, hal_flag = 0; + u32 *metadata_input; + if (ddl->decoding) { + flag = ddl->codec_data.decoder.meta_data_enable_flag; + metadata_input = + ddl->codec_data.decoder.meta_data_input. + align_physical_addr; + } else { + flag = ddl->codec_data.encoder.meta_data_enable_flag; + metadata_input = + ddl->codec_data.encoder.meta_data_input. + align_physical_addr; + } + if (flag) { + if (flag & VCD_METADATA_QPARRAY) + hal_flag |= VIDC_720P_METADATA_ENABLE_QP; + if (flag & VCD_METADATA_CONCEALMB) + hal_flag |= VIDC_720P_METADATA_ENABLE_CONCEALMB; + if (flag & VCD_METADATA_VC1) + hal_flag |= VIDC_720P_METADATA_ENABLE_VC1; + if (flag & VCD_METADATA_SEI) + hal_flag |= VIDC_720P_METADATA_ENABLE_SEI; + if (flag & VCD_METADATA_VUI) + hal_flag |= VIDC_720P_METADATA_ENABLE_VUI; + if (flag & VCD_METADATA_ENC_SLICE) + hal_flag |= VIDC_720P_METADATA_ENABLE_ENCSLICE; + if (flag & VCD_METADATA_PASSTHROUGH) + hal_flag |= VIDC_720P_METADATA_ENABLE_PASSTHROUGH; + } else { + metadata_input = 0; + } + vidc_720p_metadata_enable(hal_flag, metadata_input); +} + +u32 ddl_encode_set_metadata_output_buf(struct ddl_client_context *ddl) +{ + struct ddl_encoder_data *encoder = &ddl->codec_data.encoder; + u32 *buffer; + struct vcd_frame_data *stream = &(ddl->output_frame.vcd_frm); + u32 ext_buffer_end, hw_metadata_start; + + ext_buffer_end = (u32) stream->physical + stream->alloc_len; + if (!encoder->meta_data_enable_flag) { + ext_buffer_end &= ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES); + return ext_buffer_end; + } + hw_metadata_start = (ext_buffer_end - encoder->suffix) & + ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES); + + ext_buffer_end = (hw_metadata_start - 1) & + ~(DDL_STREAMBUF_ALIGN_GUARD_BYTES); + + buffer = encoder->meta_data_input.align_virtual_addr; + + *buffer++ = encoder->suffix; + + *buffer = hw_metadata_start; + + encoder->meta_data_offset = + hw_metadata_start - (u32) stream->physical; + + return ext_buffer_end; +} + +void ddl_decode_set_metadata_output(struct ddl_decoder_data *decoder) +{ + u32 *buffer; + u32 loopc; + + if (!decoder->meta_data_enable_flag) { + decoder->meta_data_offset = 0; + return; + } + + decoder->meta_data_offset = ddl_get_yuv_buffer_size( + &decoder->client_frame_size, &decoder->buf_format, + (!decoder->progressive_only), decoder->codec.codec); + + buffer = decoder->meta_data_input.align_virtual_addr; + + *buffer++ = decoder->suffix; + + for (loopc = 0; loopc < decoder->dp_buf.no_of_dec_pic_buf; + ++loopc) { + *buffer++ = (u32) (decoder->meta_data_offset + (u8 *) + decoder->dp_buf. + dec_pic_buffers[loopc].vcd_frm. + physical); + } +} + +void ddl_process_encoder_metadata(struct ddl_client_context *ddl) +{ + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + struct vcd_frame_data *out_frame = + &(ddl->output_frame.vcd_frm); + u32 *qfiller_hdr, *qfiller, start_addr; + u32 qfiller_size; + + if (!encoder->meta_data_enable_flag) { + out_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA); + return; + } + + if (!encoder->enc_frame_info.metadata_exists) { + out_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA); + return; + } + out_frame->flags |= VCD_FRAME_FLAG_EXTRADATA; + + start_addr = (u32) ((u8 *) out_frame->virtual + + out_frame->offset); + qfiller = (u32 *) ((out_frame->data_len + start_addr + 3) & ~3); + + qfiller_size = (u32) ((encoder->meta_data_offset + + (u8 *) out_frame->virtual) - + (u8 *) qfiller); + + qfiller_hdr = ddl_metadata_hdr_entry(ddl, VCD_METADATA_QCOMFILLER); + + *qfiller++ = qfiller_size; + *qfiller++ = qfiller_hdr[DDL_METADATA_HDR_VERSION_INDEX]; + *qfiller++ = qfiller_hdr[DDL_METADATA_HDR_PORT_INDEX]; + *qfiller++ = qfiller_hdr[DDL_METADATA_HDR_TYPE_INDEX]; + *qfiller = (u32) (qfiller_size - DDL_METADATA_HDR_SIZE); +} + +void ddl_process_decoder_metadata(struct ddl_client_context *ddl) +{ + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + struct vcd_frame_data *output_frame = + &(ddl->output_frame.vcd_frm); + u32 *qfiller_hdr, *qfiller; + u32 qfiller_size; + + if (!decoder->meta_data_enable_flag) { + output_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA); + return; + } + + if (!decoder->dec_disp_info.metadata_exists) { + output_frame->flags &= ~(VCD_FRAME_FLAG_EXTRADATA); + return; + } + output_frame->flags |= VCD_FRAME_FLAG_EXTRADATA; + + if (output_frame->data_len != decoder->meta_data_offset) { + qfiller = (u32 *) ((u32) ((output_frame->data_len + + output_frame->offset + + (u8 *) output_frame->virtual) + + 3) & ~3); + + qfiller_size = (u32) ((decoder->meta_data_offset + + (u8 *) output_frame->virtual) - + (u8 *) qfiller); + + qfiller_hdr = + ddl_metadata_hdr_entry(ddl, VCD_METADATA_QCOMFILLER); + *qfiller++ = qfiller_size; + *qfiller++ = qfiller_hdr[DDL_METADATA_HDR_VERSION_INDEX]; + *qfiller++ = qfiller_hdr[DDL_METADATA_HDR_PORT_INDEX]; + *qfiller++ = qfiller_hdr[DDL_METADATA_HDR_TYPE_INDEX]; + *qfiller = (u32) (qfiller_size - DDL_METADATA_HDR_SIZE); + } +} diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.h new file mode 100644 index 000000000000..7c9ac951bfe2 --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_metadata.h @@ -0,0 +1,79 @@ +/* Copyright (c) 2010, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#ifndef _VCD_DDL_METADATA_H_ +#define _VCD_DDL_METADATA_H_ + +#define DDL_MAX_DEC_METADATATYPE (8) +#define DDL_MAX_ENC_METADATATYPE (3) + +#define DDL_METADATA_EXTRAPAD_SIZE (256) +#define DDL_METADATA_HDR_SIZE (20) + +#define DDL_METADATA_EXTRADATANONE_SIZE (24) + +#define DDL_METADATA_ALIGNSIZE(x) ((x) = (((x) + 0x7) & ~0x7)) + +#define DDL_METADATA_MANDATORY (VCD_METADATA_DATANONE | \ + VCD_METADATA_QCOMFILLER) + +#define DDL_METADATA_VC1_PAYLOAD_SIZE (38*4) + +#define DDL_METADATA_SEI_PAYLOAD_SIZE (100) +#define DDL_METADATA_SEI_MAX (5) + +#define DDL_METADATA_VUI_PAYLOAD_SIZE (256) + +#define DDL_METADATA_PASSTHROUGH_PAYLOAD_SIZE (68) + +#define DDL_METADATA_CLIENT_INPUTBUFSIZE (256) +#define DDL_METADATA_TOTAL_INPUTBUFSIZE \ + (DDL_METADATA_CLIENT_INPUTBUFSIZE * VCD_MAX_NO_CLIENT) + +#define DDL_METADATA_CLIENT_INPUTBUF(main_buffer, client_buffer, \ + channel_id) \ +{ \ + (client_buffer)->align_physical_addr = (u32 *)\ + ((u8 *)(main_buffer)->align_physical_addr + \ + (DDL_METADATA_CLIENT_INPUTBUFSIZE * (channel_id)) \ + ); \ + (client_buffer)->align_virtual_addr = (u32 *)\ + ((u8 *)(main_buffer)->align_virtual_addr + \ + (DDL_METADATA_CLIENT_INPUTBUFSIZE * (channel_id)) \ + ); \ + (client_buffer)->virtual_base_addr = 0; \ +} + +#define DDL_METADATA_HDR_VERSION_INDEX 0 +#define DDL_METADATA_HDR_PORT_INDEX 1 +#define DDL_METADATA_HDR_TYPE_INDEX 2 + + +void ddl_set_default_meta_data_hdr(struct ddl_client_context *ddl); +u32 ddl_get_metadata_params(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value); +u32 ddl_set_metadata_params(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, + void *property_value); +void ddl_set_default_metadata_flag(struct ddl_client_context *ddl); +void ddl_set_default_decoder_metadata_buffer_size + (struct ddl_decoder_data *decoder, + struct vcd_property_frame_size *frame_size, + struct vcd_buffer_requirement *output_buf_req); +void ddl_set_default_encoder_metadata_buffer_size(struct ddl_encoder_data + *encoder); +void ddl_metadata_enable(struct ddl_client_context *ddl); +u32 ddl_encode_set_metadata_output_buf(struct ddl_client_context *ddl); +void ddl_decode_set_metadata_output(struct ddl_decoder_data *decoder); +void ddl_process_encoder_metadata(struct ddl_client_context *ddl); +void ddl_process_decoder_metadata(struct ddl_client_context *ddl); +#endif diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c new file mode 100644 index 000000000000..cdb6313da70b --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_properties.c @@ -0,0 +1,1943 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#include +#include "vcd_ddl_utils.h" +#include "vcd_ddl_metadata.h" + +static u32 ddl_set_dec_property(struct ddl_client_context *pddl, + struct vcd_property_hdr *property_hdr, + void *property_value); +static u32 ddl_set_enc_property(struct ddl_client_context *pddl, + struct vcd_property_hdr *property_hdr, + void *property_value); +static u32 ddl_get_dec_property(struct ddl_client_context *pddl, + struct vcd_property_hdr *property_hdr, + void *property_value); +static u32 ddl_get_enc_property(struct ddl_client_context *pddl, + struct vcd_property_hdr *property_hdr, + void *property_value); +static u32 ddl_set_enc_dynamic_property(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, + void *property_value); +static void ddl_set_default_enc_property(struct ddl_client_context *ddl); +static void ddl_set_default_enc_profile(struct ddl_encoder_data + *encoder); +static void ddl_set_default_enc_level(struct ddl_encoder_data *encoder); +static void ddl_set_default_enc_vop_timing(struct ddl_encoder_data + *encoder); +static void ddl_set_default_enc_intra_period(struct ddl_encoder_data + *encoder); +static void ddl_set_default_enc_rc_params(struct ddl_encoder_data + *encoder); +static u32 ddl_valid_buffer_requirement(struct vcd_buffer_requirement + *original_buf_req, + struct vcd_buffer_requirement + *req_buf_req); +static u32 ddl_decoder_min_num_dpb(struct ddl_decoder_data *decoder); +static u32 ddl_set_dec_buffers + (struct ddl_decoder_data *decoder, + struct ddl_property_dec_pic_buffers *dpb); + +u32 ddl_set_property(u32 *ddl_handle, + struct vcd_property_hdr *property_hdr, void *property_value) +{ + u32 vcd_status; + struct ddl_context *ddl_context; + struct ddl_client_context *ddl = + (struct ddl_client_context *)ddl_handle; + + if (!property_hdr || !property_value) { + VIDC_LOGERR_STRING("ddl_set_prop:Bad_argument"); + return VCD_ERR_ILLEGAL_PARM; + } + ddl_context = ddl_get_context(); + + if (!DDL_IS_INITIALIZED(ddl_context)) { + VIDC_LOGERR_STRING("ddl_set_prop:Not_inited"); + return VCD_ERR_ILLEGAL_OP; + } + + if (!ddl) { + VIDC_LOGERR_STRING("ddl_set_prop:Bad_handle"); + return VCD_ERR_BAD_HANDLE; + } + if (ddl->decoding) { + vcd_status = + ddl_set_dec_property(ddl, property_hdr, + property_value); + } else { + vcd_status = + ddl_set_enc_property(ddl, property_hdr, + property_value); + } + if (vcd_status) + VIDC_LOGERR_STRING("ddl_set_prop:FAILED"); + + return vcd_status; +} + +u32 ddl_get_property(u32 *ddl_handle, + struct vcd_property_hdr *property_hdr, void *property_value) +{ + + u32 vcd_status = VCD_ERR_ILLEGAL_PARM; + struct ddl_context *ddl_context; + struct ddl_client_context *ddl = + (struct ddl_client_context *)ddl_handle; + + if (!property_hdr || !property_value) + return VCD_ERR_ILLEGAL_PARM; + + if (property_hdr->prop_id == DDL_I_CAPABILITY) { + if (sizeof(struct ddl_property_capability) == + property_hdr->sz) { + struct ddl_property_capability *ddl_capability = + (struct ddl_property_capability *) + property_value; + ddl_capability->max_num_client = VCD_MAX_NO_CLIENT; + ddl_capability->exclusive = + VCD_COMMAND_EXCLUSIVE; + ddl_capability->frame_command_depth = + VCD_FRAME_COMMAND_DEPTH; + ddl_capability->general_command_depth = + VCD_GENERAL_COMMAND_DEPTH; + ddl_capability->ddl_time_out_in_ms = + DDL_HW_TIMEOUT_IN_MS; + vcd_status = VCD_S_SUCCESS; + } + return vcd_status; + } + ddl_context = ddl_get_context(); + if (!DDL_IS_INITIALIZED(ddl_context)) + return VCD_ERR_ILLEGAL_OP; + + if (!ddl) + return VCD_ERR_BAD_HANDLE; + + if (ddl->decoding) { + vcd_status = + ddl_get_dec_property(ddl, property_hdr, + property_value); + } else { + vcd_status = + ddl_get_enc_property(ddl, property_hdr, + property_value); + } + if (vcd_status) + VIDC_LOGERR_STRING("ddl_get_prop:FAILED"); + + return vcd_status; +} + +u32 ddl_decoder_ready_to_start(struct ddl_client_context *ddl, + struct vcd_sequence_hdr *header) +{ + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + if (!decoder->codec.codec) { + VIDC_LOGERR_STRING("ddl_dec_start_check:Codec_not_set"); + return false; + } + if ((!header) && + (!decoder->client_frame_size.height || + !decoder->client_frame_size.width) + ) { + VIDC_LOGERR_STRING + ("ddl_dec_start_check:Client_height_width_default"); + return false; + } + return true; +} + +u32 ddl_encoder_ready_to_start(struct ddl_client_context *ddl) +{ + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + + if (!encoder->codec.codec || + !encoder->frame_size.height || + !encoder->frame_size.width || + !encoder->frame_rate.fps_denominator || + !encoder->frame_rate.fps_numerator || + !encoder->target_bit_rate.target_bitrate) { + return false; + } + return true; +} + +static u32 ddl_set_dec_property + (struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value) { + u32 vcd_status = VCD_ERR_ILLEGAL_PARM; + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + switch (property_hdr->prop_id) { + case DDL_I_DPB_RELEASE: + { + if (sizeof(struct ddl_frame_data_tag) == + property_hdr->sz + && decoder->dp_buf.no_of_dec_pic_buf) { + vcd_status = + ddl_decoder_dpb_transact(decoder, + (struct ddl_frame_data_tag *) + property_value, + DDL_DPB_OP_MARK_FREE); + } + break; + } + case DDL_I_DPB: + { + struct ddl_property_dec_pic_buffers *dpb = + (struct ddl_property_dec_pic_buffers *) + property_value; + + if (sizeof(struct ddl_property_dec_pic_buffers) == + property_hdr->sz && + (DDLCLIENT_STATE_IS + (ddl, DDL_CLIENT_WAIT_FOR_INITCODEC) + || DDLCLIENT_STATE_IS(ddl, + DDL_CLIENT_WAIT_FOR_DPB) + ) && + dpb->no_of_dec_pic_buf >= + decoder->client_output_buf_req.actual_count) { + vcd_status = + ddl_set_dec_buffers(decoder, dpb); + } + break; + } + case DDL_I_REQ_OUTPUT_FLUSH: + { + if (sizeof(u32) == property_hdr->sz) { + decoder->dynamic_prop_change |= + DDL_DEC_REQ_OUTPUT_FLUSH; + decoder->dpb_mask.client_mask = 0; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case DDL_I_INPUT_BUF_REQ: + { + struct vcd_buffer_requirement *buffer_req = + (struct vcd_buffer_requirement *) + property_value; + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz && + (ddl_valid_buffer_requirement( + &decoder->min_input_buf_req, + buffer_req))) { + decoder->client_input_buf_req = *buffer_req; + decoder->client_input_buf_req.min_count = + decoder->min_input_buf_req.min_count; + decoder->client_input_buf_req.max_count = + decoder->min_input_buf_req.max_count; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case DDL_I_OUTPUT_BUF_REQ: + { + struct vcd_buffer_requirement *buffer_req = + (struct vcd_buffer_requirement *) + property_value; + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz && + (ddl_valid_buffer_requirement( + &decoder->min_output_buf_req, + buffer_req))) { + decoder->client_output_buf_req = + *buffer_req; + decoder->client_output_buf_req.min_count = + decoder->min_output_buf_req.min_count; + decoder->client_output_buf_req.max_count = + decoder->min_output_buf_req.max_count; + vcd_status = VCD_S_SUCCESS; + } + break; + } + + case VCD_I_CODEC: + { + struct vcd_property_codec *codec = + (struct vcd_property_codec *)property_value; + if (sizeof(struct vcd_property_codec) == + property_hdr->sz + && DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) + ) { + u32 status; + vcd_fw_transact(false, true, + decoder->codec.codec); + status = vcd_fw_transact(true, true, + codec->codec); + if (status) { + decoder->codec = *codec; + ddl_set_default_dec_property(ddl); + vcd_status = VCD_S_SUCCESS; + } else { + status = vcd_fw_transact(true, true, + decoder->codec.codec); + vcd_status = VCD_ERR_NOT_SUPPORTED; + } + } + break; + } + case VCD_I_POST_FILTER: + { + if (sizeof(struct vcd_property_post_filter) == + property_hdr->sz + && DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) && + (decoder->codec.codec == VCD_CODEC_MPEG4 || + decoder->codec.codec == VCD_CODEC_MPEG2) + ) { + decoder->post_filter = + *(struct vcd_property_post_filter *) + property_value; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_FRAME_SIZE: + { + struct vcd_property_frame_size *frame_size = + (struct vcd_property_frame_size *) + property_value; + + if ((sizeof(struct vcd_property_frame_size) == + property_hdr->sz) && + (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN))) { + if (decoder->client_frame_size.height != + frame_size->height + || decoder->client_frame_size.width != + frame_size->width) { + decoder->client_frame_size = + *frame_size; + ddl_set_default_decoder_buffer_req + (decoder, true); + } + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_BUFFER_FORMAT: + { + struct vcd_property_buffer_format *tile = + (struct vcd_property_buffer_format *) + property_value; + if (sizeof(struct vcd_property_buffer_format) == + property_hdr->sz && + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) && + (tile->buffer_format == VCD_BUFFER_FORMAT_NV12 + || tile->buffer_format == + VCD_BUFFER_FORMAT_TILE_4x2) + ) { + if (tile->buffer_format != + decoder->buf_format.buffer_format) { + decoder->buf_format = *tile; + ddl_set_default_decoder_buffer_req + (decoder, true); + } + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_METADATA_ENABLE: + case VCD_I_METADATA_HEADER: + { + vcd_status = ddl_set_metadata_params(ddl, + property_hdr, + property_value); + break; + } + case VCD_I_OUTPUT_ORDER: + { + if (sizeof(u32) == property_hdr->sz && + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) { + decoder->output_order = + *(u32 *)property_value; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_DEC_PICTYPE: + { + if ((sizeof(u32) == property_hdr->sz) && + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) { + decoder->idr_only_decoding = + *(u32 *)property_value; + ddl_set_default_decoder_buffer_req( + decoder, true); + vcd_status = VCD_S_SUCCESS; + } + } + break; + case VCD_I_FRAME_RATE: + { + vcd_status = VCD_S_SUCCESS; + break; + } + default: + { + vcd_status = VCD_ERR_ILLEGAL_OP; + break; + } + } + return vcd_status; +} + +static u32 ddl_set_enc_property(struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value) +{ + u32 vcd_status = VCD_ERR_ILLEGAL_PARM; + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + + if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME) || + (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE) || + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN))) + vcd_status = ddl_set_enc_dynamic_property(ddl, + property_hdr, property_value); + if (vcd_status == VCD_S_SUCCESS) + return vcd_status; + + if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) || + vcd_status != VCD_ERR_ILLEGAL_OP) { + VIDC_LOGERR_STRING + ("ddl_set_enc_property:Fails_as_not_in_open_state"); + return VCD_ERR_ILLEGAL_OP; + } + + switch (property_hdr->prop_id) { + case VCD_I_FRAME_SIZE: + { + struct vcd_property_frame_size *framesize = + (struct vcd_property_frame_size *) + property_value; + + if (sizeof(struct vcd_property_frame_size) + == property_hdr->sz && + DDL_ALLOW_ENC_FRAMESIZE(framesize->width, + framesize->height) && + (encoder->codec.codec == VCD_CODEC_H264 || + DDL_VALIDATE_ENC_FRAMESIZE(framesize->width, + framesize->height)) + ) { + encoder->frame_size = *framesize; + ddl_calculate_stride(&encoder->frame_size, + false, encoder->codec.codec); + ddl_set_default_encoder_buffer_req(encoder); + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_CODEC: + { + struct vcd_property_codec *codec = + (struct vcd_property_codec *) + property_value; + if (sizeof(struct vcd_property_codec) == + property_hdr->sz) { + u32 status; + + vcd_fw_transact(false, false, + encoder->codec.codec); + + status = vcd_fw_transact(true, false, + codec->codec); + if (status) { + encoder->codec = *codec; + ddl_set_default_enc_property(ddl); + vcd_status = VCD_S_SUCCESS; + } else { + status = vcd_fw_transact(true, false, + encoder->codec.codec); + vcd_status = VCD_ERR_NOT_SUPPORTED; + } + } + break; + } + case VCD_I_PROFILE: + { + struct vcd_property_profile *profile = + (struct vcd_property_profile *) + property_value; + if ((sizeof(struct vcd_property_profile) == + property_hdr->sz) && + ((encoder->codec.codec == + VCD_CODEC_MPEG4 && + (profile->profile == + VCD_PROFILE_MPEG4_SP || + profile->profile == + VCD_PROFILE_MPEG4_ASP)) || + (encoder->codec.codec == + VCD_CODEC_H264 && + (profile->profile >= + VCD_PROFILE_H264_BASELINE || + profile->profile <= + VCD_PROFILE_H264_HIGH)) || + (encoder->codec.codec == + VCD_CODEC_H263 && + profile->profile == + VCD_PROFILE_H263_BASELINE)) + ) { + encoder->profile = *profile; + vcd_status = VCD_S_SUCCESS; + + if (profile->profile == + VCD_PROFILE_H264_BASELINE) + encoder->entropy_control.entropy_sel + = VCD_ENTROPY_SEL_CAVLC; + else + encoder->entropy_control.entropy_sel + = VCD_ENTROPY_SEL_CABAC; + } + break; + } + case VCD_I_LEVEL: + { + struct vcd_property_level *level = + (struct vcd_property_level *) + property_value; + if ( + (sizeof(struct vcd_property_level) == + property_hdr->sz + ) && + ( + ( + (encoder->codec. + codec == VCD_CODEC_MPEG4) && + (level->level >= VCD_LEVEL_MPEG4_0) && + (level->level <= VCD_LEVEL_MPEG4_6) + ) || + ( + (encoder->codec. + codec == VCD_CODEC_H264) && + (level->level >= VCD_LEVEL_H264_1) && + (level->level <= VCD_LEVEL_H264_3p1) + ) || + ( + (encoder->codec. + codec == VCD_CODEC_H263) && + (level->level >= VCD_LEVEL_H263_10) && + (level->level <= VCD_LEVEL_H263_70) + ) + ) + ) { + encoder->level = *level; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_MULTI_SLICE: + { + struct vcd_property_multi_slice *multislice = + (struct vcd_property_multi_slice *) + property_value; + switch (multislice->m_slice_sel) { + case VCD_MSLICE_OFF: + { + vcd_status = VCD_S_SUCCESS; + break; + } + case VCD_MSLICE_BY_GOB: + { + if (encoder->codec.codec == + VCD_CODEC_H263) + vcd_status = VCD_S_SUCCESS; + break; + } + case VCD_MSLICE_BY_MB_COUNT: + { + if (multislice->m_slice_size + >= 1 && (multislice-> + m_slice_size <= + (encoder->frame_size.height + * encoder->frame_size.width + / 16 / 16)) + ) { + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_MSLICE_BY_BYTE_COUNT: + { + if (multislice->m_slice_size > 0) + vcd_status = VCD_S_SUCCESS; + break; + } + default: + { + break; + } + } + if (sizeof(struct vcd_property_multi_slice) == + property_hdr->sz && + !vcd_status) { + encoder->multi_slice = *multislice; + if (multislice->m_slice_sel == + VCD_MSLICE_OFF) + encoder->multi_slice.m_slice_size = 0; + } + break; + } + case VCD_I_RATE_CONTROL: + { + struct vcd_property_rate_control + *ratecontrol = + (struct vcd_property_rate_control *) + property_value; + if (sizeof(struct vcd_property_rate_control) == + property_hdr->sz && + ratecontrol-> + rate_control >= VCD_RATE_CONTROL_OFF && + ratecontrol-> + rate_control <= VCD_RATE_CONTROL_CBR_CFR + ) { + encoder->rc = *ratecontrol; + ddl_set_default_enc_rc_params(encoder); + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_SHORT_HEADER: + { + + if (sizeof(struct vcd_property_short_header) == + property_hdr->sz && + encoder->codec.codec == VCD_CODEC_MPEG4) { + encoder->short_header = + *(struct vcd_property_short_header *) + property_value; + vcd_status = VCD_S_SUCCESS; + } + + break; + } + case VCD_I_VOP_TIMING: + { + struct vcd_property_vop_timing *voptime = + (struct vcd_property_vop_timing *) + property_value; + if ( + (sizeof(struct vcd_property_vop_timing) == + property_hdr->sz + ) && + (encoder->frame_rate.fps_numerator <= + voptime->vop_time_resolution) + ) { + encoder->vop_timing = *voptime; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_HEADER_EXTENSION: + { + if (sizeof(u32) == property_hdr->sz && + encoder->codec.codec == VCD_CODEC_MPEG4 + ) { + encoder->hdr_ext_control = *(u32 *) + property_value; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_ENTROPY_CTRL: + { + struct vcd_property_entropy_control + *entropy_control = + (struct vcd_property_entropy_control *) + property_value; + if (sizeof(struct vcd_property_entropy_control) == + property_hdr->sz && + encoder->codec.codec == VCD_CODEC_H264 + && entropy_control-> + entropy_sel >= VCD_ENTROPY_SEL_CAVLC && + entropy_control->entropy_sel <= + VCD_ENTROPY_SEL_CABAC) { + encoder->entropy_control = *entropy_control; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_DEBLOCKING: + { + struct vcd_property_db_config *dbconfig = + (struct vcd_property_db_config *) + property_value; + if (sizeof(struct vcd_property_db_config) == + property_hdr->sz && + encoder->codec.codec == VCD_CODEC_H264 + && dbconfig->db_config >= + VCD_DB_ALL_BLOCKING_BOUNDARY + && dbconfig->db_config <= + VCD_DB_SKIP_SLICE_BOUNDARY + ) { + encoder->db_control = *dbconfig; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_QP_RANGE: + { + struct vcd_property_qp_range *qp = + (struct vcd_property_qp_range *) + property_value; + if ((sizeof(struct vcd_property_qp_range) == + property_hdr->sz) && + (qp->min_qp <= qp->max_qp) && + ( + (encoder->codec.codec == VCD_CODEC_H264 + && qp->max_qp <= DDL_MAX_H264_QP) || + (qp->max_qp <= DDL_MAX_MPEG4_QP) + ) + ) { + encoder->qp_range = *qp; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_SESSION_QP: + { + struct vcd_property_session_qp *qp = + (struct vcd_property_session_qp *) + property_value; + + if ((sizeof(struct vcd_property_session_qp) == + property_hdr->sz) && + (qp->i_frame_qp >= encoder->qp_range.min_qp) && + (qp->i_frame_qp <= encoder->qp_range.max_qp) && + (qp->p_frame_qp >= encoder->qp_range.min_qp) && + (qp->p_frame_qp <= encoder->qp_range.max_qp) + ) { + encoder->session_qp = *qp; + vcd_status = VCD_S_SUCCESS; + } + + break; + } + case VCD_I_RC_LEVEL_CONFIG: + { + struct vcd_property_rc_level *rc_level = + (struct vcd_property_rc_level *) + property_value; + if (sizeof(struct vcd_property_rc_level) == + property_hdr->sz && + ( + encoder->rc. + rate_control >= VCD_RATE_CONTROL_VBR_VFR || + encoder->rc. + rate_control <= VCD_RATE_CONTROL_CBR_VFR + ) && + (!rc_level->mb_level_rc || + encoder->codec.codec == VCD_CODEC_H264 + ) + ) { + encoder->rc_level = *rc_level; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_FRAME_LEVEL_RC: + { + + struct vcd_property_frame_level_rc_params + *frame_levelrc = + (struct vcd_property_frame_level_rc_params *) + property_value; + + if ((sizeof(struct + vcd_property_frame_level_rc_params) + == property_hdr->sz) && + (frame_levelrc->reaction_coeff) && + (encoder->rc_level.frame_level_rc) + ) { + encoder->frame_level_rc = *frame_levelrc; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_ADAPTIVE_RC: + { + + if ((sizeof(struct + vcd_property_adaptive_rc_params) + == property_hdr->sz) && + (encoder->codec. + codec == VCD_CODEC_H264) && + (encoder->rc_level.mb_level_rc)) { + + encoder->adaptive_rc = + *(struct vcd_property_adaptive_rc_params *) + property_value; + + vcd_status = VCD_S_SUCCESS; + } + + break; + } + case VCD_I_BUFFER_FORMAT: + { + struct vcd_property_buffer_format *tile = + (struct vcd_property_buffer_format *) + property_value; + if (sizeof(struct vcd_property_buffer_format) == + property_hdr->sz && + tile->buffer_format == + VCD_BUFFER_FORMAT_NV12) { + encoder->buf_format = *tile; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case DDL_I_INPUT_BUF_REQ: + { + struct vcd_buffer_requirement *buffer_req = + (struct vcd_buffer_requirement *) + property_value; + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz && + (ddl_valid_buffer_requirement( + &encoder->input_buf_req, buffer_req)) + ) { + encoder->client_input_buf_req = *buffer_req; + encoder->client_input_buf_req.min_count = + encoder->input_buf_req.min_count; + encoder->client_input_buf_req.max_count = + encoder->input_buf_req.max_count; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case DDL_I_OUTPUT_BUF_REQ: + { + struct vcd_buffer_requirement *buffer_req = + (struct vcd_buffer_requirement *) + property_value; + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz && + (ddl_valid_buffer_requirement( + &encoder->output_buf_req, buffer_req)) + ) { + encoder->client_output_buf_req = + *buffer_req; + encoder->client_output_buf_req.min_count = + encoder->output_buf_req.min_count; + encoder->client_output_buf_req.max_count = + encoder->output_buf_req.max_count; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_METADATA_ENABLE: + case VCD_I_METADATA_HEADER: + { + vcd_status = ddl_set_metadata_params( + ddl, property_hdr, property_value); + break; + } + case VCD_I_META_BUFFER_MODE: + { + vcd_status = VCD_S_SUCCESS; + break; + } + default: + { + vcd_status = VCD_ERR_ILLEGAL_OP; + break; + } + } + return vcd_status; +} + +static u32 ddl_get_dec_property + (struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value) { + u32 vcd_status = VCD_ERR_ILLEGAL_PARM; + struct ddl_decoder_data *decoder = &ddl->codec_data.decoder; + + switch (property_hdr->prop_id) { + case VCD_I_FRAME_SIZE: + { + struct vcd_property_frame_size *fz_size; + if (sizeof(struct vcd_property_frame_size) == + property_hdr->sz) { + ddl_calculate_stride( + &decoder->client_frame_size, + !decoder->progressive_only, + decoder->codec.codec); + if (decoder->buf_format.buffer_format + == VCD_BUFFER_FORMAT_TILE_4x2) { + fz_size = + &decoder->client_frame_size; + fz_size->stride = + DDL_TILE_ALIGN(fz_size->width, + DDL_TILE_ALIGN_WIDTH); + fz_size->scan_lines = + DDL_TILE_ALIGN(fz_size->height, + DDL_TILE_ALIGN_HEIGHT); + } + *(struct vcd_property_frame_size *) + property_value = + decoder->client_frame_size; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_PROFILE: + { + if (sizeof(struct vcd_property_profile) == + property_hdr->sz) { + *(struct vcd_property_profile *) + property_value = decoder->profile; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_LEVEL: + { + if (sizeof(struct vcd_property_level) == + property_hdr->sz) { + *(struct vcd_property_level *) + property_value = decoder->level; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_PROGRESSIVE_ONLY: + { + if (sizeof(u32) == property_hdr->sz) { + *(u32 *) property_value = + decoder->progressive_only; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case DDL_I_INPUT_BUF_REQ: + { + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz) { + *(struct vcd_buffer_requirement *) + property_value = + decoder->client_input_buf_req; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case DDL_I_OUTPUT_BUF_REQ: + { + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz) { + *(struct vcd_buffer_requirement *) + property_value = + decoder->client_output_buf_req; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_CODEC: + { + if (sizeof(struct vcd_property_codec) == + property_hdr->sz) { + *(struct vcd_property_codec *) + property_value = decoder->codec; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_BUFFER_FORMAT: + { + if (sizeof(struct vcd_property_buffer_format) == + property_hdr->sz) { + *(struct vcd_property_buffer_format *) + property_value = decoder->buf_format; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_POST_FILTER: + { + if (sizeof(struct vcd_property_post_filter) == + property_hdr->sz) { + *(struct vcd_property_post_filter *) + property_value = decoder->post_filter; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case DDL_I_SEQHDR_ALIGN_BYTES: + { + if (sizeof(u32) == property_hdr->sz) { + *(u32 *) property_value = + DDL_LINEAR_BUFFER_ALIGN_BYTES; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case DDL_I_FRAME_PROC_UNITS: + { + if (sizeof(u32) == property_hdr->sz) { + struct vcd_property_frame_size frame_sz = + decoder->client_frame_size; + ddl_calculate_stride(&frame_sz, + !decoder->progressive_only, + decoder->codec.codec); + *(u32 *) property_value = + ((frame_sz.stride >> 4) * + (frame_sz.scan_lines >> 4)); + vcd_status = VCD_S_SUCCESS; + } + break; + } + case DDL_I_DPB_RETRIEVE: + { + if (sizeof(struct ddl_frame_data_tag) == + property_hdr->sz) { + vcd_status = + ddl_decoder_dpb_transact(decoder, + (struct ddl_frame_data_tag *) + property_value, + DDL_DPB_OP_RETRIEVE); + } + break; + } + case VCD_I_OUTPUT_ORDER: + { + if (sizeof(u32) == property_hdr->sz) { + *(u32 *)property_value = decoder->output_order; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_METADATA_ENABLE: + case VCD_I_METADATA_HEADER: + { + vcd_status = ddl_get_metadata_params( + ddl, + property_hdr, + property_value); + break; + } + default: + { + vcd_status = VCD_ERR_ILLEGAL_OP; + break; + } + } + return vcd_status; +} + +static u32 ddl_get_enc_property + (struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value) { + u32 vcd_status = VCD_ERR_ILLEGAL_PARM; + struct ddl_encoder_data *encoder = &ddl->codec_data.encoder; + + struct vcd_property_entropy_control *entropy_control; + struct vcd_property_intra_refresh_mb_number *intra_refresh; + + switch (property_hdr->prop_id) { + case VCD_I_CODEC: + { + if (sizeof(struct vcd_property_codec) == + property_hdr->sz) { + *(struct vcd_property_codec *) + property_value = + encoder->codec; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_FRAME_SIZE: + { + if (sizeof(struct vcd_property_frame_size) == + property_hdr->sz) { + *(struct vcd_property_frame_size *) + property_value = + encoder->frame_size; + + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_FRAME_RATE: + { + if (sizeof(struct vcd_property_frame_rate) == + property_hdr->sz) { + + *(struct vcd_property_frame_rate *) + property_value = + encoder->frame_rate; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_TARGET_BITRATE: + { + + if (sizeof(struct vcd_property_target_bitrate) == + property_hdr->sz) { + *(struct vcd_property_target_bitrate *) + property_value = + encoder->target_bit_rate; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_RATE_CONTROL: + { + if (sizeof(struct vcd_property_rate_control) == + property_hdr->sz) { + *(struct vcd_property_rate_control *) + property_value = encoder->rc; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_PROFILE: + { + if (sizeof(struct vcd_property_profile) == + property_hdr->sz) { + *(struct vcd_property_profile *) + property_value = encoder->profile; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_LEVEL: + { + if (sizeof(struct vcd_property_level) == + property_hdr->sz) { + *(struct vcd_property_level *) + property_value = encoder->level; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_MULTI_SLICE: + { + if (sizeof(struct vcd_property_multi_slice) == + property_hdr->sz) { + *(struct vcd_property_multi_slice *) + property_value = encoder->multi_slice; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_SEQ_HEADER: + { + struct vcd_sequence_hdr *seq_hdr = + (struct vcd_sequence_hdr *)property_value; + if (encoder->seq_header.buffer_size && + sizeof(struct vcd_sequence_hdr) == + property_hdr->sz + && encoder->seq_header.buffer_size <= + seq_hdr->sequence_header_len) { + DDL_MEMCPY(seq_hdr->sequence_header, + encoder->seq_header. + align_virtual_addr, + encoder->seq_header.buffer_size); + seq_hdr->sequence_header_len = + encoder->seq_header.buffer_size; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case DDL_I_SEQHDR_PRESENT: + { + if (sizeof(u32) == property_hdr->sz) { + if ((encoder->codec. + codec == VCD_CODEC_MPEG4 && + !encoder->short_header.short_header) + || encoder->codec.codec == + VCD_CODEC_H264) { + *(u32 *)property_value = 0x1; + } else { + *(u32 *)property_value = 0x0; + } + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_VOP_TIMING: + { + if (sizeof(struct vcd_property_vop_timing) == + property_hdr->sz) { + *(struct vcd_property_vop_timing *) + property_value = encoder->vop_timing; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_SHORT_HEADER: + { + if (sizeof(struct vcd_property_short_header) == + property_hdr->sz) { + if (encoder->codec.codec == + VCD_CODEC_MPEG4) { + *(struct vcd_property_short_header + *)property_value = + encoder->short_header; + vcd_status = VCD_S_SUCCESS; + } else { + vcd_status = VCD_ERR_ILLEGAL_OP; + } + } + break; + } + case VCD_I_ENTROPY_CTRL: + { + entropy_control = property_value; + if (sizeof(struct vcd_property_entropy_control) == + property_hdr->sz) { + if (encoder->codec.codec == + VCD_CODEC_H264) { + *entropy_control = + encoder->entropy_control; + vcd_status = VCD_S_SUCCESS; + } else { + vcd_status = VCD_ERR_ILLEGAL_OP; + } + } + break; + } + case VCD_I_DEBLOCKING: + { + if (sizeof(struct vcd_property_db_config) == + property_hdr->sz) { + if (encoder->codec.codec == + VCD_CODEC_H264) { + *(struct vcd_property_db_config *) + property_value = + encoder->db_control; + vcd_status = VCD_S_SUCCESS; + } else { + vcd_status = VCD_ERR_ILLEGAL_OP; + } + } + break; + } + case VCD_I_INTRA_PERIOD: + { + if (sizeof(struct vcd_property_i_period) == + property_hdr->sz) { + *(struct vcd_property_i_period *) + property_value = encoder->i_period; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_QP_RANGE: + { + if (sizeof(struct vcd_property_qp_range) == + property_hdr->sz) { + *(struct vcd_property_qp_range *) + property_value = encoder->qp_range; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_SESSION_QP: + { + if (sizeof(struct vcd_property_session_qp) == + property_hdr->sz) { + *(struct vcd_property_session_qp *) + property_value = encoder->session_qp; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_RC_LEVEL_CONFIG: + { + if (sizeof(struct vcd_property_rc_level) == + property_hdr->sz) { + *(struct vcd_property_rc_level *) + property_value = encoder->rc_level; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_FRAME_LEVEL_RC: + { + if (sizeof + (struct vcd_property_frame_level_rc_params) == + property_hdr->sz) { + *(struct vcd_property_frame_level_rc_params + *)property_value = + encoder->frame_level_rc; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_ADAPTIVE_RC: + { + if (sizeof(struct vcd_property_adaptive_rc_params) + == property_hdr->sz) { + *(struct vcd_property_adaptive_rc_params *) + property_value = encoder->adaptive_rc; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_INTRA_REFRESH: + { + intra_refresh = property_value; + if (sizeof + (struct vcd_property_intra_refresh_mb_number) + == property_hdr->sz) { + *intra_refresh = encoder->intra_refresh; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case DDL_I_INPUT_BUF_REQ: + { + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz) { + *(struct vcd_buffer_requirement *) + property_value = + encoder->client_input_buf_req; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case DDL_I_OUTPUT_BUF_REQ: + { + if (sizeof(struct vcd_buffer_requirement) == + property_hdr->sz) { + *(struct vcd_buffer_requirement *) + property_value = + encoder->client_output_buf_req; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_BUFFER_FORMAT: + { + if (sizeof(struct vcd_property_buffer_format) == + property_hdr->sz) { + *(struct vcd_property_buffer_format *) + property_value = encoder->buf_format; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case DDL_I_FRAME_PROC_UNITS: + { + if (sizeof(u32) == property_hdr->sz) { + *(u32 *) property_value = + ((encoder->frame_size.width >> 4) * + (encoder->frame_size.height >> 4) + ); + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_HEADER_EXTENSION: + { + if (sizeof(u32) == property_hdr->sz && + encoder->codec.codec == VCD_CODEC_MPEG4) { + *(u32 *) property_value = + encoder->hdr_ext_control; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_METADATA_ENABLE: + case VCD_I_METADATA_HEADER: + { + vcd_status = ddl_get_metadata_params( + ddl, + property_hdr, + property_value); + break; + } + default: + { + vcd_status = VCD_ERR_ILLEGAL_OP; + break; + } + } + return vcd_status; +} + +static u32 ddl_set_enc_dynamic_property + (struct ddl_client_context *ddl, + struct vcd_property_hdr *property_hdr, void *property_value) { + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + u32 vcd_status = VCD_ERR_ILLEGAL_PARM, dynamic_prop_change = 0x0; + switch (property_hdr->prop_id) { + case VCD_I_REQ_IFRAME: + { + if (sizeof(struct vcd_property_req_i_frame) == + property_hdr->sz) { + dynamic_prop_change = DDL_ENC_REQ_IFRAME; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_TARGET_BITRATE: + { + struct vcd_property_target_bitrate *bitrate = + (struct vcd_property_target_bitrate *) + property_value; + if (sizeof(struct vcd_property_target_bitrate) == + property_hdr->sz && bitrate->target_bitrate > 0 + && bitrate->target_bitrate <= DDL_MAX_BIT_RATE) { + encoder->target_bit_rate = *bitrate; + dynamic_prop_change = DDL_ENC_CHANGE_BITRATE; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_INTRA_PERIOD: + { + struct vcd_property_i_period *iperiod = + (struct vcd_property_i_period *) + property_value; + if (sizeof(struct vcd_property_i_period) == + property_hdr->sz && + !iperiod->b_frames) { + encoder->i_period = *iperiod; + dynamic_prop_change = DDL_ENC_CHANGE_IPERIOD; + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_FRAME_RATE: + { + struct vcd_property_frame_rate *frame_rate = + (struct vcd_property_frame_rate *) + property_value; + if (sizeof(struct vcd_property_frame_rate) + == property_hdr->sz && + frame_rate->fps_denominator && + frame_rate->fps_numerator && + frame_rate->fps_denominator <= + frame_rate->fps_numerator) { + encoder->frame_rate = *frame_rate; + dynamic_prop_change = DDL_ENC_CHANGE_FRAMERATE; + if (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN) && + (encoder->codec.codec != VCD_CODEC_MPEG4 + || encoder->short_header.short_header)) + ddl_set_default_enc_vop_timing(encoder); + vcd_status = VCD_S_SUCCESS; + } + break; + } + case VCD_I_INTRA_REFRESH: + { + struct vcd_property_intra_refresh_mb_number + *intra_refresh_mbnum = ( + struct vcd_property_intra_refresh_mb_number *) + property_value; + u32 frame_mbnum = + (encoder->frame_size.width >> 4) * + (encoder->frame_size.height >> 4); + if (sizeof(struct + vcd_property_intra_refresh_mb_number) + == property_hdr->sz && + intra_refresh_mbnum->cir_mb_number <= + frame_mbnum) { + encoder->intra_refresh = + *intra_refresh_mbnum; + dynamic_prop_change = DDL_ENC_CHANGE_CIR; + vcd_status = VCD_S_SUCCESS; + } + + break; + } + default: + { + vcd_status = VCD_ERR_ILLEGAL_OP; + break; + } + } + if (vcd_status == VCD_S_SUCCESS && + (DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME) || + DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_FRAME_DONE))) + encoder->dynamic_prop_change |= dynamic_prop_change; + return vcd_status; +} + +void ddl_set_default_dec_property(struct ddl_client_context *ddl) +{ + struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder); + + if (decoder->codec.codec >= VCD_CODEC_MPEG2 && + decoder->codec.codec <= VCD_CODEC_XVID) + decoder->post_filter.post_filter = true; + else + decoder->post_filter.post_filter = false; + decoder->buf_format.buffer_format = VCD_BUFFER_FORMAT_NV12; + decoder->client_frame_size.height = 144; + decoder->client_frame_size.width = 176; + decoder->client_frame_size.stride = 176; + decoder->client_frame_size.scan_lines = 144; + decoder->progressive_only = 1; + decoder->idr_only_decoding = 0; + decoder->profile.profile = VCD_PROFILE_UNKNOWN; + decoder->level.level = VCD_LEVEL_UNKNOWN; + decoder->output_order = VCD_DEC_ORDER_DISPLAY; + ddl_set_default_metadata_flag(ddl); + ddl_set_default_decoder_buffer_req(decoder, true); +} + +static void ddl_set_default_enc_property(struct ddl_client_context *ddl) +{ + struct ddl_encoder_data *encoder = &(ddl->codec_data.encoder); + + ddl_set_default_enc_profile(encoder); + ddl_set_default_enc_level(encoder); + + encoder->rc.rate_control = VCD_RATE_CONTROL_VBR_VFR; + ddl_set_default_enc_rc_params(encoder); + + ddl_set_default_enc_intra_period(encoder); + + encoder->intra_refresh.cir_mb_number = 0; + ddl_set_default_enc_vop_timing(encoder); + + encoder->multi_slice.m_slice_sel = VCD_MSLICE_OFF; + encoder->multi_slice.m_slice_size = 0; + encoder->short_header.short_header = false; + + encoder->entropy_control.entropy_sel = VCD_ENTROPY_SEL_CAVLC; + encoder->entropy_control.cabac_model = VCD_CABAC_MODEL_NUMBER_0; + encoder->db_control.db_config = VCD_DB_ALL_BLOCKING_BOUNDARY; + encoder->db_control.slice_alpha_offset = 0; + encoder->db_control.slice_beta_offset = 0; + + encoder->re_con_buf_format.buffer_format = + VCD_BUFFER_FORMAT_TILE_4x2; + + encoder->buf_format.buffer_format = VCD_BUFFER_FORMAT_NV12; + + encoder->hdr_ext_control = 0; + + ddl_set_default_metadata_flag(ddl); + + ddl_set_default_encoder_buffer_req(encoder); +} + +static void ddl_set_default_enc_profile(struct ddl_encoder_data *encoder) +{ + enum vcd_codec codec = encoder->codec.codec; + if (codec == VCD_CODEC_MPEG4) + encoder->profile.profile = VCD_PROFILE_MPEG4_SP; + else if (codec == VCD_CODEC_H264) + encoder->profile.profile = VCD_PROFILE_H264_BASELINE; + else + encoder->profile.profile = VCD_PROFILE_H263_BASELINE; +} + +static void ddl_set_default_enc_level(struct ddl_encoder_data *encoder) +{ + enum vcd_codec codec = encoder->codec.codec; + if (codec == VCD_CODEC_MPEG4) + encoder->level.level = VCD_LEVEL_MPEG4_1; + else if (codec == VCD_CODEC_H264) + encoder->level.level = VCD_LEVEL_H264_1; + else + encoder->level.level = VCD_LEVEL_H263_10; +} + +static void ddl_set_default_enc_vop_timing + (struct ddl_encoder_data *encoder) +{ + if (encoder->codec.codec == VCD_CODEC_MPEG4) + encoder->vop_timing.vop_time_resolution = + (2 * encoder->frame_rate.fps_numerator) / + encoder->frame_rate.fps_denominator; + else + encoder->vop_timing.vop_time_resolution = 0x7530; +} + +static void ddl_set_default_enc_intra_period( + struct ddl_encoder_data *encoder) +{ + switch (encoder->rc.rate_control) { + default: + case VCD_RATE_CONTROL_VBR_VFR: + case VCD_RATE_CONTROL_VBR_CFR: + case VCD_RATE_CONTROL_CBR_VFR: + case VCD_RATE_CONTROL_OFF: + { + encoder->i_period.p_frames = + ((encoder->frame_rate.fps_numerator << 1) / + encoder->frame_rate.fps_denominator) - 1; + break; + } + case VCD_RATE_CONTROL_CBR_CFR: + { + encoder->i_period.p_frames = + ((encoder->frame_rate.fps_numerator >> 1) / + encoder->frame_rate.fps_denominator) - 1; + break; + } + } + encoder->i_period.b_frames = 0; +} + +static void ddl_set_default_enc_rc_params( + struct ddl_encoder_data *encoder) +{ + enum vcd_codec codec = encoder->codec.codec; + + encoder->rc_level.frame_level_rc = true; + encoder->qp_range.min_qp = 0x1; + + if (codec == VCD_CODEC_H264) { + encoder->qp_range.max_qp = 0x33; + encoder->session_qp.i_frame_qp = 0x14; + encoder->session_qp.p_frame_qp = 0x14; + + encoder->rc_level.mb_level_rc = true; + encoder->adaptive_rc.activity_region_flag = true; + encoder->adaptive_rc.dark_region_as_flag = true; + encoder->adaptive_rc.smooth_region_as_flag = true; + encoder->adaptive_rc.static_region_as_flag = true; + } else { + encoder->qp_range.max_qp = 0x1f; + encoder->session_qp.i_frame_qp = 0xd; + encoder->session_qp.p_frame_qp = 0xd; + encoder->rc_level.mb_level_rc = false; + } + + switch (encoder->rc.rate_control) { + default: + case VCD_RATE_CONTROL_VBR_VFR: + { + encoder->r_cframe_skip = 1; + encoder->frame_level_rc.reaction_coeff = 0x1f4; + break; + } + case VCD_RATE_CONTROL_VBR_CFR: + { + encoder->r_cframe_skip = 0; + encoder->frame_level_rc.reaction_coeff = 0x1f4; + break; + } + case VCD_RATE_CONTROL_CBR_VFR: + { + encoder->r_cframe_skip = 1; + if (codec != VCD_CODEC_H264) { + encoder->session_qp.i_frame_qp = 0xf; + encoder->session_qp.p_frame_qp = 0xf; + } + + encoder->frame_level_rc.reaction_coeff = 0x14; + break; + } + case VCD_RATE_CONTROL_CBR_CFR: + { + encoder->r_cframe_skip = 0; + encoder->frame_level_rc.reaction_coeff = 0x6; + break; + } + case VCD_RATE_CONTROL_OFF: + { + encoder->r_cframe_skip = 0; + encoder->rc_level.frame_level_rc = false; + encoder->rc_level.mb_level_rc = false; + break; + } + } +} + +void ddl_set_default_encoder_buffer_req(struct ddl_encoder_data *encoder) +{ + u32 y_cb_cr_size; + + y_cb_cr_size = ddl_get_yuv_buffer_size(&encoder->frame_size, + &encoder->buf_format, false, encoder->codec.codec); + + memset(&encoder->input_buf_req, 0, + sizeof(struct vcd_buffer_requirement)); + + encoder->input_buf_req.min_count = 1; + encoder->input_buf_req.actual_count = + encoder->input_buf_req.min_count + 8; + encoder->input_buf_req.max_count = DDL_MAX_BUFFER_COUNT; + encoder->input_buf_req.sz = y_cb_cr_size; + encoder->input_buf_req.align = DDL_LINEAR_BUFFER_ALIGN_BYTES; + + encoder->client_input_buf_req = encoder->input_buf_req; + + memset(&encoder->output_buf_req, 0, + sizeof(struct vcd_buffer_requirement)); + + encoder->output_buf_req.min_count = 2; + encoder->output_buf_req.actual_count = + encoder->output_buf_req.min_count + 3; + encoder->output_buf_req.max_count = DDL_MAX_BUFFER_COUNT; + encoder->output_buf_req.align = DDL_LINEAR_BUFFER_ALIGN_BYTES; + encoder->output_buf_req.sz = y_cb_cr_size; + ddl_set_default_encoder_metadata_buffer_size(encoder); + encoder->client_output_buf_req = encoder->output_buf_req; +} + +void ddl_set_default_decoder_buffer_req(struct ddl_decoder_data *decoder, + u32 estimate) +{ + u32 y_cb_cr_size, min_dpb, num_mb; + struct vcd_property_frame_size *frame_size; + struct vcd_buffer_requirement *output_buf_req, *input_buf_req; + + if (!decoder->codec.codec) + return; + + if (estimate) { + frame_size = &decoder->client_frame_size; + output_buf_req = &decoder->client_output_buf_req; + input_buf_req = &decoder->client_input_buf_req; + min_dpb = ddl_decoder_min_num_dpb(decoder); + y_cb_cr_size = ddl_get_yuv_buffer_size(frame_size, + &decoder->buf_format, (!decoder->progressive_only), + decoder->codec.codec); + } else { + frame_size = &decoder->frame_size; + output_buf_req = &decoder->actual_output_buf_req; + input_buf_req = &decoder->actual_input_buf_req; + y_cb_cr_size = decoder->y_cb_cr_size; + min_dpb = decoder->min_dpb_num; + } + + if (decoder->idr_only_decoding) + min_dpb = 1; + + memset(output_buf_req, 0, sizeof(struct vcd_buffer_requirement)); + + output_buf_req->min_count = min_dpb; + + num_mb = DDL_NO_OF_MB(frame_size->width, frame_size->height); + if (decoder->idr_only_decoding) { + output_buf_req->actual_count = output_buf_req->min_count; + } else { + if (num_mb >= DDL_WVGA_MBS) { + output_buf_req->actual_count = min_dpb + 2; + if (output_buf_req->actual_count < 10) + output_buf_req->actual_count = 10; + } else + output_buf_req->actual_count = min_dpb + 5; + } + output_buf_req->max_count = DDL_MAX_BUFFER_COUNT; + output_buf_req->sz = y_cb_cr_size; + if (decoder->buf_format.buffer_format != VCD_BUFFER_FORMAT_NV12) + output_buf_req->align = DDL_TILE_BUFFER_ALIGN_BYTES; + else + output_buf_req->align = DDL_LINEAR_BUFFER_ALIGN_BYTES; + + ddl_set_default_decoder_metadata_buffer_size(decoder, + frame_size, output_buf_req); + + decoder->min_output_buf_req = *output_buf_req; + + memset(input_buf_req, 0, sizeof(struct vcd_buffer_requirement)); + + input_buf_req->min_count = 1; + input_buf_req->actual_count = input_buf_req->min_count + 3; + input_buf_req->max_count = DDL_MAX_BUFFER_COUNT; + input_buf_req->sz = (1280*720*3*3) >> 3; + input_buf_req->align = DDL_LINEAR_BUFFER_ALIGN_BYTES; + + decoder->min_input_buf_req = *input_buf_req; + +} + +u32 ddl_get_yuv_buffer_size(struct vcd_property_frame_size *frame_size, + struct vcd_property_buffer_format *buf_format, u32 inter_lace, + enum vcd_codec codec) +{ + struct vcd_property_frame_size frame_sz = *frame_size; + u32 total_memory_size; + ddl_calculate_stride(&frame_sz, inter_lace, codec); + + if (buf_format->buffer_format != VCD_BUFFER_FORMAT_NV12) { + u32 component_mem_size; + u32 width_round_up; + u32 height_round_up; + u32 height_chroma = (frame_sz.scan_lines >> 1); + + width_round_up = + DDL_TILE_ALIGN(frame_sz.stride, DDL_TILE_ALIGN_WIDTH); + height_round_up = + DDL_TILE_ALIGN(frame_sz.scan_lines, DDL_TILE_ALIGN_HEIGHT); + + component_mem_size = width_round_up * height_round_up; + component_mem_size = DDL_TILE_ALIGN(component_mem_size, + DDL_TILE_MULTIPLY_FACTOR); + + total_memory_size = ((component_mem_size + + DDL_TILE_BUF_ALIGN_GUARD_BYTES) & + DDL_TILE_BUF_ALIGN_MASK); + + height_round_up = + DDL_TILE_ALIGN(height_chroma, DDL_TILE_ALIGN_HEIGHT); + component_mem_size = width_round_up * height_round_up; + component_mem_size = DDL_TILE_ALIGN(component_mem_size, + DDL_TILE_MULTIPLY_FACTOR); + total_memory_size += component_mem_size; + } else { + total_memory_size = frame_sz.scan_lines * frame_sz.stride; + total_memory_size += (total_memory_size >> 1); + } + return total_memory_size; +} + +void ddl_calculate_stride(struct vcd_property_frame_size *frame_size, + u32 interlace, enum vcd_codec codec) +{ + frame_size->stride = ((frame_size->width + 15) >> 4) << 4; + if (!interlace || codec == VCD_CODEC_MPEG4 || + codec == VCD_CODEC_DIVX_4 || + codec == VCD_CODEC_DIVX_5 || + codec == VCD_CODEC_DIVX_6 || + codec == VCD_CODEC_XVID) { + frame_size->scan_lines = + ((frame_size->height + 15) >> 4) << 4; + } else { + frame_size->scan_lines = + ((frame_size->height + 31) >> 5) << 5; + } + +} + +static u32 ddl_valid_buffer_requirement + (struct vcd_buffer_requirement *original_buf_req, + struct vcd_buffer_requirement *req_buf_req) +{ + u32 status = false; + if (original_buf_req->max_count >= req_buf_req->actual_count && + original_buf_req->min_count <= req_buf_req->actual_count && + original_buf_req->align <= req_buf_req->align && + original_buf_req->sz <= req_buf_req->sz) { + status = true; + } else { + VIDC_LOGERR_STRING("ddl_valid_buf_req:Failed"); + } + return status; +} + +static u32 ddl_decoder_min_num_dpb(struct ddl_decoder_data *decoder) +{ + u32 min_dpb = 0, yuv_size = 0; + struct vcd_property_frame_size frame_sz = decoder->client_frame_size; + switch (decoder->codec.codec) { + default: + case VCD_CODEC_MPEG4: + case VCD_CODEC_MPEG2: + case VCD_CODEC_DIVX_4: + case VCD_CODEC_DIVX_5: + case VCD_CODEC_DIVX_6: + case VCD_CODEC_XVID: + { + min_dpb = 3; + break; + } + case VCD_CODEC_H263: + { + min_dpb = 2; + break; + } + case VCD_CODEC_VC1: + case VCD_CODEC_VC1_RCV: + { + min_dpb = 4; + break; + } + case VCD_CODEC_H264: + { + ddl_calculate_stride(&frame_sz, + !decoder->progressive_only, + decoder->codec.codec); + yuv_size = + ((frame_sz.scan_lines * + frame_sz.stride * 3) >> 1); + min_dpb = 6912000 / yuv_size; + if (min_dpb > 16) + min_dpb = 16; + + min_dpb += 2; + break; + } + } + return min_dpb; +} + +static u32 ddl_set_dec_buffers + (struct ddl_decoder_data *decoder, + struct ddl_property_dec_pic_buffers *dpb) { + u32 vcd_status = VCD_S_SUCCESS; + u32 loopc; + for (loopc = 0; !vcd_status && + loopc < dpb->no_of_dec_pic_buf; ++loopc) { + if ((!DDL_ADDR_IS_ALIGNED + (dpb->dec_pic_buffers[loopc].vcd_frm.physical, + decoder->client_output_buf_req.align) + ) + || (dpb->dec_pic_buffers[loopc].vcd_frm.alloc_len < + decoder->client_output_buf_req.sz) + ) { + vcd_status = VCD_ERR_ILLEGAL_PARM; + } + } + if (vcd_status) { + VIDC_LOGERR_STRING + ("ddl_set_prop:Dpb_align_fail_or_alloc_size_small"); + return vcd_status; + } + if (decoder->dp_buf.no_of_dec_pic_buf) { + DDL_FREE(decoder->dp_buf.dec_pic_buffers); + decoder->dp_buf.no_of_dec_pic_buf = 0; + } + decoder->dp_buf.dec_pic_buffers = + DDL_MALLOC(dpb->no_of_dec_pic_buf * + sizeof(struct ddl_frame_data_tag)); + + if (!decoder->dp_buf.dec_pic_buffers) { + VIDC_LOGERR_STRING + ("ddl_dec_set_prop:Dpb_container_alloc_failed"); + return VCD_ERR_ALLOC_FAIL; + } + decoder->dp_buf.no_of_dec_pic_buf = dpb->no_of_dec_pic_buf; + for (loopc = 0; loopc < dpb->no_of_dec_pic_buf; ++loopc) { + decoder->dp_buf.dec_pic_buffers[loopc] = + dpb->dec_pic_buffers[loopc]; + } + decoder->dpb_mask.client_mask = 0; + decoder->dpb_mask.hw_mask = 0; + decoder->dynamic_prop_change = 0; + return VCD_S_SUCCESS; +} + +void ddl_set_initial_default_values(struct ddl_client_context *ddl) +{ + if (ddl->decoding) { + ddl->codec_data.decoder.codec.codec = VCD_CODEC_MPEG4; + vcd_fw_transact(true, true, + ddl->codec_data.decoder.codec.codec); + ddl_set_default_dec_property(ddl); + } else { + struct ddl_encoder_data *encoder = + &(ddl->codec_data.encoder); + encoder->codec.codec = VCD_CODEC_MPEG4; + vcd_fw_transact(true, false, + encoder->codec.codec); + + encoder->target_bit_rate.target_bitrate = 64000; + encoder->frame_size.width = 176; + encoder->frame_size.height = 144; + encoder->frame_size.stride = 176; + encoder->frame_size.scan_lines = 144; + encoder->frame_rate.fps_numerator = 30; + encoder->frame_rate.fps_denominator = 1; + ddl_set_default_enc_property(ddl); + } + + return; +} diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c new file mode 100644 index 000000000000..19d55f74b23b --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.c @@ -0,0 +1,242 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#include +#include +#include "vcd_ddl_utils.h" + +#if DEBUG +#define DBG(x...) printk(KERN_DEBUG x) +#else +#define DBG(x...) +#endif + +#define DBG_TIME(x...) printk(KERN_DEBUG x) +#define ERR(x...) printk(KERN_ERR x) + +struct time_data { + unsigned int ddl_t1; + unsigned int ddl_ttotal; + unsigned int ddl_count; +}; + +static struct time_data proc_time[MAX_TIME_DATA]; + +#ifdef NO_IN_KERNEL_PMEM + +void ddl_pmem_alloc(struct ddl_buf_addr *buff_addr, size_t sz, u32 align) +{ + u32 guard_bytes, align_mask; + u32 physical_addr, align_offset; + dma_addr_t phy_addr; + + if (align == DDL_LINEAR_BUFFER_ALIGN_BYTES) { + + guard_bytes = 31; + align_mask = 0xFFFFFFE0U; + + } else { + + guard_bytes = DDL_TILE_BUF_ALIGN_GUARD_BYTES; + align_mask = DDL_TILE_BUF_ALIGN_MASK; + } + + buff_addr->virtual_base_addr = + kmalloc((sz + guard_bytes), GFP_KERNEL); + + if (!buff_addr->virtual_base_addr) { + ERR("\n ERROR %s:%u kamlloc fails to allocate" + " sz + guard_bytes = %u\n", __func__, __LINE__, + (sz + guard_bytes)); + return; + } + + phy_addr = dma_map_single(NULL, buff_addr->virtual_base_addr, + sz + guard_bytes, DMA_TO_DEVICE); + + buff_addr->buffer_size = sz; + physical_addr = (u32) phy_addr; + buff_addr->align_physical_addr = + (u32 *) ((physical_addr + guard_bytes) & align_mask); + align_offset = + (u32) (buff_addr->align_physical_addr) - physical_addr; + buff_addr->align_virtual_addr = + (u32 *) ((u32) (buff_addr->virtual_base_addr) + + align_offset); +} + +void ddl_pmem_free(struct ddl_buf_addr *buff_addr) +{ + kfree(buff_addr->virtual_base_addr); + buff_addr->buffer_size = 0; + buff_addr->virtual_base_addr = NULL; +} + +#else + +void ddl_pmem_alloc(struct ddl_buf_addr *buff_addr, size_t sz, u32 align) +{ + u32 guard_bytes, align_mask; + u32 physical_addr; + u32 align_offset; + u32 alloc_size, flags = 0; + struct ddl_context *ddl_context; + struct msm_mapped_buffer *mapped_buffer = NULL; + + if (!buff_addr) { + ERR("\n%s() Invalid Parameters", __func__); + return; + } + + DBG_PMEM("\n%s() IN: Requested alloc size(%u)", __func__, (u32)sz); + + if (align == DDL_LINEAR_BUFFER_ALIGN_BYTES) { + + guard_bytes = 31; + align_mask = 0xFFFFFFE0U; + + } else { + + guard_bytes = DDL_TILE_BUF_ALIGN_GUARD_BYTES; + align_mask = DDL_TILE_BUF_ALIGN_MASK; + } + ddl_context = ddl_get_context(); + alloc_size = sz + guard_bytes; + + physical_addr = (u32) + allocate_contiguous_memory_nomap(alloc_size, + ddl_context->memtype, SZ_4K); + + if (!physical_addr) { + pr_err("%s(): could not allocate kernel pmem buffers\n", + __func__); + goto bailout; + } + buff_addr->physical_base_addr = (u32 *) physical_addr; + flags = MSM_SUBSYSTEM_MAP_KADDR; + buff_addr->mapped_buffer = + msm_subsystem_map_buffer((unsigned long)physical_addr, + alloc_size, flags, NULL, 0); + if (IS_ERR(buff_addr->mapped_buffer)) { + pr_err(" %s() buffer map failed", __func__); + goto free_acm_alloc; + } + mapped_buffer = buff_addr->mapped_buffer; + if (!mapped_buffer->vaddr) { + pr_err("%s() mapped virtual address is NULL", __func__); + goto free_map_buffers; + } + buff_addr->virtual_base_addr = mapped_buffer->vaddr; + memset(buff_addr->virtual_base_addr, 0 , sz + guard_bytes); + buff_addr->buffer_size = sz; + + buff_addr->align_physical_addr = + (u32 *) ((physical_addr + guard_bytes) & align_mask); + + align_offset = + (u32) (buff_addr->align_physical_addr) - physical_addr; + + buff_addr->align_virtual_addr = + (u32 *) ((u32) (buff_addr->virtual_base_addr) + + align_offset); + + DBG_PMEM("\n%s() OUT: phy_addr(%p) ker_addr(%p) size(%u)", __func__, + buff_addr->physical_base_addr, buff_addr->virtual_base_addr, + buff_addr->buffer_size); + + return; +free_map_buffers: + msm_subsystem_unmap_buffer(buff_addr->mapped_buffer); +free_acm_alloc: + free_contiguous_memory_by_paddr( + (unsigned long) physical_addr); +bailout: + buff_addr->physical_base_addr = NULL; + buff_addr->virtual_base_addr = NULL; + buff_addr->buffer_size = 0; + buff_addr->mapped_buffer = NULL; +} + +void ddl_pmem_free(struct ddl_buf_addr *buff_addr) +{ + if (!buff_addr) { + ERR("\n %s() invalid arguments %p", __func__, buff_addr); + return; + } + DBG_PMEM("\n%s() IN: phy_addr(%p) ker_addr(%p) size(%u)", __func__, + buff_addr->physical_base_addr, buff_addr->virtual_base_addr, + buff_addr->buffer_size); + + if (buff_addr->mapped_buffer) + msm_subsystem_unmap_buffer(buff_addr->mapped_buffer); + if (buff_addr->physical_base_addr) + free_contiguous_memory_by_paddr( + (unsigned long) buff_addr->physical_base_addr); + DBG_PMEM("\n%s() OUT: phy_addr(%p) ker_addr(%p) size(%u)", __func__, + buff_addr->physical_base_addr, buff_addr->virtual_base_addr, + buff_addr->buffer_size); + buff_addr->buffer_size = 0; + buff_addr->physical_base_addr = NULL; + buff_addr->virtual_base_addr = NULL; + buff_addr->mapped_buffer = NULL; +} +#endif + +void ddl_set_core_start_time(const char *func_name, u32 index) +{ + u32 act_time; + struct timeval ddl_tv; + struct time_data *time_data = &proc_time[index]; + do_gettimeofday(&ddl_tv); + act_time = (ddl_tv.tv_sec * 1000) + (ddl_tv.tv_usec / 1000); + if (!time_data->ddl_t1) { + time_data->ddl_t1 = act_time; + DBG("\n%s(): Start Time (%u)", func_name, act_time); + } else { + DBG_TIME("\n%s(): Timer already started! St(%u) Act(%u)", + func_name, time_data->ddl_t1, act_time); + } +} + +void ddl_calc_core_proc_time(const char *func_name, u32 index) +{ + struct time_data *time_data = &proc_time[index]; + if (time_data->ddl_t1) { + int ddl_t2; + struct timeval ddl_tv; + do_gettimeofday(&ddl_tv); + ddl_t2 = (ddl_tv.tv_sec * 1000) + (ddl_tv.tv_usec / 1000); + time_data->ddl_ttotal += (ddl_t2 - time_data->ddl_t1); + time_data->ddl_count++; + DBG_TIME("\n%s(): cnt(%u) Diff(%u) Avg(%u)", + func_name, time_data->ddl_count, + ddl_t2 - time_data->ddl_t1, + time_data->ddl_ttotal/time_data->ddl_count); + time_data->ddl_t1 = 0; + } +} + +void ddl_reset_core_time_variables(u32 index) +{ + proc_time[index].ddl_t1 = 0; + proc_time[index].ddl_ttotal = 0; + proc_time[index].ddl_count = 0; +} +int ddl_get_core_decode_proc_time(u32 *ddl_handle) +{ + return 0; +} + +void ddl_reset_avg_dec_time(u32 *ddl_handle) +{ + return; +} diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.h b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.h new file mode 100644 index 000000000000..633292b23e9e --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_utils.h @@ -0,0 +1,60 @@ +/* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#ifndef _VCD_DDL_UTILS_H_ +#define _VCD_DDL_UTILS_H_ + +#include "vcd_ddl_core.h" +#include "vcd_ddl.h" + +extern u32 vidc_msg_pmem; +extern u32 vidc_msg_timing; + +enum timing_data { + DEC_OP_TIME, + DEC_IP_TIME, + ENC_OP_TIME, + MAX_TIME_DATA +}; + +#define DDL_INLINE + +#define DDL_ALIGN_SIZE(sz, guard_bytes, align_mask) \ + (((u32)(sz) + guard_bytes) & align_mask) + +#define DDL_MALLOC(x) kmalloc(x, GFP_KERNEL) +#define DDL_FREE(x) { if ((x)) kfree((x)); (x) = NULL; } + +#define DBG_PMEM(x...) \ +do { \ + if (vidc_msg_pmem) \ + printk(KERN_DEBUG x); \ +} while (0) + +void ddl_set_core_start_time(const char *func_name, u32 index); + +void ddl_calc_core_proc_time(const char *func_name, u32 index); + +void ddl_reset_core_time_variables(u32 index); + +int ddl_get_core_decode_proc_time(u32 *ddl_handle); + +void ddl_reset_avg_dec_time(u32 *ddl_handle); + +#define DDL_ASSERT(x) +#define DDL_MEMSET(src, value, len) memset((src), (value), (len)) +#define DDL_MEMCPY(dest, src, len) memcpy((dest), (src), (len)) + +#define DDL_ADDR_IS_ALIGNED(addr, align_bytes) \ +(!((u32)(addr) & ((align_bytes) - 1))) + +#endif diff --git a/drivers/video/msm/vidc/720p/ddl/vidc.c b/drivers/video/msm/vidc/720p/ddl/vidc.c new file mode 100644 index 000000000000..da969ef64233 --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vidc.c @@ -0,0 +1,804 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#include +#include +#include "vidc.h" + +#if DEBUG +#define DBG(x...) printk(KERN_DEBUG x) +#else +#define DBG(x...) +#endif + +#define VIDC_720P_VERSION_STRING "VIDC_V1.0" +u8 *vidc_base_addr; + +#ifdef VIDC_REGISTER_LOG_INTO_BUFFER +char vidclog[VIDC_REGLOG_BUFSIZE]; +unsigned int vidclog_index; +#endif + +void vidc_720p_set_device_virtual_base(u8 *core_virtual_base_addr) +{ + vidc_base_addr = core_virtual_base_addr; +} + +void vidc_720p_init(char **ppsz_version, u32 i_firmware_size, + u32 *pi_firmware_address, + enum vidc_720p_endian dma_endian, + u32 interrupt_off, + enum vidc_720p_interrupt_level_selection + interrupt_sel, u32 interrupt_mask) +{ + if (ppsz_version) + *ppsz_version = VIDC_720P_VERSION_STRING; + + if (interrupt_sel == VIDC_720P_INTERRUPT_LEVEL_SEL) + VIDC_IO_OUT(REG_491082, 0); + else + VIDC_IO_OUT(REG_491082, 1); + + if (interrupt_off) + VIDC_IO_OUT(REG_609676, 1); + else + VIDC_IO_OUT(REG_609676, 0); + + VIDC_IO_OUT(REG_614776, 1); + + VIDC_IO_OUT(REG_418173, 0); + + VIDC_IO_OUT(REG_418173, interrupt_mask); + + VIDC_IO_OUT(REG_736316, dma_endian); + + VIDC_IO_OUT(REG_215724, 0); + + VIDC_IO_OUT(REG_361582, 1); + + VIDC_IO_OUT(REG_591577, i_firmware_size); + + VIDC_IO_OUT(REG_203921, pi_firmware_address); + + VIDC_IO_OUT(REG_531515_ADDR, 0); + + VIDC_IO_OUT(REG_614413, 1); +} + +u32 vidc_720p_do_sw_reset(void) +{ + + u32 fw_start = 0; + VIDC_BUSY_WAIT(5); + VIDC_IO_OUT(REG_224135, 0); + VIDC_BUSY_WAIT(5); + VIDC_IO_OUT(REG_193553, 0); + VIDC_BUSY_WAIT(5); + VIDC_IO_OUT(REG_141269, 1); + VIDC_BUSY_WAIT(15); + VIDC_IO_OUT(REG_141269, 0); + VIDC_BUSY_WAIT(5); + VIDC_IO_IN(REG_193553, &fw_start); + + if (!fw_start) { + DBG("\n VIDC-SW-RESET-FAILS!"); + return false; + } + return true; +} + +u32 vidc_720p_reset_is_success() +{ + u32 stagecounter = 0; + VIDC_IO_IN(REG_352831, &stagecounter); + stagecounter &= 0xff; + if (stagecounter != 0xe5) { + DBG("\n VIDC-CPU_RESET-FAILS!"); + VIDC_IO_OUT(REG_224135, 0); + msleep(10); + return false; + } + return true; +} + +void vidc_720p_start_cpu(enum vidc_720p_endian dma_endian, + u32 *icontext_bufferstart, + u32 *debug_core_dump_addr, + u32 debug_buffer_size) +{ + u32 dbg_info_input0_reg = 0x1; + VIDC_IO_OUT(REG_361582, 0); + VIDC_IO_OUT(REG_958768, icontext_bufferstart); + VIDC_IO_OUT(REG_736316, dma_endian); + if (debug_buffer_size) { + dbg_info_input0_reg = (debug_buffer_size << 0x10) + | (0x2 << 1) | 0x1; + VIDC_IO_OUT(REG_166247, debug_core_dump_addr); + } + VIDC_IO_OUT(REG_699747, dbg_info_input0_reg); + VIDC_IO_OUT(REG_224135, 1); +} + +u32 vidc_720p_cpu_start() +{ + u32 fw_status = 0x0; + VIDC_IO_IN(REG_381535, &fw_status); + if (fw_status != 0x02) + return false; + return true; +} + + +void vidc_720p_stop_fw(void) +{ + VIDC_IO_OUT(REG_193553, 0); + VIDC_IO_OUT(REG_224135, 0); +} + +void vidc_720p_get_interrupt_status(u32 *interrupt_status, + u32 *cmd_err_status, u32 *disp_pic_err_status, u32 *op_failed) +{ + u32 err_status; + VIDC_IO_IN(REG_512143, interrupt_status); + VIDC_IO_IN(REG_300310, &err_status); + *cmd_err_status = err_status & 0xffff; + *disp_pic_err_status = (err_status & 0xffff0000) >> 16; + VIDC_IO_INF(REG_724381, OPERATION_FAILED, \ + op_failed); +} + +void vidc_720p_interrupt_done_clear(void) +{ + VIDC_IO_OUT(REG_614776, 1); + VIDC_IO_OUT(REG_97293, 4); +} + +void vidc_720p_submit_command(u32 ch_id, u32 cmd_id) +{ + u32 fw_status; + VIDC_IO_OUT(REG_97293, ch_id); + VIDC_IO_OUT(REG_62325, cmd_id); + VIDC_DEBUG_REGISTER_LOG; + VIDC_IO_IN(REG_381535, &fw_status); + VIDC_IO_OUT(REG_926519, fw_status); +} + +u32 vidc_720p_engine_reset(u32 ch_id, + enum vidc_720p_endian dma_endian, + enum vidc_720p_interrupt_level_selection interrupt_sel, + u32 interrupt_mask +) +{ + u32 op_done = 0; + u32 counter = 0; + + VIDC_LOGERR_STRING("ENG-RESET!!"); + /* issue the engine reset command */ + vidc_720p_submit_command(ch_id, VIDC_720P_CMD_MFC_ENGINE_RESET); + + do { + VIDC_BUSY_WAIT(20); + VIDC_IO_IN(REG_982553, &op_done); + counter++; + } while (!op_done && counter < 10); + + if (!op_done) { + /* Reset fails */ + return false ; + } + + /* write invalid channel id */ + VIDC_IO_OUT(REG_97293, 4); + + /* Set INT_PULSE_SEL */ + if (interrupt_sel == VIDC_720P_INTERRUPT_LEVEL_SEL) + VIDC_IO_OUT(REG_491082, 0); + else + VIDC_IO_OUT(REG_491082, 1); + + if (!interrupt_mask) { + /* Disable interrupt */ + VIDC_IO_OUT(REG_609676, 1); + } else { + /* Enable interrupt */ + VIDC_IO_OUT(REG_609676, 0); + } + + /* Clear any pending interrupt */ + VIDC_IO_OUT(REG_614776, 1); + + /* Set INT_ENABLE_REG */ + VIDC_IO_OUT(REG_418173, interrupt_mask); + + /*Sets the DMA endianness */ + VIDC_IO_OUT(REG_736316, dma_endian); + + /*Restore ARM endianness */ + VIDC_IO_OUT(REG_215724, 0); + + /* retun engine reset success */ + return true ; +} + +void vidc_720p_set_channel(u32 i_ch_id, + enum vidc_720p_enc_dec_selection + enc_dec_sel, enum vidc_720p_codec codec, + u32 *pi_fw, u32 i_firmware_size) +{ + u32 std_sel = 0; + VIDC_IO_OUT(REG_661565, 0); + + if (enc_dec_sel) + std_sel = VIDC_REG_713080_ENC_ON_BMSK; + + std_sel |= (u32) codec; + + VIDC_IO_OUT(REG_713080, std_sel); + + switch (codec) { + default: + case VIDC_720P_DIVX: + case VIDC_720P_XVID: + case VIDC_720P_MPEG4: + { + if (enc_dec_sel == VIDC_720P_ENCODER) + VIDC_IO_OUT(REG_765787, pi_fw); + else + VIDC_IO_OUT(REG_225040, pi_fw); + break; + } + case VIDC_720P_H264: + { + if (enc_dec_sel == VIDC_720P_ENCODER) + VIDC_IO_OUT(REG_942456, pi_fw); + else + VIDC_IO_OUT(REG_942170_ADDR_3, pi_fw); + break; + } + case VIDC_720P_H263: + { + if (enc_dec_sel == VIDC_720P_ENCODER) + VIDC_IO_OUT(REG_765787, pi_fw); + else + VIDC_IO_OUT(REG_942170_ADDR_6, pi_fw); + break; + } + case VIDC_720P_VC1: + { + VIDC_IO_OUT(REG_880188, pi_fw); + break; + } + case VIDC_720P_MPEG2: + { + VIDC_IO_OUT(REG_40293, pi_fw); + break; + } + } + VIDC_IO_OUT(REG_591577, i_firmware_size); + + vidc_720p_submit_command(i_ch_id, VIDC_720P_CMD_CHSET); +} + +void vidc_720p_encode_set_profile(u32 i_profile, u32 i_level) +{ + u32 profile_level = i_profile|(i_level << 0x8); + VIDC_IO_OUT(REG_839021, profile_level); +} + +void vidc_720p_set_frame_size(u32 i_size_x, u32 i_size_y) +{ + VIDC_IO_OUT(REG_999267, i_size_x); + + VIDC_IO_OUT(REG_345712, i_size_y); +} + +void vidc_720p_encode_set_fps(u32 i_rc_frame_rate) +{ + VIDC_IO_OUT(REG_625444, i_rc_frame_rate); +} + +void vidc_720p_encode_set_short_header(u32 i_short_header) +{ + VIDC_IO_OUT(REG_314290, i_short_header); +} + +void vidc_720p_encode_set_vop_time(u32 vop_time_resolution, + u32 vop_time_increment) +{ + u32 enable_vop, vop_timing_reg; + if (!vop_time_resolution) + VIDC_IO_OUT(REG_64895, 0x0); + else { + enable_vop = 0x1; + vop_timing_reg = (enable_vop << 0x1f) | + (vop_time_resolution << 0x10) | vop_time_increment; + VIDC_IO_OUT(REG_64895, vop_timing_reg); + } +} + +void vidc_720p_encode_set_hec_period(u32 hec_period) +{ + VIDC_IO_OUT(REG_407718, hec_period); +} + +void vidc_720p_encode_set_qp_params(u32 i_max_qp, u32 i_min_qp) +{ + u32 qp = i_min_qp | (i_max_qp << 0x8); + VIDC_IO_OUT(REG_734318, qp); +} + +void vidc_720p_encode_set_rc_config(u32 enable_frame_level_rc, + u32 enable_mb_level_rc_flag, + u32 i_frame_qp, u32 pframe_qp) +{ + u32 rc_config = i_frame_qp; + + if (enable_frame_level_rc) + rc_config |= (0x1 << 0x9); + + if (enable_mb_level_rc_flag) + rc_config |= (0x1 << 0x8); + + VIDC_IO_OUT(REG_58211, rc_config); + VIDC_IO_OUT(REG_548359, pframe_qp); +} + +void vidc_720p_encode_set_bit_rate(u32 i_target_bitrate) +{ + VIDC_IO_OUT(REG_174150, i_target_bitrate); +} + +void vidc_720p_encoder_set_param_change(u32 enc_param_change) +{ + VIDC_IO_OUT(REG_804959, enc_param_change); +} + +void vidc_720p_encode_set_control_param(u32 param_val) +{ + VIDC_IO_OUT(REG_128234, param_val); +} + +void vidc_720p_encode_set_frame_level_rc_params(u32 i_reaction_coeff) +{ + VIDC_IO_OUT(REG_677784, i_reaction_coeff); +} + +void vidc_720p_encode_set_mb_level_rc_params(u32 dark_region_as_flag, + u32 smooth_region_as_flag, + u32 static_region_as_flag, + u32 activity_region_flag) +{ + u32 mb_level_rc = 0x0; + if (activity_region_flag) + mb_level_rc |= 0x1; + if (static_region_as_flag) + mb_level_rc |= (0x1 << 0x1); + if (smooth_region_as_flag) + mb_level_rc |= (0x1 << 0x2); + if (dark_region_as_flag) + mb_level_rc |= (0x1 << 0x3); + /* Write MB level rate control */ + VIDC_IO_OUT(REG_995041, mb_level_rc); +} + +void vidc_720p_encode_set_entropy_control(enum vidc_720p_entropy_sel + entropy_sel, + enum vidc_720p_cabac_model + cabac_model_number) +{ + u32 num; + u32 entropy_params = (u32)entropy_sel; + /* Set Model Number */ + if (entropy_sel == VIDC_720P_ENTROPY_SEL_CABAC) { + num = (u32)cabac_model_number; + entropy_params |= (num << 0x2); + } + /* Set Entropy parameters */ + VIDC_IO_OUT(REG_504878, entropy_params); +} + +void vidc_720p_encode_set_db_filter_control(enum vidc_720p_DBConfig + db_config, + u32 i_slice_alpha_offset, + u32 i_slice_beta_offset) +{ + u32 deblock_params; + deblock_params = (u32)db_config; + deblock_params |= + ((i_slice_beta_offset << 0x2) | (i_slice_alpha_offset << 0x7)); + + /* Write deblocking control settings */ + VIDC_IO_OUT(REG_458130, deblock_params); +} + +void vidc_720p_encode_set_intra_refresh_mb_number(u32 i_cir_mb_number) +{ + VIDC_IO_OUT(REG_857491, i_cir_mb_number); +} + +void vidc_720p_encode_set_multi_slice_info(enum + vidc_720p_MSlice_selection + m_slice_sel, + u32 multi_slice_size) +{ + switch (m_slice_sel) { + case VIDC_720P_MSLICE_BY_MB_COUNT: + { + VIDC_IO_OUT(REG_588301, 0x1); + VIDC_IO_OUT(REG_1517, m_slice_sel); + VIDC_IO_OUT(REG_105335, multi_slice_size); + break; + } + case VIDC_720P_MSLICE_BY_BYTE_COUNT: + { + VIDC_IO_OUT(REG_588301, 0x1); + VIDC_IO_OUT(REG_1517, m_slice_sel); + VIDC_IO_OUT(REG_561679, multi_slice_size); + break; + } + case VIDC_720P_MSLICE_BY_GOB: + { + VIDC_IO_OUT(REG_588301, 0x1); + break; + } + default: + case VIDC_720P_MSLICE_OFF: + { + VIDC_IO_OUT(REG_588301, 0x0); + break; + } + } +} + +void vidc_720p_encode_set_dpb_buffer(u32 *pi_enc_dpb_addr, u32 alloc_len) +{ + VIDC_IO_OUT(REG_341928_ADDR, pi_enc_dpb_addr); + VIDC_IO_OUT(REG_319934, alloc_len); +} + +void vidc_720p_encode_set_i_period(u32 i_i_period) +{ + VIDC_IO_OUT(REG_950374, i_i_period); +} + +void vidc_720p_encode_init_codec(u32 i_ch_id, + enum vidc_720p_memory_access_method + memory_access_model) +{ + + VIDC_IO_OUT(REG_841539, memory_access_model); + vidc_720p_submit_command(i_ch_id, VIDC_720P_CMD_INITCODEC); +} + +void vidc_720p_encode_unalign_bitstream(u32 upper_unalign_word, + u32 lower_unalign_word) +{ + VIDC_IO_OUT(REG_792026, upper_unalign_word); + VIDC_IO_OUT(REG_844152, lower_unalign_word); +} + +void vidc_720p_encode_set_seq_header_buffer(u32 ext_buffer_start, + u32 ext_buffer_end, + u32 start_byte_num) +{ + VIDC_IO_OUT(REG_275113_ADDR, ext_buffer_start); + + VIDC_IO_OUT(REG_87912, ext_buffer_start); + + VIDC_IO_OUT(REG_988007_ADDR, ext_buffer_end); + + VIDC_IO_OUT(REG_66693, start_byte_num); +} + +void vidc_720p_encode_frame(u32 ch_id, + u32 ext_buffer_start, + u32 ext_buffer_end, + u32 start_byte_number, u32 y_addr, + u32 c_addr) +{ + VIDC_IO_OUT(REG_275113_ADDR, ext_buffer_start); + + VIDC_IO_OUT(REG_988007_ADDR, ext_buffer_end); + + VIDC_IO_OUT(REG_87912, ext_buffer_start); + + VIDC_IO_OUT(REG_66693, start_byte_number); + + VIDC_IO_OUT(REG_99105, y_addr); + + VIDC_IO_OUT(REG_777113_ADDR, c_addr); + + vidc_720p_submit_command(ch_id, VIDC_720P_CMD_FRAMERUN); +} + +void vidc_720p_encode_get_header(u32 *pi_enc_header_size) +{ + VIDC_IO_IN(REG_114286, pi_enc_header_size); +} + +void vidc_720p_enc_frame_info(struct vidc_720p_enc_frame_info + *enc_frame_info) +{ + VIDC_IO_IN(REG_782249, &enc_frame_info->enc_size); + + VIDC_IO_IN(REG_441270, &enc_frame_info->frame); + + enc_frame_info->frame &= 0x03; + + VIDC_IO_IN(REG_613254, + &enc_frame_info->metadata_exists); +} + +void vidc_720p_decode_bitstream_header(u32 ch_id, + u32 dec_unit_size, + u32 start_byte_num, + u32 ext_buffer_start, + u32 ext_buffer_end, + enum + vidc_720p_memory_access_method + memory_access_model, + u32 decode_order) +{ + VIDC_IO_OUT(REG_965480, decode_order); + + VIDC_IO_OUT(REG_639999, 0x8080); + + VIDC_IO_OUT(REG_275113_ADDR, ext_buffer_start); + + VIDC_IO_OUT(REG_988007_ADDR, ext_buffer_end); + + VIDC_IO_OUT(REG_87912, ext_buffer_end); + + VIDC_IO_OUT(REG_761892, dec_unit_size); + + VIDC_IO_OUT(REG_66693, start_byte_num); + + VIDC_IO_OUT(REG_841539, memory_access_model); + + vidc_720p_submit_command(ch_id, VIDC_720P_CMD_INITCODEC); +} + +void vidc_720p_decode_get_seq_hdr_info(struct vidc_720p_seq_hdr_info + *seq_hdr_info) +{ + u32 display_status; + VIDC_IO_IN(REG_999267, &seq_hdr_info->img_size_x); + + VIDC_IO_IN(REG_345712, &seq_hdr_info->img_size_y); + + VIDC_IO_IN(REG_257463, &seq_hdr_info->min_num_dpb); + + VIDC_IO_IN(REG_854281, &seq_hdr_info->min_dpb_size); + + VIDC_IO_IN(REG_580603, &seq_hdr_info->dec_frm_size); + + VIDC_IO_INF(REG_606447, DISP_PIC_PROFILE, + &seq_hdr_info->profile); + + VIDC_IO_INF(REG_606447, DIS_PIC_LEVEL, + &seq_hdr_info->level); + + VIDC_IO_INF(REG_612715, DISPLAY_STATUS, + &display_status); + seq_hdr_info->progressive = + ((display_status & 0x4) >> 2); + /* bit 3 is for crop existence */ + seq_hdr_info->crop_exists = ((display_status & 0x8) >> 3); + + if (seq_hdr_info->crop_exists) { + /* read the cropping information */ + VIDC_IO_INF(REG_881638, CROP_RIGHT_OFFSET, \ + &seq_hdr_info->crop_right_offset); + VIDC_IO_INF(REG_881638, CROP_LEFT_OFFSET, \ + &seq_hdr_info->crop_left_offset); + VIDC_IO_INF(REG_161486, CROP_BOTTOM_OFFSET, \ + &seq_hdr_info->crop_bottom_offset); + VIDC_IO_INF(REG_161486, CROP_TOP_OFFSET, \ + &seq_hdr_info->crop_top_offset); + } + /* Read the MPEG4 data partitioning indication */ + VIDC_IO_INF(REG_441270, DATA_PARTITIONED, \ + &seq_hdr_info->data_partitioned); + +} + +void vidc_720p_decode_set_dpb_release_buffer_mask(u32 + i_dpb_release_buffer_mask) +{ + VIDC_IO_OUT(REG_603032, i_dpb_release_buffer_mask); +} + +void vidc_720p_decode_set_dpb_buffers(u32 i_buf_index, u32 *pi_dpb_buffer) +{ + VIDC_IO_OUTI(REG_615716, i_buf_index, pi_dpb_buffer); +} + +void vidc_720p_decode_set_comv_buffer(u32 *pi_dpb_comv_buffer, + u32 alloc_len) +{ + VIDC_IO_OUT(REG_456376_ADDR, pi_dpb_comv_buffer); + + VIDC_IO_OUT(REG_490443, alloc_len); +} + +void vidc_720p_decode_set_dpb_details(u32 num_dpb, u32 alloc_len, + u32 *ref_buffer) +{ + VIDC_IO_OUT(REG_518133, ref_buffer); + + VIDC_IO_OUT(REG_267567, 0); + + VIDC_IO_OUT(REG_883500, num_dpb); + + VIDC_IO_OUT(REG_319934, alloc_len); +} + +void vidc_720p_decode_set_mpeg4Post_filter(u32 enable_post_filter) +{ + if (enable_post_filter) + VIDC_IO_OUT(REG_443811, 0x1); + else + VIDC_IO_OUT(REG_443811, 0x0); +} + +void vidc_720p_decode_set_error_control(u32 enable_error_control) +{ + if (enable_error_control) + VIDC_IO_OUT(REG_846346, 0); + else + VIDC_IO_OUT(REG_846346, 1); +} + +void vidc_720p_set_deblock_line_buffer(u32 *pi_deblock_line_buffer_start, + u32 alloc_len) +{ + VIDC_IO_OUT(REG_979942, pi_deblock_line_buffer_start); + + VIDC_IO_OUT(REG_101184, alloc_len); +} + +void vidc_720p_decode_set_mpeg4_data_partitionbuffer(u32 *vsp_buf_start) +{ + VIDC_IO_OUT(REG_958768, vsp_buf_start); +} + +void vidc_720p_decode_setH264VSPBuffer(u32 *pi_vsp_temp_buffer_start) +{ + VIDC_IO_OUT(REG_958768, pi_vsp_temp_buffer_start); +} + +void vidc_720p_decode_frame(u32 ch_id, u32 ext_buffer_start, + u32 ext_buffer_end, u32 dec_unit_size, + u32 start_byte_num, u32 input_frame_tag) +{ + VIDC_IO_OUT(REG_275113_ADDR, ext_buffer_start); + + VIDC_IO_OUT(REG_988007_ADDR, ext_buffer_end); + + VIDC_IO_OUT(REG_87912, ext_buffer_end); + + VIDC_IO_OUT(REG_66693, start_byte_num); + + VIDC_IO_OUT(REG_94750, input_frame_tag); + + VIDC_IO_OUT(REG_761892, dec_unit_size); + + vidc_720p_submit_command(ch_id, VIDC_720P_CMD_FRAMERUN); +} + +void vidc_720p_issue_eos(u32 i_ch_id) +{ + VIDC_IO_OUT(REG_896825, 0x1); + + VIDC_IO_OUT(REG_761892, 0); + + vidc_720p_submit_command(i_ch_id, VIDC_720P_CMD_FRAMERUN); +} + +void vidc_720p_eos_info(u32 *disp_status, u32 *resl_change) +{ + VIDC_IO_INF(REG_612715, DISPLAY_STATUS, disp_status); + (*disp_status) = (*disp_status) & 0x3; + VIDC_IO_INF(REG_724381, RESOLUTION_CHANGE, resl_change); +} + +void vidc_720p_decode_display_info(struct vidc_720p_dec_disp_info + *disp_info) +{ + u32 display_status = 0; + VIDC_IO_INF(REG_612715, DISPLAY_STATUS, &display_status); + + disp_info->disp_status = + (enum vidc_720p_display_status)((display_status & 0x3)); + + disp_info->disp_is_interlace = ((display_status & 0x4) >> 2); + disp_info->crop_exists = ((display_status & 0x8) >> 3); + + disp_info->resl_change = ((display_status & 0x30) >> 4); + + VIDC_IO_INF(REG_724381, RESOLUTION_CHANGE, + &disp_info->reconfig_flush_done); + + VIDC_IO_IN(REG_999267, &disp_info->img_size_x); + + VIDC_IO_IN(REG_345712, &disp_info->img_size_y); + VIDC_IO_IN(REG_151345, &disp_info->y_addr); + VIDC_IO_IN(REG_293983, &disp_info->c_addr); + VIDC_IO_IN(REG_370409, &disp_info->tag_top); + VIDC_IO_IN(REG_438677, &disp_info->tag_bottom); + VIDC_IO_IN(REG_679165, &disp_info->pic_time_top); + VIDC_IO_IN(REG_374150, &disp_info->pic_time_bottom); + + if (disp_info->crop_exists) { + VIDC_IO_INF(REG_881638, CROP_RIGHT_OFFSET, + &disp_info->crop_right_offset); + VIDC_IO_INF(REG_881638, CROP_LEFT_OFFSET, + &disp_info->crop_left_offset); + VIDC_IO_INF(REG_161486, CROP_BOTTOM_OFFSET, + &disp_info->crop_bottom_offset); + VIDC_IO_INF(REG_161486, CROP_TOP_OFFSET, + &disp_info->crop_top_offset); + } + VIDC_IO_IN(REG_613254, &disp_info->metadata_exists); + + VIDC_IO_IN(REG_580603, + &disp_info->input_bytes_consumed); + + VIDC_IO_IN(REG_757835, &disp_info->input_frame_num); + + VIDC_IO_INF(REG_441270, FRAME_TYPE, + &disp_info->input_frame); + + disp_info->input_is_interlace = + ((disp_info->input_frame & 0x4) >> 2); + + if (disp_info->input_frame & 0x10) + disp_info->input_frame = VIDC_720P_IDRFRAME; + else + disp_info->input_frame &= 0x3; +} + +void vidc_720p_decode_skip_frm_details(u32 *free_luma_dpb) +{ + u32 disp_frm; + VIDC_IO_IN(REG_697961, &disp_frm); + + if (disp_frm == VIDC_720P_NOTCODED) + VIDC_IO_IN(REG_347105, free_luma_dpb); +} + +void vidc_720p_metadata_enable(u32 flag, u32 *input_buffer) +{ + VIDC_IO_OUT(REG_854681, flag); + VIDC_IO_OUT(REG_988552, input_buffer); +} + +void vidc_720p_decode_dynamic_req_reset(void) +{ + VIDC_IO_OUT(REG_76706, 0x0); + VIDC_IO_OUT(REG_147682, 0x0); + VIDC_IO_OUT(REG_896825, 0x0); +} + +void vidc_720p_decode_dynamic_req_set(u32 property) +{ + if (property == VIDC_720P_FLUSH_REQ) + VIDC_IO_OUT(REG_76706, 0x1); + else if (property == VIDC_720P_EXTRADATA) + VIDC_IO_OUT(REG_147682, 0x1); +} + +void vidc_720p_decode_setpassthrough_start(u32 pass_startaddr) +{ + VIDC_IO_OUT(REG_486169, pass_startaddr); +} diff --git a/drivers/video/msm/vidc/720p/ddl/vidc.h b/drivers/video/msm/vidc/720p/ddl/vidc.h new file mode 100644 index 000000000000..a09034f204d1 --- /dev/null +++ b/drivers/video/msm/vidc/720p/ddl/vidc.h @@ -0,0 +1,2705 @@ +/* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#ifndef VIDC_H +#define VIDC_H +#include +#include +#include + +#define VIDC_720P_IN(reg) VIDC_##reg##_IN +#define VIDC_720P_INM(reg, mask) VIDC_##reg##_INM(mask) +#define VIDC_720P_OUT(reg, val) VIDC_##reg##_OUT(val) +#define VIDC_720P_OUTI(reg, index, val) VIDC_##reg##_OUTI(index, val) +#define VIDC_720P_OUTM(reg, mask, val) VIDC_##reg##_OUTM(mask, val) +#define VIDC_720P_SHFT(reg, field) VIDC_##reg##_##field##_SHFT +#define VIDC_720P_FMSK(reg, field) VIDC_##reg##_##field##_BMSK + +#define VIDC_720P_INF(io, field) (VIDC_720P_INM(io, VIDC_720P_FMSK(io, field)) \ + >> VIDC_720P_SHFT(io, field)) +#define VIDC_720P_OUTF(io, field, val) \ + VIDC_720P_OUTM(io, VIDC_720P_FMSK(io, field), \ + val << VIDC_720P_SHFT(io, field)) + +#define __inpdw(port) ioread32(port) +#define __outpdw(port, val) iowrite32(val, port) + +#define in_dword_masked(addr, mask) (__inpdw(addr) & (mask)) + +#define out_dword(addr, val) __outpdw(addr, val) + +#define out_dword_masked(io, mask, val, shadow) \ +do { \ + shadow = (shadow & (u32)(~(mask))) | ((u32)((val) & (mask))); \ + (void) out_dword(io, shadow); \ +} while (0) + +#define out_dword_masked_ns(io, mask, val, current_reg_content) \ + (void) out_dword(io, ((current_reg_content & (u32)(~(mask))) | \ + ((u32)((val) & (mask))))) + +extern u8 *vidc_base_addr; + +#define VIDC720P_BASE vidc_base_addr +#define VIDC_720P_WRAPPER_REG_BASE (VIDC720P_BASE + \ + 0x00000000) +#define VIDC_720P_WRAPPER_REG_BASE_PHYS VIDC_720P_BASE_PHYS + +#define VIDC_REG_614413_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 00000000) +#define VIDC_REG_614413_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 00000000) +#define VIDC_REG_614413_RMSK 0x1 +#define VIDC_REG_614413_SHFT 0 +#define VIDC_REG_614413_IN \ + in_dword_masked(VIDC_REG_614413_ADDR, \ + VIDC_REG_614413_RMSK) +#define VIDC_REG_614413_INM(m) \ + in_dword_masked(VIDC_REG_614413_ADDR, m) +#define VIDC_REG_614413_OUT(v) \ + out_dword(VIDC_REG_614413_ADDR, v) +#define VIDC_REG_614413_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_614413_ADDR, m, v, \ + VIDC_REG_614413_IN); \ +} while (0) +#define VIDC_REG_614413_DMA_START_BMSK 0x1 +#define VIDC_REG_614413_DMA_START_SHFT 0 + +#define VIDC_REG_591577_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x0000000c) +#define VIDC_REG_591577_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000000c) +#define VIDC_REG_591577_RMSK 0xffffffff +#define VIDC_REG_591577_SHFT 0 +#define VIDC_REG_591577_IN \ + in_dword_masked(VIDC_REG_591577_ADDR, \ + VIDC_REG_591577_RMSK) +#define VIDC_REG_591577_INM(m) \ + in_dword_masked(VIDC_REG_591577_ADDR, m) +#define VIDC_REG_591577_OUT(v) \ + out_dword(VIDC_REG_591577_ADDR, v) +#define VIDC_REG_591577_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_591577_ADDR, m, v, \ + VIDC_REG_591577_IN); \ +} while (0) +#define VIDC_REG_591577_BOOTCODE_SIZE_BMSK 0xffffffff +#define VIDC_REG_591577_BOOTCODE_SIZE_SHFT 0 + +#define VIDC_REG_203921_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000014) +#define VIDC_REG_203921_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000014) +#define VIDC_REG_203921_RMSK 0xffffffff +#define VIDC_REG_203921_SHFT 0 +#define VIDC_REG_203921_IN \ + in_dword_masked(VIDC_REG_203921_ADDR, \ + VIDC_REG_203921_RMSK) +#define VIDC_REG_203921_INM(m) \ + in_dword_masked(VIDC_REG_203921_ADDR, m) +#define VIDC_REG_203921_OUT(v) \ + out_dword(VIDC_REG_203921_ADDR, v) +#define VIDC_REG_203921_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_203921_ADDR, m, v, \ + VIDC_REG_203921_IN); \ +} while (0) +#define VIDC_REG_203921_DMA_EXTADDR_BMSK 0xffffffff +#define VIDC_REG_203921_DMA_EXTADDR_SHFT 0 + +#define VIDC_REG_275113_ADDR_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000018) +#define VIDC_REG_275113_ADDR_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000018) +#define VIDC_REG_275113_ADDR_RMSK 0xffffffff +#define VIDC_REG_275113_ADDR_SHFT 0 +#define VIDC_REG_275113_ADDR_IN \ + in_dword_masked(VIDC_REG_275113_ADDR_ADDR, \ + VIDC_REG_275113_ADDR_RMSK) +#define VIDC_REG_275113_ADDR_INM(m) \ + in_dword_masked(VIDC_REG_275113_ADDR_ADDR, m) +#define VIDC_REG_275113_ADDR_OUT(v) \ + out_dword(VIDC_REG_275113_ADDR_ADDR, v) +#define VIDC_REG_275113_ADDR_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_275113_ADDR_ADDR, m, v, \ + VIDC_REG_275113_ADDR_IN); \ +} while (0) +#define VIDC_REG_742076_ADDR_BMSK 0xffffffff +#define VIDC_REG_742076_ADDR_SHFT 0 + +#define VIDC_REG_988007_ADDR_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x0000001c) +#define VIDC_REG_988007_ADDR_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000001c) +#define VIDC_REG_988007_ADDR_RMSK 0xffffffff +#define VIDC_REG_988007_ADDR_SHFT 0 +#define VIDC_REG_988007_ADDR_IN \ + in_dword_masked(VIDC_REG_988007_ADDR_ADDR, \ + VIDC_REG_988007_ADDR_RMSK) +#define VIDC_REG_988007_ADDR_INM(m) \ + in_dword_masked(VIDC_REG_988007_ADDR_ADDR, m) +#define VIDC_REG_988007_ADDR_OUT(v) \ + out_dword(VIDC_REG_988007_ADDR_ADDR, v) +#define VIDC_REG_988007_ADDR_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_988007_ADDR_ADDR, m, v, \ + VIDC_REG_988007_ADDR_IN); \ +} while (0) +#define VIDC_REG_988007_ADDR_EXT_BUF_END_ADDR_BMSK 0xffffffff +#define VIDC_REG_988007_ADDR_EXT_BUF_END_ADDR_SHFT 0 + +#define VIDC_REG_531515_ADDR_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000020) +#define VIDC_REG_531515_ADDR_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000020) +#define VIDC_REG_531515_ADDR_RMSK 0xffffffff +#define VIDC_REG_531515_ADDR_SHFT 0 +#define VIDC_REG_531515_ADDR_IN \ + in_dword_masked(VIDC_REG_531515_ADDR_ADDR, \ + VIDC_REG_531515_ADDR_RMSK) +#define VIDC_REG_531515_ADDR_INM(m) \ + in_dword_masked(VIDC_REG_531515_ADDR_ADDR, m) +#define VIDC_REG_531515_ADDR_OUT(v) \ + out_dword(VIDC_REG_531515_ADDR_ADDR, v) +#define VIDC_REG_531515_ADDR_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_531515_ADDR_ADDR, m, v, \ + VIDC_REG_531515_ADDR_IN); \ +} while (0) +#define VIDC_REG_531515_ADDR_DMA_INT_ADDR_BMSK 0xffffffff +#define VIDC_REG_531515_ADDR_DMA_INT_ADDR_SHFT 0 + +#define VIDC_REG_87912_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000024) +#define VIDC_REG_87912_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000024) +#define VIDC_REG_87912_RMSK 0xffffffff +#define VIDC_REG_87912_SHFT 0 +#define VIDC_REG_87912_IN \ + in_dword_masked(VIDC_REG_87912_ADDR, \ + VIDC_REG_87912_RMSK) +#define VIDC_REG_87912_INM(m) \ + in_dword_masked(VIDC_REG_87912_ADDR, m) +#define VIDC_REG_87912_OUT(v) \ + out_dword(VIDC_REG_87912_ADDR, v) +#define VIDC_REG_87912_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_87912_ADDR, m, v, \ + VIDC_REG_87912_IN); \ +} while (0) +#define VIDC_REG_87912_HOST_PTR_ADDR_BMSK 0xffffffff +#define VIDC_REG_87912_HOST_PTR_ADDR_SHFT 0 + +#define VIDC_REG_896825_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000028) +#define VIDC_REG_896825_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000028) +#define VIDC_REG_896825_RMSK 0x1 +#define VIDC_REG_896825_SHFT 0 +#define VIDC_REG_896825_IN \ + in_dword_masked(VIDC_REG_896825_ADDR, \ + VIDC_REG_896825_RMSK) +#define VIDC_REG_896825_INM(m) \ + in_dword_masked(VIDC_REG_896825_ADDR, m) +#define VIDC_REG_896825_OUT(v) \ + out_dword(VIDC_REG_896825_ADDR, v) +#define VIDC_REG_896825_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_896825_ADDR, m, v, \ + VIDC_REG_896825_IN); \ +} while (0) +#define VIDC_REG_896825_LAST_DEC_BMSK 0x1 +#define VIDC_REG_896825_LAST_DEC_SHFT 0 + +#define VIDC_REG_174526_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x0000002c) +#define VIDC_REG_174526_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000002c) +#define VIDC_REG_174526_RMSK 0x1 +#define VIDC_REG_174526_SHFT 0 +#define VIDC_REG_174526_IN \ + in_dword_masked(VIDC_REG_174526_ADDR, VIDC_REG_174526_RMSK) +#define VIDC_REG_174526_INM(m) \ + in_dword_masked(VIDC_REG_174526_ADDR, m) +#define VIDC_REG_174526_DONE_M_BMSK 0x1 +#define VIDC_REG_174526_DONE_M_SHFT 0 + +#define VIDC_REG_736316_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000044) +#define VIDC_REG_736316_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000044) +#define VIDC_REG_736316_RMSK 0x1 +#define VIDC_REG_736316_SHFT 0 +#define VIDC_REG_736316_IN \ + in_dword_masked(VIDC_REG_736316_ADDR, \ + VIDC_REG_736316_RMSK) +#define VIDC_REG_736316_INM(m) \ + in_dword_masked(VIDC_REG_736316_ADDR, m) +#define VIDC_REG_736316_OUT(v) \ + out_dword(VIDC_REG_736316_ADDR, v) +#define VIDC_REG_736316_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_736316_ADDR, m, v, \ + VIDC_REG_736316_IN); \ +} while (0) +#define VIDC_REG_736316_BITS_ENDIAN_BMSK 0x1 +#define VIDC_REG_736316_BITS_ENDIAN_SHFT 0 + +#define VIDC_REG_761892_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000054) +#define VIDC_REG_761892_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000054) +#define VIDC_REG_761892_RMSK 0xffffffff +#define VIDC_REG_761892_SHFT 0 +#define VIDC_REG_761892_IN \ + in_dword_masked(VIDC_REG_761892_ADDR, \ + VIDC_REG_761892_RMSK) +#define VIDC_REG_761892_INM(m) \ + in_dword_masked(VIDC_REG_761892_ADDR, m) +#define VIDC_REG_761892_OUT(v) \ + out_dword(VIDC_REG_761892_ADDR, v) +#define VIDC_REG_761892_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_761892_ADDR, m, v, \ + VIDC_REG_761892_IN); \ +} while (0) +#define VIDC_REG_761892_DEC_UNIT_SIZE_BMSK 0xffffffff +#define VIDC_REG_761892_DEC_UNIT_SIZE_SHFT 0 + +#define VIDC_REG_782249_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000058) +#define VIDC_REG_782249_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000058) +#define VIDC_REG_782249_RMSK 0xffffffff +#define VIDC_REG_782249_SHFT 0 +#define VIDC_REG_782249_IN \ + in_dword_masked(VIDC_REG_782249_ADDR, \ + VIDC_REG_782249_RMSK) +#define VIDC_REG_782249_INM(m) \ + in_dword_masked(VIDC_REG_782249_ADDR, m) +#define VIDC_REG_782249_ENC_UNIT_SIZE_BMSK 0xffffffff +#define VIDC_REG_782249_ENC_UNIT_SIZE_SHFT 0 + +#define VIDC_REG_66693_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x0000005c) +#define VIDC_REG_66693_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000005c) +#define VIDC_REG_66693_RMSK 0xf +#define VIDC_REG_66693_SHFT 0 +#define VIDC_REG_66693_IN \ + in_dword_masked(VIDC_REG_66693_ADDR, \ + VIDC_REG_66693_RMSK) +#define VIDC_REG_66693_INM(m) \ + in_dword_masked(VIDC_REG_66693_ADDR, m) +#define VIDC_REG_66693_OUT(v) \ + out_dword(VIDC_REG_66693_ADDR, v) +#define VIDC_REG_66693_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_66693_ADDR, m, v, \ + VIDC_REG_66693_IN); \ +} while (0) +#define VIDC_REG_66693_START_BYTE_NUM_BMSK 0xf +#define VIDC_REG_66693_START_BYTE_NUM_SHFT 0 + +#define VIDC_REG_114286_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000060) +#define VIDC_REG_114286_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000060) +#define VIDC_REG_114286_RMSK 0xffffffff +#define VIDC_REG_114286_SHFT 0 +#define VIDC_REG_114286_IN \ + in_dword_masked(VIDC_REG_114286_ADDR, \ + VIDC_REG_114286_RMSK) +#define VIDC_REG_114286_INM(m) \ + in_dword_masked(VIDC_REG_114286_ADDR, m) +#define VIDC_REG_114286_ENC_HEADER_SIZE_BMSK 0xffffffff +#define VIDC_REG_114286_ENC_HEADER_SIZE_SHFT 0 + +#define VIDC_REG_713080_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000100) +#define VIDC_REG_713080_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000100) +#define VIDC_REG_713080_RMSK 0x1f +#define VIDC_REG_713080_SHFT 0 +#define VIDC_REG_713080_IN \ + in_dword_masked(VIDC_REG_713080_ADDR, \ + VIDC_REG_713080_RMSK) +#define VIDC_REG_713080_INM(m) \ + in_dword_masked(VIDC_REG_713080_ADDR, m) +#define VIDC_REG_713080_OUT(v) \ + out_dword(VIDC_REG_713080_ADDR, v) +#define VIDC_REG_713080_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_713080_ADDR, m, v, \ + VIDC_REG_713080_IN); \ +} while (0) +#define VIDC_REG_713080_ENC_ON_BMSK 0x10 +#define VIDC_REG_713080_ENC_ON_SHFT 0x4 +#define VIDC_REG_713080_STANDARD_SEL_BMSK 0xf +#define VIDC_REG_713080_STANDARD_SEL_SHFT 0 + +#define VIDC_REG_97293_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000104) +#define VIDC_REG_97293_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000104) +#define VIDC_REG_97293_RMSK 0x1f +#define VIDC_REG_97293_SHFT 0 +#define VIDC_REG_97293_IN \ + in_dword_masked(VIDC_REG_97293_ADDR, VIDC_REG_97293_RMSK) +#define VIDC_REG_97293_INM(m) \ + in_dword_masked(VIDC_REG_97293_ADDR, m) +#define VIDC_REG_97293_OUT(v) \ + out_dword(VIDC_REG_97293_ADDR, v) +#define VIDC_REG_97293_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_97293_ADDR, m, v, \ + VIDC_REG_97293_IN); \ +} while (0) +#define VIDC_REG_97293_CH_ID_BMSK 0x1f +#define VIDC_REG_97293_CH_ID_SHFT 0 + +#define VIDC_REG_224135_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000108) +#define VIDC_REG_224135_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000108) +#define VIDC_REG_224135_RMSK 0x1 +#define VIDC_REG_224135_SHFT 0 +#define VIDC_REG_224135_IN \ + in_dword_masked(VIDC_REG_224135_ADDR, \ + VIDC_REG_224135_RMSK) +#define VIDC_REG_224135_INM(m) \ + in_dword_masked(VIDC_REG_224135_ADDR, m) +#define VIDC_REG_224135_OUT(v) \ + out_dword(VIDC_REG_224135_ADDR, v) +#define VIDC_REG_224135_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_224135_ADDR, m, v, \ + VIDC_REG_224135_IN); \ +} while (0) +#define VIDC_REG_224135_CPU_RESET_BMSK 0x1 +#define VIDC_REG_224135_CPU_RESET_SHFT 0 + +#define VIDC_REG_832522_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x0000010c) +#define VIDC_REG_832522_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000010c) +#define VIDC_REG_832522_RMSK 0x1 +#define VIDC_REG_832522_SHFT 0 +#define VIDC_REG_832522_IN \ + in_dword_masked(VIDC_REG_832522_ADDR, VIDC_REG_832522_RMSK) +#define VIDC_REG_832522_INM(m) \ + in_dword_masked(VIDC_REG_832522_ADDR, m) +#define VIDC_REG_832522_OUT(v) \ + out_dword(VIDC_REG_832522_ADDR, v) +#define VIDC_REG_832522_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_832522_ADDR, m, v, \ + VIDC_REG_832522_IN); \ +} while (0) +#define VIDC_REG_832522_FW_END_BMSK 0x1 +#define VIDC_REG_832522_FW_END_SHFT 0 + +#define VIDC_REG_361582_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000110) +#define VIDC_REG_361582_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000110) +#define VIDC_REG_361582_RMSK 0x1 +#define VIDC_REG_361582_SHFT 0 +#define VIDC_REG_361582_IN \ + in_dword_masked(VIDC_REG_361582_ADDR, \ + VIDC_REG_361582_RMSK) +#define VIDC_REG_361582_INM(m) \ + in_dword_masked(VIDC_REG_361582_ADDR, m) +#define VIDC_REG_361582_OUT(v) \ + out_dword(VIDC_REG_361582_ADDR, v) +#define VIDC_REG_361582_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_361582_ADDR, m, v, \ + VIDC_REG_361582_IN); \ +} while (0) +#define VIDC_REG_361582_BUS_MASTER_BMSK 0x1 +#define VIDC_REG_361582_BUS_MASTER_SHFT 0 + +#define VIDC_REG_314435_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000114) +#define VIDC_REG_314435_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000114) +#define VIDC_REG_314435_RMSK 0x1 +#define VIDC_REG_314435_SHFT 0 +#define VIDC_REG_314435_IN \ + in_dword_masked(VIDC_REG_314435_ADDR, \ + VIDC_REG_314435_RMSK) +#define VIDC_REG_314435_INM(m) \ + in_dword_masked(VIDC_REG_314435_ADDR, m) +#define VIDC_REG_314435_OUT(v) \ + out_dword(VIDC_REG_314435_ADDR, v) +#define VIDC_REG_314435_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_314435_ADDR, m, v, \ + VIDC_REG_314435_IN); \ +} while (0) +#define VIDC_REG_314435_FRAME_START_BMSK 0x1 +#define VIDC_REG_314435_FRAME_START_SHFT 0 + +#define VIDC_REG_999267_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000118) +#define VIDC_REG_999267_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000118) +#define VIDC_REG_999267_RMSK 0xffff +#define VIDC_REG_999267_SHFT 0 +#define VIDC_REG_999267_IN \ + in_dword_masked(VIDC_REG_999267_ADDR, \ + VIDC_REG_999267_RMSK) +#define VIDC_REG_999267_INM(m) \ + in_dword_masked(VIDC_REG_999267_ADDR, m) +#define VIDC_REG_999267_OUT(v) \ + out_dword(VIDC_REG_999267_ADDR, v) +#define VIDC_REG_999267_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_999267_ADDR, m, v, \ + VIDC_REG_999267_IN); \ +} while (0) +#define VIDC_REG_999267_IMG_SIZE_X_BMSK 0xffff +#define VIDC_REG_999267_IMG_SIZE_X_SHFT 0 + +#define VIDC_REG_345712_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x0000011c) +#define VIDC_REG_345712_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000011c) +#define VIDC_REG_345712_RMSK 0xffff +#define VIDC_REG_345712_SHFT 0 +#define VIDC_REG_345712_IN \ + in_dword_masked(VIDC_REG_345712_ADDR, \ + VIDC_REG_345712_RMSK) +#define VIDC_REG_345712_INM(m) \ + in_dword_masked(VIDC_REG_345712_ADDR, m) +#define VIDC_REG_345712_OUT(v) \ + out_dword(VIDC_REG_345712_ADDR, v) +#define VIDC_REG_345712_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_345712_ADDR, m, v, \ + VIDC_REG_345712_IN); \ +} while (0) +#define VIDC_REG_345712_IMG_SIZE_Y_BMSK 0xffff +#define VIDC_REG_345712_IMG_SIZE_Y_SHFT 0 + +#define VIDC_REG_443811_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000124) +#define VIDC_REG_443811_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000124) +#define VIDC_REG_443811_RMSK 0x1 +#define VIDC_REG_443811_SHFT 0 +#define VIDC_REG_443811_IN \ + in_dword_masked(VIDC_REG_443811_ADDR, VIDC_REG_443811_RMSK) +#define VIDC_REG_443811_INM(m) \ + in_dword_masked(VIDC_REG_443811_ADDR, m) +#define VIDC_REG_443811_OUT(v) \ + out_dword(VIDC_REG_443811_ADDR, v) +#define VIDC_REG_443811_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_443811_ADDR, m, v, \ + VIDC_REG_443811_IN); \ +} while (0) +#define VIDC_REG_443811_POST_ON_BMSK 0x1 +#define VIDC_REG_443811_POST_ON_SHFT 0 + +#define VIDC_REG_538267_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000128) +#define VIDC_REG_538267_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000128) +#define VIDC_REG_538267_RMSK 0xffffffff +#define VIDC_REG_538267_SHFT 0 +#define VIDC_REG_538267_IN \ + in_dword_masked(VIDC_REG_538267_ADDR, \ + VIDC_REG_538267_RMSK) +#define VIDC_REG_538267_INM(m) \ + in_dword_masked(VIDC_REG_538267_ADDR, m) +#define VIDC_REG_538267_OUT(v) \ + out_dword(VIDC_REG_538267_ADDR, v) +#define VIDC_REG_538267_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_538267_ADDR, m, v, \ + VIDC_REG_538267_IN); \ +} while (0) +#define VIDC_REG_538267_QUOTIENT_VAL_BMSK 0xffff0000 +#define VIDC_REG_538267_QUOTIENT_VAL_SHFT 0x10 +#define VIDC_REG_538267_REMAINDER_VAL_BMSK 0xffff +#define VIDC_REG_538267_REMAINDER_VAL_SHFT 0 + +#define VIDC_REG_661565_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x0000012c) +#define VIDC_REG_661565_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000012c) +#define VIDC_REG_661565_RMSK 0x1 +#define VIDC_REG_661565_SHFT 0 +#define VIDC_REG_661565_IN \ + in_dword_masked(VIDC_REG_661565_ADDR, \ + VIDC_REG_661565_RMSK) +#define VIDC_REG_661565_INM(m) \ + in_dword_masked(VIDC_REG_661565_ADDR, m) +#define VIDC_REG_661565_OUT(v) \ + out_dword(VIDC_REG_661565_ADDR, v) +#define VIDC_REG_661565_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_661565_ADDR, m, v, \ + VIDC_REG_661565_IN); \ +} while (0) +#define VIDC_REG_661565_SEQUENCE_START_BMSK 0x1 +#define VIDC_REG_661565_SEQUENCE_START_SHFT 0 + +#define VIDC_REG_141269_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000130) +#define VIDC_REG_141269_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000130) +#define VIDC_REG_141269_RMSK 0x1 +#define VIDC_REG_141269_SHFT 0 +#define VIDC_REG_141269_IN \ + in_dword_masked(VIDC_REG_141269_ADDR, \ + VIDC_REG_141269_RMSK) +#define VIDC_REG_141269_INM(m) \ + in_dword_masked(VIDC_REG_141269_ADDR, m) +#define VIDC_REG_141269_OUT(v) \ + out_dword(VIDC_REG_141269_ADDR, v) +#define VIDC_REG_141269_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_141269_ADDR, m, v, \ + VIDC_REG_141269_IN); \ +} while (0) +#define VIDC_REG_141269_SW_RESET_BMSK 0x1 +#define VIDC_REG_141269_SW_RESET_SHFT 0 + +#define VIDC_REG_193553_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000134) +#define VIDC_REG_193553_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000134) +#define VIDC_REG_193553_RMSK 0x1 +#define VIDC_REG_193553_SHFT 0 +#define VIDC_REG_193553_IN \ + in_dword_masked(VIDC_REG_193553_ADDR, \ + VIDC_REG_193553_RMSK) +#define VIDC_REG_193553_INM(m) \ + in_dword_masked(VIDC_REG_193553_ADDR, m) +#define VIDC_REG_193553_OUT(v) \ + out_dword(VIDC_REG_193553_ADDR, v) +#define VIDC_REG_193553_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_193553_ADDR, m, v, \ + VIDC_REG_193553_IN); \ +} while (0) +#define VIDC_REG_193553_FW_START_BMSK 0x1 +#define VIDC_REG_193553_FW_START_SHFT 0 + +#define VIDC_REG_215724_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000138) +#define VIDC_REG_215724_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000138) +#define VIDC_REG_215724_RMSK 0x1 +#define VIDC_REG_215724_SHFT 0 +#define VIDC_REG_215724_IN \ + in_dword_masked(VIDC_REG_215724_ADDR, \ + VIDC_REG_215724_RMSK) +#define VIDC_REG_215724_INM(m) \ + in_dword_masked(VIDC_REG_215724_ADDR, m) +#define VIDC_REG_215724_OUT(v) \ + out_dword(VIDC_REG_215724_ADDR, v) +#define VIDC_REG_215724_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_215724_ADDR, m, v, \ + VIDC_REG_215724_IN); \ +} while (0) +#define VIDC_REG_215724_ARM_ENDIAN_BMSK 0x1 +#define VIDC_REG_215724_ARM_ENDIAN_SHFT 0 + +#define VIDC_REG_846346_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x0000013c) +#define VIDC_REG_846346_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000013c) +#define VIDC_REG_846346_RMSK 0x1 +#define VIDC_REG_846346_SHFT 0 +#define VIDC_REG_846346_IN \ + in_dword_masked(VIDC_REG_846346_ADDR, \ + VIDC_REG_846346_RMSK) +#define VIDC_REG_846346_INM(m) \ + in_dword_masked(VIDC_REG_846346_ADDR, m) +#define VIDC_REG_846346_OUT(v) \ + out_dword(VIDC_REG_846346_ADDR, v) +#define VIDC_REG_846346_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_846346_ADDR, m, v, \ + VIDC_REG_846346_IN); \ +} while (0) +#define VIDC_REG_846346_ERR_CTRL_BMSK 0x1 +#define VIDC_REG_846346_ERR_CTRL_SHFT 0 + +#define VIDC_REG_765787_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000200) +#define VIDC_REG_765787_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000200) +#define VIDC_REG_765787_RMSK 0xffffffff +#define VIDC_REG_765787_SHFT 0 +#define VIDC_REG_765787_IN \ + in_dword_masked(VIDC_REG_765787_ADDR, \ + VIDC_REG_765787_RMSK) +#define VIDC_REG_765787_INM(m) \ + in_dword_masked(VIDC_REG_765787_ADDR, m) +#define VIDC_REG_765787_OUT(v) \ + out_dword(VIDC_REG_765787_ADDR, v) +#define VIDC_REG_765787_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_765787_ADDR, m, v, \ + VIDC_REG_765787_IN); \ +} while (0) +#define VIDC_REG_765787_FW_STT_ADDR_0_BMSK 0xffffffff +#define VIDC_REG_765787_FW_STT_ADDR_0_SHFT 0 + +#define VIDC_REG_225040_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000204) +#define VIDC_REG_225040_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000204) +#define VIDC_REG_225040_RMSK 0xffffffff +#define VIDC_REG_225040_SHFT 0 +#define VIDC_REG_225040_IN \ + in_dword_masked(VIDC_REG_225040_ADDR, \ + VIDC_REG_225040_RMSK) +#define VIDC_REG_225040_INM(m) \ + in_dword_masked(VIDC_REG_225040_ADDR, m) +#define VIDC_REG_225040_OUT(v) \ + out_dword(VIDC_REG_225040_ADDR, v) +#define VIDC_REG_225040_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_225040_ADDR, m, v, \ + VIDC_REG_225040_IN); \ +} while (0) +#define VIDC_REG_225040_FW_STT_ADDR_1_BMSK 0xffffffff +#define VIDC_REG_225040_FW_STT_ADDR_1_SHFT 0 + +#define VIDC_REG_942456_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000208) +#define VIDC_REG_942456_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000208) +#define VIDC_REG_942456_RMSK 0xffffffff +#define VIDC_REG_942456_SHFT 0 +#define VIDC_REG_942456_IN \ + in_dword_masked(VIDC_REG_942456_ADDR, \ + VIDC_REG_942456_RMSK) +#define VIDC_REG_942456_INM(m) \ + in_dword_masked(VIDC_REG_942456_ADDR, m) +#define VIDC_REG_942456_OUT(v) \ + out_dword(VIDC_REG_942456_ADDR, v) +#define VIDC_REG_942456_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_942456_ADDR, m, v, \ + VIDC_REG_942456_IN); \ +} while (0) +#define VIDC_REG_942456_FW_STT_ADDR_2_BMSK 0xffffffff +#define VIDC_REG_942456_FW_STT_ADDR_2_SHFT 0 + +#define VIDC_REG_942170_ADDR_3_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x0000020c) +#define VIDC_REG_942170_ADDR_3_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000020c) +#define VIDC_REG_942170_ADDR_3_RMSK 0xffffffff +#define VIDC_REG_942170_ADDR_3_SHFT 0 +#define VIDC_REG_942170_ADDR_3_IN \ + in_dword_masked(VIDC_REG_942170_ADDR_3_ADDR, \ + VIDC_REG_942170_ADDR_3_RMSK) +#define VIDC_REG_942170_ADDR_3_INM(m) \ + in_dword_masked(VIDC_REG_942170_ADDR_3_ADDR, m) +#define VIDC_REG_942170_ADDR_3_OUT(v) \ + out_dword(VIDC_REG_942170_ADDR_3_ADDR, v) +#define VIDC_REG_942170_ADDR_3_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_942170_ADDR_3_ADDR, m, v, \ + VIDC_REG_942170_ADDR_3_IN); \ +} while (0) +#define VIDC_REG_942170_ADDR_3_FW_STT_ADDR_3_BMSK 0xffffffff +#define VIDC_REG_942170_ADDR_3_FW_STT_ADDR_3_SHFT 0 + +#define VIDC_REG_880188_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000210) +#define VIDC_REG_880188_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000210) +#define VIDC_REG_880188_RMSK 0xffffffff +#define VIDC_REG_880188_SHFT 0 +#define VIDC_REG_880188_IN \ + in_dword_masked(VIDC_REG_880188_ADDR, \ + VIDC_REG_880188_RMSK) +#define VIDC_REG_880188_INM(m) \ + in_dword_masked(VIDC_REG_880188_ADDR, m) +#define VIDC_REG_880188_OUT(v) \ + out_dword(VIDC_REG_880188_ADDR, v) +#define VIDC_REG_880188_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_880188_ADDR, m, v, \ + VIDC_REG_880188_IN); \ +} while (0) +#define VIDC_REG_880188_FW_STT_ADDR_4_BMSK 0xffffffff +#define VIDC_REG_880188_FW_STT_ADDR_4_SHFT 0 + +#define VIDC_REG_40293_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000214) +#define VIDC_REG_40293_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000214) +#define VIDC_REG_40293_RMSK 0xffffffff +#define VIDC_REG_40293_SHFT 0 +#define VIDC_REG_40293_IN \ + in_dword_masked(VIDC_REG_40293_ADDR, \ + VIDC_REG_40293_RMSK) +#define VIDC_REG_40293_INM(m) \ + in_dword_masked(VIDC_REG_40293_ADDR, m) +#define VIDC_REG_40293_OUT(v) \ + out_dword(VIDC_REG_40293_ADDR, v) +#define VIDC_REG_40293_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_40293_ADDR, m, v, \ + VIDC_REG_40293_IN); \ +} while (0) +#define VIDC_REG_40293_FW_STT_ADDR_5_BMSK 0xffffffff +#define VIDC_REG_40293_FW_STT_ADDR_5_SHFT 0 + +#define VIDC_REG_942170_ADDR_6_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000218) +#define VIDC_REG_942170_ADDR_6_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000218) +#define VIDC_REG_942170_ADDR_6_RMSK 0xffffffff +#define VIDC_REG_942170_ADDR_6_SHFT 0 +#define VIDC_REG_942170_ADDR_6_IN \ + in_dword_masked(VIDC_REG_942170_ADDR_6_ADDR, \ + VIDC_REG_942170_ADDR_6_RMSK) +#define VIDC_REG_942170_ADDR_6_INM(m) \ + in_dword_masked(VIDC_REG_942170_ADDR_6_ADDR, m) +#define VIDC_REG_942170_ADDR_6_OUT(v) \ + out_dword(VIDC_REG_942170_ADDR_6_ADDR, v) +#define VIDC_REG_942170_ADDR_6_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_942170_ADDR_6_ADDR, m, v, \ + VIDC_REG_942170_ADDR_6_IN); \ +} while (0) +#define VIDC_REG_942170_ADDR_6_FW_STT_ADDR_6_BMSK 0xffffffff +#define VIDC_REG_942170_ADDR_6_FW_STT_ADDR_6_SHFT 0 + +#define VIDC_REG_958768_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000230) +#define VIDC_REG_958768_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000230) +#define VIDC_REG_958768_RMSK 0xffffffff +#define VIDC_REG_958768_SHFT 0 +#define VIDC_REG_958768_IN \ + in_dword_masked(VIDC_REG_958768_ADDR, \ + VIDC_REG_958768_RMSK) +#define VIDC_REG_958768_INM(m) \ + in_dword_masked(VIDC_REG_958768_ADDR, m) +#define VIDC_REG_958768_OUT(v) \ + out_dword(VIDC_REG_958768_ADDR, v) +#define VIDC_REG_958768_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_958768_ADDR, m, v, \ + VIDC_REG_958768_IN); \ +} while (0) +#define VIDC_REG_699384_ADDR_BMSK 0xffffffff +#define VIDC_REG_699384_ADDR_SHFT 0 + +#define VIDC_REG_979942_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000234) +#define VIDC_REG_979942_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000234) +#define VIDC_REG_979942_RMSK 0xffffffff +#define VIDC_REG_979942_SHFT 0 +#define VIDC_REG_979942_IN \ + in_dword_masked(VIDC_REG_979942_ADDR, \ + VIDC_REG_979942_RMSK) +#define VIDC_REG_979942_INM(m) \ + in_dword_masked(VIDC_REG_979942_ADDR, m) +#define VIDC_REG_979942_OUT(v) \ + out_dword(VIDC_REG_979942_ADDR, v) +#define VIDC_REG_979942_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_979942_ADDR, m, v, \ + VIDC_REG_979942_IN); \ +} while (0) +#define VIDC_REG_979942_DB_STT_ADDR_BMSK 0xffffffff +#define VIDC_REG_979942_DB_STT_ADDR_SHFT 0 + +#define VIDC_REG_839021_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000300) +#define VIDC_REG_839021_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000300) +#define VIDC_REG_839021_RMSK 0xff1f +#define VIDC_REG_839021_SHFT 0 +#define VIDC_REG_839021_IN \ + in_dword_masked(VIDC_REG_839021_ADDR, VIDC_REG_839021_RMSK) +#define VIDC_REG_839021_INM(m) \ + in_dword_masked(VIDC_REG_839021_ADDR, m) +#define VIDC_REG_839021_OUT(v) \ + out_dword(VIDC_REG_839021_ADDR, v) +#define VIDC_REG_839021_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_839021_ADDR, m, v, \ + VIDC_REG_839021_IN); \ +} while (0) +#define VIDC_REG_839021_LEVEL_BMSK 0xff00 +#define VIDC_REG_839021_LEVEL_SHFT 0x8 +#define VIDC_REG_839021_PROFILE_BMSK 0x1f +#define VIDC_REG_839021_PROFILE_SHFT 0 + +#define VIDC_REG_950374_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000308) +#define VIDC_REG_950374_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000308) +#define VIDC_REG_950374_RMSK 0xffff +#define VIDC_REG_950374_SHFT 0 +#define VIDC_REG_950374_IN \ + in_dword_masked(VIDC_REG_950374_ADDR, \ + VIDC_REG_950374_RMSK) +#define VIDC_REG_950374_INM(m) \ + in_dword_masked(VIDC_REG_950374_ADDR, m) +#define VIDC_REG_950374_OUT(v) \ + out_dword(VIDC_REG_950374_ADDR, v) +#define VIDC_REG_950374_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_950374_ADDR, m, v, \ + VIDC_REG_950374_IN); \ +} while (0) +#define VIDC_REG_950374_I_PERIOD_BMSK 0xffff +#define VIDC_REG_950374_I_PERIOD_SHFT 0 + +#define VIDC_REG_504878_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000310) +#define VIDC_REG_504878_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000310) +#define VIDC_REG_504878_RMSK 0xd +#define VIDC_REG_504878_SHFT 0 +#define VIDC_REG_504878_IN \ + in_dword_masked(VIDC_REG_504878_ADDR, \ + VIDC_REG_504878_RMSK) +#define VIDC_REG_504878_INM(m) \ + in_dword_masked(VIDC_REG_504878_ADDR, m) +#define VIDC_REG_504878_OUT(v) \ + out_dword(VIDC_REG_504878_ADDR, v) +#define VIDC_REG_504878_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_504878_ADDR, m, v, \ + VIDC_REG_504878_IN); \ +} while (0) +#define VIDC_REG_504878_FIXED_NUMBER_BMSK 0xc +#define VIDC_REG_504878_FIXED_NUMBER_SHFT 0x2 +#define VIDC_REG_504878_ENTROPY_SEL_BMSK 0x1 +#define VIDC_REG_504878_ENTROPY_SEL_SHFT 0 + +#define VIDC_REG_458130_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000314) +#define VIDC_REG_458130_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000314) +#define VIDC_REG_458130_RMSK 0xfff +#define VIDC_REG_458130_SHFT 0 +#define VIDC_REG_458130_IN \ + in_dword_masked(VIDC_REG_458130_ADDR, \ + VIDC_REG_458130_RMSK) +#define VIDC_REG_458130_INM(m) \ + in_dword_masked(VIDC_REG_458130_ADDR, m) +#define VIDC_REG_458130_OUT(v) \ + out_dword(VIDC_REG_458130_ADDR, v) +#define VIDC_REG_458130_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_458130_ADDR, m, v, \ + VIDC_REG_458130_IN); \ +} while (0) +#define VIDC_REG_458130_SLICE_ALPHA_C0_OFFSET_DIV2_BMSK \ + 0xf80 +#define VIDC_REG_458130_SLICE_ALPHA_C0_OFFSET_DIV2_SHFT \ + 0x7 +#define VIDC_REG_458130_SLICE_BETA_OFFSET_DIV2_BMSK 0x7c +#define VIDC_REG_458130_SLICE_BETA_OFFSET_DIV2_SHFT 0x2 +#define \ + \ +VIDC_REG_458130_DISABLE_DEBLOCKING_FILTER_IDC_BMSK 0x3 +#define \ + \ +VIDC_REG_458130_DISABLE_DEBLOCKING_FILTER_IDC_SHFT 0 + +#define VIDC_REG_314290_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000318) +#define VIDC_REG_314290_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000318) +#define VIDC_REG_314290_RMSK 0x1 +#define VIDC_REG_314290_SHFT 0 +#define VIDC_REG_314290_IN \ + in_dword_masked(VIDC_REG_314290_ADDR, \ + VIDC_REG_314290_RMSK) +#define VIDC_REG_314290_INM(m) \ + in_dword_masked(VIDC_REG_314290_ADDR, m) +#define VIDC_REG_314290_OUT(v) \ + out_dword(VIDC_REG_314290_ADDR, v) +#define VIDC_REG_314290_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_314290_ADDR, m, v, \ + VIDC_REG_314290_IN); \ +} while (0) +#define VIDC_REG_314290_SHORT_HD_ON_BMSK 0x1 +#define VIDC_REG_314290_SHORT_HD_ON_SHFT 0 + +#define VIDC_REG_588301_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x0000031c) +#define VIDC_REG_588301_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000031c) +#define VIDC_REG_588301_RMSK 0x1 +#define VIDC_REG_588301_SHFT 0 +#define VIDC_REG_588301_IN \ + in_dword_masked(VIDC_REG_588301_ADDR, \ + VIDC_REG_588301_RMSK) +#define VIDC_REG_588301_INM(m) \ + in_dword_masked(VIDC_REG_588301_ADDR, m) +#define VIDC_REG_588301_OUT(v) \ + out_dword(VIDC_REG_588301_ADDR, v) +#define VIDC_REG_588301_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_588301_ADDR, m, v, \ + VIDC_REG_588301_IN); \ +} while (0) +#define VIDC_REG_588301_MSLICE_ENA_BMSK 0x1 +#define VIDC_REG_588301_MSLICE_ENA_SHFT 0 + +#define VIDC_REG_1517_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000320) +#define VIDC_REG_1517_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000320) +#define VIDC_REG_1517_RMSK 0x3 +#define VIDC_REG_1517_SHFT 0 +#define VIDC_REG_1517_IN \ + in_dword_masked(VIDC_REG_1517_ADDR, \ + VIDC_REG_1517_RMSK) +#define VIDC_REG_1517_INM(m) \ + in_dword_masked(VIDC_REG_1517_ADDR, m) +#define VIDC_REG_1517_OUT(v) \ + out_dword(VIDC_REG_1517_ADDR, v) +#define VIDC_REG_1517_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_1517_ADDR, m, v, \ + VIDC_REG_1517_IN); \ +} while (0) +#define VIDC_REG_1517_MSLICE_SEL_BMSK 0x3 +#define VIDC_REG_1517_MSLICE_SEL_SHFT 0 + +#define VIDC_REG_105335_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000324) +#define VIDC_REG_105335_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000324) +#define VIDC_REG_105335_RMSK 0xffffffff +#define VIDC_REG_105335_SHFT 0 +#define VIDC_REG_105335_IN \ + in_dword_masked(VIDC_REG_105335_ADDR, \ + VIDC_REG_105335_RMSK) +#define VIDC_REG_105335_INM(m) \ + in_dword_masked(VIDC_REG_105335_ADDR, m) +#define VIDC_REG_105335_OUT(v) \ + out_dword(VIDC_REG_105335_ADDR, v) +#define VIDC_REG_105335_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_105335_ADDR, m, v, \ + VIDC_REG_105335_IN); \ +} while (0) +#define VIDC_REG_105335_MSLICE_MB_BMSK 0xffffffff +#define VIDC_REG_105335_MSLICE_MB_SHFT 0 + +#define VIDC_REG_561679_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000328) +#define VIDC_REG_561679_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000328) +#define VIDC_REG_561679_RMSK 0xffffffff +#define VIDC_REG_561679_SHFT 0 +#define VIDC_REG_561679_IN \ + in_dword_masked(VIDC_REG_561679_ADDR, \ + VIDC_REG_561679_RMSK) +#define VIDC_REG_561679_INM(m) \ + in_dword_masked(VIDC_REG_561679_ADDR, m) +#define VIDC_REG_561679_OUT(v) \ + out_dword(VIDC_REG_561679_ADDR, v) +#define VIDC_REG_561679_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_561679_ADDR, m, v, \ + VIDC_REG_561679_IN); \ +} while (0) +#define VIDC_REG_561679_MSLICE_BYTE_BMSK 0xffffffff +#define VIDC_REG_561679_MSLICE_BYTE_SHFT 0 + +#define VIDC_REG_151345_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000400) +#define VIDC_REG_151345_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000400) +#define VIDC_REG_151345_RMSK 0xffffffff +#define VIDC_REG_151345_SHFT 0 +#define VIDC_REG_151345_IN \ + in_dword_masked(VIDC_REG_151345_ADDR, \ + VIDC_REG_151345_RMSK) +#define VIDC_REG_151345_INM(m) \ + in_dword_masked(VIDC_REG_151345_ADDR, m) +#define VIDC_REG_151345_DISPLAY_Y_ADR_BMSK 0xffffffff +#define VIDC_REG_151345_DISPLAY_Y_ADR_SHFT 0 + +#define VIDC_REG_293983_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000404) +#define VIDC_REG_293983_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000404) +#define VIDC_REG_293983_RMSK 0xffffffff +#define VIDC_REG_293983_SHFT 0 +#define VIDC_REG_293983_IN \ + in_dword_masked(VIDC_REG_293983_ADDR, \ + VIDC_REG_293983_RMSK) +#define VIDC_REG_293983_INM(m) \ + in_dword_masked(VIDC_REG_293983_ADDR, m) +#define VIDC_REG_293983_DISPLAY_C_ADR_BMSK 0xffffffff +#define VIDC_REG_293983_DISPLAY_C_ADR_SHFT 0 + +#define VIDC_REG_612715_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000408) +#define VIDC_REG_612715_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000408) +#define VIDC_REG_612715_RMSK 0x3f +#define VIDC_REG_612715_SHFT 0 +#define VIDC_REG_612715_IN \ + in_dword_masked(VIDC_REG_612715_ADDR, \ + VIDC_REG_612715_RMSK) +#define VIDC_REG_612715_INM(m) \ + in_dword_masked(VIDC_REG_612715_ADDR, m) +#define VIDC_REG_612715_DISPLAY_STATUS_BMSK 0x3f +#define VIDC_REG_612715_DISPLAY_STATUS_SHFT 0 + +#define VIDC_REG_209364_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x0000040c) +#define VIDC_REG_209364_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000040c) +#define VIDC_REG_209364_RMSK 0x1 +#define VIDC_REG_209364_SHFT 0 +#define VIDC_REG_209364_IN \ + in_dword_masked(VIDC_REG_209364_ADDR, \ + VIDC_REG_209364_RMSK) +#define VIDC_REG_209364_INM(m) \ + in_dword_masked(VIDC_REG_209364_ADDR, m) +#define VIDC_REG_209364_HEADER_DONE_BMSK 0x1 +#define VIDC_REG_209364_HEADER_DONE_SHFT 0 + +#define VIDC_REG_757835_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000410) +#define VIDC_REG_757835_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000410) +#define VIDC_REG_757835_RMSK 0xffffffff +#define VIDC_REG_757835_SHFT 0 +#define VIDC_REG_757835_IN \ + in_dword_masked(VIDC_REG_757835_ADDR, \ + VIDC_REG_757835_RMSK) +#define VIDC_REG_757835_INM(m) \ + in_dword_masked(VIDC_REG_757835_ADDR, m) +#define VIDC_REG_757835_FRAME_NUM_BMSK 0xffffffff +#define VIDC_REG_757835_FRAME_NUM_SHFT 0 + +#define VIDC_REG_352831_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000414) +#define VIDC_REG_352831_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000414) +#define VIDC_REG_352831_RMSK 0xffffffff +#define VIDC_REG_352831_SHFT 0 +#define VIDC_REG_352831_IN \ + in_dword_masked(VIDC_REG_352831_ADDR, \ + VIDC_REG_352831_RMSK) +#define VIDC_REG_352831_INM(m) \ + in_dword_masked(VIDC_REG_352831_ADDR, m) +#define VIDC_REG_352831_DBG_INFO_OUTPUT0_BMSK 0xffffffff +#define VIDC_REG_352831_DBG_INFO_OUTPUT0_SHFT 0 + +#define VIDC_REG_668634_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000418) +#define VIDC_REG_668634_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000418) +#define VIDC_REG_668634_RMSK 0xffffffff +#define VIDC_REG_668634_SHFT 0 +#define VIDC_REG_668634_IN \ + in_dword_masked(VIDC_REG_668634_ADDR, \ + VIDC_REG_668634_RMSK) +#define VIDC_REG_668634_INM(m) \ + in_dword_masked(VIDC_REG_668634_ADDR, m) +#define VIDC_REG_668634_DBG_INFO_OUTPUT1_BMSK 0xffffffff +#define VIDC_REG_668634_DBG_INFO_OUTPUT1_SHFT 0 + +#define VIDC_REG_609676_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000500) +#define VIDC_REG_609676_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000500) +#define VIDC_REG_609676_RMSK 0x1 +#define VIDC_REG_609676_SHFT 0 +#define VIDC_REG_609676_IN \ + in_dword_masked(VIDC_REG_609676_ADDR, VIDC_REG_609676_RMSK) +#define VIDC_REG_609676_INM(m) \ + in_dword_masked(VIDC_REG_609676_ADDR, m) +#define VIDC_REG_609676_OUT(v) \ + out_dword(VIDC_REG_609676_ADDR, v) +#define VIDC_REG_609676_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_609676_ADDR, m, v, \ + VIDC_REG_609676_IN); \ +} while (0) +#define VIDC_REG_609676_INT_OFF_BMSK 0x1 +#define VIDC_REG_609676_INT_OFF_SHFT 0 + +#define VIDC_REG_491082_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000504) +#define VIDC_REG_491082_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000504) +#define VIDC_REG_491082_RMSK 0x1 +#define VIDC_REG_491082_SHFT 0 +#define VIDC_REG_491082_IN \ + in_dword_masked(VIDC_REG_491082_ADDR, \ + VIDC_REG_491082_RMSK) +#define VIDC_REG_491082_INM(m) \ + in_dword_masked(VIDC_REG_491082_ADDR, m) +#define VIDC_REG_491082_OUT(v) \ + out_dword(VIDC_REG_491082_ADDR, v) +#define VIDC_REG_491082_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_491082_ADDR, m, v, \ + VIDC_REG_491082_IN); \ +} while (0) +#define VIDC_REG_491082_INT_PULSE_SEL_BMSK 0x1 +#define VIDC_REG_491082_INT_PULSE_SEL_SHFT 0 + +#define VIDC_REG_614776_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000508) +#define VIDC_REG_614776_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000508) +#define VIDC_REG_614776_RMSK 0x1 +#define VIDC_REG_614776_SHFT 0 +#define VIDC_REG_614776_IN \ + in_dword_masked(VIDC_REG_614776_ADDR, \ + VIDC_REG_614776_RMSK) +#define VIDC_REG_614776_INM(m) \ + in_dword_masked(VIDC_REG_614776_ADDR, m) +#define VIDC_REG_614776_OUT(v) \ + out_dword(VIDC_REG_614776_ADDR, v) +#define VIDC_REG_614776_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_614776_ADDR, m, v, \ + VIDC_REG_614776_IN); \ +} while (0) +#define VIDC_REG_614776_INT_DONE_CLEAR_BMSK 0x1 +#define VIDC_REG_614776_INT_DONE_CLEAR_SHFT 0 + +#define VIDC_REG_982553_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x0000050c) +#define VIDC_REG_982553_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000050c) +#define VIDC_REG_982553_RMSK 0x1 +#define VIDC_REG_982553_SHFT 0 +#define VIDC_REG_982553_IN \ + in_dword_masked(VIDC_REG_982553_ADDR, \ + VIDC_REG_982553_RMSK) +#define VIDC_REG_982553_INM(m) \ + in_dword_masked(VIDC_REG_982553_ADDR, m) +#define VIDC_REG_982553_OPERATION_DONE_BMSK 0x1 +#define VIDC_REG_982553_OPERATION_DONE_SHFT 0 + +#define VIDC_REG_259967_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000510) +#define VIDC_REG_259967_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000510) +#define VIDC_REG_259967_RMSK 0x1 +#define VIDC_REG_259967_SHFT 0 +#define VIDC_REG_259967_IN \ + in_dword_masked(VIDC_REG_259967_ADDR, VIDC_REG_259967_RMSK) +#define VIDC_REG_259967_INM(m) \ + in_dword_masked(VIDC_REG_259967_ADDR, m) +#define VIDC_REG_259967_FW_DONE_BMSK 0x1 +#define VIDC_REG_259967_FW_DONE_SHFT 0 + +#define VIDC_REG_512143_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000514) +#define VIDC_REG_512143_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000514) +#define VIDC_REG_512143_RMSK 0x1f8 +#define VIDC_REG_512143_SHFT 0 +#define VIDC_REG_512143_IN \ + in_dword_masked(VIDC_REG_512143_ADDR, \ + VIDC_REG_512143_RMSK) +#define VIDC_REG_512143_INM(m) \ + in_dword_masked(VIDC_REG_512143_ADDR, m) +#define VIDC_REG_512143_FRAME_DONE_STAT_BMSK 0x100 +#define VIDC_REG_512143_FRAME_DONE_STAT_SHFT 0x8 +#define VIDC_REG_512143_DMA_DONE_STAT_BMSK 0x80 +#define VIDC_REG_512143_DMA_DONE_STAT_SHFT 0x7 +#define VIDC_REG_512143_HEADER_DONE_STAT_BMSK 0x40 +#define VIDC_REG_512143_HEADER_DONE_STAT_SHFT 0x6 +#define VIDC_REG_512143_FW_DONE_STAT_BMSK 0x20 +#define VIDC_REG_512143_FW_DONE_STAT_SHFT 0x5 +#define VIDC_REG_512143_OPERATION_FAILED_BMSK 0x10 +#define VIDC_REG_512143_OPERATION_FAILED_SHFT 0x4 +#define VIDC_REG_512143_STREAM_HDR_CHANGED_BMSK 0x8 +#define VIDC_REG_512143_STREAM_HDR_CHANGED_SHFT 0x3 + +#define VIDC_REG_418173_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000518) +#define VIDC_REG_418173_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000518) +#define VIDC_REG_418173_RMSK 0x1fa +#define VIDC_REG_418173_SHFT 0 +#define VIDC_REG_418173_IN \ + in_dword_masked(VIDC_REG_418173_ADDR, \ + VIDC_REG_418173_RMSK) +#define VIDC_REG_418173_INM(m) \ + in_dword_masked(VIDC_REG_418173_ADDR, m) +#define VIDC_REG_418173_OUT(v) \ + out_dword(VIDC_REG_418173_ADDR, v) +#define VIDC_REG_418173_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_418173_ADDR, m, v, \ + VIDC_REG_418173_IN); \ +} while (0) +#define VIDC_REG_418173_FRAME_DONE_ENABLE_BMSK 0x100 +#define VIDC_REG_418173_FRAME_DONE_ENABLE_SHFT 0x8 +#define VIDC_REG_418173_DMA_DONE_ENABLE_BMSK 0x80 +#define VIDC_REG_418173_DMA_DONE_ENABLE_SHFT 0x7 +#define VIDC_REG_418173_HEADER_DONE_ENABLE_BMSK 0x40 +#define VIDC_REG_418173_HEADER_DONE_ENABLE_SHFT 0x6 +#define VIDC_REG_418173_FW_DONE_ENABLE_BMSK 0x20 +#define VIDC_REG_418173_FW_DONE_ENABLE_SHFT 0x5 +#define VIDC_REG_418173_OPERATION_FAILED_ENABLE_BMSK 0x10 +#define VIDC_REG_418173_OPERATION_FAILED_ENABLE_SHFT 0x4 +#define VIDC_REG_418173_STREAM_HDR_CHANGED_ENABLE_BMSK 0x8 +#define VIDC_REG_418173_STREAM_HDR_CHANGED_ENABLE_SHFT 0x3 +#define VIDC_REG_418173_BUFFER_FULL_ENABLE_BMSK 0x2 +#define VIDC_REG_418173_BUFFER_FULL_ENABLE_SHFT 0x1 + +#define VIDC_REG_841539_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000600) +#define VIDC_REG_841539_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000600) +#define VIDC_REG_841539_RMSK 0x3 +#define VIDC_REG_841539_SHFT 0 +#define VIDC_REG_841539_IN \ + in_dword_masked(VIDC_REG_841539_ADDR, \ + VIDC_REG_841539_RMSK) +#define VIDC_REG_841539_INM(m) \ + in_dword_masked(VIDC_REG_841539_ADDR, m) +#define VIDC_REG_841539_OUT(v) \ + out_dword(VIDC_REG_841539_ADDR, v) +#define VIDC_REG_841539_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_841539_ADDR, m, v, \ + VIDC_REG_841539_IN); \ +} while (0) +#define VIDC_REG_841539_TILE_MODE_BMSK 0x3 +#define VIDC_REG_841539_TILE_MODE_SHFT 0 + +#define VIDC_REG_99105_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000800) +#define VIDC_REG_99105_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000800) +#define VIDC_REG_99105_RMSK 0xffffffff +#define VIDC_REG_99105_SHFT 0 +#define VIDC_REG_99105_IN \ + in_dword_masked(VIDC_REG_99105_ADDR, \ + VIDC_REG_99105_RMSK) +#define VIDC_REG_99105_INM(m) \ + in_dword_masked(VIDC_REG_99105_ADDR, m) +#define VIDC_REG_99105_OUT(v) \ + out_dword(VIDC_REG_99105_ADDR, v) +#define VIDC_REG_99105_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_99105_ADDR, m, v, \ + VIDC_REG_99105_IN); \ +} while (0) +#define VIDC_REG_99105_ENC_CUR_Y_ADDR_BMSK 0xffffffff +#define VIDC_REG_99105_ENC_CUR_Y_ADDR_SHFT 0 + +#define VIDC_REG_777113_ADDR_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000804) +#define VIDC_REG_777113_ADDR_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000804) +#define VIDC_REG_777113_ADDR_RMSK 0xffffffff +#define VIDC_REG_777113_ADDR_SHFT 0 +#define VIDC_REG_777113_ADDR_IN \ + in_dword_masked(VIDC_REG_777113_ADDR_ADDR, \ + VIDC_REG_777113_ADDR_RMSK) +#define VIDC_REG_777113_ADDR_INM(m) \ + in_dword_masked(VIDC_REG_777113_ADDR_ADDR, m) +#define VIDC_REG_777113_ADDR_OUT(v) \ + out_dword(VIDC_REG_777113_ADDR_ADDR, v) +#define VIDC_REG_777113_ADDR_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_777113_ADDR_ADDR, m, v, \ + VIDC_REG_777113_ADDR_IN); \ +} while (0) +#define VIDC_REG_777113_ADDR_ENC_CUR_C_ADDR_BMSK 0xffffffff +#define VIDC_REG_777113_ADDR_ENC_CUR_C_ADDR_SHFT 0 + +#define VIDC_REG_341928_ADDR_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x0000080c) +#define VIDC_REG_341928_ADDR_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000080c) +#define VIDC_REG_341928_ADDR_RMSK 0xffffffff +#define VIDC_REG_341928_ADDR_SHFT 0 +#define VIDC_REG_341928_ADDR_IN \ + in_dword_masked(VIDC_REG_341928_ADDR_ADDR, \ + VIDC_REG_341928_ADDR_RMSK) +#define VIDC_REG_341928_ADDR_INM(m) \ + in_dword_masked(VIDC_REG_341928_ADDR_ADDR, m) +#define VIDC_REG_341928_ADDR_OUT(v) \ + out_dword(VIDC_REG_341928_ADDR_ADDR, v) +#define VIDC_REG_341928_ADDR_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_341928_ADDR_ADDR, m, v, \ + VIDC_REG_341928_ADDR_IN); \ +} while (0) +#define VIDC_REG_341928_ADDR_ENC_DPB_ADR_BMSK 0xffffffff +#define VIDC_REG_341928_ADDR_ENC_DPB_ADR_SHFT 0 + +#define VIDC_REG_857491_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000810) +#define VIDC_REG_857491_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000810) +#define VIDC_REG_857491_RMSK 0xfff +#define VIDC_REG_857491_SHFT 0 +#define VIDC_REG_857491_IN \ + in_dword_masked(VIDC_REG_857491_ADDR, \ + VIDC_REG_857491_RMSK) +#define VIDC_REG_857491_INM(m) \ + in_dword_masked(VIDC_REG_857491_ADDR, m) +#define VIDC_REG_857491_OUT(v) \ + out_dword(VIDC_REG_857491_ADDR, v) +#define VIDC_REG_857491_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_857491_ADDR, m, v, \ + VIDC_REG_857491_IN); \ +} while (0) +#define VIDC_REG_857491_CIR_MB_NUM_BMSK 0xfff +#define VIDC_REG_857491_CIR_MB_NUM_SHFT 0 + +#define VIDC_REG_518133_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000900) +#define VIDC_REG_518133_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000900) +#define VIDC_REG_518133_RMSK 0xffffffff +#define VIDC_REG_518133_SHFT 0 +#define VIDC_REG_518133_IN \ + in_dword_masked(VIDC_REG_518133_ADDR, \ + VIDC_REG_518133_RMSK) +#define VIDC_REG_518133_INM(m) \ + in_dword_masked(VIDC_REG_518133_ADDR, m) +#define VIDC_REG_518133_OUT(v) \ + out_dword(VIDC_REG_518133_ADDR, v) +#define VIDC_REG_518133_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_518133_ADDR, m, v, \ + VIDC_REG_518133_IN); \ +} while (0) +#define VIDC_REG_518133_DEC_DPB_ADDR_BMSK 0xffffffff +#define VIDC_REG_518133_DEC_DPB_ADDR_SHFT 0 + +#define VIDC_REG_456376_ADDR_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000904) +#define VIDC_REG_456376_ADDR_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000904) +#define VIDC_REG_456376_ADDR_RMSK 0xffffffff +#define VIDC_REG_456376_ADDR_SHFT 0 +#define VIDC_REG_456376_ADDR_IN \ + in_dword_masked(VIDC_REG_456376_ADDR_ADDR, \ + VIDC_REG_456376_ADDR_RMSK) +#define VIDC_REG_456376_ADDR_INM(m) \ + in_dword_masked(VIDC_REG_456376_ADDR_ADDR, m) +#define VIDC_REG_456376_ADDR_OUT(v) \ + out_dword(VIDC_REG_456376_ADDR_ADDR, v) +#define VIDC_REG_456376_ADDR_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_456376_ADDR_ADDR, m, v, \ + VIDC_REG_456376_ADDR_IN); \ +} while (0) +#define VIDC_REG_456376_ADDR_DPB_COMV_ADDR_BMSK 0xffffffff +#define VIDC_REG_456376_ADDR_DPB_COMV_ADDR_SHFT 0 + +#define VIDC_REG_267567_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000908) +#define VIDC_REG_267567_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000908) +#define VIDC_REG_267567_RMSK 0xffffffff +#define VIDC_REG_267567_SHFT 0 +#define VIDC_REG_267567_IN \ + in_dword_masked(VIDC_REG_267567_ADDR, \ + VIDC_REG_267567_RMSK) +#define VIDC_REG_267567_INM(m) \ + in_dword_masked(VIDC_REG_267567_ADDR, m) +#define VIDC_REG_267567_OUT(v) \ + out_dword(VIDC_REG_267567_ADDR, v) +#define VIDC_REG_267567_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_267567_ADDR, m, v, \ + VIDC_REG_267567_IN); \ +} while (0) +#define VIDC_REG_798486_ADDR_BMSK 0xffffffff +#define VIDC_REG_798486_ADDR_SHFT 0 + +#define VIDC_REG_105770_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x0000090c) +#define VIDC_REG_105770_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x0000090c) +#define VIDC_REG_105770_RMSK 0xff +#define VIDC_REG_105770_SHFT 0 +#define VIDC_REG_105770_IN \ + in_dword_masked(VIDC_REG_105770_ADDR, \ + VIDC_REG_105770_RMSK) +#define VIDC_REG_105770_INM(m) \ + in_dword_masked(VIDC_REG_105770_ADDR, m) +#define VIDC_REG_105770_DPB_SIZE_BMSK 0xff +#define VIDC_REG_105770_DPB_SIZE_SHFT 0 + +#define VIDC_REG_58211_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000a00) +#define VIDC_REG_58211_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000a00) +#define VIDC_REG_58211_RMSK 0x33f +#define VIDC_REG_58211_SHFT 0 +#define VIDC_REG_58211_IN \ + in_dword_masked(VIDC_REG_58211_ADDR, \ + VIDC_REG_58211_RMSK) +#define VIDC_REG_58211_INM(m) \ + in_dword_masked(VIDC_REG_58211_ADDR, m) +#define VIDC_REG_58211_OUT(v) \ + out_dword(VIDC_REG_58211_ADDR, v) +#define VIDC_REG_58211_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_58211_ADDR, m, v, \ + VIDC_REG_58211_IN); \ +} while (0) +#define VIDC_REG_58211_FR_RC_EN_BMSK 0x200 +#define VIDC_REG_58211_FR_RC_EN_SHFT 0x9 +#define VIDC_REG_58211_MB_RC_EN_BMSK 0x100 +#define VIDC_REG_58211_MB_RC_EN_SHFT 0x8 +#define VIDC_REG_58211_FRAME_QP_BMSK 0x3f +#define VIDC_REG_58211_FRAME_QP_SHFT 0 + +#define VIDC_REG_548359_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000a04) +#define VIDC_REG_548359_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000a04) +#define VIDC_REG_548359_RMSK 0x3f +#define VIDC_REG_548359_SHFT 0 +#define VIDC_REG_548359_IN \ + in_dword_masked(VIDC_REG_548359_ADDR, \ + VIDC_REG_548359_RMSK) +#define VIDC_REG_548359_INM(m) \ + in_dword_masked(VIDC_REG_548359_ADDR, m) +#define VIDC_REG_548359_OUT(v) \ + out_dword(VIDC_REG_548359_ADDR, v) +#define VIDC_REG_548359_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_548359_ADDR, m, v, \ + VIDC_REG_548359_IN); \ +} while (0) +#define VIDC_REG_548359_P_FRAME_QP_BMSK 0x3f +#define VIDC_REG_548359_P_FRAME_QP_SHFT 0 + +#define VIDC_REG_174150_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000a08) +#define VIDC_REG_174150_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000a08) +#define VIDC_REG_174150_RMSK 0xffffffff +#define VIDC_REG_174150_SHFT 0 +#define VIDC_REG_174150_IN \ + in_dword_masked(VIDC_REG_174150_ADDR, \ + VIDC_REG_174150_RMSK) +#define VIDC_REG_174150_INM(m) \ + in_dword_masked(VIDC_REG_174150_ADDR, m) +#define VIDC_REG_174150_OUT(v) \ + out_dword(VIDC_REG_174150_ADDR, v) +#define VIDC_REG_174150_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_174150_ADDR, m, v, \ + VIDC_REG_174150_IN); \ +} while (0) +#define VIDC_REG_174150_BIT_RATE_BMSK 0xffffffff +#define VIDC_REG_174150_BIT_RATE_SHFT 0 + +#define VIDC_REG_734318_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000a0c) +#define VIDC_REG_734318_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000a0c) +#define VIDC_REG_734318_RMSK 0x3f3f +#define VIDC_REG_734318_SHFT 0 +#define VIDC_REG_734318_IN \ + in_dword_masked(VIDC_REG_734318_ADDR, \ + VIDC_REG_734318_RMSK) +#define VIDC_REG_734318_INM(m) \ + in_dword_masked(VIDC_REG_734318_ADDR, m) +#define VIDC_REG_734318_OUT(v) \ + out_dword(VIDC_REG_734318_ADDR, v) +#define VIDC_REG_734318_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_734318_ADDR, m, v, \ + VIDC_REG_734318_IN); \ +} while (0) +#define VIDC_REG_734318_MAX_QP_BMSK 0x3f00 +#define VIDC_REG_734318_MAX_QP_SHFT 0x8 +#define VIDC_REG_734318_MIN_QP_BMSK 0x3f +#define VIDC_REG_734318_MIN_QP_SHFT 0 + +#define VIDC_REG_677784_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000a10) +#define VIDC_REG_677784_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000a10) +#define VIDC_REG_677784_RMSK 0xffff +#define VIDC_REG_677784_SHFT 0 +#define VIDC_REG_677784_IN \ + in_dword_masked(VIDC_REG_677784_ADDR, \ + VIDC_REG_677784_RMSK) +#define VIDC_REG_677784_INM(m) \ + in_dword_masked(VIDC_REG_677784_ADDR, m) +#define VIDC_REG_677784_OUT(v) \ + out_dword(VIDC_REG_677784_ADDR, v) +#define VIDC_REG_677784_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_677784_ADDR, m, v, \ + VIDC_REG_677784_IN); \ +} while (0) +#define VIDC_REG_677784_REACT_PARA_BMSK 0xffff +#define VIDC_REG_677784_REACT_PARA_SHFT 0 + +#define VIDC_REG_995041_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000a14) +#define VIDC_REG_995041_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000a14) +#define VIDC_REG_995041_RMSK 0xf +#define VIDC_REG_995041_SHFT 0 +#define VIDC_REG_995041_IN \ + in_dword_masked(VIDC_REG_995041_ADDR, \ + VIDC_REG_995041_RMSK) +#define VIDC_REG_995041_INM(m) \ + in_dword_masked(VIDC_REG_995041_ADDR, m) +#define VIDC_REG_995041_OUT(v) \ + out_dword(VIDC_REG_995041_ADDR, v) +#define VIDC_REG_995041_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_995041_ADDR, m, v, \ + VIDC_REG_995041_IN); \ +} while (0) +#define VIDC_REG_995041_DARK_DISABLE_BMSK 0x8 +#define VIDC_REG_995041_DARK_DISABLE_SHFT 0x3 +#define VIDC_REG_995041_SMOOTH_DISABLE_BMSK 0x4 +#define VIDC_REG_995041_SMOOTH_DISABLE_SHFT 0x2 +#define VIDC_REG_995041_STATIC_DISABLE_BMSK 0x2 +#define VIDC_REG_995041_STATIC_DISABLE_SHFT 0x1 +#define VIDC_REG_995041_ACT_DISABLE_BMSK 0x1 +#define VIDC_REG_995041_ACT_DISABLE_SHFT 0 + +#define VIDC_REG_273649_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000a18) +#define VIDC_REG_273649_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000a18) +#define VIDC_REG_273649_RMSK 0x3f +#define VIDC_REG_273649_SHFT 0 +#define VIDC_REG_273649_IN \ + in_dword_masked(VIDC_REG_273649_ADDR, VIDC_REG_273649_RMSK) +#define VIDC_REG_273649_INM(m) \ + in_dword_masked(VIDC_REG_273649_ADDR, m) +#define VIDC_REG_273649_QP_OUT_BMSK 0x3f +#define VIDC_REG_273649_QP_OUT_SHFT 0 + +#define VIDC_REG_548823_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000b00) +#define VIDC_REG_548823_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000b00) +#define VIDC_REG_548823_RMSK 0xffffffff +#define VIDC_REG_548823_SHFT 0 +#define VIDC_REG_548823_IN \ + in_dword_masked(VIDC_REG_548823_ADDR, \ + VIDC_REG_548823_RMSK) +#define VIDC_REG_548823_INM(m) \ + in_dword_masked(VIDC_REG_548823_ADDR, m) +#define VIDC_REG_548823_720P_VERSION_BMSK 0xffffffff +#define VIDC_REG_548823_720P_VERSION_SHFT 0 + +#define VIDC_REG_881638_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000c00) +#define VIDC_REG_881638_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000c00) +#define VIDC_REG_881638_RMSK 0xffffffff +#define VIDC_REG_881638_SHFT 0 +#define VIDC_REG_881638_IN \ + in_dword_masked(VIDC_REG_881638_ADDR, \ + VIDC_REG_881638_RMSK) +#define VIDC_REG_881638_INM(m) \ + in_dword_masked(VIDC_REG_881638_ADDR, m) +#define VIDC_REG_881638_CROP_RIGHT_OFFSET_BMSK 0xffff0000 +#define VIDC_REG_881638_CROP_RIGHT_OFFSET_SHFT 0x10 +#define VIDC_REG_881638_CROP_LEFT_OFFSET_BMSK 0xffff +#define VIDC_REG_881638_CROP_LEFT_OFFSET_SHFT 0 + +#define VIDC_REG_161486_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000c04) +#define VIDC_REG_161486_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000c04) +#define VIDC_REG_161486_RMSK 0xffffffff +#define VIDC_REG_161486_SHFT 0 +#define VIDC_REG_161486_IN \ + in_dword_masked(VIDC_REG_161486_ADDR, \ + VIDC_REG_161486_RMSK) +#define VIDC_REG_161486_INM(m) \ + in_dword_masked(VIDC_REG_161486_ADDR, m) +#define VIDC_REG_161486_CROP_BOTTOM_OFFSET_BMSK 0xffff0000 +#define VIDC_REG_161486_CROP_BOTTOM_OFFSET_SHFT 0x10 +#define VIDC_REG_161486_CROP_TOP_OFFSET_BMSK 0xffff +#define VIDC_REG_161486_CROP_TOP_OFFSET_SHFT 0 + +#define VIDC_REG_580603_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000c08) +#define VIDC_REG_580603_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000c08) +#define VIDC_REG_580603_RMSK 0xffffffff +#define VIDC_REG_580603_SHFT 0 +#define VIDC_REG_580603_IN \ + in_dword_masked(VIDC_REG_580603_ADDR, \ + VIDC_REG_580603_RMSK) +#define VIDC_REG_580603_INM(m) \ + in_dword_masked(VIDC_REG_580603_ADDR, m) +#define VIDC_REG_580603_720P_DEC_FRM_SIZE_BMSK 0xffffffff +#define VIDC_REG_580603_720P_DEC_FRM_SIZE_SHFT 0 + + +#define VIDC_REG_606447_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000c0c) +#define VIDC_REG_606447_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000c0c) +#define VIDC_REG_606447_RMSK 0xff1f +#define VIDC_REG_606447_SHFT 0 +#define VIDC_REG_606447_IN \ + in_dword_masked(VIDC_REG_606447_ADDR, \ + VIDC_REG_606447_RMSK) +#define VIDC_REG_606447_INM(m) \ + in_dword_masked(VIDC_REG_606447_ADDR, m) +#define VIDC_REG_606447_OUT(v) \ + out_dword(VIDC_REG_606447_ADDR, v) +#define VIDC_REG_606447_OUTM(m, v) \ + out_dword_masked_ns(VIDC_REG_606447_ADDR, \ + m, v, VIDC_REG_606447_IN); \ + +#define VIDC_REG_606447_DIS_PIC_LEVEL_BMSK 0xff00 +#define VIDC_REG_606447_DIS_PIC_LEVEL_SHFT 0x8 +#define VIDC_REG_606447_DISP_PIC_PROFILE_BMSK 0x1f +#define VIDC_REG_606447_DISP_PIC_PROFILE_SHFT 0 + +#define VIDC_REG_854281_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000c10) +#define VIDC_REG_854281_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000c10) +#define VIDC_REG_854281_RMSK 0xffffffff +#define VIDC_REG_854281_SHFT 0 +#define VIDC_REG_854281_IN \ + in_dword_masked(VIDC_REG_854281_ADDR, \ + VIDC_REG_854281_RMSK) +#define VIDC_REG_854281_INM(m) \ + in_dword_masked(VIDC_REG_854281_ADDR, m) +#define VIDC_REG_854281_MIN_DPB_SIZE_BMSK 0xffffffff +#define VIDC_REG_854281_MIN_DPB_SIZE_SHFT 0 + + +#define VIDC_REG_381535_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000c14) +#define VIDC_REG_381535_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000c14) +#define VIDC_REG_381535_RMSK 0xffffffff +#define VIDC_REG_381535_SHFT 0 +#define VIDC_REG_381535_IN \ + in_dword_masked(VIDC_REG_381535_ADDR, \ + VIDC_REG_381535_RMSK) +#define VIDC_REG_381535_INM(m) \ + in_dword_masked(VIDC_REG_381535_ADDR, m) +#define VIDC_REG_381535_720P_FW_STATUS_BMSK 0xffffffff +#define VIDC_REG_381535_720P_FW_STATUS_SHFT 0 + + +#define VIDC_REG_347105_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000c18) +#define VIDC_REG_347105_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000c18) +#define VIDC_REG_347105_RMSK 0xffffffff +#define VIDC_REG_347105_SHFT 0 +#define VIDC_REG_347105_IN \ + in_dword_masked(VIDC_REG_347105_ADDR, \ + VIDC_REG_347105_RMSK) +#define VIDC_REG_347105_INM(m) \ + in_dword_masked(VIDC_REG_347105_ADDR, m) +#define VIDC_REG_347105_FREE_LUMA_DPB_BMSK 0xffffffff +#define VIDC_REG_347105_FREE_LUMA_DPB_SHFT 0 + + +#define VIDC_REG_62325_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000d00) +#define VIDC_REG_62325_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000d00) +#define VIDC_REG_62325_RMSK 0xf +#define VIDC_REG_62325_SHFT 0 +#define VIDC_REG_62325_IN \ + in_dword_masked(VIDC_REG_62325_ADDR, \ + VIDC_REG_62325_RMSK) +#define VIDC_REG_62325_INM(m) \ + in_dword_masked(VIDC_REG_62325_ADDR, m) +#define VIDC_REG_62325_OUT(v) \ + out_dword(VIDC_REG_62325_ADDR, v) +#define VIDC_REG_62325_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_62325_ADDR, m, v, \ + VIDC_REG_62325_IN); \ +} while (0) +#define VIDC_REG_62325_COMMAND_TYPE_BMSK 0xf +#define VIDC_REG_62325_COMMAND_TYPE_SHFT 0 + +#define VIDC_REG_101184_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000d04) +#define VIDC_REG_101184_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000d04) +#define VIDC_REG_101184_RMSK 0xffffffff +#define VIDC_REG_101184_SHFT 0 +#define VIDC_REG_101184_OUT(v) \ + out_dword(VIDC_REG_101184_ADDR, v) + +#define VIDC_REG_490443_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000d08) +#define VIDC_REG_490443_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000d08) +#define VIDC_REG_490443_RMSK \ + 0xffffffff +#define \ + \ +VIDC_REG_490443_SHFT 0 +#define VIDC_REG_490443_OUT(v) \ + out_dword(VIDC_REG_490443_ADDR, v) + +#define VIDC_REG_625444_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000d14) +#define VIDC_REG_625444_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000d14) +#define VIDC_REG_625444_RMSK 0xffffffff +#define VIDC_REG_625444_SHFT 0 +#define VIDC_REG_625444_IN \ + in_dword_masked(VIDC_REG_625444_ADDR, \ + VIDC_REG_625444_RMSK) +#define VIDC_REG_625444_INM(m) \ + in_dword_masked(VIDC_REG_625444_ADDR, m) +#define VIDC_REG_625444_OUT(v) \ + out_dword(VIDC_REG_625444_ADDR, v) +#define VIDC_REG_625444_OUTM(m, v) \ +do { \ + out_dword_masked_ns(VIDC_REG_625444_ADDR, m, v, \ + VIDC_REG_625444_IN); \ +} while (0) +#define VIDC_REG_625444_FRAME_RATE_BMSK 0xffffffff +#define VIDC_REG_625444_FRAME_RATE_SHFT 0 + +#define VIDC_REG_639999_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000d20) +#define VIDC_REG_639999_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000d20) +#define VIDC_REG_639999_RMSK 0xffff +#define VIDC_REG_639999_SHFT 0 +#define VIDC_REG_639999_OUT(v) \ + out_dword(VIDC_REG_639999_ADDR, v) + +#define VIDC_REG_64895_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000e00) +#define VIDC_REG_64895_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000e00) +#define VIDC_REG_64895_RMSK 0xffffffff +#define VIDC_REG_64895_SHFT 0 +#define VIDC_REG_64895_OUT(v) \ + out_dword(VIDC_REG_64895_ADDR, v) + +#define VIDC_REG_965480_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000e04) +#define VIDC_REG_965480_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000e04) +#define VIDC_REG_965480_RMSK 0x1 +#define VIDC_REG_965480_SHFT 0 +#define VIDC_REG_965480_OUT(v) \ + out_dword(VIDC_REG_965480_ADDR, v) + +#define VIDC_REG_804959_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000e08) +#define VIDC_REG_804959_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000e08) +#define VIDC_REG_804959_RMSK 0x7 +#define VIDC_REG_804959_SHFT 0 +#define VIDC_REG_804959_OUT(v) \ + out_dword(VIDC_REG_804959_ADDR, v) + +#define VIDC_REG_257463_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000e10) +#define VIDC_REG_257463_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000e10) +#define VIDC_REG_257463_RMSK 0xffffffff +#define VIDC_REG_257463_SHFT 0 +#define VIDC_REG_257463_IN \ + in_dword_masked(VIDC_REG_257463_ADDR, \ + VIDC_REG_257463_RMSK) +#define VIDC_REG_257463_INM(m) \ + in_dword_masked(VIDC_REG_257463_ADDR, m) +#define VIDC_REG_257463_MIN_NUM_DPB_BMSK 0xffffffff +#define VIDC_REG_257463_MIN_NUM_DPB_SHFT 0 + +#define VIDC_REG_883500_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000e14) +#define VIDC_REG_883500_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000e14) +#define VIDC_REG_883500_RMSK 0xffffffff +#define VIDC_REG_883500_SHFT 0 +#define VIDC_REG_883500_OUT(v) \ + out_dword(VIDC_REG_883500_ADDR, v) + +#define VIDC_REG_615716_ADDR(n) \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000e18 + 4 * (n)) +#define VIDC_REG_615716_PHYS(n) \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000e18 + 4 * (n)) +#define VIDC_REG_615716_RMSK 0xffffffff +#define VIDC_REG_615716_SHFT 0 +#define VIDC_REG_615716_OUTI(n, v) \ + out_dword(VIDC_REG_615716_ADDR(n), v) + +#define VIDC_REG_603032_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000e98) +#define VIDC_REG_603032_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000e98) +#define VIDC_REG_603032_RMSK 0xffffffff +#define VIDC_REG_603032_SHFT 0 +#define VIDC_REG_603032_OUT(v) \ + out_dword(VIDC_REG_603032_ADDR, v) + +#define VIDC_REG_300310_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000e9c) +#define VIDC_REG_300310_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000e9c) +#define VIDC_REG_300310_RMSK 0xffffffff +#define VIDC_REG_300310_SHFT 0 +#define VIDC_REG_300310_IN \ + in_dword_masked(VIDC_REG_300310_ADDR, \ + VIDC_REG_300310_RMSK) +#define VIDC_REG_300310_INM(m) \ + in_dword_masked(VIDC_REG_300310_ADDR, m) +#define VIDC_REG_300310_ERROR_STATUS_BMSK 0xffffffff +#define VIDC_REG_300310_ERROR_STATUS_SHFT 0 + +#define VIDC_REG_792026_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000ea0) +#define VIDC_REG_792026_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ea0) +#define VIDC_REG_792026_RMSK 0xffffffff +#define VIDC_REG_792026_SHFT 0 +#define VIDC_REG_792026_OUT(v) \ + out_dword(VIDC_REG_792026_ADDR, v) + +#define VIDC_REG_844152_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000ea4) +#define VIDC_REG_844152_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ea4) +#define VIDC_REG_844152_RMSK 0xffffffff +#define VIDC_REG_844152_SHFT 0 +#define VIDC_REG_844152_OUT(v) \ + out_dword(VIDC_REG_844152_ADDR, v) + +#define VIDC_REG_370409_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000ea8) +#define VIDC_REG_370409_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ea8) +#define VIDC_REG_370409_RMSK 0xffffffff +#define VIDC_REG_370409_SHFT 0 +#define VIDC_REG_370409_IN \ + in_dword_masked(VIDC_REG_370409_ADDR, \ + VIDC_REG_370409_RMSK) +#define VIDC_REG_370409_INM(m) \ + in_dword_masked(VIDC_REG_370409_ADDR, m) +#define VIDC_REG_370409_GET_FRAME_TAG_TOP_BMSK 0xffffffff +#define VIDC_REG_370409_GET_FRAME_TAG_TOP_SHFT 0 + +#define VIDC_REG_147682_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000eac) +#define VIDC_REG_147682_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000eac) +#define VIDC_REG_147682_RMSK 0x1 +#define VIDC_REG_147682_SHFT 0 +#define VIDC_REG_147682_OUT(v) \ + out_dword(VIDC_REG_147682_ADDR, v) + +#define VIDC_REG_407718_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000eb0) +#define VIDC_REG_407718_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000eb0) +#define VIDC_REG_407718_RMSK 0xffffffff +#define VIDC_REG_407718_SHFT 0 +#define VIDC_REG_407718_OUT(v) \ + out_dword(VIDC_REG_407718_ADDR, v) + +#define VIDC_REG_697961_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000eb4) +#define VIDC_REG_697961_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000eb4) +#define VIDC_REG_697961_RMSK 0x3 +#define VIDC_REG_697961_SHFT 0 +#define VIDC_REG_697961_IN \ + in_dword_masked(VIDC_REG_697961_ADDR, \ + VIDC_REG_697961_RMSK) +#define VIDC_REG_697961_INM(m) \ + in_dword_masked(VIDC_REG_697961_ADDR, m) +#define VIDC_REG_697961_FRAME_TYPE_BMSK 0x3 +#define VIDC_REG_697961_FRAME_TYPE_SHFT 0 + + +#define VIDC_REG_613254_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000eb8) +#define VIDC_REG_613254_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000eb8) +#define VIDC_REG_613254_RMSK 0x1 +#define VIDC_REG_613254_SHFT 0 +#define VIDC_REG_613254_IN \ + in_dword_masked(VIDC_REG_613254_ADDR, \ + VIDC_REG_613254_RMSK) +#define VIDC_REG_613254_INM(m) \ + in_dword_masked(VIDC_REG_613254_ADDR, m) +#define VIDC_REG_613254_METADATA_STATUS_BMSK 0x1 +#define VIDC_REG_613254_METADATA_STATUS_SHFT 0 +#define VIDC_REG_441270_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000ebc) +#define VIDC_REG_441270_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ebc) +#define VIDC_REG_441270_RMSK 0x1f +#define VIDC_REG_441270_SHFT 0 +#define VIDC_REG_441270_IN \ + in_dword_masked(VIDC_REG_441270_ADDR, \ + VIDC_REG_441270_RMSK) +#define VIDC_REG_441270_INM(m) \ + in_dword_masked(VIDC_REG_441270_ADDR, m) +#define VIDC_REG_441270_DATA_PARTITIONED_BMSK 0x8 +#define VIDC_REG_441270_DATA_PARTITIONED_SHFT 0x3 + +#define VIDC_REG_441270_FRAME_TYPE_BMSK 0x17 +#define VIDC_REG_441270_FRAME_TYPE_SHFT 0 + +#define VIDC_REG_724381_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000ec0) +#define VIDC_REG_724381_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ec0) +#define VIDC_REG_724381_RMSK 0x3 +#define VIDC_REG_724381_SHFT 0 +#define VIDC_REG_724381_IN \ + in_dword_masked(VIDC_REG_724381_ADDR, \ + VIDC_REG_724381_RMSK) +#define VIDC_REG_724381_INM(m) \ + in_dword_masked(VIDC_REG_724381_ADDR, m) +#define VIDC_REG_724381_MORE_FIELD_NEEDED_BMSK 0x4 +#define VIDC_REG_724381_MORE_FIELD_NEEDED_SHFT 0x2 +#define VIDC_REG_724381_OPERATION_FAILED_BMSK 0x2 +#define VIDC_REG_724381_OPERATION_FAILED_SHFT 0x1 +#define VIDC_REG_724381_RESOLUTION_CHANGE_BMSK 0x1 +#define VIDC_REG_724381_RESOLUTION_CHANGE_SHFT 0 + +#define VIDC_REG_854681_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000ec4) +#define VIDC_REG_854681_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ec4) +#define VIDC_REG_854681_RMSK 0x7f +#define VIDC_REG_854681_SHFT 0 +#define VIDC_REG_854681_OUT(v) \ + out_dword(VIDC_REG_854681_ADDR, v) + +#define VIDC_REG_128234_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000ec8) +#define VIDC_REG_128234_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ec8) +#define VIDC_REG_128234_RMSK 0xffff000f +#define VIDC_REG_128234_SHFT 0 +#define VIDC_REG_128234_OUT(v) \ + out_dword(VIDC_REG_128234_ADDR, v) + +#define VIDC_REG_1137_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000ecc) +#define VIDC_REG_1137_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ecc) +#define VIDC_REG_1137_RMSK 0xffffffff +#define VIDC_REG_1137_SHFT 0 +#define VIDC_REG_1137_IN \ + in_dword_masked(VIDC_REG_1137_ADDR, \ + VIDC_REG_1137_RMSK) +#define VIDC_REG_1137_INM(m) \ + in_dword_masked(VIDC_REG_1137_ADDR, m) +#define VIDC_REG_1137_METADATA_DISPLAY_INDEX_BMSK \ + 0xffffffff +#define \ + \ +VIDC_REG_1137_METADATA_DISPLAY_INDEX_SHFT 0 + +#define VIDC_REG_988552_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000ed0) +#define VIDC_REG_988552_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ed0) +#define VIDC_REG_988552_RMSK 0xffffffff +#define VIDC_REG_988552_SHFT 0 +#define VIDC_REG_988552_OUT(v) \ + out_dword(VIDC_REG_988552_ADDR, v) + +#define VIDC_REG_319934_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000ed4) +#define VIDC_REG_319934_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ed4) +#define VIDC_REG_319934_RMSK 0xffffffff +#define VIDC_REG_319934_SHFT 0 +#define VIDC_REG_319934_OUT(v) \ + out_dword(VIDC_REG_319934_ADDR, v) + +#define VIDC_REG_679165_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000ed8) +#define VIDC_REG_679165_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ed8) +#define VIDC_REG_679165_RMSK 0xffffffff +#define VIDC_REG_679165_SHFT 0 +#define VIDC_REG_679165_IN \ + in_dword_masked(VIDC_REG_679165_ADDR, \ + VIDC_REG_679165_RMSK) +#define VIDC_REG_679165_INM(m) \ + in_dword_masked(VIDC_REG_679165_ADDR, m) +#define VIDC_REG_679165_PIC_TIME_TOP_BMSK 0xffffffff +#define VIDC_REG_679165_PIC_TIME_TOP_SHFT 0 + +#define VIDC_REG_374150_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000edc) +#define VIDC_REG_374150_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000edc) +#define VIDC_REG_374150_RMSK 0xffffffff +#define VIDC_REG_374150_SHFT 0 +#define VIDC_REG_374150_IN \ + in_dword_masked(VIDC_REG_374150_ADDR, \ + VIDC_REG_374150_RMSK) +#define VIDC_REG_374150_INM(m) \ + in_dword_masked(VIDC_REG_374150_ADDR, m) +#define VIDC_REG_374150_PIC_TIME_BOTTOM_BMSK 0xffffffff +#define VIDC_REG_374150_PIC_TIME_BOTTOM_SHFT 0 + +#define VIDC_REG_94750_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000ee0) +#define VIDC_REG_94750_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ee0) +#define VIDC_REG_94750_RMSK 0xffffffff +#define VIDC_REG_94750_SHFT 0 +#define VIDC_REG_94750_OUT(v) \ + out_dword(VIDC_REG_94750_ADDR, v) + +#define VIDC_REG_438677_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000ee4) +#define VIDC_REG_438677_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ee4) +#define VIDC_REG_438677_RMSK 0xffffffff +#define VIDC_REG_438677_SHFT 0 +#define VIDC_REG_438677_IN \ + in_dword_masked(VIDC_REG_438677_ADDR, \ + VIDC_REG_438677_RMSK) +#define VIDC_REG_438677_INM(m) \ + in_dword_masked(VIDC_REG_438677_ADDR, m) +#define VIDC_REG_438677_GET_FRAME_TAG_BOTTOM_BMSK 0xffffffff +#define VIDC_REG_438677_GET_FRAME_TAG_BOTTOM_SHFT 0 + +#define VIDC_REG_76706_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000ee8) +#define VIDC_REG_76706_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000ee8) +#define VIDC_REG_76706_RMSK 0x1 +#define VIDC_REG_76706_SHFT 0 +#define VIDC_REG_76706_OUT(v) \ + out_dword(VIDC_REG_76706_ADDR, v) + +#define VIDC_REG_809984_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00001000) +#define VIDC_REG_809984_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00001000) +#define VIDC_REG_809984_RMSK 0xffff0007 +#define VIDC_REG_809984_SHFT 0 +#define VIDC_REG_809984_IN \ + in_dword_masked(VIDC_REG_809984_ADDR, VIDC_REG_809984_RMSK) +#define VIDC_REG_809984_INM(m) \ + in_dword_masked(VIDC_REG_809984_ADDR, m) +#define VIDC_REG_809984_720PV_720P_WRAPPER_VERSION_BMSK 0xffff0000 +#define VIDC_REG_809984_720PV_720P_WRAPPER_VERSION_SHFT 0x10 +#define VIDC_REG_809984_TEST_MUX_SEL_BMSK 0x7 +#define VIDC_REG_809984_TEST_MUX_SEL_SHFT 0 + + +#define VIDC_REG_699747_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000d0c) +#define VIDC_REG_699747_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000d0c) +#define VIDC_REG_699747_RMSK 0xffffffff +#define VIDC_REG_699747_SHFT 0 +#define VIDC_REG_699747_OUT(v) \ + out_dword(VIDC_REG_699747_ADDR, v) + +#define VIDC_REG_166247_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000d10) +#define VIDC_REG_166247_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000d10) +#define VIDC_REG_166247_RMSK 0xffffffff +#define VIDC_REG_166247_SHFT 0 +#define VIDC_REG_166247_OUT(v) \ + out_dword(VIDC_REG_166247_ADDR, v) + +#define VIDC_REG_486169_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000d18) +#define VIDC_REG_486169_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000d18) +#define VIDC_REG_486169_RMSK 0xffffffff +#define VIDC_REG_486169_SHFT 0 +#define VIDC_REG_486169_OUT(v) \ + out_dword(VIDC_REG_486169_ADDR, v) + +#define VIDC_REG_926519_ADDR \ + (VIDC_720P_WRAPPER_REG_BASE + 0x00000d1c) +#define VIDC_REG_926519_PHYS \ + (VIDC_720P_WRAPPER_REG_BASE_PHYS + 0x00000d1c) +#define VIDC_REG_926519_RMSK 0xffffffff +#define VIDC_REG_926519_SHFT 0 +#define VIDC_REG_926519_OUT(v) \ + out_dword(VIDC_REG_926519_ADDR, v) + +/** List all the levels and their register valus */ + +#define VIDC_720P_PROFILE_MPEG4_SP 0 +#define VIDC_720P_PROFILE_MPEG4_ASP 1 +#define VIDC_720P_PROFILE_H264_BASELINE 0 +#define VIDC_720P_PROFILE_H264_MAIN 1 +#define VIDC_720P_PROFILE_H264_HIGH 2 +#define VIDC_720P_PROFILE_H264_CPB 3 +#define VIDC_720P_PROFILE_H263_BASELINE 0 + +#define VIDC_720P_PROFILE_VC1_SP 0 +#define VIDC_720P_PROFILE_VC1_MAIN 1 +#define VIDC_720P_PROFILE_VC1_ADV 2 +#define VIDC_720P_PROFILE_MPEG2_MAIN 4 +#define VIDC_720P_PROFILE_MPEG2_SP 5 + +#define VIDC_720P_MPEG4_LEVEL0 0 +#define VIDC_720P_MPEG4_LEVEL0b 9 +#define VIDC_720P_MPEG4_LEVEL1 1 +#define VIDC_720P_MPEG4_LEVEL2 2 +#define VIDC_720P_MPEG4_LEVEL3 3 +#define VIDC_720P_MPEG4_LEVEL3b 7 +#define VIDC_720P_MPEG4_LEVEL4a 4 +#define VIDC_720P_MPEG4_LEVEL5 5 +#define VIDC_720P_MPEG4_LEVEL6 6 + +#define VIDC_720P_H264_LEVEL1 10 +#define VIDC_720P_H264_LEVEL1b 9 +#define VIDC_720P_H264_LEVEL1p1 11 +#define VIDC_720P_H264_LEVEL1p2 12 +#define VIDC_720P_H264_LEVEL1p3 13 +#define VIDC_720P_H264_LEVEL2 20 +#define VIDC_720P_H264_LEVEL2p1 21 +#define VIDC_720P_H264_LEVEL2p2 22 +#define VIDC_720P_H264_LEVEL3 30 +#define VIDC_720P_H264_LEVEL3p1 31 +#define VIDC_720P_H264_LEVEL3p2 32 + +#define VIDC_720P_H263_LEVEL10 10 +#define VIDC_720P_H263_LEVEL20 20 +#define VIDC_720P_H263_LEVEL30 30 +#define VIDC_720P_H263_LEVEL40 40 +#define VIDC_720P_H263_LEVEL45 45 +#define VIDC_720P_H263_LEVEL50 50 +#define VIDC_720P_H263_LEVEL60 60 +#define VIDC_720P_H263_LEVEL70 70 + +#define VIDC_720P_VC1_LEVEL_LOW 0 +#define VIDC_720P_VC1_LEVEL_MED 2 +#define VIDC_720P_VC1_LEVEL_HIGH 4 +#define VIDC_720P_VC1_LEVEL0 0 +#define VIDC_720P_VC1_LEVEL1 1 +#define VIDC_720P_VC1_LEVEL2 2 +#define VIDC_720P_VC1_LEVEL3 3 +#define VIDC_720P_VC1_LEVEL4 4 + +#define VIDCL_720P_MPEG2_LEVEL_LOW 10 +#define VIDCL_720P_MPEG2_LEVEL_MAIN 8 +#define VIDCL_720P_MPEG2_LEVEL_HIGH14 6 + +#define VIDC_720P_CMD_CHSET 0x0 +#define VIDC_720P_CMD_CHEND 0x2 +#define VIDC_720P_CMD_INITCODEC 0x3 +#define VIDC_720P_CMD_FRAMERUN 0x4 +#define VIDC_720P_CMD_INITBUFFERS 0x5 +#define VIDC_720P_CMD_FRAMERUN_REALLOCATE 0x6 +#define VIDC_720P_CMD_MFC_ENGINE_RESET 0x7 + +enum vidc_720p_endian { + VIDC_720P_BIG_ENDIAN = 0x0, + VIDC_720P_LITTLE_ENDIAN = 0x1 +}; + +enum vidc_720p_memory_access_method { + VIDC_720P_TILE_LINEAR = 0, + VIDC_720P_TILE_16x16 = 2, + VIDC_720P_TILE_64x32 = 3 +}; + +enum vidc_720p_interrupt_control_mode { + VIDC_720P_INTERRUPT_MODE = 0, + VIDC_720P_POLL_MODE = 1 +}; + +enum vidc_720p_interrupt_level_selection { + VIDC_720P_INTERRUPT_LEVEL_SEL = 0, + VIDC_720P_INTERRUPT_PULSE_SEL = 1 +}; + +#define VIDC_720P_INTR_BUFFER_FULL 0x002 +#define VIDC_720P_INTR_FW_DONE 0x020 +#define VIDC_720P_INTR_HEADER_DONE 0x040 +#define VIDC_720P_INTR_DMA_DONE 0x080 +#define VIDC_720P_INTR_FRAME_DONE 0x100 + +enum vidc_720p_enc_dec_selection { + VIDC_720P_DECODER = 0, + VIDC_720P_ENCODER = 1 +}; + +enum vidc_720p_codec { + VIDC_720P_MPEG4 = 0, + VIDC_720P_H264 = 1, + VIDC_720P_DIVX = 2, + VIDC_720P_XVID = 3, + VIDC_720P_H263 = 4, + VIDC_720P_MPEG2 = 5, + VIDC_720P_VC1 = 6 +}; + +enum vidc_720p_frame { + VIDC_720P_NOTCODED = 0, + VIDC_720P_IFRAME = 1, + VIDC_720P_PFRAME = 2, + VIDC_720P_BFRAME = 3, + VIDC_720P_IDRFRAME = 4 +}; + +enum vidc_720p_entropy_sel { + VIDC_720P_ENTROPY_SEL_CAVLC = 0, + VIDC_720P_ENTROPY_SEL_CABAC = 1 +}; + +enum vidc_720p_cabac_model { + VIDC_720P_CABAC_MODEL_NUMBER_0 = 0, + VIDC_720P_CABAC_MODEL_NUMBER_1 = 1, + VIDC_720P_CABAC_MODEL_NUMBER_2 = 2 +}; + +enum vidc_720p_DBConfig { + VIDC_720P_DB_ALL_BLOCKING_BOUNDARY = 0, + VIDC_720P_DB_DISABLE = 1, + VIDC_720P_DB_SKIP_SLICE_BOUNDARY = 2 +}; + +enum vidc_720p_MSlice_selection { + VIDC_720P_MSLICE_BY_MB_COUNT = 0, + VIDC_720P_MSLICE_BY_BYTE_COUNT = 1, + VIDC_720P_MSLICE_BY_GOB = 2, + VIDC_720P_MSLICE_OFF = 3 +}; + +enum vidc_720p_display_status { + VIDC_720P_DECODE_ONLY = 0, + VIDC_720P_DECODE_AND_DISPLAY = 1, + VIDC_720P_DISPLAY_ONLY = 2, + VIDC_720P_EMPTY_BUFFER = 3 +}; + +#define VIDC_720P_ENC_IFRAME_REQ 0x1 +#define VIDC_720P_ENC_IPERIOD_CHANGE 0x1 +#define VIDC_720P_ENC_FRAMERATE_CHANGE 0x2 +#define VIDC_720P_ENC_BITRATE_CHANGE 0x4 + +#define VIDC_720P_FLUSH_REQ 0x1 +#define VIDC_720P_EXTRADATA 0x2 + +#define VIDC_720P_METADATA_ENABLE_QP 0x01 +#define VIDC_720P_METADATA_ENABLE_CONCEALMB 0x02 +#define VIDC_720P_METADATA_ENABLE_VC1 0x04 +#define VIDC_720P_METADATA_ENABLE_SEI 0x08 +#define VIDC_720P_METADATA_ENABLE_VUI 0x10 +#define VIDC_720P_METADATA_ENABLE_ENCSLICE 0x20 +#define VIDC_720P_METADATA_ENABLE_PASSTHROUGH 0x40 + +struct vidc_720p_dec_disp_info { + enum vidc_720p_display_status disp_status; + u32 resl_change; + u32 reconfig_flush_done; + u32 img_size_x; + u32 img_size_y; + u32 y_addr; + u32 c_addr; + u32 tag_top; + u32 pic_time_top; + u32 disp_is_interlace; + u32 tag_bottom; + u32 pic_time_bottom; + u32 metadata_exists; + u32 crop_exists; + u32 crop_right_offset; + u32 crop_left_offset; + u32 crop_bottom_offset; + u32 crop_top_offset; + u32 input_frame; + u32 input_bytes_consumed; + u32 input_is_interlace; + u32 input_frame_num; +}; + +struct vidc_720p_seq_hdr_info { + u32 img_size_x; + u32 img_size_y; + u32 dec_frm_size; + u32 min_num_dpb; + u32 min_dpb_size; + u32 profile; + u32 level; + u32 progressive; + u32 data_partitioned; + u32 crop_exists; + u32 crop_right_offset; + u32 crop_left_offset; + u32 crop_bottom_offset; + u32 crop_top_offset; +}; + +struct vidc_720p_enc_frame_info { + u32 enc_size; + u32 frame; + u32 metadata_exists; +}; + +void vidc_720p_set_device_virtual_base(u8 *core_virtual_base_addr); + +void vidc_720p_init(char **ppsz_version, u32 i_firmware_size, + u32 *pi_firmware_address, enum vidc_720p_endian dma_endian, + u32 interrupt_off, + enum vidc_720p_interrupt_level_selection interrupt_sel, + u32 interrupt_mask); + +u32 vidc_720p_do_sw_reset(void); + +u32 vidc_720p_reset_is_success(void); + +void vidc_720p_start_cpu(enum vidc_720p_endian dma_endian, + u32 *icontext_bufferstart, u32 *debug_core_dump_addr, + u32 debug_buffer_size); + +u32 vidc_720p_cpu_start(void); + +void vidc_720p_stop_fw(void); + +void vidc_720p_get_interrupt_status(u32 *interrupt_status, + u32 *cmd_err_status, u32 *disp_pic_err_status, + u32 *op_failed); + +void vidc_720p_interrupt_done_clear(void); + +void vidc_720p_submit_command(u32 ch_id, u32 cmd_id); + + +void vidc_720p_set_channel(u32 i_ch_id, + enum vidc_720p_enc_dec_selection enc_dec_sel, + enum vidc_720p_codec codec, u32 *pi_fw, u32 i_firmware_size); + +u32 vidc_720p_engine_reset(u32 ch_id, + enum vidc_720p_endian dma_endian, + enum vidc_720p_interrupt_level_selection interrupt_sel, + u32 interrupt_mask +); + +void vidc_720p_encode_set_profile(u32 i_profile, u32 i_level); + +void vidc_720p_set_frame_size(u32 i_size_x, u32 i_size_y); + +void vidc_720p_encode_set_fps(u32 i_rc_frame_rate); + +void vidc_720p_encode_set_vop_time(u32 vop_time_resolution, + u32 vop_time_increment); + +void vidc_720p_encode_set_hec_period(u32 hec_period); + +void vidc_720p_encode_set_short_header(u32 i_short_header); + +void vidc_720p_encode_set_qp_params(u32 i_max_qp, u32 i_min_qp); + +void vidc_720p_encode_set_rc_config(u32 enable_frame_level_rc, + u32 enable_mb_level_rc_flag, u32 i_frame_qp, u32 pframe_qp); + +void vidc_720p_encode_set_bit_rate(u32 i_target_bitrate); + +void vidc_720p_encoder_set_param_change(u32 enc_param_change); + +void vidc_720p_encode_set_control_param(u32 param_val); + +void vidc_720p_encode_set_frame_level_rc_params(u32 i_reaction_coeff); + +void vidc_720p_encode_set_mb_level_rc_params(u32 dark_region_as_flag, + u32 smooth_region_as_flag, u32 static_region_as_flag, + u32 activity_region_flag); + +void vidc_720p_encode_set_entropy_control(enum vidc_720p_entropy_sel \ + entropy_sel, + enum vidc_720p_cabac_model cabac_model_number); + +void vidc_720p_encode_set_db_filter_control(enum vidc_720p_DBConfig + db_config, u32 i_slice_alpha_offset, u32 i_slice_beta_offset); + +void vidc_720p_encode_set_intra_refresh_mb_number(u32 i_cir_mb_number); + +void vidc_720p_encode_set_multi_slice_info( + enum vidc_720p_MSlice_selection m_slice_sel, + u32 multi_slice_size); + +void vidc_720p_encode_set_dpb_buffer(u32 *pi_enc_dpb_addr, u32 alloc_len); + +void vidc_720p_set_deblock_line_buffer(u32 *pi_deblock_line_buffer_start, + u32 alloc_len); + +void vidc_720p_encode_set_i_period(u32 i_i_period); + +void vidc_720p_encode_init_codec(u32 i_ch_id, + enum vidc_720p_memory_access_method memory_access_model); + +void vidc_720p_encode_unalign_bitstream(u32 upper_unalign_word, + u32 lower_unalign_word); + +void vidc_720p_encode_set_seq_header_buffer(u32 ext_buffer_start, + u32 ext_buffer_end, u32 start_byte_num); + +void vidc_720p_encode_frame(u32 ch_id, u32 ext_buffer_start, + u32 ext_buffer_end, u32 start_byte_number, + u32 y_addr, u32 c_addr); + +void vidc_720p_encode_get_header(u32 *pi_enc_header_size); + +void vidc_720p_enc_frame_info + (struct vidc_720p_enc_frame_info *enc_frame_info); + +void vidc_720p_decode_bitstream_header(u32 ch_id, u32 dec_unit_size, + u32 start_byte_num, u32 ext_buffer_start, u32 ext_buffer_end, + enum vidc_720p_memory_access_method memory_access_model, + u32 decode_order); + +void vidc_720p_decode_get_seq_hdr_info + (struct vidc_720p_seq_hdr_info *seq_hdr_info); + +void vidc_720p_decode_set_dpb_release_buffer_mask + (u32 i_dpb_release_buffer_mask); + +void vidc_720p_decode_set_dpb_buffers(u32 i_buf_index, u32 *pi_dpb_buffer); + +void vidc_720p_decode_set_comv_buffer + (u32 *pi_dpb_comv_buffer, u32 alloc_len); + +void vidc_720p_decode_set_dpb_details + (u32 num_dpb, u32 alloc_len, u32 *ref_buffer); + +void vidc_720p_decode_set_mpeg4Post_filter(u32 enable_post_filter); + +void vidc_720p_decode_set_error_control(u32 enable_error_control); + +void vidc_720p_decode_set_mpeg4_data_partitionbuffer(u32 *vsp_buf_start); + +void vidc_720p_decode_setH264VSPBuffer(u32 *pi_vsp_temp_buffer_start); + +void vidc_720p_decode_frame(u32 ch_id, u32 ext_buffer_start, + u32 ext_buffer_end, u32 dec_unit_size, + u32 start_byte_num, u32 input_frame_tag); + +void vidc_720p_issue_eos(u32 i_ch_id); +void vidc_720p_eos_info(u32 *disp_status, u32 *resl_change); + +void vidc_720p_decode_display_info + (struct vidc_720p_dec_disp_info *disp_info); + +void vidc_720p_decode_skip_frm_details(u32 *free_luma_dpb); + +void vidc_720p_metadata_enable(u32 flag, u32 *input_buffer); + +void vidc_720p_decode_dynamic_req_reset(void); + +void vidc_720p_decode_dynamic_req_set(u32 property); + +void vidc_720p_decode_setpassthrough_start(u32 pass_startaddr); + + + +#define DDL_720P_REG_BASE VIDC_720P_WRAPPER_REG_BASE +#define VIDC_BUSY_WAIT(n) udelay(n) + +#undef VIDC_REGISTER_LOG_MSG +#undef VIDC_REGISTER_LOG_INTO_BUFFER + +#ifdef VIDC_REGISTER_LOG_MSG +#define VIDC_MSG1(msg_format, a) printk(KERN_INFO msg_format, a) +#define VIDC_MSG2(msg_format, a, b) printk(KERN_INFO msg_format, a, b) +#define VIDC_MSG3(msg_format, a, b, c) printk(KERN_INFO msg_format, a, b, c) +#else +#define VIDC_MSG1(msg_format, a) +#define VIDC_MSG2(msg_format, a, b) +#define VIDC_MSG3(msg_format, a, b, c) +#endif + +#ifdef VIDC_REGISTER_LOG_INTO_BUFFER + +#define VIDC_REGLOG_BUFSIZE 200000 +#define VIDC_REGLOG_MAX_PRINT_SIZE 100 +extern char vidclog[VIDC_REGLOG_BUFSIZE]; +extern unsigned int vidclog_index; + +#define VIDC_LOG_BUFFER_INIT \ +{if (vidclog_index) \ + memset(vidclog, 0, vidclog_index+1); \ + vidclog_index = 0; } + +#define VIDC_REGLOG_CHECK_BUFINDEX(req_size) \ + vidclog_index = \ + (vidclog_index+(req_size) < VIDC_REGLOG_BUFSIZE) ? vidclog_index : 0; + +#define VIDC_LOG_WRITE(reg, val) \ +{unsigned int len; \ + VIDC_REGLOG_CHECK_BUFINDEX(VIDC_REGLOG_MAX_PRINT_SIZE); \ + len = snprintf(&vidclog[vidclog_index], VIDC_REGLOG_MAX_PRINT_SIZE, \ + "(0x%x:"#reg"=0x%x)" , VIDC_##reg##_ADDR - DDL_720P_REG_BASE, val);\ + vidclog_index += len; } + +#define VIDC_LOG_WRITEI(reg, index, val) \ +{unsigned int len; \ + VIDC_REGLOG_CHECK_BUFINDEX(VIDC_REGLOG_MAX_PRINT_SIZE); \ + len = snprintf(&vidclog[vidclog_index], VIDC_REGLOG_MAX_PRINT_SIZE, \ + "(0x%x:"#reg"=0x%x)" , VIDC_##reg##_ADDR(index)-DDL_720P_REG_BASE, \ + val); vidclog_index += len; } + +#define VIDC_LOG_WRITEF(reg, field, val) \ +{unsigned int len; \ + VIDC_REGLOG_CHECK_BUFINDEX(VIDC_REGLOG_MAX_PRINT_SIZE); \ + len = snprintf(&vidclog[vidclog_index], VIDC_REGLOG_MAX_PRINT_SIZE, \ + "(0x%x:"#reg":0x%x:=0x%x)" , VIDC_##reg##_ADDR - DDL_720P_REG_BASE, \ + VIDC_##reg##_##field##_BMSK, val);\ + vidclog_index += len; } + +#define VIDC_LOG_READ(reg, pval) \ +{ unsigned int len; \ + VIDC_REGLOG_CHECK_BUFINDEX(VIDC_REGLOG_MAX_PRINT_SIZE); \ + len = snprintf(&vidclog[vidclog_index], VIDC_REGLOG_MAX_PRINT_SIZE, \ + "(0x%x:"#reg"==0x%x)" , VIDC_##reg##_ADDR - DDL_720P_REG_BASE, \ + (u32)*pval); \ + vidclog_index += len; } + +#define VIDC_STR_LOGBUFFER(str) \ +{ unsigned int len; \ + VIDC_REGLOG_CHECK_BUFINDEX(VIDC_REGLOG_MAX_PRINT_SIZE); \ + len = snprintf(&vidclog[vidclog_index], VIDC_REGLOG_MAX_PRINT_SIZE, \ + "<%s>" , str); vidclog_index += len; } + +#define VIDC_LONG_LOGBUFFER(str, arg1) \ +{ unsigned int len; \ + VIDC_REGLOG_CHECK_BUFINDEX(VIDC_REGLOG_MAX_PRINT_SIZE); \ + len = snprintf(&vidclog[vidclog_index], VIDC_REGLOG_MAX_PRINT_SIZE, \ + "<%s=0x%x>" , str, arg1); vidclog_index += len; } + +#define VIDC_DEBUG_REGISTER_LOG \ +{ u32 val; unsigned int len; \ + val = VIDC_720P_IN(REG_881638); \ + VIDC_REGLOG_CHECK_BUFINDEX(VIDC_REGLOG_MAX_PRINT_SIZE); \ + len = snprintf(&vidclog[vidclog_index], 50, "[dbg1=%x]" , val); \ + vidclog_index += len; \ + val = VIDC_720P_IN(REG_161486); \ + VIDC_REGLOG_CHECK_BUFINDEX(VIDC_REGLOG_MAX_PRINT_SIZE); \ + len = snprintf(&vidclog[vidclog_index], 50, "[dbg2=%x]" , val); \ + vidclog_index += len; } + +#else +#define VIDC_LOG_WRITE(reg, val) +#define VIDC_LOG_WRITEI(reg, index, val) +#define VIDC_LOG_WRITEF(reg, field, val) +#define VIDC_LOG_READ(reg, pval) +#define VIDC_LOG_BUFFER_INIT +#define VIDC_STR_LOGBUFFER(str) +#define VIDC_LONG_LOGBUFFER(str, arg1) +#define VIDC_DEBUG_REGISTER_LOG +#endif + +void vidcputlog(char *str); +void vidcput_debug_reglog(void); + +#define VIDC_LOGERR_STRING(str) \ +do { \ + VIDC_STR_LOGBUFFER(str); \ + VIDC_MSG1("\n<%s>", str); \ +} while (0) + +#define VIDC_LOG_STRING(str) \ +do { \ + VIDC_STR_LOGBUFFER(str); \ + VIDC_MSG1("\n<%s>", str); \ +} while (0) + +#define VIDC_LOG1(str, arg1) \ +do { \ + VIDC_LONG_LOGBUFFER(str, arg1); \ + VIDC_MSG2("\n<%s=0x%08x>", str, arg1); \ +} while (0) + +#define VIDC_IO_OUT(reg, val) \ +do { \ + VIDC_LOG_WRITE(reg, (u32)val); \ + VIDC_MSG2("\n(0x%08x:"#reg"=0x%08x)", \ + (u32)(VIDC_##reg##_ADDR - DDL_720P_REG_BASE), (u32)val); \ + mb(); \ + VIDC_720P_OUT(reg, val); \ +} while (0) + +#define VIDC_IO_OUTI(reg, index, val) \ +do { \ + VIDC_LOG_WRITEI(reg, index, (u32)val); \ + VIDC_MSG2("\n(0x%08x:"#reg"=0x%08x)", \ + (u32)(VIDC_##reg##_ADDR(index)-DDL_720P_REG_BASE), (u32)val); \ + mb(); \ + VIDC_720P_OUTI(reg, index, val); \ +} while (0) + +#define VIDC_IO_OUTF(reg, field, val) \ +do { \ + VIDC_LOG_WRITEF(reg, field, val); \ + VIDC_MSG3("\n(0x%08x:"#reg":0x%x:=0x%08x)", \ + (u32)(VIDC_##reg##_ADDR - DDL_720P_REG_BASE), \ + VIDC_##reg##_##field##_BMSK, (u32)val); \ + mb(); \ + VIDC_720P_OUTF(reg, field, val); \ +} while (0) + +#define VIDC_IO_IN(reg, pval) \ +do { \ + mb(); \ + *pval = (u32) VIDC_720P_IN(reg); \ + VIDC_LOG_READ(reg, pval); \ + VIDC_MSG2("\n(0x%08x:"#reg"==0x%08x)", \ + (u32)(VIDC_##reg##_ADDR - DDL_720P_REG_BASE), (u32) *pval); \ +} while (0) + +#define VIDC_IO_INF(reg, mask, pval) \ +do { \ + mb(); \ + *pval = VIDC_720P_INF(reg, mask); \ + VIDC_LOG_READ(reg, pval); \ + VIDC_MSG2("\n(0x%08x:"#reg"==0x%08x)", \ + (u32)(VIDC_##reg##_ADDR - DDL_720P_REG_BASE), *pval); \ +} while (0) + +#endif diff --git a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c new file mode 100644 index 000000000000..79b2e673a43a --- /dev/null +++ b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c @@ -0,0 +1,771 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "vcd_res_tracker.h" + +#define MSM_AXI_QOS_NAME "msm_vidc_reg" +#define AXI_CLK_SCALING + +#define QVGA_PERF_LEVEL (300 * 30) +#define VGA_PERF_LEVEL (1200 * 30) +#define WVGA_PERF_LEVEL (1500 * 30) + +static unsigned int mfc_clk_freq_table[3] = { + 61440000, 122880000, 170667000 +}; + +static unsigned int axi_clk_freq_table_enc[2] = { + 122880, 192000 +}; +static unsigned int axi_clk_freq_table_dec[2] = { + 122880, 192000 +}; + +static struct res_trk_context resource_context; + +#define VIDC_BOOT_FW "vidc_720p_command_control.fw" +#define VIDC_MPG4_DEC_FW "vidc_720p_mp4_dec_mc.fw" +#define VIDC_H263_DEC_FW "vidc_720p_h263_dec_mc.fw" +#define VIDC_H264_DEC_FW "vidc_720p_h264_dec_mc.fw" +#define VIDC_MPG4_ENC_FW "vidc_720p_mp4_enc_mc.fw" +#define VIDC_H264_ENC_FW "vidc_720p_h264_enc_mc.fw" +#define VIDC_VC1_DEC_FW "vidc_720p_vc1_dec_mc.fw" + +unsigned char *vidc_command_control_fw; +u32 vidc_command_control_fw_size; + +unsigned char *vidc_mpg4_dec_fw; +u32 vidc_mpg4_dec_fw_size; + +unsigned char *vidc_h263_dec_fw; +u32 vidc_h263_dec_fw_size; + +unsigned char *vidc_h264_dec_fw; +u32 vidc_h264_dec_fw_size; + +unsigned char *vidc_mpg4_enc_fw; +u32 vidc_mpg4_enc_fw_size; + +unsigned char *vidc_h264_enc_fw; +u32 vidc_h264_enc_fw_size; + +unsigned char *vidc_vc1_dec_fw; +u32 vidc_vc1_dec_fw_size; + +static u32 res_trk_disable_videocore(void) +{ + int rc = -1; + mutex_lock(&resource_context.lock); + + if (!resource_context.rail_enabled) { + mutex_unlock(&resource_context.lock); + return false; + } + + if (!resource_context.clock_enabled && + resource_context.pclk && + resource_context.hclk && + resource_context.hclk_div2) { + + VCDRES_MSG_LOW("\nEnabling clk before disabling pwr rail\n"); + if (clk_set_rate(resource_context.hclk, + mfc_clk_freq_table[0])) { + VCDRES_MSG_ERROR("\n pwr_rail_disable:" + " set clk rate failed\n"); + goto bail_out; + } + + if (clk_prepare_enable(resource_context.pclk)) { + VCDRES_MSG_ERROR("vidc pclk Enable failed\n"); + goto bail_out; + } + + if (clk_prepare_enable(resource_context.hclk)) { + VCDRES_MSG_ERROR("vidc hclk Enable failed\n"); + goto disable_pclk; + } + + if (clk_prepare_enable(resource_context.hclk_div2)) { + VCDRES_MSG_ERROR("vidc hclk_div2 Enable failed\n"); + goto disable_hclk; + } + } else { + VCDRES_MSG_ERROR("\ndisabling pwr rail: Enabling clk failed\n"); + goto bail_out; + } + + resource_context.rail_enabled = 0; + rc = clk_reset(resource_context.pclk, CLK_RESET_ASSERT); + if (rc) { + VCDRES_MSG_ERROR("\n clk_reset failed %d\n", rc); + mutex_unlock(&resource_context.lock); + return false; + } + msleep(20); + + clk_disable_unprepare(resource_context.pclk); + clk_disable_unprepare(resource_context.hclk); + clk_disable_unprepare(resource_context.hclk_div2); + + clk_put(resource_context.hclk_div2); + clk_put(resource_context.hclk); + clk_put(resource_context.pclk); + + rc = regulator_disable(resource_context.regulator); + if (rc) { + VCDRES_MSG_ERROR("\n regulator disable failed %d\n", rc); + mutex_unlock(&resource_context.lock); + return false; + } + + resource_context.hclk_div2 = NULL; + resource_context.hclk = NULL; + resource_context.pclk = NULL; + + mutex_unlock(&resource_context.lock); + + return true; + +disable_hclk: + clk_disable_unprepare(resource_context.hclk); +disable_pclk: + clk_disable_unprepare(resource_context.pclk); +bail_out: + if (resource_context.pclk) { + clk_put(resource_context.pclk); + resource_context.pclk = NULL; + } + if (resource_context.hclk) { + clk_put(resource_context.hclk); + resource_context.hclk = NULL; + } + if (resource_context.hclk_div2) { + clk_put(resource_context.hclk_div2); + resource_context.hclk_div2 = NULL; + } + mutex_unlock(&resource_context.lock); + return false; +} + +u32 res_trk_enable_clocks(void) +{ + VCDRES_MSG_LOW("\n in res_trk_enable_clocks()"); + + mutex_lock(&resource_context.lock); + if (!resource_context.clock_enabled) { + VCDRES_MSG_LOW("Enabling IRQ in %s()\n", __func__); + enable_irq(resource_context.irq_num); + + VCDRES_MSG_LOW("%s(): Enabling the clocks ...\n", __func__); + + if (clk_prepare_enable(resource_context.pclk)) { + VCDRES_MSG_ERROR("vidc pclk Enable failed\n"); + + clk_put(resource_context.hclk); + clk_put(resource_context.hclk_div2); + mutex_unlock(&resource_context.lock); + return false; + } + + if (clk_prepare_enable(resource_context.hclk)) { + VCDRES_MSG_ERROR("vidc hclk Enable failed\n"); + clk_put(resource_context.pclk); + clk_put(resource_context.hclk_div2); + mutex_unlock(&resource_context.lock); + return false; + } + + if (clk_prepare_enable(resource_context.hclk_div2)) { + VCDRES_MSG_ERROR("vidc hclk Enable failed\n"); + clk_put(resource_context.hclk); + clk_put(resource_context.pclk); + mutex_unlock(&resource_context.lock); + return false; + } + } + + resource_context.clock_enabled = 1; + mutex_unlock(&resource_context.lock); + return true; +} + +static u32 res_trk_sel_clk_rate(unsigned long hclk_rate) +{ + mutex_lock(&resource_context.lock); + if (clk_set_rate(resource_context.hclk, + hclk_rate)) { + VCDRES_MSG_ERROR("vidc hclk set rate failed\n"); + mutex_unlock(&resource_context.lock); + return false; + } + resource_context.hclk_rate = hclk_rate; + mutex_unlock(&resource_context.lock); + return true; +} + +static u32 res_trk_get_clk_rate(unsigned long *phclk_rate) +{ + if (!phclk_rate) { + VCDRES_MSG_ERROR("%s(): phclk_rate is NULL\n", __func__); + return false; + } + mutex_lock(&resource_context.lock); + *phclk_rate = clk_get_rate(resource_context.hclk); + if (!(*phclk_rate)) { + VCDRES_MSG_ERROR("vidc hclk get rate failed\n"); + mutex_unlock(&resource_context.lock); + return false; + } + mutex_unlock(&resource_context.lock); + return true; +} + +u32 res_trk_disable_clocks(void) +{ + VCDRES_MSG_LOW("in res_trk_disable_clocks()\n"); + + mutex_lock(&resource_context.lock); + + if (!resource_context.clock_enabled) { + mutex_unlock(&resource_context.lock); + return false; + } + + VCDRES_MSG_LOW("Disabling IRQ in %s()\n", __func__); + disable_irq_nosync(resource_context.irq_num); + VCDRES_MSG_LOW("%s(): Disabling the clocks ...\n", __func__); + + resource_context.clock_enabled = 0; + clk_disable_unprepare(resource_context.hclk); + clk_disable_unprepare(resource_context.hclk_div2); + clk_disable_unprepare(resource_context.pclk); + mutex_unlock(&resource_context.lock); + + return true; +} + +static u32 res_trk_enable_videocore(void) +{ + mutex_lock(&resource_context.lock); + if (!resource_context.rail_enabled) { + int rc = -1; + + rc = regulator_enable(resource_context.regulator); + if (rc) { + VCDRES_MSG_ERROR("%s(): regulator_enable failed %d\n", + __func__, rc); + goto bail_out; + } + VCDRES_MSG_LOW("%s(): regulator enable Success %d\n", + __func__, rc); + + resource_context.pclk = clk_get(resource_context.device, + "iface_clk"); + + if (IS_ERR(resource_context.pclk)) { + VCDRES_MSG_ERROR("%s(): iface_clk get failed\n" + , __func__); + goto disable_regulator; + } + + resource_context.hclk = clk_get(resource_context.device, + "core_clk"); + + if (IS_ERR(resource_context.hclk)) { + VCDRES_MSG_ERROR("%s(): core_clk get failed\n" + , __func__); + + goto release_pclk; + } + + resource_context.hclk_div2 = + clk_get(resource_context.device, "core_div2_clk"); + + if (IS_ERR(resource_context.hclk_div2)) { + VCDRES_MSG_ERROR("%s(): core_div2_clk get failed\n" + , __func__); + goto release_hclk_pclk; + } + + if (clk_set_rate(resource_context.hclk, + mfc_clk_freq_table[0])) { + VCDRES_MSG_ERROR("\n pwr_rail_enable:" + " set clk rate failed\n"); + goto release_all_clks; + } + + if (clk_prepare_enable(resource_context.pclk)) { + VCDRES_MSG_ERROR("vidc pclk Enable failed\n"); + goto release_all_clks; + } + + if (clk_prepare_enable(resource_context.hclk)) { + VCDRES_MSG_ERROR("vidc hclk Enable failed\n"); + goto disable_pclk; + } + + if (clk_prepare_enable(resource_context.hclk_div2)) { + VCDRES_MSG_ERROR("vidc hclk_div2 Enable failed\n"); + goto disable_hclk_pclk; + } + + rc = clk_reset(resource_context.pclk, CLK_RESET_DEASSERT); + if (rc) { + VCDRES_MSG_ERROR("\n clk_reset failed %d\n", rc); + goto disable_and_release_all_clks; + } + msleep(20); + + clk_disable_unprepare(resource_context.pclk); + clk_disable_unprepare(resource_context.hclk); + clk_disable_unprepare(resource_context.hclk_div2); + + } + resource_context.rail_enabled = 1; + mutex_unlock(&resource_context.lock); + return true; + +disable_and_release_all_clks: + clk_disable_unprepare(resource_context.hclk_div2); +disable_hclk_pclk: + clk_disable_unprepare(resource_context.hclk); +disable_pclk: + clk_disable_unprepare(resource_context.pclk); +release_all_clks: + clk_put(resource_context.hclk_div2); + resource_context.hclk_div2 = NULL; +release_hclk_pclk: + clk_put(resource_context.hclk); + resource_context.hclk = NULL; +release_pclk: + clk_put(resource_context.pclk); + resource_context.pclk = NULL; +disable_regulator: + regulator_disable(resource_context.regulator); +bail_out: + mutex_unlock(&resource_context.lock); + return false; +} + +static u32 res_trk_convert_freq_to_perf_lvl(u64 freq) +{ + u64 perf_lvl; + u64 temp; + + VCDRES_MSG_MED("\n %s():: freq = %u\n", __func__, (u32)freq); + + if (!freq) + return 0; + + temp = freq * 1000; + do_div(temp, VCD_RESTRK_HZ_PER_1000_PERFLVL); + perf_lvl = (u32)temp; + VCDRES_MSG_MED("\n %s(): perf_lvl = %u\n", __func__, + (u32)perf_lvl); + + return (u32)perf_lvl; +} + +static u32 res_trk_convert_perf_lvl_to_freq(u64 perf_lvl) +{ + u64 freq, temp; + + VCDRES_MSG_MED("\n %s():: perf_lvl = %u\n", __func__, + (u32)perf_lvl); + temp = (perf_lvl * VCD_RESTRK_HZ_PER_1000_PERFLVL) + 999; + do_div(temp, 1000); + freq = (u32)temp; + VCDRES_MSG_MED("\n %s(): freq = %u\n", __func__, (u32)freq); + + return (u32)freq; +} + +static struct clk *ebi1_clk; + +u32 res_trk_power_up(void) +{ + VCDRES_MSG_LOW("clk_regime_rail_enable"); + VCDRES_MSG_LOW("clk_regime_sel_rail_control"); +#ifdef AXI_CLK_SCALING +{ + VCDRES_MSG_MED("\n res_trk_power_up():: " + "Calling AXI add requirement\n"); + ebi1_clk = clk_get(resource_context.device, "mem_clk"); + if (IS_ERR(ebi1_clk)) { + VCDRES_MSG_ERROR("Request AXI bus QOS fails."); + return false; + } + clk_prepare_enable(ebi1_clk); +} +#endif + + VCDRES_MSG_MED("\n res_trk_power_up():: Calling " + "vidc_enable_pwr_rail()\n"); + return res_trk_enable_videocore(); +} + +u32 res_trk_power_down(void) +{ + VCDRES_MSG_LOW("clk_regime_rail_disable"); +#ifdef AXI_CLK_SCALING + VCDRES_MSG_MED("\n res_trk_power_down()::" + "Calling AXI remove requirement\n"); + clk_disable_unprepare(ebi1_clk); + clk_put(ebi1_clk); +#endif + VCDRES_MSG_MED("\n res_trk_power_down():: Calling " + "res_trk_disable_videocore()\n"); + return res_trk_disable_videocore(); +} + +u32 res_trk_get_max_perf_level(u32 *pn_max_perf_lvl) +{ + if (!pn_max_perf_lvl) { + VCDRES_MSG_ERROR("%s(): pn_max_perf_lvl is NULL\n", + __func__); + return false; + } + + *pn_max_perf_lvl = VCD_RESTRK_MAX_PERF_LEVEL; + return true; +} + +u32 res_trk_set_perf_level(u32 req_perf_lvl, u32 *pn_set_perf_lvl, + struct vcd_dev_ctxt *dev_ctxt) +{ + struct vcd_clnt_ctxt *cctxt_itr = NULL; + u32 axi_freq = 0, mfc_freq = 0, calc_mfc_freq = 0; + u8 enc_clnt_present = false; + + if (!pn_set_perf_lvl || !dev_ctxt) { + VCDRES_MSG_ERROR("%s(): NULL pointer! dev_ctxt(%p)\n", + __func__, dev_ctxt); + return false; + } + + VCDRES_MSG_LOW("%s(), req_perf_lvl = %d", __func__, req_perf_lvl); + calc_mfc_freq = res_trk_convert_perf_lvl_to_freq( + (u64)req_perf_lvl); + + if (calc_mfc_freq < VCD_RESTRK_MIN_FREQ_POINT) + calc_mfc_freq = VCD_RESTRK_MIN_FREQ_POINT; + else if (calc_mfc_freq > VCD_RESTRK_MAX_FREQ_POINT) + calc_mfc_freq = VCD_RESTRK_MAX_FREQ_POINT; + + cctxt_itr = dev_ctxt->cctxt_list_head; + while (cctxt_itr) { + VCDRES_MSG_LOW("\n cctxt_itr = %p", cctxt_itr); + if (!cctxt_itr->decoding) { + VCDRES_MSG_LOW("\n Encoder client"); + enc_clnt_present = true; + break; + } else { + VCDRES_MSG_LOW("\n Decoder client"); + } + cctxt_itr = cctxt_itr->next; + } + + if (enc_clnt_present) { + if (req_perf_lvl >= VGA_PERF_LEVEL) { + mfc_freq = mfc_clk_freq_table[2]; + axi_freq = axi_clk_freq_table_enc[1]; + } else { + mfc_freq = mfc_clk_freq_table[0]; + axi_freq = axi_clk_freq_table_enc[0]; + } + VCDRES_MSG_MED("\n ENCODER: axi_freq = %u" + ", mfc_freq = %u, calc_mfc_freq = %u," + " req_perf_lvl = %u", axi_freq, + mfc_freq, calc_mfc_freq, + req_perf_lvl); + } else { + if (req_perf_lvl <= QVGA_PERF_LEVEL) { + mfc_freq = mfc_clk_freq_table[0]; + axi_freq = axi_clk_freq_table_dec[0]; + } else { + axi_freq = axi_clk_freq_table_dec[0]; + if (req_perf_lvl <= VGA_PERF_LEVEL) + mfc_freq = mfc_clk_freq_table[0]; + else if (req_perf_lvl <= WVGA_PERF_LEVEL) + mfc_freq = mfc_clk_freq_table[1]; + else { + mfc_freq = mfc_clk_freq_table[2]; + axi_freq = axi_clk_freq_table_dec[1]; + } + } + VCDRES_MSG_MED("\n DECODER: axi_freq = %u" + ", mfc_freq = %u, calc_mfc_freq = %u," + " req_perf_lvl = %u", axi_freq, + mfc_freq, calc_mfc_freq, + req_perf_lvl); + } + +#ifdef AXI_CLK_SCALING + if (req_perf_lvl != VCD_RESTRK_MIN_PERF_LEVEL) { + VCDRES_MSG_MED("\n %s(): Setting AXI freq to %u", + __func__, axi_freq); + clk_set_rate(ebi1_clk, axi_freq * 1000); + } +#endif + +#ifdef USE_RES_TRACKER + if (req_perf_lvl != VCD_RESTRK_MIN_PERF_LEVEL) { + VCDRES_MSG_MED("\n %s(): Setting MFC freq to %u", + __func__, mfc_freq); + if (!res_trk_sel_clk_rate(mfc_freq)) { + VCDRES_MSG_ERROR("%s(): res_trk_sel_clk_rate FAILED\n", + __func__); + *pn_set_perf_lvl = 0; + return false; + } + } +#endif + + *pn_set_perf_lvl = + res_trk_convert_freq_to_perf_lvl((u64) mfc_freq); + return true; +} + +u32 res_trk_get_curr_perf_level(u32 *pn_perf_lvl) +{ + unsigned long freq; + + if (!pn_perf_lvl) { + VCDRES_MSG_ERROR("%s(): pn_perf_lvl is NULL\n", + __func__); + return false; + } + VCDRES_MSG_LOW("clk_regime_msm_get_clk_freq_hz"); + if (!res_trk_get_clk_rate(&freq)) { + VCDRES_MSG_ERROR("%s(): res_trk_get_clk_rate FAILED\n", + __func__); + *pn_perf_lvl = 0; + return false; + } + + *pn_perf_lvl = res_trk_convert_freq_to_perf_lvl((u64) freq); + VCDRES_MSG_MED("%s(): freq = %lu, *pn_perf_lvl = %u", __func__, + freq, *pn_perf_lvl); + return true; +} + +u32 res_trk_download_firmware(void) +{ + const struct firmware *fw_boot = NULL; + const struct firmware *fw_mpg4_dec = NULL; + const struct firmware *fw_h263_dec = NULL; + const struct firmware *fw_h264_dec = NULL; + const struct firmware *fw_mpg4_enc = NULL; + const struct firmware *fw_h264_enc = NULL; + const struct firmware *fw_vc1_dec = NULL; + int rc = 0; + u32 status = true; + + VCDRES_MSG_HIGH("%s(): Request firmware download\n", + __func__); + mutex_lock(&resource_context.lock); + rc = request_firmware(&fw_boot, VIDC_BOOT_FW, + resource_context.device); + if (rc) { + VCDRES_MSG_ERROR("request_firmware for %s error %d\n", + VIDC_BOOT_FW, rc); + mutex_unlock(&resource_context.lock); + return false; + } + vidc_command_control_fw = (unsigned char *)fw_boot->data; + vidc_command_control_fw_size = (u32) fw_boot->size; + + rc = request_firmware(&fw_mpg4_dec, VIDC_MPG4_DEC_FW, + resource_context.device); + if (rc) { + VCDRES_MSG_ERROR("request_firmware for %s error %d\n", + VIDC_MPG4_DEC_FW, rc); + status = false; + goto boot_fw_free; + } + vidc_mpg4_dec_fw = (unsigned char *)fw_mpg4_dec->data; + vidc_mpg4_dec_fw_size = (u32) fw_mpg4_dec->size; + + + rc = request_firmware(&fw_h263_dec, VIDC_H263_DEC_FW, + resource_context.device); + if (rc) { + VCDRES_MSG_ERROR("request_firmware for %s error %d\n", + VIDC_H263_DEC_FW, rc); + status = false; + goto mp4dec_fw_free; + } + vidc_h263_dec_fw = (unsigned char *)fw_h263_dec->data; + vidc_h263_dec_fw_size = (u32) fw_h263_dec->size; + + rc = request_firmware(&fw_h264_dec, VIDC_H264_DEC_FW, + resource_context.device); + if (rc) { + VCDRES_MSG_ERROR("request_firmware for %s error %d\n", + VIDC_H264_DEC_FW, rc); + status = false; + goto h263dec_fw_free; + } + vidc_h264_dec_fw = (unsigned char *)fw_h264_dec->data; + vidc_h264_dec_fw_size = (u32) fw_h264_dec->size; + + rc = request_firmware(&fw_mpg4_enc, VIDC_MPG4_ENC_FW, + resource_context.device); + if (rc) { + VCDRES_MSG_ERROR("request_firmware for %s error %d\n", + VIDC_MPG4_ENC_FW, rc); + status = false; + goto h264dec_fw_free; + } + vidc_mpg4_enc_fw = (unsigned char *)fw_mpg4_enc->data; + vidc_mpg4_enc_fw_size = (u32) fw_mpg4_enc->size; + + rc = request_firmware(&fw_h264_enc, VIDC_H264_ENC_FW, + resource_context.device); + if (rc) { + VCDRES_MSG_ERROR("request_firmware for %s error %d\n", + VIDC_H264_ENC_FW, rc); + status = false; + goto mp4enc_fw_free; + } + vidc_h264_enc_fw = (unsigned char *)fw_h264_enc->data; + vidc_h264_enc_fw_size = (u32) fw_h264_enc->size; + + rc = request_firmware(&fw_vc1_dec, VIDC_VC1_DEC_FW, + resource_context.device); + if (rc) { + VCDRES_MSG_ERROR("request_firmware for %s error %d\n", + VIDC_VC1_DEC_FW, rc); + status = false; + goto h264enc_fw_free; + } + vidc_vc1_dec_fw = (unsigned char *)fw_vc1_dec->data; + vidc_vc1_dec_fw_size = (u32) fw_vc1_dec->size; + mutex_unlock(&resource_context.lock); + return status; + +h264enc_fw_free: + release_firmware(fw_h264_enc); +mp4enc_fw_free: + release_firmware(fw_mpg4_enc); +h264dec_fw_free: + release_firmware(fw_h264_dec); +h263dec_fw_free: + release_firmware(fw_h263_dec); +mp4dec_fw_free: + release_firmware(fw_mpg4_dec); +boot_fw_free: + release_firmware(fw_boot); + mutex_unlock(&resource_context.lock); + return false; +} + +void res_trk_init(struct device *device, u32 irq) +{ + if (resource_context.device || resource_context.irq_num || + !device) { + VCDRES_MSG_ERROR("%s() Resource Tracker Init error\n", + __func__); + return; + } + memset(&resource_context, 0, sizeof(resource_context)); + mutex_init(&resource_context.lock); + resource_context.device = device; + resource_context.irq_num = irq; + resource_context.core_type = VCD_CORE_720P; + resource_context.regulator = regulator_get(NULL, "fs_mfc"); + resource_context.vidc_platform_data = + (struct msm_vidc_platform_data *) device->platform_data; + if (resource_context.vidc_platform_data) { + resource_context.memtype = + resource_context.vidc_platform_data->memtype; + } else { + resource_context.memtype = -1; + } +} + +u32 res_trk_get_core_type(void){ + return resource_context.core_type; +} + +u32 res_trk_get_mem_type(void){ + return resource_context.memtype; +} + +u32 res_trk_get_enable_ion(void) +{ + return 0; +} + +struct ion_client *res_trk_get_ion_client(void) +{ + return NULL; +} + +void res_trk_set_mem_type(enum ddl_mem_area mem_type) +{ + return; +} + +u32 res_trk_get_disable_fullhd(void) +{ + return 0; +} + +int res_trk_check_for_sec_session() +{ + return 0; +} + +void res_trk_secure_unset(void) +{ + return; +} + +void res_trk_secure_set(void) +{ + return; +} + +int res_trk_open_secure_session() +{ + return -EINVAL; +} + +int res_trk_close_secure_session() +{ + return 0; +} +u32 get_res_trk_perf_level(enum vcd_perf_level perf_level) +{ + return -ENOTSUPP; +} +u32 res_trk_is_cp_enabled(void) +{ + if (resource_context.vidc_platform_data->cp_enabled) + return 1; + else + return 0; +} +u32 res_trk_estimate_perf_level(u32 pn_perf_lvl) +{ + return 0; +} + diff --git a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h new file mode 100644 index 000000000000..d255772a2a0f --- /dev/null +++ b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h @@ -0,0 +1,57 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#ifndef _VIDEO_720P_RESOURCE_TRACKER_H_ +#define _VIDEO_720P_RESOURCE_TRACKER_H_ +#include +#include "vcd_res_tracker_api.h" + +#define VCD_RESTRK_MIN_PERF_LEVEL 37900 +#define VCD_RESTRK_MAX_PERF_LEVEL 108000 +#define VCD_RESTRK_MIN_FREQ_POINT 61440000 +#define VCD_RESTRK_MAX_FREQ_POINT 170667000 +#define VCD_RESTRK_HZ_PER_1000_PERFLVL 1580250 + +struct res_trk_context { + struct device *device; + u32 irq_num; + struct mutex lock; + struct clk *hclk; + struct clk *hclk_div2; + struct clk *pclk; + unsigned long hclk_rate; + unsigned int clock_enabled; + unsigned int rail_enabled; + struct regulator *regulator; + struct msm_vidc_platform_data *vidc_platform_data; + u32 core_type; + int memtype; + u32 secure_session; +}; + +#if DEBUG + +#define VCDRES_MSG_LOW(xx_fmt...) printk(KERN_INFO "\n\t* " xx_fmt) +#define VCDRES_MSG_MED(xx_fmt...) printk(KERN_INFO "\n * " xx_fmt) + +#else + +#define VCDRES_MSG_LOW(xx_fmt...) +#define VCDRES_MSG_MED(xx_fmt...) + +#endif + +#define VCDRES_MSG_HIGH(xx_fmt...) printk(KERN_WARNING "\n" xx_fmt) +#define VCDRES_MSG_ERROR(xx_fmt...) printk(KERN_ERR "\n err: " xx_fmt) +#define VCDRES_MSG_FATAL(xx_fmt...) printk(KERN_ERR "\n " xx_fmt) + +#endif diff --git a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h new file mode 100644 index 000000000000..1b2b4fa1cbb6 --- /dev/null +++ b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h @@ -0,0 +1,43 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#ifndef _VIDEO_720P_RESOURCE_TRACKER_API_H_ +#define _VIDEO_720P_RESOURCE_TRACKER_API_H_ + +#include "vcd_core.h" +#include "vcd_ddl.h" + +void res_trk_init(struct device *device, u32 irq); +u32 res_trk_power_up(void); +u32 res_trk_power_down(void); +u32 res_trk_enable_clocks(void); +u32 res_trk_disable_clocks(void); +u32 res_trk_get_max_perf_level(u32 *pn_max_perf_lvl); +u32 res_trk_set_perf_level(u32 req_perf_lvl, u32 *pn_set_perf_lvl, + struct vcd_dev_ctxt *dev_ctxt); +u32 res_trk_get_curr_perf_level(u32 *pn_perf_lvl); +u32 res_trk_download_firmware(void); +u32 res_trk_get_core_type(void); +u32 res_trk_get_mem_type(void); +u32 res_trk_get_disable_fullhd(void); +u32 res_trk_get_enable_ion(void); +u32 res_trk_is_cp_enabled(void); +struct ion_client *res_trk_get_ion_client(void); +void res_trk_set_mem_type(enum ddl_mem_area mem_type); +int res_trk_check_for_sec_session(void); +int res_trk_open_secure_session(void); +int res_trk_close_secure_session(void); +void res_trk_secure_set(void); +void res_trk_secure_unset(void); +u32 get_res_trk_perf_level(enum vcd_perf_level perf_level); +u32 res_trk_estimate_perf_level(u32 pn_perf_lvl); +#endif diff --git a/drivers/video/msm/vidc/Kconfig b/drivers/video/msm/vidc/Kconfig new file mode 100644 index 000000000000..9ffcb154af1d --- /dev/null +++ b/drivers/video/msm/vidc/Kconfig @@ -0,0 +1,39 @@ +# +# VIDEO CORE +# +menuconfig MSM_VIDC + bool "Video Core Driver" + depends on ARCH_MSM8X60 || ARCH_MSM7X30 || ARCH_MSM8960 + default y + ---help--- + Say Y here to see options for video device drivers. + If you say N, all options in this submenu will be skipped and disabled. + +config MSM_VIDC_720P + bool "720P Video Core" + depends on MSM_VIDC && ARCH_MSM7X30 + default y + help + This option enables support for Video core. + +config MSM_VIDC_1080P + bool "1080P Video Core" + depends on MSM_VIDC && (ARCH_MSM8X60 || ARCH_MSM8960) + default y + help + This option enables support for Video core. + +config MSM_VIDC_VENC + tristate "Video encoder" + depends on MSM_VIDC + default y + help + This option enables support for Video encoder. + +config MSM_VIDC_VDEC + tristate "Video decoder" + depends on MSM_VIDC + default y + help + This option enables support for Video decoder. + diff --git a/drivers/video/msm/vidc/Makefile b/drivers/video/msm/vidc/Makefile new file mode 100644 index 000000000000..af41f181878e --- /dev/null +++ b/drivers/video/msm/vidc/Makefile @@ -0,0 +1,62 @@ +ifdef CONFIG_MSM_VIDC_720P +EXTRA_CFLAGS += -Idrivers/video/msm/vidc/720p/ddl +EXTRA_CFLAGS += -Idrivers/video/msm/vidc/720p/resource_tracker +endif + +ifdef CONFIG_MSM_VIDC_1080P +EXTRA_CFLAGS += -Idrivers/video/msm/vidc/1080p/ddl +EXTRA_CFLAGS += -Idrivers/video/msm/vidc/1080p/resource_tracker +endif + +EXTRA_CFLAGS += -Idrivers/video/msm/vidc/common/dec +EXTRA_CFLAGS += -Idrivers/video/msm/vidc/common/enc +EXTRA_CFLAGS += -Idrivers/video/msm/vidc/common/vcd +EXTRA_CFLAGS += -Idrivers/video/msm/vidc/common/init + +obj-$(CONFIG_MSM_VIDC) += vidc.o + +vidc-objs := common/init/vidc_init.o \ + common/vcd/vcd_api.o \ + common/vcd/vcd_power_sm.o \ + common/vcd/vcd_client_sm.o \ + common/vcd/vcd_device_sm.o \ + common/vcd/vcd_scheduler.o \ + common/vcd/vcd_sub.o \ + +ifdef CONFIG_MSM_VIDC_720P +vidc-objs += 720p/ddl/vcd_ddl_firmware.o \ + 720p/ddl/vcd_ddl_metadata.o \ + 720p/ddl/vidc.o \ + 720p/ddl/vcd_ddl_utils.o \ + 720p/ddl/vcd_ddl.o \ + 720p/ddl/vcd_ddl_helper.o \ + 720p/ddl/vcd_ddl_interrupt_handler.o \ + 720p/ddl/vcd_ddl_hal.o \ + 720p/ddl/vcd_ddl_properties.o \ + 720p/resource_tracker/vcd_res_tracker.o \ + 720p/ddl/vcd_ddl_errors.o +endif + +ifdef CONFIG_MSM_VIDC_1080P +vidc-objs += 1080p/ddl/vcd_ddl_helper.o \ + 1080p/ddl/vcd_ddl_utils.o \ + 1080p/ddl/vcd_ddl_interrupt_handler.o \ + 1080p/ddl/vcd_ddl_properties.o \ + 1080p/ddl/vcd_ddl_errors.o \ + 1080p/ddl/vcd_ddl_shared_mem.o \ + 1080p/ddl/vidc.o \ + 1080p/ddl/vidc_pix_cache.o \ + 1080p/ddl/vcd_ddl_vidc.o \ + 1080p/ddl/vcd_ddl.o \ + 1080p/ddl/vcd_ddl_metadata.o \ + 1080p/resource_tracker/vcd_res_tracker.o +endif + +obj-$(CONFIG_MSM_VIDC_VDEC) += vidc_vdec.o + +vidc_vdec-objs := common/dec/vdec.o + +obj-$(CONFIG_MSM_VIDC_VENC) += vidc_venc.o + +vidc_venc-objs := common/enc/venc.o \ + common/enc/venc_internal.o diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c new file mode 100644 index 000000000000..716b04952e24 --- /dev/null +++ b/drivers/video/msm/vidc/common/dec/vdec.c @@ -0,0 +1,2380 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "vcd_res_tracker_api.h" +#include "vdec_internal.h" + + + +#define DBG(x...) pr_debug(x) +#define INFO(x...) pr_info(x) +#define ERR(x...) pr_err(x) + +#define VID_DEC_NAME "msm_vidc_dec" + +static char *node_name[2] = {"", "_sec"}; +static struct vid_dec_dev *vid_dec_device_p; +static dev_t vid_dec_dev_num; +static struct class *vid_dec_class; + +static unsigned int vidc_mmu_subsystem[] = { + MSM_SUBSYSTEM_VIDEO}; +static s32 vid_dec_get_empty_client_index(void) +{ + u32 i, found = false; + + for (i = 0; i < VIDC_MAX_NUM_CLIENTS; i++) { + if (!vid_dec_device_p->vdec_clients[i].vcd_handle) { + found = true; + break; + } + } + if (!found) { + ERR("%s():ERROR No space for new client\n", __func__); + return -ENOMEM; + } else { + DBG("%s(): available client index = %u\n", __func__, i); + return i; + } +} + +u32 vid_dec_get_status(u32 status) +{ + u32 vdec_status; + + switch (status) { + case VCD_ERR_SEQHDR_PARSE_FAIL: + case VCD_ERR_BITSTREAM_ERR: + vdec_status = VDEC_S_INPUT_BITSTREAM_ERR; + break; + case VCD_S_SUCCESS: + vdec_status = VDEC_S_SUCCESS; + break; + case VCD_ERR_FAIL: + vdec_status = VDEC_S_EFAIL; + break; + case VCD_ERR_ALLOC_FAIL: + vdec_status = VDEC_S_ENOSWRES; + break; + case VCD_ERR_ILLEGAL_OP: + vdec_status = VDEC_S_EINVALCMD; + break; + case VCD_ERR_ILLEGAL_PARM: + vdec_status = VDEC_S_EBADPARAM; + break; + case VCD_ERR_BAD_POINTER: + case VCD_ERR_BAD_HANDLE: + vdec_status = VDEC_S_EFATAL; + break; + case VCD_ERR_NOT_SUPPORTED: + vdec_status = VDEC_S_ENOTSUPP; + break; + case VCD_ERR_BAD_STATE: + vdec_status = VDEC_S_EINVALSTATE; + break; + case VCD_ERR_BUSY: + vdec_status = VDEC_S_BUSY; + break; + case VCD_ERR_MAX_CLIENT: + vdec_status = VDEC_S_ENOHWRES; + break; + default: + vdec_status = VDEC_S_EFAIL; + break; + } + + return vdec_status; +} + +static void vid_dec_notify_client(struct video_client_ctx *client_ctx) +{ + if (client_ctx) + complete(&client_ctx->event); +} + +void vid_dec_vcd_open_done(struct video_client_ctx *client_ctx, + struct vcd_handle_container *handle_container) +{ + DBG("vid_dec_vcd_open_done\n"); + + if (client_ctx) { + if (handle_container) + client_ctx->vcd_handle = handle_container->handle; + else + ERR("%s(): ERROR. handle_container is NULL\n", + __func__); + + vid_dec_notify_client(client_ctx); + } else + ERR("%s(): ERROR. client_ctx is NULL\n", __func__); +} + +static void vid_dec_handle_field_drop(struct video_client_ctx *client_ctx, + u32 event, u32 status, int64_t time_stamp) +{ + struct vid_dec_msg *vdec_msg; + + if (!client_ctx) { + ERR("%s() NULL pointer\n", __func__); + return; + } + + vdec_msg = kzalloc(sizeof(struct vid_dec_msg), GFP_KERNEL); + if (!vdec_msg) { + ERR("%s(): cannot allocate vid_dec_msg " + " buffer\n", __func__); + return; + } + vdec_msg->vdec_msg_info.status_code = vid_dec_get_status(status); + if (event == VCD_EVT_IND_INFO_FIELD_DROPPED) { + vdec_msg->vdec_msg_info.msgcode = + VDEC_MSG_EVT_INFO_FIELD_DROPPED; + vdec_msg->vdec_msg_info.msgdata.output_frame.time_stamp + = time_stamp; + DBG("Send FIELD_DROPPED message to client = %p\n", client_ctx); + } else { + ERR("vid_dec_input_frame_done(): invalid event type: " + "%d\n", event); + vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_INVALID; + } + vdec_msg->vdec_msg_info.msgdatasize = + sizeof(struct vdec_output_frameinfo); + mutex_lock(&client_ctx->msg_queue_lock); + list_add_tail(&vdec_msg->list, &client_ctx->msg_queue); + mutex_unlock(&client_ctx->msg_queue_lock); + wake_up(&client_ctx->msg_wait); +} + +static void vid_dec_input_frame_done(struct video_client_ctx *client_ctx, + u32 event, u32 status, + struct vcd_frame_data *vcd_frame_data) +{ + struct vid_dec_msg *vdec_msg; + + if (!client_ctx || !vcd_frame_data) { + ERR("vid_dec_input_frame_done() NULL pointer\n"); + return; + } + + kfree(vcd_frame_data->desc_buf); + vcd_frame_data->desc_buf = NULL; + vcd_frame_data->desc_size = 0; + + vdec_msg = kzalloc(sizeof(struct vid_dec_msg), GFP_KERNEL); + if (!vdec_msg) { + ERR("vid_dec_input_frame_done(): cannot allocate vid_dec_msg " + " buffer\n"); + return; + } + + vdec_msg->vdec_msg_info.status_code = vid_dec_get_status(status); + + if (event == VCD_EVT_RESP_INPUT_DONE) { + vdec_msg->vdec_msg_info.msgcode = + VDEC_MSG_RESP_INPUT_BUFFER_DONE; + DBG("Send INPUT_DON message to client = %p\n", client_ctx); + + } else if (event == VCD_EVT_RESP_INPUT_FLUSHED) { + vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_RESP_INPUT_FLUSHED; + DBG("Send INPUT_FLUSHED message to client = %p\n", client_ctx); + } else { + ERR("vid_dec_input_frame_done(): invalid event type: " + "%d\n", event); + vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_INVALID; + } + + vdec_msg->vdec_msg_info.msgdata.input_frame_clientdata = + (void *)vcd_frame_data->frm_clnt_data; + vdec_msg->vdec_msg_info.msgdatasize = sizeof(void *); + + mutex_lock(&client_ctx->msg_queue_lock); + list_add_tail(&vdec_msg->list, &client_ctx->msg_queue); + mutex_unlock(&client_ctx->msg_queue_lock); + wake_up(&client_ctx->msg_wait); +} + +static void vid_dec_output_frame_done(struct video_client_ctx *client_ctx, + u32 event, u32 status, + struct vcd_frame_data *vcd_frame_data) +{ + struct vid_dec_msg *vdec_msg; + + unsigned long kernel_vaddr = 0, phy_addr = 0, user_vaddr = 0; + int pmem_fd; + struct file *file; + s32 buffer_index = -1; + enum vdec_picture pic_type; + u32 ion_flag = 0; + struct ion_handle *buff_handle = NULL; + struct vdec_output_frameinfo *output_frame; + + if (!client_ctx || !vcd_frame_data) { + ERR("vid_dec_input_frame_done() NULL pointer\n"); + return; + } + + vdec_msg = kzalloc(sizeof(struct vid_dec_msg), GFP_KERNEL); + if (!vdec_msg) { + ERR("vid_dec_input_frame_done(): cannot allocate vid_dec_msg " + " buffer\n"); + return; + } + + vdec_msg->vdec_msg_info.status_code = vid_dec_get_status(status); + + if (event == VCD_EVT_RESP_OUTPUT_DONE) + vdec_msg->vdec_msg_info.msgcode = + VDEC_MSG_RESP_OUTPUT_BUFFER_DONE; + else if (event == VCD_EVT_RESP_OUTPUT_FLUSHED) + vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_RESP_OUTPUT_FLUSHED; + else { + ERR("QVD: vid_dec_output_frame_done invalid cmd type: " + "%d\n", event); + vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_INVALID; + } + + kernel_vaddr = (unsigned long)vcd_frame_data->virtual; + + if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT, + false, &user_vaddr, &kernel_vaddr, + &phy_addr, &pmem_fd, &file, + &buffer_index) || + (vcd_frame_data->flags & VCD_FRAME_FLAG_EOS)) { + /* Buffer address in user space */ + vdec_msg->vdec_msg_info.msgdata.output_frame.bufferaddr = + (u8 *) user_vaddr; + /* Data length */ + vdec_msg->vdec_msg_info.msgdata.output_frame.len = + vcd_frame_data->data_len; + vdec_msg->vdec_msg_info.msgdata.output_frame.flags = + vcd_frame_data->flags; + /* Timestamp pass-through from input frame */ + vdec_msg->vdec_msg_info.msgdata.output_frame.time_stamp = + vcd_frame_data->time_stamp; + /* Output frame client data */ + vdec_msg->vdec_msg_info.msgdata.output_frame.client_data = + (void *)vcd_frame_data->frm_clnt_data; + /* Associated input frame client data */ + vdec_msg->vdec_msg_info.msgdata.output_frame. + input_frame_clientdata = + (void *)vcd_frame_data->ip_frm_tag; + /* Decoded picture width and height */ + vdec_msg->vdec_msg_info.msgdata.output_frame.framesize. + bottom = + vcd_frame_data->dec_op_prop.disp_frm.bottom; + vdec_msg->vdec_msg_info.msgdata.output_frame.framesize.left = + vcd_frame_data->dec_op_prop.disp_frm.left; + vdec_msg->vdec_msg_info.msgdata.output_frame.framesize.right = + vcd_frame_data->dec_op_prop.disp_frm.right; + vdec_msg->vdec_msg_info.msgdata.output_frame.framesize.top = + vcd_frame_data->dec_op_prop.disp_frm.top; + if (vcd_frame_data->interlaced) { + vdec_msg->vdec_msg_info.msgdata. + output_frame.interlaced_format = + VDEC_InterlaceInterleaveFrameTopFieldFirst; + } else { + vdec_msg->vdec_msg_info.msgdata. + output_frame.interlaced_format = + VDEC_InterlaceFrameProgressive; + } + /* Decoded picture type */ + switch (vcd_frame_data->frame) { + case VCD_FRAME_I: + pic_type = PICTURE_TYPE_I; + break; + case VCD_FRAME_P: + pic_type = PICTURE_TYPE_P; + break; + case VCD_FRAME_B: + pic_type = PICTURE_TYPE_B; + break; + case VCD_FRAME_NOTCODED: + pic_type = PICTURE_TYPE_SKIP; + break; + case VCD_FRAME_IDR: + pic_type = PICTURE_TYPE_IDR; + break; + default: + pic_type = PICTURE_TYPE_UNKNOWN; + } + vdec_msg->vdec_msg_info.msgdata.output_frame.pic_type = + pic_type; + output_frame = &vdec_msg->vdec_msg_info.msgdata.output_frame; + output_frame->aspect_ratio_info.aspect_ratio = + vcd_frame_data->aspect_ratio_info.aspect_ratio; + output_frame->aspect_ratio_info.par_width = + vcd_frame_data->aspect_ratio_info.extended_par_width; + output_frame->aspect_ratio_info.par_height = + vcd_frame_data->aspect_ratio_info.extended_par_height; + vdec_msg->vdec_msg_info.msgdatasize = + sizeof(struct vdec_output_frameinfo); + } else { + ERR("vid_dec_output_frame_done UVA can not be found\n"); + vdec_msg->vdec_msg_info.status_code = VDEC_S_EFATAL; + } + if (vcd_frame_data->data_len > 0) { + ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_OUTPUT, + pmem_fd, kernel_vaddr, buffer_index, + &buff_handle); + if (ion_flag == CACHED && buff_handle) { + msm_ion_do_cache_op(client_ctx->user_ion_client, + buff_handle, + (unsigned long *) kernel_vaddr, + (unsigned long)vcd_frame_data->data_len, + ION_IOC_INV_CACHES); + } + } + mutex_lock(&client_ctx->msg_queue_lock); + list_add_tail(&vdec_msg->list, &client_ctx->msg_queue); + mutex_unlock(&client_ctx->msg_queue_lock); + wake_up(&client_ctx->msg_wait); +} + +static void vid_dec_lean_event(struct video_client_ctx *client_ctx, + u32 event, u32 status) +{ + struct vid_dec_msg *vdec_msg; + + if (!client_ctx) { + ERR("%s(): !client_ctx pointer\n", __func__); + return; + } + + vdec_msg = kzalloc(sizeof(struct vid_dec_msg), GFP_KERNEL); + if (!vdec_msg) { + ERR("%s(): cannot allocate vid_dec_msg buffer\n", __func__); + return; + } + + vdec_msg->vdec_msg_info.status_code = vid_dec_get_status(status); + + switch (event) { + case VCD_EVT_IND_OUTPUT_RECONFIG: + DBG("msm_vidc_dec: Sending VDEC_MSG_EVT_CONFIG_CHANGED" + " to client"); + vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_EVT_CONFIG_CHANGED; + break; + case VCD_EVT_IND_RESOURCES_LOST: + DBG("msm_vidc_dec: Sending VDEC_EVT_RESOURCES_LOST" + " to client"); + vdec_msg->vdec_msg_info.msgcode = VDEC_EVT_RESOURCES_LOST; + break; + case VCD_EVT_RESP_FLUSH_INPUT_DONE: + DBG("msm_vidc_dec: Sending VDEC_MSG_RESP_FLUSH_INPUT_DONE" + " to client"); + vdec_msg->vdec_msg_info.msgcode = + VDEC_MSG_RESP_FLUSH_INPUT_DONE; + break; + case VCD_EVT_RESP_FLUSH_OUTPUT_DONE: + DBG("msm_vidc_dec: Sending VDEC_MSG_RESP_FLUSH_OUTPUT_DONE" + " to client"); + vdec_msg->vdec_msg_info.msgcode = + VDEC_MSG_RESP_FLUSH_OUTPUT_DONE; + break; + case VCD_EVT_IND_HWERRFATAL: + DBG("msm_vidc_dec: Sending VDEC_MSG_EVT_HW_ERROR" + " to client"); + vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_EVT_HW_ERROR; + break; + case VCD_EVT_RESP_START: + DBG("msm_vidc_dec: Sending VDEC_MSG_RESP_START_DONE" + " to client"); + vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_RESP_START_DONE; + break; + case VCD_EVT_RESP_STOP: + DBG("msm_vidc_dec: Sending VDEC_MSG_RESP_STOP_DONE" + " to client"); + vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_RESP_STOP_DONE; + break; + case VCD_EVT_RESP_PAUSE: + DBG("msm_vidc_dec: Sending VDEC_MSG_RESP_PAUSE_DONE" + " to client"); + vdec_msg->vdec_msg_info.msgcode = VDEC_MSG_RESP_PAUSE_DONE; + break; + case VCD_EVT_IND_INFO_OUTPUT_RECONFIG: + DBG("msm_vidc_dec: Sending VDEC_MSG_EVT_INFO_CONFIG_CHANGED" + " to client"); + vdec_msg->vdec_msg_info.msgcode = + VDEC_MSG_EVT_INFO_CONFIG_CHANGED; + break; + default: + ERR("%s() : unknown event type\n", __func__); + break; + } + + vdec_msg->vdec_msg_info.msgdatasize = 0; + if (client_ctx->stop_sync_cb && + (event == VCD_EVT_RESP_STOP || event == VCD_EVT_IND_HWERRFATAL)) { + client_ctx->stop_sync_cb = false; + complete(&client_ctx->event); + kfree(vdec_msg); + return; + } + mutex_lock(&client_ctx->msg_queue_lock); + list_add_tail(&vdec_msg->list, &client_ctx->msg_queue); + mutex_unlock(&client_ctx->msg_queue_lock); + wake_up(&client_ctx->msg_wait); +} + + +void vid_dec_vcd_cb(u32 event, u32 status, + void *info, size_t sz, void *handle, void *const client_data) +{ + struct video_client_ctx *client_ctx = + (struct video_client_ctx *)client_data; + + DBG("Entering %s()\n", __func__); + + if (!client_ctx) { + ERR("%s(): client_ctx is NULL\n", __func__); + return; + } + + client_ctx->event_status = status; + + switch (event) { + case VCD_EVT_RESP_OPEN: + vid_dec_vcd_open_done(client_ctx, + (struct vcd_handle_container *) + info); + break; + case VCD_EVT_RESP_INPUT_DONE: + case VCD_EVT_RESP_INPUT_FLUSHED: + vid_dec_input_frame_done(client_ctx, event, status, + (struct vcd_frame_data *)info); + break; + case VCD_EVT_IND_INFO_FIELD_DROPPED: + if (info) + vid_dec_handle_field_drop(client_ctx, event, + status, *((int64_t *)info)); + else + pr_err("Wrong Payload for Field dropped\n"); + break; + case VCD_EVT_RESP_OUTPUT_DONE: + case VCD_EVT_RESP_OUTPUT_FLUSHED: + vid_dec_output_frame_done(client_ctx, event, status, + (struct vcd_frame_data *)info); + break; + case VCD_EVT_RESP_PAUSE: + case VCD_EVT_RESP_STOP: + case VCD_EVT_RESP_FLUSH_INPUT_DONE: + case VCD_EVT_RESP_FLUSH_OUTPUT_DONE: + case VCD_EVT_IND_OUTPUT_RECONFIG: + case VCD_EVT_IND_HWERRFATAL: + case VCD_EVT_IND_RESOURCES_LOST: + case VCD_EVT_IND_INFO_OUTPUT_RECONFIG: + vid_dec_lean_event(client_ctx, event, status); + break; + case VCD_EVT_RESP_START: + if (!client_ctx->seq_header_set) + vid_dec_lean_event(client_ctx, event, status); + else + vid_dec_notify_client(client_ctx); + break; + default: + ERR("%s() : Error - Invalid event type =%u\n", __func__, + event); + break; + } +} + +static u32 vid_dec_set_codec(struct video_client_ctx *client_ctx, + enum vdec_codec *vdec_codec) +{ + u32 result = true; + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_codec codec; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx || !vdec_codec) + return false; + + vcd_property_hdr.prop_id = VCD_I_CODEC; + vcd_property_hdr.sz = sizeof(struct vcd_property_codec); + + switch (*vdec_codec) { + case VDEC_CODECTYPE_MPEG4: + codec.codec = VCD_CODEC_MPEG4; + break; + case VDEC_CODECTYPE_H264: + codec.codec = VCD_CODEC_H264; + break; + case VDEC_CODECTYPE_DIVX_3: + codec.codec = VCD_CODEC_DIVX_3; + break; + case VDEC_CODECTYPE_DIVX_4: + codec.codec = VCD_CODEC_DIVX_4; + break; + case VDEC_CODECTYPE_DIVX_5: + codec.codec = VCD_CODEC_DIVX_5; + break; + case VDEC_CODECTYPE_DIVX_6: + codec.codec = VCD_CODEC_DIVX_6; + break; + case VDEC_CODECTYPE_XVID: + codec.codec = VCD_CODEC_XVID; + break; + case VDEC_CODECTYPE_H263: + codec.codec = VCD_CODEC_H263; + break; + case VDEC_CODECTYPE_MPEG2: + codec.codec = VCD_CODEC_MPEG2; + break; + case VDEC_CODECTYPE_VC1: + codec.codec = VCD_CODEC_VC1; + break; + case VDEC_CODECTYPE_VC1_RCV: + codec.codec = VCD_CODEC_VC1_RCV; + break; + default: + result = false; + break; + } + + if (result) { + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &codec); + if (vcd_status) + result = false; + } + return result; +} + +static u32 vid_dec_set_output_format(struct video_client_ctx *client_ctx, + enum vdec_output_fromat *output_format) +{ + u32 result = true; + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_buffer_format vcd_prop_buffer_format; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx || !output_format) + return false; + + vcd_property_hdr.prop_id = VCD_I_BUFFER_FORMAT;; + vcd_property_hdr.sz = + sizeof(struct vcd_property_buffer_format); + + switch (*output_format) { + case VDEC_YUV_FORMAT_NV12: + vcd_prop_buffer_format.buffer_format = VCD_BUFFER_FORMAT_NV12; + break; + case VDEC_YUV_FORMAT_TILE_4x2: + vcd_prop_buffer_format.buffer_format = + VCD_BUFFER_FORMAT_TILE_4x2; + break; + default: + result = false; + break; + } + + if (result) + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, + &vcd_prop_buffer_format); + + if (vcd_status) + return false; + else + return true; +} + +static u32 vid_dec_set_frame_resolution(struct video_client_ctx *client_ctx, + struct vdec_picsize *video_resoultion) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_frame_size frame_resolution; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx || !video_resoultion) + return false; + + vcd_property_hdr.prop_id = VCD_I_FRAME_SIZE; + vcd_property_hdr.sz = sizeof(struct vcd_property_frame_size); + frame_resolution.width = video_resoultion->frame_width; + frame_resolution.height = video_resoultion->frame_height; + frame_resolution.stride = video_resoultion->stride; + frame_resolution.scan_lines = video_resoultion->scan_lines; + + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &frame_resolution); + + if (vcd_status) + return false; + else + return true; +} + +static u32 vid_dec_get_frame_resolution(struct video_client_ctx *client_ctx, + struct vdec_picsize *video_resoultion) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_frame_size frame_resolution; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx || !video_resoultion) + return false; + + vcd_property_hdr.prop_id = VCD_I_FRAME_SIZE; + vcd_property_hdr.sz = sizeof(struct vcd_property_frame_size); + + vcd_status = vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr, + &frame_resolution); + + video_resoultion->frame_width = frame_resolution.width; + video_resoultion->frame_height = frame_resolution.height; + video_resoultion->scan_lines = frame_resolution.scan_lines; + video_resoultion->stride = frame_resolution.stride; + + if (vcd_status) + return false; + else + return true; +} + +static u32 vid_dec_get_progressive_only(struct video_client_ctx *client_ctx, + u32 *progressive_only) +{ + struct vcd_property_hdr vcd_property_hdr; + if (!client_ctx || !progressive_only) + return false; + vcd_property_hdr.prop_id = VCD_I_PROGRESSIVE_ONLY; + vcd_property_hdr.sz = sizeof(u32); + if (vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr, + progressive_only)) + return false; + else + return true; +} + +static u32 vid_dec_get_disable_dmx_support(struct video_client_ctx *client_ctx, + u32 *disable_dmx) +{ + + struct vcd_property_hdr vcd_property_hdr; + if (!client_ctx || !disable_dmx) + return false; + vcd_property_hdr.prop_id = VCD_I_DISABLE_DMX_SUPPORT; + vcd_property_hdr.sz = sizeof(u32); + if (vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr, + disable_dmx)) + return false; + else + return true; +} +static u32 vid_dec_get_disable_dmx(struct video_client_ctx *client_ctx, + u32 *disable_dmx) +{ + + struct vcd_property_hdr vcd_property_hdr; + if (!client_ctx || !disable_dmx) + return false; + vcd_property_hdr.prop_id = VCD_I_DISABLE_DMX; + vcd_property_hdr.sz = sizeof(u32); + if (vcd_get_property(client_ctx->vcd_handle, &vcd_property_hdr, + disable_dmx)) + return false; + else + return true; +} + +static u32 vid_dec_set_disable_dmx(struct video_client_ctx *client_ctx) +{ + + struct vcd_property_hdr vcd_property_hdr; + u32 vcd_disable_dmx; + if (!client_ctx) + return false; + vcd_property_hdr.prop_id = VCD_I_DISABLE_DMX; + vcd_property_hdr.sz = sizeof(u32); + vcd_disable_dmx = true; + DBG("%s() : Setting Disable DMX: %d\n", + __func__, vcd_disable_dmx); + + if (vcd_set_property(client_ctx->vcd_handle, &vcd_property_hdr, + &vcd_disable_dmx)) + return false; + else + return true; +} + +static u32 vid_dec_set_picture_order(struct video_client_ctx *client_ctx, + u32 *picture_order) +{ + struct vcd_property_hdr vcd_property_hdr; + u32 vcd_status = VCD_ERR_FAIL, vcd_picture_order, ret = true; + if (!client_ctx || !picture_order) + return false; + vcd_property_hdr.prop_id = VCD_I_OUTPUT_ORDER; + vcd_property_hdr.sz = sizeof(u32); + if (*picture_order == VDEC_ORDER_DISPLAY) + vcd_picture_order = VCD_DEC_ORDER_DISPLAY; + else if (*picture_order == VDEC_ORDER_DECODE) + vcd_picture_order = VCD_DEC_ORDER_DECODE; + else + ret = false; + if (ret) { + DBG("%s() : Setting output picture order: %d\n", + __func__, vcd_picture_order); + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &vcd_picture_order); + if (vcd_status != VCD_S_SUCCESS) + ret = false; + } + return ret; +} + +static u32 vid_dec_set_frame_rate(struct video_client_ctx *client_ctx, + struct vdec_framerate *frame_rate) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_frame_rate vcd_frame_rate; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx || !frame_rate) + return false; + + vcd_property_hdr.prop_id = VCD_I_FRAME_RATE; + vcd_property_hdr.sz = sizeof(struct vcd_property_frame_rate); + vcd_frame_rate.fps_numerator = frame_rate->fps_numerator; + vcd_frame_rate.fps_denominator = frame_rate->fps_denominator; + + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &vcd_frame_rate); + + if (vcd_status) + return false; + else + return true; +} + +static u32 vid_dec_set_extradata(struct video_client_ctx *client_ctx, + u32 *extradata_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_meta_data_enable vcd_meta_data; + u32 vcd_status = VCD_ERR_FAIL; + if (!client_ctx || !extradata_flag) + return false; + vcd_property_hdr.prop_id = VCD_I_METADATA_ENABLE; + vcd_property_hdr.sz = sizeof(struct vcd_property_meta_data_enable); + vcd_meta_data.meta_data_enable_flag = *extradata_flag; + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &vcd_meta_data); + if (vcd_status) + return false; + else + return true; +} + +static u32 vid_dec_set_idr_only_decoding(struct video_client_ctx *client_ctx) +{ + struct vcd_property_hdr vcd_property_hdr; + u32 vcd_status = VCD_ERR_FAIL; + u32 enable = true; + if (!client_ctx) + return false; + vcd_property_hdr.prop_id = VCD_I_DEC_PICTYPE; + vcd_property_hdr.sz = sizeof(u32); + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &enable); + if (vcd_status) + return false; + return true; +} + +static u32 vid_dec_set_h264_mv_buffers(struct video_client_ctx *client_ctx, + struct vdec_h264_mv *mv_data) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_h264_mv_buffer *vcd_h264_mv_buffer = NULL; + struct msm_mapped_buffer *mapped_buffer = NULL; + u32 vcd_status = VCD_ERR_FAIL; + u32 len = 0, flags = 0; + struct file *file; + int rc = 0; + unsigned long ionflag = 0; + unsigned long buffer_size = 0; + unsigned long iova = 0; + + if (!client_ctx || !mv_data) + return false; + + vcd_property_hdr.prop_id = VCD_I_H264_MV_BUFFER; + vcd_property_hdr.sz = sizeof(struct vcd_property_h264_mv_buffer); + vcd_h264_mv_buffer = &client_ctx->vcd_h264_mv_buffer; + + memset(&client_ctx->vcd_h264_mv_buffer, 0, + sizeof(struct vcd_property_h264_mv_buffer)); + vcd_h264_mv_buffer->size = mv_data->size; + vcd_h264_mv_buffer->count = mv_data->count; + vcd_h264_mv_buffer->pmem_fd = mv_data->pmem_fd; + vcd_h264_mv_buffer->offset = mv_data->offset; + + if (!vcd_get_ion_status()) { + if (get_pmem_file(vcd_h264_mv_buffer->pmem_fd, + (unsigned long *) (&(vcd_h264_mv_buffer-> + physical_addr)), + (unsigned long *) (&vcd_h264_mv_buffer-> + kernel_virtual_addr), + (unsigned long *) (&len), &file)) { + ERR("%s(): get_pmem_file failed\n", __func__); + return false; + } + put_pmem_file(file); + flags = MSM_SUBSYSTEM_MAP_IOVA; + mapped_buffer = msm_subsystem_map_buffer( + (unsigned long)vcd_h264_mv_buffer->physical_addr, len, + flags, vidc_mmu_subsystem, + sizeof(vidc_mmu_subsystem)/ + sizeof(unsigned int)); + if (IS_ERR(mapped_buffer)) { + pr_err("buffer map failed"); + return false; + } + vcd_h264_mv_buffer->client_data = (void *) mapped_buffer; + vcd_h264_mv_buffer->dev_addr = (u8 *)mapped_buffer->iova[0]; + } else { + client_ctx->h264_mv_ion_handle = ion_import_fd( + client_ctx->user_ion_client, + vcd_h264_mv_buffer->pmem_fd); + if (IS_ERR_OR_NULL(client_ctx->h264_mv_ion_handle)) { + ERR("%s(): get_ION_handle failed\n", __func__); + goto import_ion_error; + } + rc = ion_handle_get_flags(client_ctx->user_ion_client, + client_ctx->h264_mv_ion_handle, + &ionflag); + if (rc) { + ERR("%s():get_ION_flags fail\n", + __func__); + goto import_ion_error; + } + vcd_h264_mv_buffer->kernel_virtual_addr = (u8 *) ion_map_kernel( + client_ctx->user_ion_client, + client_ctx->h264_mv_ion_handle, + ionflag); + if (!vcd_h264_mv_buffer->kernel_virtual_addr) { + ERR("%s(): get_ION_kernel virtual addr failed\n", + __func__); + goto import_ion_error; + } + if (res_trk_check_for_sec_session()) { + rc = ion_phys(client_ctx->user_ion_client, + client_ctx->h264_mv_ion_handle, + (unsigned long *) (&(vcd_h264_mv_buffer-> + physical_addr)), &len); + if (rc) { + ERR("%s():get_ION_kernel physical addr fail\n", + __func__); + goto ion_map_error; + } + vcd_h264_mv_buffer->client_data = NULL; + vcd_h264_mv_buffer->dev_addr = (u8 *) + vcd_h264_mv_buffer->physical_addr; + } else { + rc = ion_map_iommu(client_ctx->user_ion_client, + client_ctx->h264_mv_ion_handle, + VIDEO_DOMAIN, VIDEO_MAIN_POOL, + SZ_4K, 0, (unsigned long *)&iova, + (unsigned long *)&buffer_size, + UNCACHED, 0); + if (rc) { + ERR("%s():get_ION_kernel physical addr fail\n", + __func__); + goto ion_map_error; + } + vcd_h264_mv_buffer->physical_addr = (u8 *) iova; + vcd_h264_mv_buffer->client_data = NULL; + vcd_h264_mv_buffer->dev_addr = (u8 *) iova; + } + } + DBG("Virt: %p, Phys %p, fd: %d", vcd_h264_mv_buffer-> + kernel_virtual_addr, vcd_h264_mv_buffer->physical_addr, + vcd_h264_mv_buffer->pmem_fd); + DBG("Dev addr %p", vcd_h264_mv_buffer->dev_addr); + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, vcd_h264_mv_buffer); + + if (vcd_status) + return false; + else + return true; +ion_map_error: + if (vcd_h264_mv_buffer->kernel_virtual_addr) { + ion_unmap_kernel(client_ctx->user_ion_client, + client_ctx->h264_mv_ion_handle); + vcd_h264_mv_buffer->kernel_virtual_addr = NULL; + } + if (!IS_ERR_OR_NULL(client_ctx->h264_mv_ion_handle)) { + ion_free(client_ctx->user_ion_client, + client_ctx->h264_mv_ion_handle); + client_ctx->h264_mv_ion_handle = NULL; + } +import_ion_error: + return false; +} + +static u32 vid_dec_set_cont_on_reconfig(struct video_client_ctx *client_ctx) +{ + struct vcd_property_hdr vcd_property_hdr; + u32 vcd_status = VCD_ERR_FAIL; + u32 enable = true; + if (!client_ctx) + return false; + vcd_property_hdr.prop_id = VCD_I_CONT_ON_RECONFIG; + vcd_property_hdr.sz = sizeof(u32); + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &enable); + if (vcd_status) + return false; + return true; +} + +static u32 vid_dec_get_h264_mv_buffer_size(struct video_client_ctx *client_ctx, + struct vdec_mv_buff_size *mv_buff) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_buffer_size h264_mv_buffer_size; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx || !mv_buff) + return false; + + vcd_property_hdr.prop_id = VCD_I_GET_H264_MV_SIZE; + vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size); + + h264_mv_buffer_size.width = mv_buff->width; + h264_mv_buffer_size.height = mv_buff->height; + + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &h264_mv_buffer_size); + + mv_buff->width = h264_mv_buffer_size.width; + mv_buff->height = h264_mv_buffer_size.height; + mv_buff->size = h264_mv_buffer_size.size; + mv_buff->alignment = h264_mv_buffer_size.alignment; + + if (vcd_status) + return false; + else + return true; +} + +static u32 vid_dec_free_h264_mv_buffers(struct video_client_ctx *client_ctx) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_buffer_size h264_mv_buffer_size; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx) + return false; + if (client_ctx->vcd_h264_mv_buffer.client_data) + msm_subsystem_unmap_buffer((struct msm_mapped_buffer *) + client_ctx->vcd_h264_mv_buffer.client_data); + + vcd_property_hdr.prop_id = VCD_I_FREE_H264_MV_BUFFER; + vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size); + + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &h264_mv_buffer_size); + + if (!IS_ERR_OR_NULL(client_ctx->h264_mv_ion_handle)) { + ion_unmap_kernel(client_ctx->user_ion_client, + client_ctx->h264_mv_ion_handle); + if (!res_trk_check_for_sec_session()) { + ion_unmap_iommu(client_ctx->user_ion_client, + client_ctx->h264_mv_ion_handle, + VIDEO_DOMAIN, + VIDEO_MAIN_POOL); + } + ion_free(client_ctx->user_ion_client, + client_ctx->h264_mv_ion_handle); + client_ctx->h264_mv_ion_handle = NULL; + } + + if (vcd_status) + return false; + else + return true; +} + +static u32 vid_dec_get_buffer_req(struct video_client_ctx *client_ctx, + struct vdec_allocatorproperty *vdec_buf_req) +{ + u32 vcd_status = VCD_ERR_FAIL; + struct vcd_buffer_requirement vcd_buf_req; + + if (!client_ctx || !vdec_buf_req) + return false; + + if (vdec_buf_req->buffer_type == VDEC_BUFFER_TYPE_INPUT) { + vcd_status = vcd_get_buffer_requirements(client_ctx->vcd_handle, + VCD_BUFFER_INPUT, + &vcd_buf_req); + } else { + vcd_status = vcd_get_buffer_requirements(client_ctx->vcd_handle, + VCD_BUFFER_OUTPUT, + &vcd_buf_req); + } + + if (vcd_status) { + return false; + } else { + vdec_buf_req->mincount = vcd_buf_req.min_count; + vdec_buf_req->maxcount = vcd_buf_req.max_count; + vdec_buf_req->actualcount = vcd_buf_req.actual_count; + vdec_buf_req->buffer_size = vcd_buf_req.sz; + vdec_buf_req->alignment = vcd_buf_req.align; + vdec_buf_req->buf_poolid = vcd_buf_req.buf_pool_id; + + return true; + } +} + +static u32 vid_dec_set_buffer(struct video_client_ctx *client_ctx, + struct vdec_setbuffer_cmd *buffer_info) +{ + enum vcd_buffer_type buffer = VCD_BUFFER_INPUT; + enum buffer_dir dir_buffer = BUFFER_TYPE_INPUT; + u32 vcd_status = VCD_ERR_FAIL; + unsigned long kernel_vaddr, buf_adr_offset = 0, length; + + if (!client_ctx || !buffer_info) + return false; + + if (buffer_info->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { + dir_buffer = BUFFER_TYPE_OUTPUT; + buffer = VCD_BUFFER_OUTPUT; + buf_adr_offset = (unsigned long)buffer_info->buffer.offset; + } + length = buffer_info->buffer.buffer_len; + /*If buffer cannot be set, ignore */ + if (!vidc_insert_addr_table(client_ctx, dir_buffer, + (unsigned long)buffer_info->buffer.bufferaddr, + &kernel_vaddr, buffer_info->buffer.pmem_fd, + buf_adr_offset, MAX_VIDEO_NUM_OF_BUFF, length)) { + DBG("%s() : user_virt_addr = %p cannot be set.", + __func__, buffer_info->buffer.bufferaddr); + return false; + } + vcd_status = vcd_set_buffer(client_ctx->vcd_handle, + buffer, (u8 *) kernel_vaddr, + buffer_info->buffer.buffer_len); + + if (!vcd_status) + return true; + else + return false; +} + + +static u32 vid_dec_free_buffer(struct video_client_ctx *client_ctx, + struct vdec_setbuffer_cmd *buffer_info) +{ + enum vcd_buffer_type buffer = VCD_BUFFER_INPUT; + enum buffer_dir dir_buffer = BUFFER_TYPE_INPUT; + u32 vcd_status = VCD_ERR_FAIL; + unsigned long kernel_vaddr; + + if (!client_ctx || !buffer_info) + return false; + + if (buffer_info->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { + dir_buffer = BUFFER_TYPE_OUTPUT; + buffer = VCD_BUFFER_OUTPUT; + } + + /*If buffer NOT set, ignore */ + if (!vidc_delete_addr_table(client_ctx, dir_buffer, + (unsigned long)buffer_info->buffer.bufferaddr, + &kernel_vaddr)) { + DBG("%s() : user_virt_addr = %p has not been set.", + __func__, buffer_info->buffer.bufferaddr); + return true; + } + vcd_status = vcd_free_buffer(client_ctx->vcd_handle, buffer, + (u8 *)kernel_vaddr); + + if (!vcd_status) + return true; + else + return false; +} + +static u32 vid_dec_pause_resume(struct video_client_ctx *client_ctx, u32 pause) +{ + u32 vcd_status; + + if (!client_ctx) { + ERR("\n %s(): Invalid client_ctx", __func__); + return false; + } + + if (pause) { + DBG("msm_vidc_dec: PAUSE command from client = %p\n", + client_ctx); + vcd_status = vcd_pause(client_ctx->vcd_handle); + } else{ + DBG("msm_vidc_dec: RESUME command from client = %p\n", + client_ctx); + vcd_status = vcd_resume(client_ctx->vcd_handle); + } + + if (vcd_status) + return false; + + return true; + +} + +static u32 vid_dec_start_stop(struct video_client_ctx *client_ctx, u32 start) +{ + struct vid_dec_msg *vdec_msg = NULL; + u32 vcd_status; + + DBG("msm_vidc_dec: Inside %s()", __func__); + if (!client_ctx) { + ERR("\n Invalid client_ctx"); + return false; + } + + if (start) { + if (client_ctx->seq_header_set) { + DBG("%s(): Seq Hdr set: Send START_DONE to client", + __func__); + vdec_msg = kzalloc(sizeof(*vdec_msg), GFP_KERNEL); + if (!vdec_msg) { + ERR("vid_dec_start_stop: cannot allocate" + "buffer\n"); + return false; + } + vdec_msg->vdec_msg_info.msgcode = + VDEC_MSG_RESP_START_DONE; + vdec_msg->vdec_msg_info.status_code = VDEC_S_SUCCESS; + vdec_msg->vdec_msg_info.msgdatasize = 0; + mutex_lock(&client_ctx->msg_queue_lock); + list_add_tail(&vdec_msg->list, &client_ctx->msg_queue); + mutex_unlock(&client_ctx->msg_queue_lock); + + wake_up(&client_ctx->msg_wait); + + DBG("Send START_DONE message to client = %p\n", + client_ctx); + + } else { + DBG("%s(): Calling decode_start()", __func__); + vcd_status = + vcd_decode_start(client_ctx->vcd_handle, NULL); + + if (vcd_status) { + ERR("%s(): vcd_decode_start failed." + " vcd_status = %u\n", __func__, vcd_status); + return false; + } + } + } else { + DBG("%s(): Calling vcd_stop()", __func__); + mutex_lock(&vid_dec_device_p->lock); + vcd_status = VCD_ERR_FAIL; + if (!client_ctx->stop_called) { + client_ctx->stop_called = true; + vcd_status = vcd_stop(client_ctx->vcd_handle); + } + if (vcd_status) { + ERR("%s(): vcd_stop failed. vcd_status = %u\n", + __func__, vcd_status); + mutex_unlock(&vid_dec_device_p->lock); + return false; + } + DBG("Send STOP_DONE message to client = %p\n", client_ctx); + mutex_unlock(&vid_dec_device_p->lock); + } + return true; +} + +static u32 vid_dec_decode_frame(struct video_client_ctx *client_ctx, + struct vdec_input_frameinfo *input_frame_info, + u8 *desc_buf, u32 desc_size) +{ + struct vcd_frame_data vcd_input_buffer; + unsigned long kernel_vaddr, phy_addr, user_vaddr; + int pmem_fd; + struct file *file; + s32 buffer_index = -1; + u32 vcd_status = VCD_ERR_FAIL; + u32 ion_flag = 0; + struct ion_handle *buff_handle = NULL; + + if (!client_ctx || !input_frame_info) + return false; + + user_vaddr = (unsigned long)input_frame_info->bufferaddr; + + if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_INPUT, + true, &user_vaddr, &kernel_vaddr, + &phy_addr, &pmem_fd, &file, + &buffer_index)) { + + /* kernel_vaddr is found. send the frame to VCD */ + memset((void *)&vcd_input_buffer, 0, + sizeof(struct vcd_frame_data)); + vcd_input_buffer.virtual = + (u8 *) (kernel_vaddr + input_frame_info->pmem_offset); + vcd_input_buffer.offset = input_frame_info->offset; + vcd_input_buffer.frm_clnt_data = + (u32) input_frame_info->client_data; + vcd_input_buffer.ip_frm_tag = + (u32) input_frame_info->client_data; + vcd_input_buffer.data_len = input_frame_info->datalen; + vcd_input_buffer.time_stamp = input_frame_info->timestamp; + /* Rely on VCD using the same flags as OMX */ + vcd_input_buffer.flags = input_frame_info->flags; + vcd_input_buffer.desc_buf = desc_buf; + vcd_input_buffer.desc_size = desc_size; + if (vcd_input_buffer.data_len > 0) { + ion_flag = vidc_get_fd_info(client_ctx, + BUFFER_TYPE_INPUT, + pmem_fd, + kernel_vaddr, + buffer_index, + &buff_handle); + if (ion_flag == CACHED && buff_handle) { + msm_ion_do_cache_op(client_ctx->user_ion_client, + buff_handle, + (unsigned long *)kernel_vaddr, + (unsigned long) vcd_input_buffer.data_len, + ION_IOC_CLEAN_CACHES); + } + } + vcd_status = vcd_decode_frame(client_ctx->vcd_handle, + &vcd_input_buffer); + if (!vcd_status) + return true; + else { + ERR("%s(): vcd_decode_frame failed = %u\n", __func__, + vcd_status); + return false; + } + + } else { + ERR("%s(): kernel_vaddr not found\n", __func__); + return false; + } +} + +static u32 vid_dec_fill_output_buffer(struct video_client_ctx *client_ctx, + struct vdec_fillbuffer_cmd *fill_buffer_cmd) +{ + unsigned long kernel_vaddr, phy_addr, user_vaddr; + int pmem_fd; + struct file *file; + s32 buffer_index = -1; + u32 vcd_status = VCD_ERR_FAIL; + struct ion_handle *buff_handle = NULL; + + struct vcd_frame_data vcd_frame; + + if (!client_ctx || !fill_buffer_cmd) + return false; + + user_vaddr = (unsigned long)fill_buffer_cmd->buffer.bufferaddr; + + if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT, + true, &user_vaddr, &kernel_vaddr, + &phy_addr, &pmem_fd, &file, + &buffer_index)) { + + memset((void *)&vcd_frame, 0, + sizeof(struct vcd_frame_data)); + vcd_frame.virtual = (u8 *) kernel_vaddr; + vcd_frame.frm_clnt_data = (u32) fill_buffer_cmd->client_data; + vcd_frame.alloc_len = fill_buffer_cmd->buffer.buffer_len; + vcd_frame.ion_flag = vidc_get_fd_info(client_ctx, + BUFFER_TYPE_OUTPUT, + pmem_fd, kernel_vaddr, + buffer_index, + &buff_handle); + vcd_frame.buff_ion_handle = buff_handle; + vcd_status = vcd_fill_output_buffer(client_ctx->vcd_handle, + &vcd_frame); + if (!vcd_status) + return true; + else { + ERR("%s(): vcd_fill_output_buffer failed = %u\n", + __func__, vcd_status); + return false; + } + } else { + ERR("%s(): kernel_vaddr not found\n", __func__); + return false; + } +} + + +static u32 vid_dec_flush(struct video_client_ctx *client_ctx, + enum vdec_bufferflush flush_dir) +{ + u32 vcd_status = VCD_ERR_FAIL; + + DBG("msm_vidc_dec: %s() called with dir = %u", __func__, + flush_dir); + if (!client_ctx) { + ERR("\n Invalid client_ctx"); + return false; + } + + switch (flush_dir) { + case VDEC_FLUSH_TYPE_INPUT: + vcd_status = vcd_flush(client_ctx->vcd_handle, VCD_FLUSH_INPUT); + break; + case VDEC_FLUSH_TYPE_OUTPUT: + vcd_status = vcd_flush(client_ctx->vcd_handle, + VCD_FLUSH_OUTPUT); + break; + case VDEC_FLUSH_TYPE_ALL: + vcd_status = vcd_flush(client_ctx->vcd_handle, VCD_FLUSH_ALL); + break; + default: + ERR("%s(): Inavlid flush cmd. flush_dir = %u\n", __func__, + flush_dir); + return false; + break; + } + + if (!vcd_status) + return true; + else { + ERR("%s(): vcd_flush failed. vcd_status = %u " + " flush_dir = %u\n", __func__, vcd_status, flush_dir); + return false; + } +} + +static u32 vid_dec_msg_pending(struct video_client_ctx *client_ctx) +{ + u32 islist_empty = 0; + mutex_lock(&client_ctx->msg_queue_lock); + islist_empty = list_empty(&client_ctx->msg_queue); + mutex_unlock(&client_ctx->msg_queue_lock); + + if (islist_empty) { + DBG("%s(): vid_dec msg queue empty\n", __func__); + if (client_ctx->stop_msg) { + DBG("%s(): List empty and Stop Msg set\n", + __func__); + return client_ctx->stop_msg; + } + } else + DBG("%s(): vid_dec msg queue Not empty\n", __func__); + + return !islist_empty; +} + +static int vid_dec_get_next_msg(struct video_client_ctx *client_ctx, + struct vdec_msginfo *vdec_msg_info) +{ + int rc; + struct vid_dec_msg *vid_dec_msg = NULL; + + if (!client_ctx) + return false; + + rc = wait_event_interruptible(client_ctx->msg_wait, + vid_dec_msg_pending(client_ctx)); + if (rc < 0) { + DBG("rc = %d, stop_msg = %u\n", rc, client_ctx->stop_msg); + return rc; + } else if (client_ctx->stop_msg) { + DBG("rc = %d, stop_msg = %u\n", rc, client_ctx->stop_msg); + return -EIO; + } + + mutex_lock(&client_ctx->msg_queue_lock); + if (!list_empty(&client_ctx->msg_queue)) { + DBG("%s(): After Wait\n", __func__); + vid_dec_msg = list_first_entry(&client_ctx->msg_queue, + struct vid_dec_msg, list); + list_del(&vid_dec_msg->list); + memcpy(vdec_msg_info, &vid_dec_msg->vdec_msg_info, + sizeof(struct vdec_msginfo)); + kfree(vid_dec_msg); + } + mutex_unlock(&client_ctx->msg_queue_lock); + return 0; +} + +static long vid_dec_ioctl(struct file *file, + unsigned cmd, unsigned long u_arg) +{ + struct video_client_ctx *client_ctx = NULL; + struct vdec_ioctl_msg vdec_msg; + u32 vcd_status; + unsigned long kernel_vaddr, phy_addr, len; + unsigned long ker_vaddr; + struct file *pmem_file; + u32 result = true; + void __user *arg = (void __user *)u_arg; + int rc = 0; + size_t ion_len; + + DBG("%s\n", __func__); + if (_IOC_TYPE(cmd) != VDEC_IOCTL_MAGIC) + return -ENOTTY; + + client_ctx = (struct video_client_ctx *)file->private_data; + if (!client_ctx) { + ERR("!client_ctx. Cannot attach to device handle\n"); + return -ENODEV; + } + + switch (cmd) { + case VDEC_IOCTL_SET_CODEC: + { + enum vdec_codec vdec_codec; + DBG("VDEC_IOCTL_SET_CODEC\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&vdec_codec, vdec_msg.in, + sizeof(vdec_codec))) + return -EFAULT; + DBG("setting code type = %u\n", vdec_codec); + result = vid_dec_set_codec(client_ctx, &vdec_codec); + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_SET_OUTPUT_FORMAT: + { + enum vdec_output_fromat output_format; + DBG("VDEC_IOCTL_SET_OUTPUT_FORMAT\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&output_format, vdec_msg.in, + sizeof(output_format))) + return -EFAULT; + + result = vid_dec_set_output_format(client_ctx, &output_format); + + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_SET_PICRES: + { + struct vdec_picsize video_resoultion; + DBG("VDEC_IOCTL_SET_PICRES\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&video_resoultion, vdec_msg.in, + sizeof(video_resoultion))) + return -EFAULT; + result = + vid_dec_set_frame_resolution(client_ctx, &video_resoultion); + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_GET_PICRES: + { + struct vdec_picsize video_resoultion; + DBG("VDEC_IOCTL_GET_PICRES\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&video_resoultion, vdec_msg.out, + sizeof(video_resoultion))) + return -EFAULT; + + result = vid_dec_get_frame_resolution(client_ctx, + &video_resoultion); + + if (result) { + if (copy_to_user(vdec_msg.out, &video_resoultion, + sizeof(video_resoultion))) + return -EFAULT; + } else + return -EIO; + break; + } + case VDEC_IOCTL_SET_BUFFER_REQ: + { + struct vdec_allocatorproperty vdec_buf_req; + struct vcd_buffer_requirement buffer_req; + DBG("VDEC_IOCTL_SET_BUFFER_REQ\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + + if (copy_from_user(&vdec_buf_req, vdec_msg.in, + sizeof(vdec_buf_req))) + return -EFAULT; + + buffer_req.actual_count = vdec_buf_req.actualcount; + buffer_req.align = vdec_buf_req.alignment; + buffer_req.max_count = vdec_buf_req.maxcount; + buffer_req.min_count = vdec_buf_req.mincount; + buffer_req.sz = vdec_buf_req.buffer_size; + + switch (vdec_buf_req.buffer_type) { + case VDEC_BUFFER_TYPE_INPUT: + vcd_status = + vcd_set_buffer_requirements(client_ctx->vcd_handle, + VCD_BUFFER_INPUT, &buffer_req); + break; + case VDEC_BUFFER_TYPE_OUTPUT: + vcd_status = + vcd_set_buffer_requirements(client_ctx->vcd_handle, + VCD_BUFFER_OUTPUT, &buffer_req); + break; + default: + vcd_status = VCD_ERR_BAD_POINTER; + break; + } + + if (vcd_status) + return -EFAULT; + break; + } + case VDEC_IOCTL_GET_BUFFER_REQ: + { + struct vdec_allocatorproperty vdec_buf_req; + DBG("VDEC_IOCTL_GET_BUFFER_REQ\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&vdec_buf_req, vdec_msg.out, + sizeof(vdec_buf_req))) + return -EFAULT; + + result = vid_dec_get_buffer_req(client_ctx, &vdec_buf_req); + + if (result) { + if (copy_to_user(vdec_msg.out, &vdec_buf_req, + sizeof(vdec_buf_req))) + return -EFAULT; + } else + return -EIO; + break; + } + case VDEC_IOCTL_SET_BUFFER: + { + struct vdec_setbuffer_cmd setbuffer; + DBG("VDEC_IOCTL_SET_BUFFER\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&setbuffer, vdec_msg.in, + sizeof(setbuffer))) + return -EFAULT; + result = vid_dec_set_buffer(client_ctx, &setbuffer); + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_FREE_BUFFER: + { + struct vdec_setbuffer_cmd setbuffer; + DBG("VDEC_IOCTL_FREE_BUFFER\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&setbuffer, vdec_msg.in, + sizeof(setbuffer))) + return -EFAULT; + result = vid_dec_free_buffer(client_ctx, &setbuffer); + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_CMD_START: + { + DBG(" VDEC_IOCTL_CMD_START\n"); + result = vid_dec_start_stop(client_ctx, true); + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_CMD_STOP: + { + DBG("VDEC_IOCTL_CMD_STOP\n"); + result = vid_dec_start_stop(client_ctx, false); + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_CMD_PAUSE: + { + result = vid_dec_pause_resume(client_ctx, true); + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_CMD_RESUME: + { + DBG("VDEC_IOCTL_CMD_PAUSE\n"); + result = vid_dec_pause_resume(client_ctx, false); + + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_DECODE_FRAME: + { + struct vdec_input_frameinfo input_frame_info; + u8 *desc_buf = NULL; + u32 desc_size = 0; + DBG("VDEC_IOCTL_DECODE_FRAME\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&input_frame_info, vdec_msg.in, + sizeof(input_frame_info))) + return -EFAULT; + if (client_ctx->dmx_disable) { + if (input_frame_info.desc_addr) { + desc_size = input_frame_info.desc_size; + desc_buf = kzalloc(desc_size, GFP_KERNEL); + if (desc_buf) { + if (copy_from_user(desc_buf, + input_frame_info.desc_addr, + desc_size)) { + kfree(desc_buf); + desc_buf = NULL; + return -EFAULT; + } + } + } else + return -EINVAL; + } + result = vid_dec_decode_frame(client_ctx, &input_frame_info, + desc_buf, desc_size); + + if (!result) { + kfree(desc_buf); + desc_buf = NULL; + return -EIO; + } + break; + } + case VDEC_IOCTL_FILL_OUTPUT_BUFFER: + { + struct vdec_fillbuffer_cmd fill_buffer_cmd; + DBG("VDEC_IOCTL_FILL_OUTPUT_BUFFER\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&fill_buffer_cmd, vdec_msg.in, + sizeof(fill_buffer_cmd))) + return -EFAULT; + result = vid_dec_fill_output_buffer(client_ctx, + &fill_buffer_cmd); + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_CMD_FLUSH: + { + enum vdec_bufferflush flush_dir; + DBG("VDEC_IOCTL_CMD_FLUSH\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&flush_dir, vdec_msg.in, + sizeof(flush_dir))) + return -EFAULT; + result = vid_dec_flush(client_ctx, flush_dir); + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_GET_NEXT_MSG: + { + struct vdec_msginfo vdec_msg_info; + DBG("VDEC_IOCTL_GET_NEXT_MSG\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + result = vid_dec_get_next_msg(client_ctx, &vdec_msg_info); + if (result) + return result; + if (copy_to_user(vdec_msg.out, &vdec_msg_info, + sizeof(vdec_msg_info))) + return -EFAULT; + break; + } + case VDEC_IOCTL_STOP_NEXT_MSG: + { + DBG("VDEC_IOCTL_STOP_NEXT_MSG\n"); + client_ctx->stop_msg = 1; + wake_up(&client_ctx->msg_wait); + break; + } + case VDEC_IOCTL_SET_SEQUENCE_HEADER: + { + struct vdec_seqheader seq_header; + struct vcd_sequence_hdr vcd_seq_hdr; + unsigned long ionflag; + DBG("VDEC_IOCTL_SET_SEQUENCE_HEADER\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) { + ERR("Copy from user vdec_msg failed\n"); + return -EFAULT; + } + if (copy_from_user(&seq_header, vdec_msg.in, + sizeof(seq_header))) { + ERR("Copy from user seq_header failed\n"); + return -EFAULT; + } + if (!seq_header.seq_header_len) { + ERR("Seq Len is Zero\n"); + return -EFAULT; + } + + if (!vcd_get_ion_status()) { + if (get_pmem_file(seq_header.pmem_fd, + &phy_addr, &kernel_vaddr, &len, &pmem_file)) { + ERR("%s(): get_pmem_file failed\n", __func__); + return false; + } + put_pmem_file(pmem_file); + } else { + client_ctx->seq_hdr_ion_handle = ion_import_fd( + client_ctx->user_ion_client, + seq_header.pmem_fd); + if (!client_ctx->seq_hdr_ion_handle) { + ERR("%s(): get_ION_handle failed\n", __func__); + return false; + } + rc = ion_handle_get_flags(client_ctx->user_ion_client, + client_ctx->seq_hdr_ion_handle, + &ionflag); + if (rc) { + ERR("%s():get_ION_flags fail\n", + __func__); + ion_free(client_ctx->user_ion_client, + client_ctx->seq_hdr_ion_handle); + return false; + } + ker_vaddr = (unsigned long) ion_map_kernel( + client_ctx->user_ion_client, + client_ctx->seq_hdr_ion_handle, ionflag); + if (!ker_vaddr) { + ERR("%s():get_ION_kernel virtual addr fail\n", + __func__); + ion_free(client_ctx->user_ion_client, + client_ctx->seq_hdr_ion_handle); + return false; + } + kernel_vaddr = ker_vaddr; + rc = ion_phys(client_ctx->user_ion_client, + client_ctx->seq_hdr_ion_handle, + &phy_addr, &ion_len); + if (rc) { + ERR("%s():get_ION_kernel physical addr fail\n", + __func__); + ion_unmap_kernel(client_ctx->user_ion_client, + client_ctx->seq_hdr_ion_handle); + ion_free(client_ctx->user_ion_client, + client_ctx->seq_hdr_ion_handle); + return false; + } + len = ion_len; + } + vcd_seq_hdr.sequence_header_len = seq_header.seq_header_len; + kernel_vaddr += (unsigned long)seq_header.pmem_offset; + vcd_seq_hdr.sequence_header = (u8 *)kernel_vaddr; + if (!vcd_seq_hdr.sequence_header) { + ERR("Sequence Header pointer failed\n"); + return -EFAULT; + } + client_ctx->seq_header_set = true; + if (vcd_decode_start(client_ctx->vcd_handle, &vcd_seq_hdr)) { + ERR("Decode start Failed\n"); + client_ctx->seq_header_set = false; + return -EFAULT; + } + DBG("Wait Client completion Sequence Header\n"); + wait_for_completion(&client_ctx->event); + vcd_seq_hdr.sequence_header = NULL; + if (client_ctx->event_status) { + ERR("Set Seq Header status is failed"); + return -EFAULT; + } + if (vcd_get_ion_status()) { + if (client_ctx->seq_hdr_ion_handle) { + ion_unmap_kernel(client_ctx->user_ion_client, + client_ctx->seq_hdr_ion_handle); + ion_free(client_ctx->user_ion_client, + client_ctx->seq_hdr_ion_handle); + } + } + break; + } + case VDEC_IOCTL_GET_NUMBER_INSTANCES: + { + DBG("VDEC_IOCTL_GET_NUMBER_INSTANCES\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_to_user(vdec_msg.out, + &vid_dec_device_p->num_clients, sizeof(u32))) + return -EFAULT; + break; + } + case VDEC_IOCTL_GET_INTERLACE_FORMAT: + { + u32 progressive_only, interlace_format; + DBG("VDEC_IOCTL_GET_INTERLACE_FORMAT\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + result = vid_dec_get_progressive_only(client_ctx, + &progressive_only); + if (result) { + interlace_format = progressive_only ? + VDEC_InterlaceFrameProgressive : + VDEC_InterlaceInterleaveFrameTopFieldFirst; + if (copy_to_user(vdec_msg.out, &interlace_format, + sizeof(u32))) + return -EFAULT; + } else + return -EIO; + break; + } + + case VDEC_IOCTL_GET_DISABLE_DMX_SUPPORT: + { + u32 disable_dmx; + DBG("VDEC_IOCTL_GET_DISABLE_DMX_SUPPORT\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + result = vid_dec_get_disable_dmx_support(client_ctx, + &disable_dmx); + if (result) { + if (copy_to_user(vdec_msg.out, &disable_dmx, + sizeof(u32))) + return -EFAULT; + } else + return -EIO; + break; + } + case VDEC_IOCTL_GET_DISABLE_DMX: + { + u32 disable_dmx; + DBG("VDEC_IOCTL_GET_DISABLE_DMX\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + result = vid_dec_get_disable_dmx(client_ctx, + &disable_dmx); + if (result) { + if (copy_to_user(vdec_msg.out, &disable_dmx, + sizeof(u32))) + return -EFAULT; + } else + return -EIO; + break; + } + case VDEC_IOCTL_SET_DISABLE_DMX: + { + DBG("VDEC_IOCTL_SET_DISABLE_DMX\n"); + result = vid_dec_set_disable_dmx(client_ctx); + if (!result) + return -EIO; + client_ctx->dmx_disable = 1; + break; + } + case VDEC_IOCTL_SET_PICTURE_ORDER: + { + u32 picture_order; + DBG("VDEC_IOCTL_SET_PICTURE_ORDER\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&picture_order, vdec_msg.in, + sizeof(u32))) + return -EFAULT; + result = vid_dec_set_picture_order(client_ctx, &picture_order); + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_SET_FRAME_RATE: + { + struct vdec_framerate frame_rate; + DBG("VDEC_IOCTL_SET_FRAME_RATE\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&frame_rate, vdec_msg.in, + sizeof(frame_rate))) + return -EFAULT; + result = vid_dec_set_frame_rate(client_ctx, &frame_rate); + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_SET_EXTRADATA: + { + u32 extradata_flag; + DBG("VDEC_IOCTL_SET_EXTRADATA\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&extradata_flag, vdec_msg.in, + sizeof(u32))) + return -EFAULT; + result = vid_dec_set_extradata(client_ctx, &extradata_flag); + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_SET_H264_MV_BUFFER: + { + struct vdec_h264_mv mv_data; + DBG("VDEC_IOCTL_SET_H264_MV_BUFFER\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&mv_data, vdec_msg.in, + sizeof(mv_data))) + return -EFAULT; + result = vid_dec_set_h264_mv_buffers(client_ctx, &mv_data); + + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_FREE_H264_MV_BUFFER: + { + DBG("VDEC_IOCTL_FREE_H264_MV_BUFFER\n"); + result = vid_dec_free_h264_mv_buffers(client_ctx); + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_GET_MV_BUFFER_SIZE: + { + struct vdec_mv_buff_size mv_buff; + DBG("VDEC_IOCTL_GET_MV_BUFFER_SIZE\n"); + if (copy_from_user(&vdec_msg, arg, sizeof(vdec_msg))) + return -EFAULT; + if (copy_from_user(&mv_buff, vdec_msg.out, + sizeof(mv_buff))) + return -EFAULT; + result = vid_dec_get_h264_mv_buffer_size(client_ctx, &mv_buff); + if (result) { + DBG(" Returning W: %d, H: %d, S: %d, A: %d", + mv_buff.width, mv_buff.height, + mv_buff.size, mv_buff.alignment); + if (copy_to_user(vdec_msg.out, &mv_buff, + sizeof(mv_buff))) + return -EFAULT; + } else + return -EIO; + break; + } + case VDEC_IOCTL_SET_IDR_ONLY_DECODING: + { + result = vid_dec_set_idr_only_decoding(client_ctx); + if (!result) + return -EIO; + break; + } + case VDEC_IOCTL_SET_CONT_ON_RECONFIG: + { + result = vid_dec_set_cont_on_reconfig(client_ctx); + if (!result) + return -EIO; + break; + } + default: + ERR("%s(): Unsupported ioctl\n", __func__); + return -ENOTTY; + break; + } + + return 0; +} + +static u32 vid_dec_close_client(struct video_client_ctx *client_ctx) +{ + struct vid_dec_msg *vdec_msg; + u32 vcd_status; + + DBG("msm_vidc_dec: Inside %s()", __func__); + if (!client_ctx || (!client_ctx->vcd_handle)) { + ERR("\n Invalid client_ctx"); + return false; + } + + mutex_lock(&vid_dec_device_p->lock); + if (!client_ctx->stop_called) { + client_ctx->stop_called = true; + client_ctx->stop_sync_cb = true; + vcd_status = vcd_stop(client_ctx->vcd_handle); + DBG("\n Stuck at the stop call"); + if (!vcd_status) + wait_for_completion(&client_ctx->event); + DBG("\n Came out of wait event"); + } + mutex_lock(&client_ctx->msg_queue_lock); + while (!list_empty(&client_ctx->msg_queue)) { + DBG("%s(): Delete remaining entries\n", __func__); + vdec_msg = list_first_entry(&client_ctx->msg_queue, + struct vid_dec_msg, list); + if (vdec_msg) { + list_del(&vdec_msg->list); + kfree(vdec_msg); + } + } + mutex_unlock(&client_ctx->msg_queue_lock); + vcd_status = vcd_close(client_ctx->vcd_handle); + + if (vcd_status) { + mutex_unlock(&vid_dec_device_p->lock); + return false; + } + client_ctx->user_ion_client = NULL; + memset((void *)client_ctx, 0, sizeof(struct video_client_ctx)); + vid_dec_device_p->num_clients--; + mutex_unlock(&vid_dec_device_p->lock); + return true; +} + +int vid_dec_open_client(struct video_client_ctx **vid_clnt_ctx, int flags) +{ + int rc = 0; + s32 client_index; + struct video_client_ctx *client_ctx = NULL; + u8 client_count; + + if (!vid_clnt_ctx) { + ERR("Invalid input\n"); + return -EINVAL; + } + *vid_clnt_ctx = NULL; + client_count = vcd_get_num_of_clients(); + if (client_count == VIDC_MAX_NUM_CLIENTS) { + ERR("ERROR : vid_dec_open() max number of clients" + "limit reached\n"); + rc = -ENOMEM; + goto client_failure; + } + + DBG(" Virtual Address of ioremap is %p\n", vid_dec_device_p->virt_base); + if (!vid_dec_device_p->num_clients) { + if (!vidc_load_firmware()) { + rc = -ENOMEM; + goto client_failure; + } + } + + client_index = vid_dec_get_empty_client_index(); + if (client_index == -1) { + ERR("%s() : No free clients client_index == -1\n", __func__); + rc = -ENOMEM; + goto client_failure; + } + client_ctx = &vid_dec_device_p->vdec_clients[client_index]; + vid_dec_device_p->num_clients++; + init_completion(&client_ctx->event); + mutex_init(&client_ctx->msg_queue_lock); + mutex_init(&client_ctx->enrty_queue_lock); + INIT_LIST_HEAD(&client_ctx->msg_queue); + init_waitqueue_head(&client_ctx->msg_wait); + client_ctx->stop_msg = 0; + client_ctx->stop_called = false; + client_ctx->stop_sync_cb = false; + client_ctx->dmx_disable = 0; + if (vcd_get_ion_status()) { + client_ctx->user_ion_client = vcd_get_ion_client(); + if (!client_ctx->user_ion_client) { + ERR("vcd_open ion client get failed"); + rc = -ENOMEM; + goto client_failure; + } + } + rc = vcd_open(vid_dec_device_p->device_handle, true, + vid_dec_vcd_cb, client_ctx, flags); + if (!rc) { + wait_for_completion(&client_ctx->event); + if (client_ctx->event_status) { + ERR("callback for vcd_open returned error: %u", + client_ctx->event_status); + rc = -ENODEV; + goto client_failure; + } + } else { + ERR("vcd_open returned error: %u", rc); + goto client_failure; + } + client_ctx->seq_header_set = false; + *vid_clnt_ctx = client_ctx; +client_failure: + return rc; +} + +static int vid_dec_open_secure(struct inode *inode, struct file *file) +{ + int rc = 0; + struct video_client_ctx *client_ctx; + mutex_lock(&vid_dec_device_p->lock); + rc = vid_dec_open_client(&client_ctx, VCD_CP_SESSION); + if (rc) + goto error; + if (!client_ctx) { + rc = -ENOMEM; + goto error; + } + + file->private_data = client_ctx; + if (res_trk_open_secure_session()) { + ERR("Secure session operation failure\n"); + rc = -EACCES; + goto error; + } + mutex_unlock(&vid_dec_device_p->lock); + return 0; +error: + mutex_unlock(&vid_dec_device_p->lock); + return rc; +} + +static int vid_dec_open(struct inode *inode, struct file *file) +{ + int rc = 0; + struct video_client_ctx *client_ctx; + INFO("msm_vidc_dec: Inside %s()", __func__); + mutex_lock(&vid_dec_device_p->lock); + rc = vid_dec_open_client(&client_ctx, 0); + if (rc) { + mutex_unlock(&vid_dec_device_p->lock); + return rc; + } + if (!client_ctx) { + mutex_unlock(&vid_dec_device_p->lock); + return -ENOMEM; + } + + file->private_data = client_ctx; + mutex_unlock(&vid_dec_device_p->lock); + return rc; +} + +static int vid_dec_release_secure(struct inode *inode, struct file *file) +{ + struct video_client_ctx *client_ctx = file->private_data; + + INFO("msm_vidc_dec: Inside %s()", __func__); + vidc_cleanup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT); + vidc_cleanup_addr_table(client_ctx, BUFFER_TYPE_INPUT); + vid_dec_close_client(client_ctx); + vidc_release_firmware(); +#ifndef USE_RES_TRACKER + vidc_disable_clk(); +#endif + INFO("msm_vidc_dec: Return from %s()", __func__); + return 0; +} + +static int vid_dec_release(struct inode *inode, struct file *file) +{ + struct video_client_ctx *client_ctx = file->private_data; + + INFO("msm_vidc_dec: Inside %s()", __func__); + vidc_cleanup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT); + vidc_cleanup_addr_table(client_ctx, BUFFER_TYPE_INPUT); + vid_dec_close_client(client_ctx); + vidc_release_firmware(); +#ifndef USE_RES_TRACKER + vidc_disable_clk(); +#endif + INFO("msm_vidc_dec: Return from %s()", __func__); + return 0; +} + +static const struct file_operations vid_dec_fops[2] = { + { + .owner = THIS_MODULE, + .open = vid_dec_open, + .release = vid_dec_release, + .unlocked_ioctl = vid_dec_ioctl, + }, + { + .owner = THIS_MODULE, + .open = vid_dec_open_secure, + .release = vid_dec_release_secure, + .unlocked_ioctl = vid_dec_ioctl, + }, + +}; + +void vid_dec_interrupt_deregister(void) +{ +} + +void vid_dec_interrupt_register(void *device_name) +{ +} + +void vid_dec_interrupt_clear(void) +{ +} + +void *vid_dec_map_dev_base_addr(void *device_name) +{ + return vid_dec_device_p->virt_base; +} + +static int vid_dec_vcd_init(void) +{ + int rc; + struct vcd_init_config vcd_init_config; + u32 i; + + /* init_timer(&hw_timer); */ + DBG("msm_vidc_dec: Inside %s()", __func__); + vid_dec_device_p->num_clients = 0; + + for (i = 0; i < VIDC_MAX_NUM_CLIENTS; i++) { + memset((void *)&vid_dec_device_p->vdec_clients[i], 0, + sizeof(vid_dec_device_p->vdec_clients[i])); + } + + mutex_init(&vid_dec_device_p->lock); + vid_dec_device_p->virt_base = vidc_get_ioaddr(); + DBG("%s() : base address for VIDC core %u\n", __func__, \ + (int)vid_dec_device_p->virt_base); + + if (!vid_dec_device_p->virt_base) { + ERR("%s() : ioremap failed\n", __func__); + return -ENOMEM; + } + + vcd_init_config.device_name = "VIDC"; + vcd_init_config.map_dev_base_addr = vid_dec_map_dev_base_addr; + vcd_init_config.interrupt_clr = vid_dec_interrupt_clear; + vcd_init_config.register_isr = vid_dec_interrupt_register; + vcd_init_config.deregister_isr = vid_dec_interrupt_deregister; + vcd_init_config.timer_create = vidc_timer_create; + vcd_init_config.timer_release = vidc_timer_release; + vcd_init_config.timer_start = vidc_timer_start; + vcd_init_config.timer_stop = vidc_timer_stop; + + rc = vcd_init(&vcd_init_config, &vid_dec_device_p->device_handle); + + if (rc) { + ERR("%s() : vcd_init failed\n", __func__); + return -ENODEV; + } + return 0; +} + +static int __init vid_dec_init(void) +{ + int rc = 0, i = 0, j = 0; + struct device *class_devp; + + DBG("msm_vidc_dec: Inside %s()", __func__); + vid_dec_device_p = kzalloc(sizeof(struct vid_dec_dev), GFP_KERNEL); + if (!vid_dec_device_p) { + ERR("%s Unable to allocate memory for vid_dec_dev\n", + __func__); + return -ENOMEM; + } + + rc = alloc_chrdev_region(&vid_dec_dev_num, 0, NUM_OF_DRIVER_NODES, + VID_DEC_NAME); + if (rc < 0) { + ERR("%s: alloc_chrdev_region Failed rc = %d\n", + __func__, rc); + goto error_vid_dec_alloc_chrdev_region; + } + + vid_dec_class = class_create(THIS_MODULE, VID_DEC_NAME); + if (IS_ERR(vid_dec_class)) { + rc = PTR_ERR(vid_dec_class); + ERR("%s: couldn't create vid_dec_class rc = %d\n", + __func__, rc); + + goto error_vid_dec_class_create; + } + for (i = 0; i < NUM_OF_DRIVER_NODES; i++) { + class_devp = device_create(vid_dec_class, NULL, + (vid_dec_dev_num + i), + NULL, VID_DEC_NAME "%s", + node_name[i]); + + if (IS_ERR(class_devp)) { + rc = PTR_ERR(class_devp); + ERR("%s: class device_create failed %d\n", + __func__, rc); + if (!i) + goto error_vid_dec_class_device_create; + else + goto error_vid_dec_cdev_add; + } + + vid_dec_device_p->device[i] = class_devp; + + cdev_init(&vid_dec_device_p->cdev[i], &vid_dec_fops[i]); + vid_dec_device_p->cdev[i].owner = THIS_MODULE; + rc = cdev_add(&(vid_dec_device_p->cdev[i]), + (vid_dec_dev_num+i), 1); + + if (rc < 0) { + ERR("%s: cdev_add failed %d\n", __func__, rc); + goto error_vid_dec_cdev_add; + } + } + vid_dec_vcd_init(); + return 0; + +error_vid_dec_cdev_add: + for (j = i-1; j >= 0; j--) + cdev_del(&(vid_dec_device_p->cdev[j])); + device_destroy(vid_dec_class, vid_dec_dev_num); +error_vid_dec_class_device_create: + class_destroy(vid_dec_class); +error_vid_dec_class_create: + unregister_chrdev_region(vid_dec_dev_num, NUM_OF_DRIVER_NODES); +error_vid_dec_alloc_chrdev_region: + kfree(vid_dec_device_p); + return rc; +} + +static void __exit vid_dec_exit(void) +{ + int i = 0; + INFO("msm_vidc_dec: Inside %s()", __func__); + for (i = 0; i < NUM_OF_DRIVER_NODES; i++) + cdev_del(&(vid_dec_device_p->cdev[i])); + device_destroy(vid_dec_class, vid_dec_dev_num); + class_destroy(vid_dec_class); + unregister_chrdev_region(vid_dec_dev_num, NUM_OF_DRIVER_NODES); + kfree(vid_dec_device_p); + DBG("msm_vidc_dec: Return from %s()", __func__); +} + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Video decoder driver"); +MODULE_VERSION("1.0"); + +module_init(vid_dec_init); +module_exit(vid_dec_exit); diff --git a/drivers/video/msm/vidc/common/dec/vdec_internal.h b/drivers/video/msm/vidc/common/dec/vdec_internal.h new file mode 100644 index 000000000000..a7a32a58e062 --- /dev/null +++ b/drivers/video/msm/vidc/common/dec/vdec_internal.h @@ -0,0 +1,45 @@ +/* Copyright (c) 2010, 2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#ifndef VDEC_INTERNAL_H +#define VDEC_INTERNAL_H + +#include +#include +#include + +#define NUM_OF_DRIVER_NODES 2 + +struct vid_dec_msg { + struct list_head list; + struct vdec_msginfo vdec_msg_info; +}; + +struct vid_dec_dev { + struct cdev cdev[NUM_OF_DRIVER_NODES]; + struct device *device[NUM_OF_DRIVER_NODES]; + resource_size_t phys_base; + void __iomem *virt_base; + unsigned int irq; + struct clk *hclk; + struct clk *hclk_div2; + struct clk *pclk; + unsigned long hclk_rate; + struct mutex lock; + s32 device_handle; + struct video_client_ctx vdec_clients[VIDC_MAX_NUM_CLIENTS]; + u32 num_clients; + void(*timer_handler)(void *); +}; + +#endif diff --git a/drivers/video/msm/vidc/common/enc/venc.c b/drivers/video/msm/vidc/common/enc/venc.c new file mode 100644 index 000000000000..29b74d176e36 --- /dev/null +++ b/drivers/video/msm/vidc/common/enc/venc.c @@ -0,0 +1,1650 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "venc_internal.h" +#include "vcd_res_tracker_api.h" + +#define VID_ENC_NAME "msm_vidc_enc" + +#if DEBUG +#define DBG(x...) printk(KERN_DEBUG x) +#else +#define DBG(x...) +#endif + +#define INFO(x...) printk(KERN_INFO x) +#define ERR(x...) printk(KERN_ERR x) + +static struct vid_enc_dev *vid_enc_device_p; +static dev_t vid_enc_dev_num; +static struct class *vid_enc_class; +static long vid_enc_ioctl(struct file *file, + unsigned cmd, unsigned long arg); +static int stop_cmd; + +static s32 vid_enc_get_empty_client_index(void) +{ + u32 i; + u32 found = false; + + for (i = 0; i < VIDC_MAX_NUM_CLIENTS; i++) { + if (!vid_enc_device_p->venc_clients[i].vcd_handle) { + found = true; + break; + } + } + if (!found) { + ERR("%s():ERROR No space for new client\n", + __func__); + return -ENOMEM; + } else { + DBG("%s(): available client index = %u\n", + __func__, i); + return i; + } +} + + +u32 vid_enc_get_status(u32 status) +{ + u32 venc_status; + + switch (status) { + case VCD_S_SUCCESS: + venc_status = VEN_S_SUCCESS; + break; + case VCD_ERR_FAIL: + venc_status = VEN_S_EFAIL; + break; + case VCD_ERR_ALLOC_FAIL: + venc_status = VEN_S_ENOSWRES; + break; + case VCD_ERR_ILLEGAL_OP: + venc_status = VEN_S_EINVALCMD; + break; + case VCD_ERR_ILLEGAL_PARM: + venc_status = VEN_S_EBADPARAM; + break; + case VCD_ERR_BAD_POINTER: + case VCD_ERR_BAD_HANDLE: + venc_status = VEN_S_EFATAL; + break; + case VCD_ERR_NOT_SUPPORTED: + venc_status = VEN_S_ENOTSUPP; + break; + case VCD_ERR_BAD_STATE: + venc_status = VEN_S_EINVALSTATE; + break; + case VCD_ERR_MAX_CLIENT: + venc_status = VEN_S_ENOHWRES; + break; + default: + venc_status = VEN_S_EFAIL; + break; + } + return venc_status; +} + +static void vid_enc_notify_client(struct video_client_ctx *client_ctx) +{ + if (client_ctx) + complete(&client_ctx->event); +} + +void vid_enc_vcd_open_done(struct video_client_ctx *client_ctx, + struct vcd_handle_container *handle_container) +{ + DBG("vid_enc_vcd_open_done\n"); + + if (client_ctx) { + if (handle_container) + client_ctx->vcd_handle = handle_container->handle; + else + ERR("%s(): ERROR. handle_container is NULL\n", + __func__); + vid_enc_notify_client(client_ctx); + } else + ERR("%s(): ERROR. client_ctx is NULL\n", + __func__); +} + +static void vid_enc_input_frame_done(struct video_client_ctx *client_ctx, + u32 event, u32 status, + struct vcd_frame_data *vcd_frame_data) +{ + struct vid_enc_msg *venc_msg; + + if (!client_ctx || !vcd_frame_data) { + ERR("vid_enc_input_frame_done() NULL pointer\n"); + return; + } + + venc_msg = kzalloc(sizeof(struct vid_enc_msg), + GFP_KERNEL); + if (!venc_msg) { + ERR("vid_enc_input_frame_done(): cannot allocate vid_enc_msg " + " buffer\n"); + return; + } + + venc_msg->venc_msg_info.statuscode = vid_enc_get_status(status); + + venc_msg->venc_msg_info.msgcode = VEN_MSG_INPUT_BUFFER_DONE; + + switch (event) { + case VCD_EVT_RESP_INPUT_DONE: + DBG("Send INPUT_DON message to client = %p\n", + client_ctx); + break; + case VCD_EVT_RESP_INPUT_FLUSHED: + DBG("Send INPUT_FLUSHED message to client = %p\n", + client_ctx); + break; + default: + ERR("vid_enc_input_frame_done(): invalid event type: " + "%d\n", event); + venc_msg->venc_msg_info.statuscode = VEN_S_EFATAL; + break; + } + + venc_msg->venc_msg_info.buf.clientdata = + (void *)vcd_frame_data->frm_clnt_data; + venc_msg->venc_msg_info.msgdata_size = + sizeof(struct vid_enc_msg); + + mutex_lock(&client_ctx->msg_queue_lock); + list_add_tail(&venc_msg->list, &client_ctx->msg_queue); + mutex_unlock(&client_ctx->msg_queue_lock); + wake_up(&client_ctx->msg_wait); +} + +static void vid_enc_output_frame_done(struct video_client_ctx *client_ctx, + u32 event, u32 status, + struct vcd_frame_data *vcd_frame_data) +{ + struct vid_enc_msg *venc_msg; + unsigned long kernel_vaddr, phy_addr, user_vaddr; + int pmem_fd; + struct file *file; + s32 buffer_index = -1; + u32 ion_flag = 0; + struct ion_handle *buff_handle = NULL; + + if (!client_ctx || !vcd_frame_data) { + ERR("vid_enc_input_frame_done() NULL pointer\n"); + return; + } + + venc_msg = kzalloc(sizeof(struct vid_enc_msg), + GFP_KERNEL); + if (!venc_msg) { + ERR("vid_enc_input_frame_done(): cannot allocate vid_enc_msg " + " buffer\n"); + return; + } + + venc_msg->venc_msg_info.statuscode = vid_enc_get_status(status); + venc_msg->venc_msg_info.msgcode = VEN_MSG_OUTPUT_BUFFER_DONE; + + switch (event) { + case VCD_EVT_RESP_OUTPUT_DONE: + DBG("Send INPUT_DON message to client = %p\n", + client_ctx); + break; + case VCD_EVT_RESP_OUTPUT_FLUSHED: + DBG("Send INPUT_FLUSHED message to client = %p\n", + client_ctx); + break; + default: + ERR("QVD: vid_enc_output_frame_done invalid cmd type: %d\n", event); + venc_msg->venc_msg_info.statuscode = VEN_S_EFATAL; + break; + } + + kernel_vaddr = + (unsigned long)vcd_frame_data->virtual; + + if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT, + false, &user_vaddr, &kernel_vaddr, + &phy_addr, &pmem_fd, &file, + &buffer_index)) { + + /* Buffer address in user space */ + venc_msg->venc_msg_info.buf.ptrbuffer = (u8 *) user_vaddr; + /* Buffer address in user space */ + venc_msg->venc_msg_info.buf.clientdata = (void *) + vcd_frame_data->frm_clnt_data; + /* Data length */ + venc_msg->venc_msg_info.buf.len = + vcd_frame_data->data_len; + venc_msg->venc_msg_info.buf.flags = + vcd_frame_data->flags; + /* Timestamp pass-through from input frame */ + venc_msg->venc_msg_info.buf.timestamp = + vcd_frame_data->time_stamp; + venc_msg->venc_msg_info.buf.sz = + vcd_frame_data->alloc_len; + + /* Decoded picture width and height */ + venc_msg->venc_msg_info.msgdata_size = + sizeof(struct venc_buffer); + } else { + ERR("vid_enc_output_frame_done UVA can not be found\n"); + venc_msg->venc_msg_info.statuscode = + VEN_S_EFATAL; + } + if (venc_msg->venc_msg_info.buf.len > 0) { + ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_OUTPUT, + pmem_fd, kernel_vaddr, buffer_index, + &buff_handle); + if (ion_flag == CACHED && buff_handle) { + msm_ion_do_cache_op(client_ctx->user_ion_client, + buff_handle, + (unsigned long *) kernel_vaddr, + (unsigned long)venc_msg->venc_msg_info.buf.sz, + ION_IOC_CLEAN_INV_CACHES); + } + } + mutex_lock(&client_ctx->msg_queue_lock); + list_add_tail(&venc_msg->list, &client_ctx->msg_queue); + mutex_unlock(&client_ctx->msg_queue_lock); + wake_up(&client_ctx->msg_wait); +} + +static void vid_enc_lean_event(struct video_client_ctx *client_ctx, + u32 event, u32 status) +{ + struct vid_enc_msg *venc_msg; + if (!client_ctx) { + ERR("%s(): !client_ctx pointer\n", + __func__); + return; + } + + venc_msg = kzalloc(sizeof(struct vid_enc_msg), + GFP_KERNEL); + if (!venc_msg) { + ERR("%s(): cannot allocate vid_enc_msg buffer\n", + __func__); + return; + } + + venc_msg->venc_msg_info.statuscode = + vid_enc_get_status(status); + + switch (event) { + case VCD_EVT_RESP_FLUSH_INPUT_DONE: + INFO("\n msm_vidc_enc: Sending VCD_EVT_RESP_FLUSH_INPUT_DONE" + " to client"); + venc_msg->venc_msg_info.msgcode = + VEN_MSG_FLUSH_INPUT_DONE; + break; + case VCD_EVT_RESP_FLUSH_OUTPUT_DONE: + INFO("\n msm_vidc_enc: Sending VCD_EVT_RESP_FLUSH_OUTPUT_DONE" + " to client"); + venc_msg->venc_msg_info.msgcode = + VEN_MSG_FLUSH_OUPUT_DONE; + break; + + case VCD_EVT_RESP_START: + INFO("\n msm_vidc_enc: Sending VCD_EVT_RESP_START" + " to client"); + venc_msg->venc_msg_info.msgcode = + VEN_MSG_START; + break; + + case VCD_EVT_RESP_STOP: + INFO("\n msm_vidc_enc: Sending VCD_EVT_RESP_STOP" + " to client"); + venc_msg->venc_msg_info.msgcode = + VEN_MSG_STOP; + break; + + case VCD_EVT_RESP_PAUSE: + INFO("\n msm_vidc_enc: Sending VCD_EVT_RESP_PAUSE" + " to client"); + venc_msg->venc_msg_info.msgcode = + VEN_MSG_PAUSE; + break; + + default: + ERR("%s() : unknown event type %u\n", + __func__, event); + break; + } + + venc_msg->venc_msg_info.msgdata_size = 0; + + mutex_lock(&client_ctx->msg_queue_lock); + list_add_tail(&venc_msg->list, &client_ctx->msg_queue); + mutex_unlock(&client_ctx->msg_queue_lock); + wake_up(&client_ctx->msg_wait); +} + + +void vid_enc_vcd_cb(u32 event, u32 status, + void *info, size_t sz, void *handle, + void *const client_data) +{ + struct video_client_ctx *client_ctx = + (struct video_client_ctx *)client_data; + + DBG("Entering %s()\n", __func__); + + if (!client_ctx) { + ERR("%s(): client_ctx is NULL\n", __func__); + return; + } + + client_ctx->event_status = status; + + switch (event) { + case VCD_EVT_RESP_OPEN: + vid_enc_vcd_open_done(client_ctx, + (struct vcd_handle_container *)info); + break; + + case VCD_EVT_RESP_INPUT_DONE: + case VCD_EVT_RESP_INPUT_FLUSHED: + vid_enc_input_frame_done(client_ctx, event, + status, (struct vcd_frame_data *)info); + break; + + case VCD_EVT_RESP_OUTPUT_DONE: + case VCD_EVT_RESP_OUTPUT_FLUSHED: + vid_enc_output_frame_done(client_ctx, event, status, + (struct vcd_frame_data *)info); + break; + + case VCD_EVT_RESP_PAUSE: + case VCD_EVT_RESP_START: + case VCD_EVT_RESP_STOP: + case VCD_EVT_RESP_FLUSH_INPUT_DONE: + case VCD_EVT_RESP_FLUSH_OUTPUT_DONE: + case VCD_EVT_IND_OUTPUT_RECONFIG: + case VCD_EVT_IND_HWERRFATAL: + case VCD_EVT_IND_RESOURCES_LOST: + vid_enc_lean_event(client_ctx, event, status); + break; + + default: + ERR("%s() : Error - Invalid event type =%u\n", + __func__, event); + break; + } +} + +static u32 vid_enc_msg_pending(struct video_client_ctx *client_ctx) +{ + u32 islist_empty = 0; + + mutex_lock(&client_ctx->msg_queue_lock); + islist_empty = list_empty(&client_ctx->msg_queue); + mutex_unlock(&client_ctx->msg_queue_lock); + + if (islist_empty) { + DBG("%s(): vid_enc msg queue empty\n", + __func__); + if (client_ctx->stop_msg) { + DBG("%s(): List empty and Stop Msg set\n", + __func__); + return client_ctx->stop_msg; + } + } else + DBG("%s(): vid_enc msg queue Not empty\n", + __func__); + + return !islist_empty; +} + +static int vid_enc_get_next_msg(struct video_client_ctx *client_ctx, + struct venc_msg *venc_msg_info) +{ + int rc; + struct vid_enc_msg *vid_enc_msg = NULL; + + if (!client_ctx) + return -EIO; + + rc = wait_event_interruptible(client_ctx->msg_wait, + vid_enc_msg_pending(client_ctx)); + + if (rc < 0) { + DBG("rc = %d,stop_msg= %u\n", rc, client_ctx->stop_msg); + return rc; + } else if (client_ctx->stop_msg) { + DBG("stopped stop_msg = %u\n", client_ctx->stop_msg); + return -EIO; + } + + mutex_lock(&client_ctx->msg_queue_lock); + + if (!list_empty(&client_ctx->msg_queue)) { + DBG("%s(): After Wait\n", __func__); + vid_enc_msg = list_first_entry(&client_ctx->msg_queue, + struct vid_enc_msg, list); + list_del(&vid_enc_msg->list); + memcpy(venc_msg_info, &vid_enc_msg->venc_msg_info, + sizeof(struct venc_msg)); + kfree(vid_enc_msg); + } + mutex_unlock(&client_ctx->msg_queue_lock); + return 0; +} + +static u32 vid_enc_close_client(struct video_client_ctx *client_ctx) +{ + struct vid_enc_msg *vid_enc_msg = NULL; + u32 vcd_status; + int rc; + + INFO("\n msm_vidc_enc: Inside %s()", __func__); + if (!client_ctx || (!client_ctx->vcd_handle)) { + ERR("\n %s(): Invalid client_ctx", __func__); + return false; + } + + mutex_lock(&vid_enc_device_p->lock); + + if (!stop_cmd) { + vcd_status = vcd_stop(client_ctx->vcd_handle); + DBG("Waiting for VCD_STOP: Before Timeout\n"); + if (!vcd_status) { + rc = wait_for_completion_timeout(&client_ctx->event, + 5 * HZ); + if (!rc) { + ERR("%s:ERROR vcd_stop time out" + "rc = %d\n", __func__, rc); + } + + if (client_ctx->event_status) { + ERR("%s:ERROR " + "vcd_stop Not successs\n", __func__); + } + } + } + DBG("VCD_STOPPED: After Timeout, calling VCD_CLOSE\n"); + mutex_lock(&client_ctx->msg_queue_lock); + while (!list_empty(&client_ctx->msg_queue)) { + DBG("%s(): Delete remaining entries\n", __func__); + vid_enc_msg = list_first_entry(&client_ctx->msg_queue, + struct vid_enc_msg, list); + list_del(&vid_enc_msg->list); + kfree(vid_enc_msg); + } + mutex_unlock(&client_ctx->msg_queue_lock); + vcd_status = vcd_close(client_ctx->vcd_handle); + + if (vcd_status) { + mutex_unlock(&vid_enc_device_p->lock); + return false; + } + memset((void *)client_ctx, 0, + sizeof(struct video_client_ctx)); + + vid_enc_device_p->num_clients--; + stop_cmd = 0; + mutex_unlock(&vid_enc_device_p->lock); + return true; +} + + +static int vid_enc_open(struct inode *inode, struct file *file) +{ + s32 client_index; + struct video_client_ctx *client_ctx; + int rc = 0; + u8 client_count = 0; + + INFO("\n msm_vidc_enc: Inside %s()", __func__); + + mutex_lock(&vid_enc_device_p->lock); + + stop_cmd = 0; + client_count = vcd_get_num_of_clients(); + if (client_count == VIDC_MAX_NUM_CLIENTS) { + ERR("ERROR : vid_enc_open() max number of clients" + "limit reached\n"); + mutex_unlock(&vid_enc_device_p->lock); + return -ENODEV; + } + + DBG(" Virtual Address of ioremap is %p\n", vid_enc_device_p->virt_base); + if (!vid_enc_device_p->num_clients) { + if (!vidc_load_firmware()) + return -ENODEV; + } + + client_index = vid_enc_get_empty_client_index(); + + if (client_index == -1) { + ERR("%s() : No free clients client_index == -1\n", + __func__); + return -ENODEV; + } + + client_ctx = + &vid_enc_device_p->venc_clients[client_index]; + vid_enc_device_p->num_clients++; + + init_completion(&client_ctx->event); + mutex_init(&client_ctx->msg_queue_lock); + mutex_init(&client_ctx->enrty_queue_lock); + INIT_LIST_HEAD(&client_ctx->msg_queue); + init_waitqueue_head(&client_ctx->msg_wait); + if (vcd_get_ion_status()) { + client_ctx->user_ion_client = vcd_get_ion_client(); + if (!client_ctx->user_ion_client) { + ERR("vcd_open ion get client failed"); + return -EFAULT; + } + } + rc = vcd_open(vid_enc_device_p->device_handle, false, + vid_enc_vcd_cb, client_ctx, 0); + client_ctx->stop_msg = 0; + + if (!rc) { + wait_for_completion(&client_ctx->event); + if (client_ctx->event_status) { + ERR("callback for vcd_open returned error: %u", + client_ctx->event_status); + mutex_unlock(&vid_enc_device_p->lock); + return -EFAULT; + } + } else { + ERR("vcd_open returned error: %u", rc); + mutex_unlock(&vid_enc_device_p->lock); + return rc; + } + file->private_data = client_ctx; + mutex_unlock(&vid_enc_device_p->lock); + return rc; +} + +static int vid_enc_release(struct inode *inode, struct file *file) +{ + struct video_client_ctx *client_ctx = file->private_data; + INFO("\n msm_vidc_enc: Inside %s()", __func__); + vid_enc_close_client(client_ctx); + vidc_release_firmware(); +#ifndef USE_RES_TRACKER + vidc_disable_clk(); +#endif + INFO("\n msm_vidc_enc: Return from %s()", __func__); + return 0; +} + +static const struct file_operations vid_enc_fops = { + .owner = THIS_MODULE, + .open = vid_enc_open, + .release = vid_enc_release, + .unlocked_ioctl = vid_enc_ioctl, +}; + +void vid_enc_interrupt_deregister(void) +{ +} + +void vid_enc_interrupt_register(void *device_name) +{ +} + +void vid_enc_interrupt_clear(void) +{ +} + +void *vid_enc_map_dev_base_addr(void *device_name) +{ + return vid_enc_device_p->virt_base; +} + +static int vid_enc_vcd_init(void) +{ + int rc; + struct vcd_init_config vcd_init_config; + u32 i; + + INFO("\n msm_vidc_enc: Inside %s()", __func__); + vid_enc_device_p->num_clients = 0; + + for (i = 0; i < VIDC_MAX_NUM_CLIENTS; i++) { + memset((void *)&vid_enc_device_p->venc_clients[i], 0, + sizeof(vid_enc_device_p->venc_clients[i])); + } + + mutex_init(&vid_enc_device_p->lock); + vid_enc_device_p->virt_base = vidc_get_ioaddr(); + + if (!vid_enc_device_p->virt_base) { + ERR("%s() : ioremap failed\n", __func__); + return -ENOMEM; + } + + vcd_init_config.device_name = "VIDC"; + vcd_init_config.map_dev_base_addr = + vid_enc_map_dev_base_addr; + vcd_init_config.interrupt_clr = + vid_enc_interrupt_clear; + vcd_init_config.register_isr = + vid_enc_interrupt_register; + vcd_init_config.deregister_isr = + vid_enc_interrupt_deregister; + + rc = vcd_init(&vcd_init_config, + &vid_enc_device_p->device_handle); + + if (rc) { + ERR("%s() : vcd_init failed\n", + __func__); + return -ENODEV; + } + return 0; +} + +static int __init vid_enc_init(void) +{ + int rc = 0; + struct device *class_devp; + + INFO("\n msm_vidc_enc: Inside %s()", __func__); + vid_enc_device_p = kzalloc(sizeof(struct vid_enc_dev), + GFP_KERNEL); + if (!vid_enc_device_p) { + ERR("%s Unable to allocate memory for vid_enc_dev\n", + __func__); + return -ENOMEM; + } + + rc = alloc_chrdev_region(&vid_enc_dev_num, 0, 1, VID_ENC_NAME); + if (rc < 0) { + ERR("%s: alloc_chrdev_region Failed rc = %d\n", + __func__, rc); + goto error_vid_enc_alloc_chrdev_region; + } + + vid_enc_class = class_create(THIS_MODULE, VID_ENC_NAME); + if (IS_ERR(vid_enc_class)) { + rc = PTR_ERR(vid_enc_class); + ERR("%s: couldn't create vid_enc_class rc = %d\n", + __func__, rc); + goto error_vid_enc_class_create; + } + + class_devp = device_create(vid_enc_class, NULL, + vid_enc_dev_num, NULL, VID_ENC_NAME); + + if (IS_ERR(class_devp)) { + rc = PTR_ERR(class_devp); + ERR("%s: class device_create failed %d\n", + __func__, rc); + goto error_vid_enc_class_device_create; + } + + vid_enc_device_p->device = class_devp; + + cdev_init(&vid_enc_device_p->cdev, &vid_enc_fops); + vid_enc_device_p->cdev.owner = THIS_MODULE; + rc = cdev_add(&(vid_enc_device_p->cdev), vid_enc_dev_num, 1); + + if (rc < 0) { + ERR("%s: cdev_add failed %d\n", + __func__, rc); + goto error_vid_enc_cdev_add; + } + vid_enc_vcd_init(); + return 0; + +error_vid_enc_cdev_add: + device_destroy(vid_enc_class, vid_enc_dev_num); +error_vid_enc_class_device_create: + class_destroy(vid_enc_class); +error_vid_enc_class_create: + unregister_chrdev_region(vid_enc_dev_num, 1); +error_vid_enc_alloc_chrdev_region: + kfree(vid_enc_device_p); + + return rc; +} + +static void __exit vid_enc_exit(void) +{ + INFO("\n msm_vidc_enc: Inside %s()", __func__); + cdev_del(&(vid_enc_device_p->cdev)); + device_destroy(vid_enc_class, vid_enc_dev_num); + class_destroy(vid_enc_class); + unregister_chrdev_region(vid_enc_dev_num, 1); + kfree(vid_enc_device_p); + INFO("\n msm_vidc_enc: Return from %s()", __func__); +} +static long vid_enc_ioctl(struct file *file, + unsigned cmd, unsigned long u_arg) +{ + struct video_client_ctx *client_ctx = NULL; + struct venc_ioctl_msg venc_msg; + void __user *arg = (void __user *)u_arg; + u32 result = true; + int result_read = -1; + + DBG("%s\n", __func__); + + client_ctx = (struct video_client_ctx *)file->private_data; + if (!client_ctx) { + ERR("!client_ctx. Cannot attach to device handle\n"); + return -ENODEV; + } + + switch (cmd) { + case VEN_IOCTL_CMD_READ_NEXT_MSG: + { + struct venc_msg cb_msg; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_CMD_READ_NEXT_MSG\n"); + result_read = vid_enc_get_next_msg(client_ctx, &cb_msg); + if (result_read < 0) + return result_read; + if (copy_to_user(venc_msg.out, &cb_msg, sizeof(cb_msg))) + return -EFAULT; + break; + } + case VEN_IOCTL_CMD_STOP_READ_MSG: + { + DBG("VEN_IOCTL_CMD_STOP_READ_MSG\n"); + client_ctx->stop_msg = 1; + wake_up(&client_ctx->msg_wait); + break; + } + case VEN_IOCTL_CMD_ENCODE_FRAME: + case VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER: + { + struct venc_buffer enc_buffer; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_CMD_ENCODE_FRAME" + "/VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER\n"); + if (copy_from_user(&enc_buffer, venc_msg.in, + sizeof(enc_buffer))) + return -EFAULT; + if (cmd == VEN_IOCTL_CMD_ENCODE_FRAME) + result = vid_enc_encode_frame(client_ctx, + &enc_buffer); + else + result = vid_enc_fill_output_buffer(client_ctx, + &enc_buffer); + if (!result) { + DBG("\n VEN_IOCTL_CMD_ENCODE_FRAME/" + "VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER failed"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_INPUT_BUFFER: + case VEN_IOCTL_SET_OUTPUT_BUFFER: + { + enum venc_buffer_dir buffer_dir; + struct venc_bufferpayload buffer_info; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_SET_INPUT_BUFFER/VEN_IOCTL_SET_OUTPUT_BUFFER\n"); + if (copy_from_user(&buffer_info, venc_msg.in, + sizeof(buffer_info))) + return -EFAULT; + buffer_dir = VEN_BUFFER_TYPE_INPUT; + if (cmd == VEN_IOCTL_SET_OUTPUT_BUFFER) + buffer_dir = VEN_BUFFER_TYPE_OUTPUT; + result = vid_enc_set_buffer(client_ctx, &buffer_info, + buffer_dir); + if (!result) { + DBG("\n VEN_IOCTL_SET_INPUT_BUFFER" + "/VEN_IOCTL_SET_OUTPUT_BUFFER failed"); + return -EIO; + } + break; + } + case VEN_IOCTL_CMD_FREE_INPUT_BUFFER: + case VEN_IOCTL_CMD_FREE_OUTPUT_BUFFER: + { + enum venc_buffer_dir buffer_dir; + struct venc_bufferpayload buffer_info; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + + DBG("VEN_IOCTL_CMD_FREE_INPUT_BUFFER/" + "VEN_IOCTL_CMD_FREE_OUTPUT_BUFFER\n"); + + if (copy_from_user(&buffer_info, venc_msg.in, + sizeof(buffer_info))) + return -EFAULT; + + buffer_dir = VEN_BUFFER_TYPE_INPUT; + if (cmd == VEN_IOCTL_CMD_FREE_OUTPUT_BUFFER) + buffer_dir = VEN_BUFFER_TYPE_OUTPUT; + + result = vid_enc_free_buffer(client_ctx, &buffer_info, + buffer_dir); + if (!result) { + DBG("\n VEN_IOCTL_CMD_FREE_OUTPUT_BUFFER" + "/VEN_IOCTL_CMD_FREE_OUTPUT_BUFFER failed"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_INPUT_BUFFER_REQ: + case VEN_IOCTL_SET_OUTPUT_BUFFER_REQ: + { + struct venc_allocatorproperty allocatorproperty; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + + DBG("VEN_IOCTL_SET_INPUT_BUFFER_REQ" + "/VEN_IOCTL_SET_OUTPUT_BUFFER_REQ\n"); + + if (copy_from_user(&allocatorproperty, venc_msg.in, + sizeof(allocatorproperty))) + return -EFAULT; + + if (cmd == VEN_IOCTL_SET_OUTPUT_BUFFER_REQ) + result = vid_enc_set_buffer_req(client_ctx, + &allocatorproperty, false); + else + result = vid_enc_set_buffer_req(client_ctx, + &allocatorproperty, true); + if (!result) { + DBG("setting VEN_IOCTL_SET_OUTPUT_BUFFER_REQ/" + "VEN_IOCTL_SET_INPUT_BUFFER_REQ failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_GET_INPUT_BUFFER_REQ: + case VEN_IOCTL_GET_OUTPUT_BUFFER_REQ: + { + struct venc_allocatorproperty allocatorproperty; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + + DBG("VEN_IOCTL_GET_INPUT_BUFFER_REQ/" + "VEN_IOCTL_GET_OUTPUT_BUFFER_REQ\n"); + + if (cmd == VEN_IOCTL_GET_OUTPUT_BUFFER_REQ) + result = vid_enc_get_buffer_req(client_ctx, + &allocatorproperty, false); + else + result = vid_enc_get_buffer_req(client_ctx, + &allocatorproperty, true); + if (!result) + return -EIO; + if (copy_to_user(venc_msg.out, &allocatorproperty, + sizeof(allocatorproperty))) + return -EFAULT; + break; + } + case VEN_IOCTL_CMD_FLUSH: + { + struct venc_bufferflush bufferflush; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + + DBG("VEN_IOCTL_CMD_FLUSH\n"); + if (copy_from_user(&bufferflush, venc_msg.in, + sizeof(bufferflush))) + return -EFAULT; + INFO("\n %s(): Calling vid_enc_flush with mode = %lu", + __func__, bufferflush.flush_mode); + result = vid_enc_flush(client_ctx, &bufferflush); + + if (!result) { + ERR("setting VEN_IOCTL_CMD_FLUSH failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_CMD_START: + { + INFO("\n %s(): Executing VEN_IOCTL_CMD_START", __func__); + result = vid_enc_start_stop(client_ctx, true); + if (!result) { + ERR("setting VEN_IOCTL_CMD_START failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_CMD_STOP: + { + INFO("\n %s(): Executing VEN_IOCTL_CMD_STOP", __func__); + result = vid_enc_start_stop(client_ctx, false); + if (!result) { + ERR("setting VEN_IOCTL_CMD_STOP failed\n"); + return -EIO; + } + stop_cmd = 1; + break; + } + case VEN_IOCTL_CMD_PAUSE: + { + INFO("\n %s(): Executing VEN_IOCTL_CMD_PAUSE", __func__); + result = vid_enc_pause_resume(client_ctx, true); + if (!result) { + ERR("setting VEN_IOCTL_CMD_PAUSE failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_CMD_RESUME: + { + INFO("\n %s(): Executing VEN_IOCTL_CMD_RESUME", __func__); + result = vid_enc_pause_resume(client_ctx, false); + if (!result) { + ERR("setting VEN_IOCTL_CMD_RESUME failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_RECON_BUFFER: + { + struct venc_recon_addr venc_recon; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_SET_RECON_BUFFER\n"); + if (copy_from_user(&venc_recon, venc_msg.in, + sizeof(venc_recon))) + return -EFAULT; + result = vid_enc_set_recon_buffers(client_ctx, + &venc_recon); + if (!result) { + ERR("setting VEN_IOCTL_SET_RECON_BUFFER failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_FREE_RECON_BUFFER: + { + struct venc_recon_addr venc_recon; + DBG("VEN_IOCTL_FREE_RECON_BUFFER\n"); + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + if (copy_from_user(&venc_recon, venc_msg.in, + sizeof(venc_recon))) + return -EFAULT; + result = vid_enc_free_recon_buffers(client_ctx, + &venc_recon); + if (!result) { + ERR("VEN_IOCTL_FREE_RECON_BUFFER failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_GET_RECON_BUFFER_SIZE: + { + struct venc_recon_buff_size venc_recon_size; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_GET_RECON_BUFFER_SIZE\n"); + if (copy_from_user(&venc_recon_size, venc_msg.out, + sizeof(venc_recon_size))) + return -EFAULT; + result = vid_enc_get_recon_buffer_size(client_ctx, + &venc_recon_size); + if (result) { + if (copy_to_user(venc_msg.out, &venc_recon_size, + sizeof(venc_recon_size))) + return -EFAULT; + } else { + ERR("setting VEN_IOCTL_GET_RECON_BUFFER_SIZE" + "failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_QP_RANGE: + case VEN_IOCTL_GET_QP_RANGE: + { + struct venc_qprange qprange; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_G(S)ET_QP_RANGE\n"); + if (cmd == VEN_IOCTL_SET_QP_RANGE) { + if (copy_from_user(&qprange, venc_msg.in, + sizeof(qprange))) + return -EFAULT; + result = vid_enc_set_get_qprange(client_ctx, + &qprange, true); + } else { + result = vid_enc_set_get_qprange(client_ctx, + &qprange, false); + if (result) { + if (copy_to_user(venc_msg.out, &qprange, + sizeof(qprange))) + return -EFAULT; + } + } + if (!result) { + ERR("setting VEN_IOCTL_G(S)ET_QP_RANGE failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_HEC: + case VEN_IOCTL_GET_HEC: + { + struct venc_headerextension headerextension; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_(G)SET_HEC\n"); + if (cmd == VEN_IOCTL_SET_HEC) { + if (copy_from_user(&headerextension, venc_msg.in, + sizeof(headerextension))) + return -EFAULT; + + result = vid_enc_set_get_headerextension(client_ctx, + &headerextension, true); + } else { + result = vid_enc_set_get_headerextension(client_ctx, + &headerextension, false); + if (result) { + if (copy_to_user(venc_msg.out, &headerextension, + sizeof(headerextension))) + return -EFAULT; + } + } + + if (!result) { + ERR("setting VEN_IOCTL_(G)SET_HEC failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_TARGET_BITRATE: + case VEN_IOCTL_GET_TARGET_BITRATE: + { + struct venc_targetbitrate targetbitrate; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_(G)SET_TARGET_BITRATE\n"); + if (cmd == VEN_IOCTL_SET_TARGET_BITRATE) { + if (copy_from_user(&targetbitrate, venc_msg.in, + sizeof(targetbitrate))) + return -EFAULT; + + result = vid_enc_set_get_bitrate(client_ctx, + &targetbitrate, true); + } else { + result = vid_enc_set_get_bitrate(client_ctx, + &targetbitrate, false); + if (result) { + if (copy_to_user(venc_msg.out, &targetbitrate, + sizeof(targetbitrate))) + return -EFAULT; + } + } + if (!result) { + ERR("setting VEN_IOCTL_(G)SET_TARGET_BITRATE failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_FRAME_RATE: + case VEN_IOCTL_GET_FRAME_RATE: + { + struct venc_framerate framerate; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_(G)SET_FRAME_RATE\n"); + if (cmd == VEN_IOCTL_SET_FRAME_RATE) { + if (copy_from_user(&framerate, venc_msg.in, + sizeof(framerate))) + return -EFAULT; + result = vid_enc_set_get_framerate(client_ctx, + &framerate, true); + } else { + result = vid_enc_set_get_framerate(client_ctx, + &framerate, false); + if (result) { + if (copy_to_user(venc_msg.out, &framerate, + sizeof(framerate))) + return -EFAULT; + } + } + + if (!result) { + ERR("VEN_IOCTL_(G)SET_FRAME_RATE failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_VOP_TIMING_CFG: + case VEN_IOCTL_GET_VOP_TIMING_CFG: + { + struct venc_voptimingcfg voptimingcfg; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + + DBG("VEN_IOCTL_(G)SET_VOP_TIMING_CFG\n"); + if (cmd == VEN_IOCTL_SET_VOP_TIMING_CFG) { + if (copy_from_user(&voptimingcfg, venc_msg.in, + sizeof(voptimingcfg))) + return -EFAULT; + result = vid_enc_set_get_voptimingcfg(client_ctx, + &voptimingcfg, true); + } else { + result = vid_enc_set_get_voptimingcfg(client_ctx, + &voptimingcfg, false); + if (result) { + if (copy_to_user(venc_msg.out, &voptimingcfg, + sizeof(voptimingcfg))) + return -EFAULT; + } + } + if (!result) { + ERR("VEN_IOCTL_(G)SET_VOP_TIMING_CFG failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_RATE_CTRL_CFG: + case VEN_IOCTL_GET_RATE_CTRL_CFG: + { + struct venc_ratectrlcfg ratectrlcfg; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_(G)SET_RATE_CTRL_CFG\n"); + if (cmd == VEN_IOCTL_SET_RATE_CTRL_CFG) { + if (copy_from_user(&ratectrlcfg, venc_msg.in, + sizeof(ratectrlcfg))) + return -EFAULT; + + result = vid_enc_set_get_ratectrlcfg(client_ctx, + &ratectrlcfg, true); + } else { + result = vid_enc_set_get_ratectrlcfg(client_ctx, + &ratectrlcfg, false); + if (result) { + if (copy_to_user(venc_msg.out, &ratectrlcfg, + sizeof(ratectrlcfg))) + return -EFAULT; + } + } + if (!result) { + ERR("setting VEN_IOCTL_(G)SET_RATE_CTRL_CFG failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_MULTI_SLICE_CFG: + case VEN_IOCTL_GET_MULTI_SLICE_CFG: + { + struct venc_multiclicecfg multiclicecfg; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_(G)SET_MULTI_SLICE_CFG\n"); + if (cmd == VEN_IOCTL_SET_MULTI_SLICE_CFG) { + if (copy_from_user(&multiclicecfg, venc_msg.in, + sizeof(multiclicecfg))) + return -EFAULT; + + result = vid_enc_set_get_multiclicecfg(client_ctx, + &multiclicecfg, true); + } else { + result = vid_enc_set_get_multiclicecfg(client_ctx, + &multiclicecfg, false); + if (result) { + if (copy_to_user(venc_msg.out, &multiclicecfg, + sizeof(multiclicecfg))) + return -EFAULT; + } + } + if (!result) { + ERR("VEN_IOCTL_(G)SET_MULTI_SLICE_CFG failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_INTRA_REFRESH: + case VEN_IOCTL_GET_INTRA_REFRESH: + { + struct venc_intrarefresh intrarefresh; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_(G)SET_INTRA_REFRESH\n"); + if (cmd == VEN_IOCTL_SET_INTRA_REFRESH) { + if (copy_from_user(&intrarefresh, venc_msg.in, + sizeof(intrarefresh))) + return -EFAULT; + result = vid_enc_set_get_intrarefresh(client_ctx, + &intrarefresh, true); + } else { + result = vid_enc_set_get_intrarefresh(client_ctx, + &intrarefresh, false); + if (result) { + if (copy_to_user(venc_msg.out, &intrarefresh, + sizeof(intrarefresh))) + return -EFAULT; + } + } + if (!result) { + ERR("setting VEN_IOCTL_SET_INTRA_REFRESH failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_DEBLOCKING_CFG: + case VEN_IOCTL_GET_DEBLOCKING_CFG: + { + struct venc_dbcfg dbcfg; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + + DBG("VEN_IOCTL_(G)SET_DEBLOCKING_CFG\n"); + if (cmd == VEN_IOCTL_SET_DEBLOCKING_CFG) { + if (copy_from_user(&dbcfg, venc_msg.in, + sizeof(dbcfg))) + return -EFAULT; + result = vid_enc_set_get_dbcfg(client_ctx, + &dbcfg, true); + } else { + result = vid_enc_set_get_dbcfg(client_ctx, + &dbcfg, false); + if (result) { + if (copy_to_user(venc_msg.out, &dbcfg, + sizeof(dbcfg))) + return -EFAULT; + } + } + if (!result) { + ERR("setting VEN_IOCTL_SET_DEBLOCKING_CFG failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_ENTROPY_CFG: + case VEN_IOCTL_GET_ENTROPY_CFG: + { + struct venc_entropycfg entropy_cfg; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_(G)SET_ENTROPY_CFG\n"); + if (cmd == VEN_IOCTL_SET_ENTROPY_CFG) { + if (copy_from_user(&entropy_cfg, venc_msg.in, + sizeof(entropy_cfg))) + return -EFAULT; + result = vid_enc_set_get_entropy_cfg(client_ctx, + &entropy_cfg, true); + } else { + result = vid_enc_set_get_entropy_cfg(client_ctx, + &entropy_cfg, false); + if (result) { + if (copy_to_user(venc_msg.out, &entropy_cfg, + sizeof(entropy_cfg))) + return -EFAULT; + } + } + if (!result) { + ERR("setting VEN_IOCTL_(G)SET_ENTROPY_CFG failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_GET_SEQUENCE_HDR: + { + struct venc_seqheader seq_header; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + + if (copy_from_user(&seq_header, venc_msg.in, + sizeof(seq_header))) + return -EFAULT; + + DBG("VEN_IOCTL_GET_SEQUENCE_HDR\n"); + result = vid_enc_get_sequence_header(client_ctx, + &seq_header); + if (!result) { + ERR("get sequence header failed\n"); + return -EIO; + } + DBG("seq_header: buf=%x, sz=%d, hdrlen=%d\n", + (int)seq_header.hdrbufptr, + (int)seq_header.bufsize, + (int)seq_header.hdrlen); + if (copy_to_user(venc_msg.out, &seq_header, + sizeof(seq_header))) + return -EFAULT; + break; + } + case VEN_IOCTL_CMD_REQUEST_IFRAME: + { + result = vid_enc_request_iframe(client_ctx); + if (!result) { + ERR("setting VEN_IOCTL_CMD_REQUEST_IFRAME failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_INTRA_PERIOD: + case VEN_IOCTL_GET_INTRA_PERIOD: + { + struct venc_intraperiod intraperiod; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_(G)SET_INTRA_PERIOD\n"); + if (cmd == VEN_IOCTL_SET_INTRA_PERIOD) { + if (copy_from_user(&intraperiod, venc_msg.in, + sizeof(intraperiod))) + return -EFAULT; + result = vid_enc_set_get_intraperiod(client_ctx, + &intraperiod, true); + } else { + result = vid_enc_set_get_intraperiod(client_ctx, + &intraperiod, false); + if (result) { + if (copy_to_user(venc_msg.out, &intraperiod, + sizeof(intraperiod))) + return -EFAULT; + } + } + if (!result) { + ERR("setting VEN_IOCTL_(G)SET_INTRA_PERIOD failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_SESSION_QP: + case VEN_IOCTL_GET_SESSION_QP: + { + struct venc_sessionqp session_qp; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("VEN_IOCTL_(G)SET_SESSION_QP\n"); + if (cmd == VEN_IOCTL_SET_SESSION_QP) { + if (copy_from_user(&session_qp, venc_msg.in, + sizeof(session_qp))) + return -EFAULT; + result = vid_enc_set_get_session_qp(client_ctx, + &session_qp, true); + } else { + result = vid_enc_set_get_session_qp(client_ctx, + &session_qp, false); + if (result) { + if (copy_to_user(venc_msg.out, &session_qp, + sizeof(session_qp))) + return -EFAULT; + } + } + if (!result) { + ERR("setting VEN_IOCTL_(G)SET_SESSION_QP failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_PROFILE_LEVEL: + case VEN_IOCTL_GET_PROFILE_LEVEL: + { + struct ven_profilelevel profile_level; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + + DBG("VEN_IOCTL_(G)SET_PROFILE_LEVEL\n"); + if (cmd == VEN_IOCTL_SET_PROFILE_LEVEL) { + if (copy_from_user(&profile_level, venc_msg.in, + sizeof(profile_level))) + return -EFAULT; + result = vid_enc_set_get_profile_level(client_ctx, + &profile_level, true); + } else { + result = vid_enc_set_get_profile_level(client_ctx, + &profile_level, false); + if (result) { + if (copy_to_user(venc_msg.out, + &profile_level, sizeof(profile_level))) + return -EFAULT; + } + } + if (!result) { + ERR("setting VEN_IOCTL_SET_PROFILE_LEVEL failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_CODEC_PROFILE: + case VEN_IOCTL_GET_CODEC_PROFILE: + { + struct venc_profile profile; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + + DBG("VEN_IOCTL_(G)SET_CODEC_PROFILE\n"); + if (cmd == VEN_IOCTL_SET_CODEC_PROFILE) { + if (copy_from_user(&profile, venc_msg.in, + sizeof(profile))) + return -EFAULT; + result = vid_enc_set_get_profile(client_ctx, + &profile, true); + } else { + result = vid_enc_set_get_profile(client_ctx, + &profile, false); + if (result) { + if (copy_to_user(venc_msg.out, &profile, + sizeof(profile))) + return -EFAULT; + } + } + if (!result) { + ERR("setting VEN_IOCTL_SET_CODEC_PROFILE failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_SHORT_HDR: + case VEN_IOCTL_GET_SHORT_HDR: + { + struct venc_switch encoder_switch; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + DBG("Getting VEN_IOCTL_(G)SET_SHORT_HDR\n"); + if (cmd == VEN_IOCTL_SET_SHORT_HDR) { + if (copy_from_user(&encoder_switch, venc_msg.in, + sizeof(encoder_switch))) + return -EFAULT; + + result = vid_enc_set_get_short_header(client_ctx, + &encoder_switch, true); + } else { + result = vid_enc_set_get_short_header(client_ctx, + &encoder_switch, false); + if (result) { + if (copy_to_user(venc_msg.out, &encoder_switch, + sizeof(encoder_switch))) + return -EFAULT; + } + } + if (!result) { + ERR("setting VEN_IOCTL_(G)SET_SHORT_HDR failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_BASE_CFG: + case VEN_IOCTL_GET_BASE_CFG: + { + struct venc_basecfg base_config; + DBG("VEN_IOCTL_SET_BASE_CFG\n"); + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + if (cmd == VEN_IOCTL_SET_BASE_CFG) { + if (copy_from_user(&base_config, venc_msg.in, + sizeof(base_config))) + return -EFAULT; + result = vid_enc_set_get_base_cfg(client_ctx, + &base_config, true); + } else { + result = vid_enc_set_get_base_cfg(client_ctx, + &base_config, false); + if (result) { + if (copy_to_user(venc_msg.out, &base_config, + sizeof(base_config))) + return -EFAULT; + } + } + if (!result) { + ERR("setting VEN_IOCTL_SET_BASE_CFG failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_LIVE_MODE: + case VEN_IOCTL_GET_LIVE_MODE: + { + struct venc_switch encoder_switch; + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + + DBG("Getting VEN_IOCTL_(G)SET_LIVE_MODE\n"); + if (cmd == VEN_IOCTL_SET_LIVE_MODE) { + if (copy_from_user(&encoder_switch, venc_msg.in, + sizeof(encoder_switch))) + return -EFAULT; + result = vid_enc_set_get_live_mode(client_ctx, + &encoder_switch, true); + } else { + result = vid_enc_set_get_live_mode(client_ctx, + &encoder_switch, false); + if (result) { + if (copy_to_user(venc_msg.out, &encoder_switch, + sizeof(encoder_switch))) + return -EFAULT; + } + } + if (!result) { + ERR("setting VEN_IOCTL_(G)SET_LIVE_MODE failed\n"); + return -EIO; + } + break; + } + case VEN_IOCTL_GET_NUMBER_INSTANCES: + { + DBG("VEN_IOCTL_GET_NUMBER_INSTANCES\n"); + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + if (copy_to_user(venc_msg.out, + &vid_enc_device_p->num_clients, sizeof(u32))) + return -EFAULT; + break; + } + case VEN_IOCTL_SET_METABUFFER_MODE: + { + u32 metabuffer_mode, vcd_status; + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_live live_mode; + + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + if (copy_from_user(&metabuffer_mode, venc_msg.in, + sizeof(metabuffer_mode))) + return -EFAULT; + vcd_property_hdr.prop_id = VCD_I_META_BUFFER_MODE; + vcd_property_hdr.sz = + sizeof(struct vcd_property_live); + live_mode.live = metabuffer_mode; + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &live_mode); + if (vcd_status) { + pr_err(" Setting metabuffer mode failed"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_EXTRADATA: + case VEN_IOCTL_GET_EXTRADATA: + { + u32 extradata_flag; + DBG("VEN_IOCTL_(G)SET_EXTRADATA\n"); + if (copy_from_user(&venc_msg, arg, sizeof(venc_msg))) + return -EFAULT; + if (cmd == VEN_IOCTL_SET_EXTRADATA) { + if (copy_from_user(&extradata_flag, venc_msg.in, + sizeof(u32))) + return -EFAULT; + result = vid_enc_set_get_extradata(client_ctx, + &extradata_flag, true); + } else { + result = vid_enc_set_get_extradata(client_ctx, + &extradata_flag, false); + if (result) { + if (copy_to_user(venc_msg.out, &extradata_flag, + sizeof(u32))) + return -EFAULT; + } + } + if (!result) { + ERR("setting VEN_IOCTL_(G)SET_LIVE_MODE failed\n"); + } + break; + } + case VEN_IOCTL_SET_SLICE_DELIVERY_MODE: + { + struct vcd_property_hdr vcd_property_hdr; + u32 vcd_status = VCD_ERR_FAIL; + u32 enable = true; + vcd_property_hdr.prop_id = VCD_I_SLICE_DELIVERY_MODE; + vcd_property_hdr.sz = sizeof(u32); + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &enable); + if (vcd_status) { + pr_err(" Setting slice delivery mode failed"); + return -EIO; + } + break; + } + case VEN_IOCTL_SET_AC_PREDICTION: + case VEN_IOCTL_GET_AC_PREDICTION: + case VEN_IOCTL_SET_RVLC: + case VEN_IOCTL_GET_RVLC: + case VEN_IOCTL_SET_ROTATION: + case VEN_IOCTL_GET_ROTATION: + case VEN_IOCTL_SET_DATA_PARTITION: + case VEN_IOCTL_GET_DATA_PARTITION: + case VEN_IOCTL_GET_CAPABILITY: + default: + ERR("%s(): Unsupported ioctl %d\n", __func__, cmd); + return -ENOTTY; + + break; + } + return 0; +} + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Video encoder driver"); +MODULE_VERSION("1.0"); + +module_init(vid_enc_init); +module_exit(vid_enc_exit); diff --git a/drivers/video/msm/vidc/common/enc/venc_internal.c b/drivers/video/msm/vidc/common/enc/venc_internal.c new file mode 100644 index 000000000000..2fb71d40dc8a --- /dev/null +++ b/drivers/video/msm/vidc/common/enc/venc_internal.c @@ -0,0 +1,1995 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "vcd_res_tracker_api.h" +#include "venc_internal.h" + +#if DEBUG +#define DBG(x...) printk(KERN_DEBUG x) +#else +#define DBG(x...) +#endif + +#define ERR(x...) printk(KERN_ERR x) +static unsigned int vidc_mmu_subsystem[] = { + MSM_SUBSYSTEM_VIDEO}; + + +u32 vid_enc_set_get_base_cfg(struct video_client_ctx *client_ctx, + struct venc_basecfg *base_config, u32 set_flag) +{ + struct venc_targetbitrate venc_bitrate; + struct venc_framerate frame_rate; + u32 current_codec; + + if (!client_ctx || !base_config) + return false; + + if (!vid_enc_set_get_codec(client_ctx, ¤t_codec, false)) + return false; + + DBG("%s(): Current Codec Type = %u\n", __func__, current_codec); + if (current_codec != base_config->codectype) { + if (!vid_enc_set_get_codec(client_ctx, + (u32 *)&base_config->codectype, set_flag)) + return false; + } + + if (!vid_enc_set_get_inputformat(client_ctx, + (u32 *)&base_config->inputformat, set_flag)) + return false; + + if (!vid_enc_set_get_framesize(client_ctx, + (u32 *)&base_config->input_height, + (u32 *)&base_config->input_width, set_flag)) + return false; + + if (set_flag) + venc_bitrate.target_bitrate = base_config->targetbitrate; + + if (!vid_enc_set_get_bitrate(client_ctx, &venc_bitrate, set_flag)) + return false; + + if (!set_flag) + base_config->targetbitrate = venc_bitrate.target_bitrate; + + if (set_flag) { + frame_rate.fps_denominator = base_config->fps_den; + frame_rate.fps_numerator = base_config->fps_num; + } + + if (!vid_enc_set_get_framerate(client_ctx, &frame_rate, set_flag)) + return false; + + if (!set_flag) { + base_config->fps_den = frame_rate.fps_denominator; + base_config->fps_num = frame_rate.fps_numerator; + } + + return true; +} + +u32 vid_enc_set_get_inputformat(struct video_client_ctx *client_ctx, + u32 *input_format, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_buffer_format format; + u32 vcd_status = VCD_ERR_FAIL; + u32 status = true; + + if (!client_ctx || !input_format) + return false; + + vcd_property_hdr.prop_id = VCD_I_BUFFER_FORMAT; + vcd_property_hdr.sz = + sizeof(struct vcd_property_buffer_format); + + if (set_flag) { + switch (*input_format) { + case VEN_INPUTFMT_NV12: + format.buffer_format = VCD_BUFFER_FORMAT_NV12; + break; + case VEN_INPUTFMT_NV12_16M2KA: + format.buffer_format = + VCD_BUFFER_FORMAT_NV12_16M2KA; + break; + default: + status = false; + break; + } + + if (status) { + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &format); + if (vcd_status) { + status = false; + ERR("%s(): Set VCD_I_BUFFER_FORMAT Failed\n", + __func__); + } + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &format); + + if (vcd_status) { + status = false; + ERR("%s(): Get VCD_I_BUFFER_FORMAT Failed\n", __func__); + } else { + switch (format.buffer_format) { + case VCD_BUFFER_FORMAT_NV12: + *input_format = VEN_INPUTFMT_NV12; + break; + case VCD_BUFFER_FORMAT_TILE_4x2: + *input_format = VEN_INPUTFMT_NV21; + break; + default: + status = false; + break; + } + } + } + return status; +} + +u32 vid_enc_set_get_codec(struct video_client_ctx *client_ctx, u32 *codec, + u32 set_flag) +{ + struct vcd_property_codec vcd_property_codec; + struct vcd_property_hdr vcd_property_hdr; + u32 vcd_status = VCD_ERR_FAIL; + u32 status = true; + + if (!client_ctx || !codec) + return false; + + vcd_property_hdr.prop_id = VCD_I_CODEC; + vcd_property_hdr.sz = sizeof(struct vcd_property_codec); + + if (set_flag) { + switch (*codec) { + case VEN_CODEC_MPEG4: + vcd_property_codec.codec = VCD_CODEC_MPEG4; + break; + case VEN_CODEC_H263: + vcd_property_codec.codec = VCD_CODEC_H263; + break; + case VEN_CODEC_H264: + vcd_property_codec.codec = VCD_CODEC_H264; + break; + default: + status = false; + break; + } + + if (status) { + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &vcd_property_codec); + if (vcd_status) { + status = false; + ERR("%s(): Set VCD_I_CODEC Failed\n", __func__); + } + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &vcd_property_codec); + + if (vcd_status) { + status = false; + ERR("%s(): Get VCD_I_CODEC Failed\n", + __func__); + } else { + switch (vcd_property_codec.codec) { + case VCD_CODEC_H263: + *codec = VEN_CODEC_H263; + break; + case VCD_CODEC_H264: + *codec = VEN_CODEC_H264; + break; + case VCD_CODEC_MPEG4: + *codec = VEN_CODEC_MPEG4; + break; + case VCD_CODEC_DIVX_3: + case VCD_CODEC_DIVX_4: + case VCD_CODEC_DIVX_5: + case VCD_CODEC_DIVX_6: + case VCD_CODEC_MPEG1: + case VCD_CODEC_MPEG2: + case VCD_CODEC_VC1: + case VCD_CODEC_VC1_RCV: + case VCD_CODEC_XVID: + default: + status = false; + break; + } + } + } + return status; +} + +u32 vid_enc_set_get_framesize(struct video_client_ctx *client_ctx, + u32 *height, u32 *width, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_frame_size frame_size; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx || !height || !width) + return false; + + vcd_property_hdr.prop_id = VCD_I_FRAME_SIZE; + vcd_property_hdr.sz = + sizeof(struct vcd_property_frame_size); + + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &frame_size); + + if (vcd_status) { + ERR("%s(): Get VCD_I_FRAME_SIZE Failed\n", + __func__); + return false; + } + if (set_flag) { + if (frame_size.height != *height || + frame_size.width != *width) { + DBG("%s(): ENC Set Size (%d x %d)\n", + __func__, *height, *width); + frame_size.height = *height; + frame_size.width = *width; + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &frame_size); + if (vcd_status) { + ERR("%s(): Set VCD_I_FRAME_SIZE Failed\n", + __func__); + return false; + } + } + } else { + *height = frame_size.height; + *width = frame_size.width; + } + return true; +} + +u32 vid_enc_set_get_bitrate(struct video_client_ctx *client_ctx, + struct venc_targetbitrate *venc_bitrate, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_target_bitrate bit_rate; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx || !venc_bitrate) + return false; + + vcd_property_hdr.prop_id = VCD_I_TARGET_BITRATE; + vcd_property_hdr.sz = + sizeof(struct vcd_property_target_bitrate); + if (set_flag) { + bit_rate.target_bitrate = venc_bitrate->target_bitrate; + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &bit_rate); + + if (vcd_status) { + ERR("%s(): Set VCD_I_TARGET_BITRATE Failed\n", + __func__); + return false; + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &bit_rate); + + if (vcd_status) { + ERR("%s(): Get VCD_I_TARGET_BITRATE Failed\n", + __func__); + return false; + } + venc_bitrate->target_bitrate = bit_rate.target_bitrate; + } + return true; +} + +u32 vid_enc_set_get_extradata(struct video_client_ctx *client_ctx, + u32 *extradata_flag, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_meta_data_enable vcd_meta_data; + u32 vcd_status = VCD_ERR_FAIL; + if (!client_ctx || !extradata_flag) + return false; + vcd_property_hdr.prop_id = VCD_I_METADATA_ENABLE; + vcd_property_hdr.sz = sizeof(struct vcd_property_meta_data_enable); + if (set_flag) { + DBG("vcd_set_property: VCD_I_METADATA_ENABLE = %d\n", + *extradata_flag); + vcd_meta_data.meta_data_enable_flag = *extradata_flag; + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &vcd_meta_data); + if (vcd_status) { + ERR("%s(): Set VCD_I_METADATA_ENABLE Failed\n", + __func__); + return false; + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &vcd_meta_data); + if (vcd_status) { + ERR("%s(): Get VCD_I_METADATA_ENABLE Failed\n", + __func__); + return false; + } + *extradata_flag = vcd_meta_data.meta_data_enable_flag; + DBG("vcd_get_property: VCD_I_METADATA_ENABLE = %d\n", + *extradata_flag); + } + return true; +} + +u32 vid_enc_set_get_framerate(struct video_client_ctx *client_ctx, + struct venc_framerate *frame_rate, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_frame_rate vcd_frame_rate; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx || !frame_rate) + return false; + + vcd_property_hdr.prop_id = VCD_I_FRAME_RATE; + vcd_property_hdr.sz = + sizeof(struct vcd_property_frame_rate); + + if (set_flag) { + vcd_frame_rate.fps_denominator = frame_rate->fps_denominator; + vcd_frame_rate.fps_numerator = frame_rate->fps_numerator; + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &vcd_frame_rate); + + if (vcd_status) { + ERR("%s(): Set VCD_I_FRAME_RATE Failed\n", + __func__); + return false; + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &vcd_frame_rate); + + if (vcd_status) { + ERR("%s(): Get VCD_I_FRAME_RATE Failed\n", + __func__); + return false; + } + frame_rate->fps_denominator = vcd_frame_rate.fps_denominator; + frame_rate->fps_numerator = vcd_frame_rate.fps_numerator; + } + return true; +} + +u32 vid_enc_set_get_live_mode(struct video_client_ctx *client_ctx, + struct venc_switch *encoder_switch, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_live live_mode; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx) + return false; + + vcd_property_hdr.prop_id = VCD_I_LIVE; + vcd_property_hdr.sz = + sizeof(struct vcd_property_live); + + if (set_flag) { + live_mode.live = 1; + if (!encoder_switch->status) + live_mode.live = 0; + + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &live_mode); + if (vcd_status) { + ERR("%s(): Set VCD_I_LIVE Failed\n", + __func__); + return false; + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &live_mode); + + if (vcd_status) { + ERR("%s(): Get VCD_I_LIVE Failed\n", + __func__); + return false; + } else { + encoder_switch->status = 1; + if (!live_mode.live) + encoder_switch->status = 0; + } + } + return true; +} + +u32 vid_enc_set_get_short_header(struct video_client_ctx *client_ctx, + struct venc_switch *encoder_switch, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_short_header short_header; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx || !encoder_switch) + return false; + + vcd_property_hdr.prop_id = VCD_I_SHORT_HEADER; + vcd_property_hdr.sz = + sizeof(struct vcd_property_short_header); + + if (set_flag) { + short_header.short_header = (u32) encoder_switch->status; + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &short_header); + + if (vcd_status) { + ERR("%s(): Set VCD_I_SHORT_HEADER Failed\n", + __func__); + return false; + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &short_header); + + if (vcd_status) { + ERR("%s(): Get VCD_I_SHORT_HEADER Failed\n", + __func__); + return false; + } else { + encoder_switch->status = + (u8) short_header.short_header; + } + } + return true; +} + +u32 vid_enc_set_get_profile(struct video_client_ctx *client_ctx, + struct venc_profile *profile, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_profile profile_type; + u32 vcd_status = VCD_ERR_FAIL; + u32 status = true; + + if (!client_ctx || !profile) + return false; + + vcd_property_hdr.prop_id = VCD_I_PROFILE; + vcd_property_hdr.sz = + sizeof(struct vcd_property_profile); + + if (set_flag) { + switch (profile->profile) { + case VEN_PROFILE_MPEG4_SP: + profile_type.profile = VCD_PROFILE_MPEG4_SP; + break; + case VEN_PROFILE_MPEG4_ASP: + profile_type.profile = VCD_PROFILE_MPEG4_ASP; + break; + case VEN_PROFILE_H264_BASELINE: + profile_type.profile = VCD_PROFILE_H264_BASELINE; + break; + case VEN_PROFILE_H264_MAIN: + profile_type.profile = VCD_PROFILE_H264_MAIN; + break; + case VEN_PROFILE_H264_HIGH: + profile_type.profile = VCD_PROFILE_H264_HIGH; + break; + case VEN_PROFILE_H263_BASELINE: + profile_type.profile = VCD_PROFILE_H263_BASELINE; + break; + default: + status = false; + break; + } + + if (status) { + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &profile_type); + + if (vcd_status) { + ERR("%s(): Set VCD_I_PROFILE Failed\n", + __func__); + return false; + } + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &profile_type); + + if (vcd_status) { + ERR("%s(): Get VCD_I_PROFILE Failed\n", + __func__); + return false; + } else { + switch (profile_type.profile) { + case VCD_PROFILE_H263_BASELINE: + profile->profile = VEN_PROFILE_H263_BASELINE; + break; + case VCD_PROFILE_H264_BASELINE: + profile->profile = VEN_PROFILE_H264_BASELINE; + break; + case VCD_PROFILE_H264_HIGH: + profile->profile = VEN_PROFILE_H264_HIGH; + break; + case VCD_PROFILE_H264_MAIN: + profile->profile = VEN_PROFILE_H264_MAIN; + break; + case VCD_PROFILE_MPEG4_ASP: + profile->profile = VEN_PROFILE_MPEG4_ASP; + break; + case VCD_PROFILE_MPEG4_SP: + profile->profile = VEN_PROFILE_MPEG4_SP; + break; + default: + status = false; + break; + } + } + } + return status; +} + +u32 vid_enc_set_get_profile_level(struct video_client_ctx *client_ctx, + struct ven_profilelevel *profile_level, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_level level; + u32 vcd_status = VCD_ERR_FAIL; + u32 status = true; + + if (!client_ctx || !profile_level) + return false; + + vcd_property_hdr.prop_id = VCD_I_LEVEL; + vcd_property_hdr.sz = + sizeof(struct vcd_property_level); + + if (set_flag) { + switch (profile_level->level) { + case VEN_LEVEL_MPEG4_0: + level.level = VCD_LEVEL_MPEG4_0; + break; + case VEN_LEVEL_MPEG4_1: + level.level = VCD_LEVEL_MPEG4_1; + break; + case VEN_LEVEL_MPEG4_2: + level.level = VCD_LEVEL_MPEG4_2; + break; + case VEN_LEVEL_MPEG4_3: + level.level = VCD_LEVEL_MPEG4_3; + break; + case VEN_LEVEL_MPEG4_4: + level.level = VCD_LEVEL_MPEG4_4; + break; + case VEN_LEVEL_MPEG4_5: + level.level = VCD_LEVEL_MPEG4_5; + break; + case VEN_LEVEL_MPEG4_3b: + level.level = VCD_LEVEL_MPEG4_3b; + break; + case VEN_LEVEL_MPEG4_6: + level.level = VCD_LEVEL_MPEG4_6; + break; + case VEN_LEVEL_H264_1: + level.level = VCD_LEVEL_H264_1; + break; + case VEN_LEVEL_H264_1b: + level.level = VCD_LEVEL_H264_1b; + break; + case VEN_LEVEL_H264_1p1: + level.level = VCD_LEVEL_H264_1p1; + break; + case VEN_LEVEL_H264_1p2: + level.level = VCD_LEVEL_H264_1p2; + break; + case VEN_LEVEL_H264_1p3: + level.level = VCD_LEVEL_H264_1p3; + break; + case VEN_LEVEL_H264_2: + level.level = VCD_LEVEL_H264_2; + break; + case VEN_LEVEL_H264_2p1: + level.level = VCD_LEVEL_H264_2p1; + break; + case VEN_LEVEL_H264_2p2: + level.level = VCD_LEVEL_H264_2p2; + break; + case VEN_LEVEL_H264_3: + level.level = VCD_LEVEL_H264_3; + break; + case VEN_LEVEL_H264_3p1: + level.level = VCD_LEVEL_H264_3p1; + break; + case VEN_LEVEL_H264_3p2: + level.level = VCD_LEVEL_H264_3p2; + break; + case VEN_LEVEL_H264_4: + level.level = VCD_LEVEL_H264_4; + break; + case VEN_LEVEL_H263_10: + level.level = VCD_LEVEL_H263_10; + break; + case VEN_LEVEL_H263_20: + level.level = VCD_LEVEL_H263_20; + break; + case VEN_LEVEL_H263_30: + level.level = VCD_LEVEL_H263_30; + break; + case VEN_LEVEL_H263_40: + level.level = VCD_LEVEL_H263_40; + break; + case VEN_LEVEL_H263_45: + level.level = VCD_LEVEL_H263_45; + break; + case VEN_LEVEL_H263_50: + level.level = VCD_LEVEL_H263_50; + break; + case VEN_LEVEL_H263_60: + level.level = VCD_LEVEL_H263_60; + break; + case VEN_LEVEL_H263_70: + level.level = VCD_LEVEL_H263_70; + break; + default: + status = false; + break; + } + if (status) { + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &level); + + if (vcd_status) { + ERR("%s(): Set VCD_I_LEVEL Failed\n", + __func__); + return false; + } + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &level); + + if (vcd_status) { + ERR("%s(): Get VCD_I_LEVEL Failed\n", + __func__); + return false; + } else { + switch (level.level) { + case VCD_LEVEL_MPEG4_0: + profile_level->level = VEN_LEVEL_MPEG4_0; + break; + case VCD_LEVEL_MPEG4_1: + profile_level->level = VEN_LEVEL_MPEG4_1; + break; + case VCD_LEVEL_MPEG4_2: + profile_level->level = VEN_LEVEL_MPEG4_2; + break; + case VCD_LEVEL_MPEG4_3: + profile_level->level = VEN_LEVEL_MPEG4_3; + break; + case VCD_LEVEL_MPEG4_4: + profile_level->level = VEN_LEVEL_MPEG4_4; + break; + case VCD_LEVEL_MPEG4_5: + profile_level->level = VEN_LEVEL_MPEG4_5; + break; + case VCD_LEVEL_MPEG4_3b: + profile_level->level = VEN_LEVEL_MPEG4_3b; + break; + case VCD_LEVEL_H264_1: + profile_level->level = VEN_LEVEL_H264_1; + break; + case VCD_LEVEL_H264_1b: + profile_level->level = VEN_LEVEL_H264_1b; + break; + case VCD_LEVEL_H264_1p1: + profile_level->level = VEN_LEVEL_H264_1p1; + break; + case VCD_LEVEL_H264_1p2: + profile_level->level = VEN_LEVEL_H264_1p2; + break; + case VCD_LEVEL_H264_1p3: + profile_level->level = VEN_LEVEL_H264_1p3; + break; + case VCD_LEVEL_H264_2: + profile_level->level = VEN_LEVEL_H264_2; + break; + case VCD_LEVEL_H264_2p1: + profile_level->level = VEN_LEVEL_H264_2p1; + break; + case VCD_LEVEL_H264_2p2: + profile_level->level = VEN_LEVEL_H264_2p2; + break; + case VCD_LEVEL_H264_3: + profile_level->level = VEN_LEVEL_H264_3; + break; + case VCD_LEVEL_H264_3p1: + profile_level->level = VEN_LEVEL_H264_3p1; + break; + case VCD_LEVEL_H264_3p2: + profile_level->level = VEN_LEVEL_H264_3p2; + break; + case VCD_LEVEL_H264_4: + profile_level->level = VEN_LEVEL_H264_4; + break; + case VCD_LEVEL_H263_10: + profile_level->level = VEN_LEVEL_H263_10; + break; + case VCD_LEVEL_H263_20: + profile_level->level = VEN_LEVEL_H263_20; + break; + case VCD_LEVEL_H263_30: + profile_level->level = VEN_LEVEL_H263_30; + break; + case VCD_LEVEL_H263_40: + profile_level->level = VEN_LEVEL_H263_40; + break; + case VCD_LEVEL_H263_45: + profile_level->level = VEN_LEVEL_H263_45; + break; + case VCD_LEVEL_H263_50: + profile_level->level = VEN_LEVEL_H263_50; + break; + case VCD_LEVEL_H263_60: + profile_level->level = VEN_LEVEL_H263_60; + break; + case VCD_LEVEL_H263_70: + status = false; + break; + default: + status = false; + break; + } + } + } + return status; +} + +u32 vid_enc_set_get_session_qp(struct video_client_ctx *client_ctx, + struct venc_sessionqp *session_qp, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_session_qp qp; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx || !session_qp) + return false; + + vcd_property_hdr.prop_id = VCD_I_SESSION_QP; + vcd_property_hdr.sz = + sizeof(struct vcd_property_session_qp); + + if (set_flag) { + qp.i_frame_qp = session_qp->iframeqp; + qp.p_frame_qp = session_qp->pframqp; + + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &qp); + + if (vcd_status) { + ERR("%s(): Set VCD_I_SESSION_QP Failed\n", + __func__); + return false; + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &qp); + + if (vcd_status) { + ERR("%s(): Set VCD_I_SESSION_QP Failed\n", + __func__); + return false; + } else { + session_qp->iframeqp = qp.i_frame_qp; + session_qp->pframqp = qp.p_frame_qp; + } + } + return true; +} + +u32 vid_enc_set_get_intraperiod(struct video_client_ctx *client_ctx, + struct venc_intraperiod *intraperiod, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_i_period period; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx || !intraperiod) + return false; + + vcd_property_hdr.prop_id = VCD_I_INTRA_PERIOD; + vcd_property_hdr.sz = + sizeof(struct vcd_property_i_period); + + if (set_flag) { + period.p_frames = intraperiod->num_pframes; + period.b_frames = intraperiod->num_bframes; + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &period); + + if (vcd_status) { + ERR("%s(): Set VCD_I_INTRA_PERIOD Failed\n", + __func__); + return false; + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &period); + + if (vcd_status) { + ERR("%s(): Get VCD_I_INTRA_PERIOD Failed\n", + __func__); + return false; + } else + intraperiod->num_pframes = period.p_frames; + } + return true; +} + +u32 vid_enc_request_iframe(struct video_client_ctx *client_ctx) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_req_i_frame request; + u32 vcd_status = VCD_ERR_FAIL; + u32 status = true; + + if (!client_ctx) + return false; + + vcd_property_hdr.prop_id = VCD_I_REQ_IFRAME; + vcd_property_hdr.sz = + sizeof(struct vcd_property_req_i_frame); + request.req_i_frame = 1; + + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &request); + + if (vcd_status) { + ERR("%s(): Set VCD_I_REQ_IFRAME Failed\n", + __func__); + return false; + } + return status; +} + +u32 vid_enc_get_sequence_header(struct video_client_ctx *client_ctx, + struct venc_seqheader *seq_header) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_sequence_hdr hdr; + u32 vcd_status = VCD_ERR_FAIL; + u32 status = true; + + if (!client_ctx || !seq_header || !seq_header->bufsize) + return false; + + vcd_property_hdr.prop_id = VCD_I_SEQ_HEADER; + vcd_property_hdr.sz = sizeof(struct vcd_sequence_hdr); + + hdr.sequence_header = seq_header->hdrbufptr; + hdr.sequence_header_len = seq_header->bufsize; + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &hdr); + seq_header->hdrlen = hdr.sequence_header_len; + + if (vcd_status) { + ERR("%s(): Get VCD_I_SEQ_HEADER Failed\n", + __func__); + status = false; + } + return true; +} + +u32 vid_enc_set_get_entropy_cfg(struct video_client_ctx *client_ctx, + struct venc_entropycfg *entropy_cfg, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_entropy_control control; + u32 vcd_status = VCD_ERR_FAIL; + u32 status = true; + + if (!client_ctx || !entropy_cfg) + return false; + + vcd_property_hdr.prop_id = VCD_I_ENTROPY_CTRL; + vcd_property_hdr.sz = + sizeof(struct vcd_property_entropy_control); + if (set_flag) { + switch (entropy_cfg->longentropysel) { + case VEN_ENTROPY_MODEL_CAVLC: + control.entropy_sel = VCD_ENTROPY_SEL_CAVLC; + break; + case VEN_ENTROPY_MODEL_CABAC: + control.entropy_sel = VCD_ENTROPY_SEL_CABAC; + break; + default: + status = false; + break; + } + + if (status && entropy_cfg->cabacmodel == + VCD_ENTROPY_SEL_CABAC) { + switch (entropy_cfg->cabacmodel) { + case VEN_CABAC_MODEL_0: + control.cabac_model = + VCD_CABAC_MODEL_NUMBER_0; + break; + case VEN_CABAC_MODEL_1: + control.cabac_model = + VCD_CABAC_MODEL_NUMBER_1; + break; + case VEN_CABAC_MODEL_2: + control.cabac_model = + VCD_CABAC_MODEL_NUMBER_2; + break; + default: + status = false; + break; + } + } + if (status) { + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + + if (vcd_status) { + ERR("%s(): Set VCD_I_ENTROPY_CTRL Failed\n", + __func__); + status = false; + } + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + + if (vcd_status) { + ERR("%s(): Get VCD_I_ENTROPY_CTRL Failed\n", + __func__); + status = false; + } else { + switch (control.entropy_sel) { + case VCD_ENTROPY_SEL_CABAC: + entropy_cfg->cabacmodel = + VEN_ENTROPY_MODEL_CABAC; + break; + case VCD_ENTROPY_SEL_CAVLC: + entropy_cfg->cabacmodel = + VEN_ENTROPY_MODEL_CAVLC; + break; + default: + status = false; + break; + } + + if (status && control.entropy_sel == + VCD_ENTROPY_SEL_CABAC) { + switch (control.cabac_model) { + case VCD_CABAC_MODEL_NUMBER_0: + entropy_cfg->cabacmodel = + VEN_CABAC_MODEL_0; + break; + case VCD_CABAC_MODEL_NUMBER_1: + entropy_cfg->cabacmodel = + VEN_CABAC_MODEL_1; + break; + case VCD_CABAC_MODEL_NUMBER_2: + entropy_cfg->cabacmodel = + VEN_CABAC_MODEL_2; + break; + default: + status = false; + break; + } + } + } + } + return status; +} + +u32 vid_enc_set_get_dbcfg(struct video_client_ctx *client_ctx, + struct venc_dbcfg *dbcfg, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_db_config control; + u32 vcd_status = VCD_ERR_FAIL; + u32 status = true; + + if (!client_ctx || !dbcfg) + return false; + + vcd_property_hdr.prop_id = VCD_I_DEBLOCKING; + vcd_property_hdr.sz = + sizeof(struct vcd_property_db_config); + + if (set_flag) { + switch (dbcfg->db_mode) { + case VEN_DB_DISABLE: + control.db_config = VCD_DB_DISABLE; + break; + case VEN_DB_ALL_BLKG_BNDRY: + control.db_config = VCD_DB_ALL_BLOCKING_BOUNDARY; + break; + case VEN_DB_SKIP_SLICE_BNDRY: + control.db_config = VCD_DB_SKIP_SLICE_BOUNDARY; + break; + default: + status = false; + break; + } + + if (status) { + control.slice_alpha_offset = + dbcfg->slicealpha_offset; + control.slice_beta_offset = + dbcfg->slicebeta_offset; + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + if (vcd_status) { + ERR("%s(): Set VCD_I_DEBLOCKING Failed\n", + __func__); + status = false; + } + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + if (vcd_status) { + ERR("%s(): Get VCD_I_DEBLOCKING Failed\n", + __func__); + status = false; + } else { + switch (control.db_config) { + case VCD_DB_ALL_BLOCKING_BOUNDARY: + dbcfg->db_mode = VEN_DB_ALL_BLKG_BNDRY; + break; + case VCD_DB_DISABLE: + dbcfg->db_mode = VEN_DB_DISABLE; + break; + case VCD_DB_SKIP_SLICE_BOUNDARY: + dbcfg->db_mode = VEN_DB_SKIP_SLICE_BNDRY; + break; + default: + status = false; + break; + } + dbcfg->slicealpha_offset = + control.slice_alpha_offset; + dbcfg->slicebeta_offset = + control.slice_beta_offset; + } + } + return status; +} + +u32 vid_enc_set_get_intrarefresh(struct video_client_ctx *client_ctx, + struct venc_intrarefresh *intrarefresh, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_intra_refresh_mb_number control; + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx || !intrarefresh) + return false; + + vcd_property_hdr.prop_id = VCD_I_INTRA_REFRESH; + vcd_property_hdr.sz = + sizeof(struct vcd_property_intra_refresh_mb_number); + + if (set_flag) { + control.cir_mb_number = intrarefresh->mbcount; + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + + if (vcd_status) { + ERR("%s(): Set VCD_I_INTRA_REFRESH Failed\n", + __func__); + return false; + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + + if (vcd_status) { + ERR("%s(): Set VCD_I_INTRA_REFRESH Failed\n", + __func__); + return false; + } else + intrarefresh->mbcount = control.cir_mb_number; + } + return true; +} + +u32 vid_enc_set_get_multiclicecfg(struct video_client_ctx *client_ctx, + struct venc_multiclicecfg *multiclicecfg, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_multi_slice control; + u32 vcd_status = VCD_ERR_FAIL; + u32 status = true; + + if (!client_ctx || !multiclicecfg) + return false; + + vcd_property_hdr.prop_id = VCD_I_MULTI_SLICE; + vcd_property_hdr.sz = + sizeof(struct vcd_property_multi_slice); + + if (set_flag) { + switch (multiclicecfg->mslice_mode) { + case VEN_MSLICE_OFF: + control.m_slice_sel = + VCD_MSLICE_OFF; + break; + case VEN_MSLICE_CNT_MB: + control.m_slice_sel = + VCD_MSLICE_BY_MB_COUNT; + break; + case VEN_MSLICE_CNT_BYTE: + control.m_slice_sel = + VCD_MSLICE_BY_BYTE_COUNT; + break; + case VEN_MSLICE_GOB: + control.m_slice_sel = + VCD_MSLICE_BY_GOB; + break; + default: + status = false; + break; + } + + if (status) { + control.m_slice_size = + multiclicecfg->mslice_size; + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + + if (vcd_status) { + ERR("%s(): Set VCD_I_MULTI_SLICE Failed\n", + __func__); + status = false; + } + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + + if (vcd_status) { + ERR("%s(): Get VCD_I_MULTI_SLICE Failed\n", + __func__); + status = false; + } else { + multiclicecfg->mslice_size = + control.m_slice_size; + switch (control.m_slice_sel) { + case VCD_MSLICE_OFF: + multiclicecfg->mslice_mode = VEN_MSLICE_OFF; + break; + case VCD_MSLICE_BY_MB_COUNT: + multiclicecfg->mslice_mode = VEN_MSLICE_CNT_MB; + break; + case VCD_MSLICE_BY_BYTE_COUNT: + multiclicecfg->mslice_mode = + VEN_MSLICE_CNT_BYTE; + break; + case VCD_MSLICE_BY_GOB: + multiclicecfg->mslice_mode = + VEN_MSLICE_GOB; + break; + default: + status = false; + break; + } + } + } + return status; +} + +u32 vid_enc_set_get_ratectrlcfg(struct video_client_ctx *client_ctx, + struct venc_ratectrlcfg *ratectrlcfg, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_rate_control control; + u32 vcd_status = VCD_ERR_FAIL; + u32 status = true; + + if (!client_ctx || !ratectrlcfg) + return false; + + vcd_property_hdr.prop_id = VCD_I_RATE_CONTROL; + vcd_property_hdr.sz = + sizeof(struct vcd_property_rate_control); + + if (set_flag) { + switch (ratectrlcfg->rcmode) { + case VEN_RC_OFF: + control.rate_control = VCD_RATE_CONTROL_OFF; + break; + case VEN_RC_CBR_VFR: + control.rate_control = VCD_RATE_CONTROL_CBR_VFR; + break; + case VEN_RC_VBR_CFR: + control.rate_control = VCD_RATE_CONTROL_VBR_CFR; + break; + case VEN_RC_VBR_VFR: + control.rate_control = VCD_RATE_CONTROL_VBR_VFR; + break; + case VEN_RC_CBR_CFR: + control.rate_control = VCD_RATE_CONTROL_CBR_CFR; + break; + default: + status = false; + break; + } + + if (status) { + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + if (vcd_status) { + ERR("%s(): Set VCD_I_RATE_CONTROL Failed\n", + __func__); + status = false; + } + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + + if (vcd_status) { + ERR("%s(): Get VCD_I_RATE_CONTROL Failed\n", + __func__); + status = false; + } else { + switch (control.rate_control) { + case VCD_RATE_CONTROL_OFF: + ratectrlcfg->rcmode = VEN_RC_OFF; + break; + case VCD_RATE_CONTROL_CBR_VFR: + ratectrlcfg->rcmode = VEN_RC_CBR_VFR; + break; + case VCD_RATE_CONTROL_VBR_CFR: + ratectrlcfg->rcmode = VEN_RC_VBR_CFR; + break; + case VCD_RATE_CONTROL_VBR_VFR: + ratectrlcfg->rcmode = VEN_RC_VBR_VFR; + break; + case VCD_RATE_CONTROL_CBR_CFR: + ratectrlcfg->rcmode = VEN_RC_CBR_CFR; + break; + default: + status = false; + break; + } + } + } + return status; +} + +u32 vid_enc_set_get_voptimingcfg(struct video_client_ctx *client_ctx, + struct venc_voptimingcfg *voptimingcfg, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_vop_timing control; + u32 vcd_status = VCD_ERR_FAIL; + u32 status = true; + + if (!client_ctx || !voptimingcfg) + return false; + + vcd_property_hdr.prop_id = VCD_I_VOP_TIMING; + vcd_property_hdr.sz = + sizeof(struct vcd_property_vop_timing); + + if (set_flag) { + control.vop_time_resolution = + voptimingcfg->voptime_resolution; + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + + if (vcd_status) { + ERR("%s(): Set VCD_I_VOP_TIMING Failed\n", + __func__); + status = false; + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + if (vcd_status) { + ERR("%s(): Get VCD_I_VOP_TIMING Failed\n", + __func__); + status = false; + } else + voptimingcfg->voptime_resolution = + control.vop_time_resolution; + } + return status; +} + +u32 vid_enc_set_get_headerextension(struct video_client_ctx *client_ctx, + struct venc_headerextension *headerextension, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + u32 control; + u32 vcd_status = VCD_ERR_FAIL; + u32 status = true; + + if (!client_ctx || !headerextension) + return false; + + vcd_property_hdr.prop_id = VCD_I_HEADER_EXTENSION; + vcd_property_hdr.sz = sizeof(u32); + + if (set_flag) { + control = headerextension->header_extension; + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + if (vcd_status) { + ERR("%s(): Set VCD_I_HEADER_EXTENSION Failed\n", + __func__); + status = false; + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + if (vcd_status) { + ERR("%s(): Get VCD_I_HEADER_EXTENSION Failed\n", + __func__); + status = false; + } else { + headerextension->header_extension = control; + } + } + return status; +} + +u32 vid_enc_set_get_qprange(struct video_client_ctx *client_ctx, + struct venc_qprange *qprange, u32 set_flag) +{ + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_qp_range control; + u32 vcd_status = VCD_ERR_FAIL; + u32 status = true; + + if (!client_ctx || !qprange) + return false; + + vcd_property_hdr.prop_id = VCD_I_QP_RANGE; + vcd_property_hdr.sz = + sizeof(struct vcd_property_qp_range); + + if (set_flag) { + control.max_qp = qprange->maxqp; + control.min_qp = qprange->minqp; + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + + if (vcd_status) { + ERR("%s(): Set VCD_I_QP_RANGE Failed\n", + __func__); + status = false; + } + } else { + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + if (vcd_status) { + ERR("%s(): Get VCD_I_QP_RANGE Failed\n", + __func__); + status = false; + } else { + qprange->maxqp = control.max_qp; + qprange->minqp = control.min_qp; + } + } + return status; +} + +u32 vid_enc_start_stop(struct video_client_ctx *client_ctx, u32 start) +{ + u32 vcd_status; + + if (!client_ctx) + return false; + + if (start) { + vcd_status = vcd_encode_start(client_ctx->vcd_handle); + + if (vcd_status) { + ERR("%s(): vcd_encode_start failed." + " vcd_status = %u\n", __func__, vcd_status); + return false; + } + } else { + vcd_status = vcd_stop(client_ctx->vcd_handle); + if (vcd_status) { + ERR("%s(): vcd_stop failed. vcd_status = %u\n", + __func__, vcd_status); + return false; + } + DBG("Send STOP_DONE message to client = %p\n", + client_ctx); + } + return true; +} + +u32 vid_enc_pause_resume(struct video_client_ctx *client_ctx, u32 pause) +{ + u32 vcd_status; + + if (!client_ctx) + return false; + + if (pause) { + DBG("PAUSE command from client = %p\n", + client_ctx); + vcd_status = vcd_pause(client_ctx->vcd_handle); + } else { + DBG("Resume command from client = %p\n", + client_ctx); + vcd_status = vcd_resume(client_ctx->vcd_handle); + } + + if (vcd_status) + return false; + + return true; +} + +u32 vid_enc_flush(struct video_client_ctx *client_ctx, + struct venc_bufferflush *bufferflush) +{ + u32 status = true, mode, vcd_status; + + if (!client_ctx || !bufferflush) + return false; + + switch (bufferflush->flush_mode) { + case VEN_FLUSH_INPUT: + mode = VCD_FLUSH_INPUT; + break; + case VEN_FLUSH_OUTPUT: + mode = VCD_FLUSH_OUTPUT; + break; + case VEN_FLUSH_ALL: + mode = VCD_FLUSH_ALL; + break; + default: + status = false; + break; + } + if (status) { + vcd_status = vcd_flush(client_ctx->vcd_handle, mode); + if (vcd_status) + status = false; + } + return status; +} + +u32 vid_enc_get_buffer_req(struct video_client_ctx *client_ctx, + struct venc_allocatorproperty *venc_buf_req, u32 input_dir) +{ + enum vcd_buffer_type buffer; + struct vcd_buffer_requirement buffer_req; + u32 status = true; + u32 vcd_status; + + if (!client_ctx || !venc_buf_req) + return false; + + buffer = VCD_BUFFER_OUTPUT; + if (input_dir) + buffer = VCD_BUFFER_INPUT; + + vcd_status = vcd_get_buffer_requirements(client_ctx->vcd_handle, + buffer, &buffer_req); + + if (vcd_status) + status = false; + + if (status) { + venc_buf_req->actualcount = buffer_req.actual_count; + venc_buf_req->alignment = buffer_req.align; + venc_buf_req->datasize = buffer_req.sz; + venc_buf_req->mincount = buffer_req.min_count; + venc_buf_req->maxcount = buffer_req.max_count; + venc_buf_req->alignment = buffer_req.align; + venc_buf_req->bufpoolid = buffer_req.buf_pool_id; + venc_buf_req->suffixsize = 0; + DBG("%s: actual_count=%d, align=%d, sz=%d, min_count=%d, " + "max_count=%d, buf_pool_id=%d\n", __func__, + buffer_req.actual_count, buffer_req.align, + buffer_req.sz, buffer_req.min_count, + buffer_req.max_count, buffer_req.buf_pool_id); + } + return status; +} + +u32 vid_enc_set_buffer_req(struct video_client_ctx *client_ctx, + struct venc_allocatorproperty *venc_buf_req, u32 input_dir) +{ + enum vcd_buffer_type buffer; + struct vcd_buffer_requirement buffer_req; + u32 status = true; + u32 vcd_status; + + if (!client_ctx || !venc_buf_req) + return false; + + buffer = VCD_BUFFER_OUTPUT; + if (input_dir) + buffer = VCD_BUFFER_INPUT; + + buffer_req.actual_count = venc_buf_req->actualcount; + buffer_req.align = venc_buf_req->alignment; + buffer_req.sz = venc_buf_req->datasize; + buffer_req.min_count = venc_buf_req->mincount; + buffer_req.max_count = venc_buf_req->maxcount; + buffer_req.align = venc_buf_req->alignment; + buffer_req.buf_pool_id = 0; + + DBG("%s: actual_count=%d, align=%d, sz=%d, min_count=%d, " + "max_count=%d, buf_pool_id=%d\n", __func__, + buffer_req.actual_count, buffer_req.align, buffer_req.sz, + buffer_req.min_count, buffer_req.max_count, + buffer_req.buf_pool_id); + vcd_status = vcd_set_buffer_requirements(client_ctx->vcd_handle, + buffer, &buffer_req); + + if (vcd_status) + status = false; + return status; +} + +u32 vid_enc_set_buffer(struct video_client_ctx *client_ctx, + struct venc_bufferpayload *buffer_info, + enum venc_buffer_dir buffer) +{ + enum vcd_buffer_type vcd_buffer_t = VCD_BUFFER_INPUT; + enum buffer_dir dir_buffer = BUFFER_TYPE_INPUT; + u32 vcd_status = VCD_ERR_FAIL; + unsigned long kernel_vaddr, length = 0; + + if (!client_ctx || !buffer_info) + return false; + + if (buffer == VEN_BUFFER_TYPE_OUTPUT) { + dir_buffer = BUFFER_TYPE_OUTPUT; + vcd_buffer_t = VCD_BUFFER_OUTPUT; + } + length = buffer_info->sz; + /*If buffer cannot be set, ignore */ + if (!vidc_insert_addr_table(client_ctx, dir_buffer, + (unsigned long)buffer_info->pbuffer, + &kernel_vaddr, + buffer_info->fd, + (unsigned long)buffer_info->offset, + VID_ENC_MAX_NUM_OF_BUFF, length)) { + DBG("%s() : user_virt_addr = %p cannot be set.", + __func__, buffer_info->pbuffer); + return false; + } + + vcd_status = vcd_set_buffer(client_ctx->vcd_handle, + vcd_buffer_t, (u8 *) kernel_vaddr, + buffer_info->sz); + + if (!vcd_status) + return true; + else + return false; +} + +u32 vid_enc_free_buffer(struct video_client_ctx *client_ctx, + struct venc_bufferpayload *buffer_info, + enum venc_buffer_dir buffer) +{ + enum vcd_buffer_type buffer_vcd = VCD_BUFFER_INPUT; + enum buffer_dir dir_buffer = BUFFER_TYPE_INPUT; + u32 vcd_status = VCD_ERR_FAIL; + unsigned long kernel_vaddr; + + if (!client_ctx || !buffer_info) + return false; + + if (buffer == VEN_BUFFER_TYPE_OUTPUT) { + dir_buffer = BUFFER_TYPE_OUTPUT; + buffer_vcd = VCD_BUFFER_OUTPUT; + } + /*If buffer NOT set, ignore */ + if (!vidc_delete_addr_table(client_ctx, dir_buffer, + (unsigned long)buffer_info->pbuffer, + &kernel_vaddr)) { + DBG("%s() : user_virt_addr = %p has not been set.", + __func__, buffer_info->pbuffer); + return true; + } + vcd_status = vcd_free_buffer(client_ctx->vcd_handle, buffer_vcd, + (u8 *)kernel_vaddr); + + if (!vcd_status) + return true; + else + return false; +} + +u32 vid_enc_encode_frame(struct video_client_ctx *client_ctx, + struct venc_buffer *input_frame_info) +{ + struct vcd_frame_data vcd_input_buffer; + unsigned long kernel_vaddr, phy_addr, user_vaddr; + int pmem_fd; + struct file *file; + s32 buffer_index = -1; + u32 ion_flag = 0; + struct ion_handle *buff_handle = NULL; + + u32 vcd_status = VCD_ERR_FAIL; + + if (!client_ctx || !input_frame_info) + return false; + + user_vaddr = (unsigned long)input_frame_info->ptrbuffer; + + if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_INPUT, + true, &user_vaddr, &kernel_vaddr, + &phy_addr, &pmem_fd, &file, + &buffer_index)) { + + /* kernel_vaddr is found. send the frame to VCD */ + memset((void *)&vcd_input_buffer, 0, + sizeof(struct vcd_frame_data)); + + vcd_input_buffer.virtual = + (u8 *) (kernel_vaddr + input_frame_info->offset); + + vcd_input_buffer.offset = input_frame_info->offset; + vcd_input_buffer.frm_clnt_data = + (u32) input_frame_info->clientdata; + vcd_input_buffer.ip_frm_tag = + (u32) input_frame_info->clientdata; + vcd_input_buffer.data_len = input_frame_info->len; + vcd_input_buffer.time_stamp = input_frame_info->timestamp; + + /* Rely on VCD using the same flags as OMX */ + vcd_input_buffer.flags = input_frame_info->flags; + + ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_INPUT, + pmem_fd, kernel_vaddr, buffer_index, + &buff_handle); + + if (vcd_input_buffer.data_len > 0) { + if (ion_flag == CACHED && buff_handle) { + msm_ion_do_cache_op( + client_ctx->user_ion_client, + buff_handle, + (unsigned long *) vcd_input_buffer.virtual, + (unsigned long) vcd_input_buffer.data_len, + ION_IOC_CLEAN_CACHES); + } + } + + vcd_status = vcd_encode_frame(client_ctx->vcd_handle, + &vcd_input_buffer); + if (!vcd_status) + return true; + else { + ERR("%s(): vcd_encode_frame failed = %u\n", + __func__, vcd_status); + return false; + } + + } else { + ERR("%s(): kernel_vaddr not found\n", + __func__); + return false; + } +} + +u32 vid_enc_fill_output_buffer(struct video_client_ctx *client_ctx, + struct venc_buffer *output_frame_info) +{ + unsigned long kernel_vaddr, phy_addr, user_vaddr; + int pmem_fd; + struct file *file; + s32 buffer_index = -1; + u32 vcd_status = VCD_ERR_FAIL; + struct ion_handle *buff_handle = NULL; + + struct vcd_frame_data vcd_frame; + + if (!client_ctx || !output_frame_info) + return false; + + user_vaddr = (unsigned long)output_frame_info->ptrbuffer; + + if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT, + true, &user_vaddr, &kernel_vaddr, + &phy_addr, &pmem_fd, &file, + &buffer_index)) { + + memset((void *)&vcd_frame, 0, + sizeof(struct vcd_frame_data)); + vidc_get_fd_info(client_ctx, BUFFER_TYPE_OUTPUT, + pmem_fd, kernel_vaddr, buffer_index, + &buff_handle); + vcd_frame.virtual = (u8 *) kernel_vaddr; + vcd_frame.frm_clnt_data = (u32) output_frame_info->clientdata; + vcd_frame.alloc_len = output_frame_info->sz; + vcd_frame.buff_ion_handle = buff_handle; + + vcd_status = vcd_fill_output_buffer(client_ctx->vcd_handle, + &vcd_frame); + if (!vcd_status) + return true; + else { + ERR("%s(): vcd_fill_output_buffer failed = %u\n", + __func__, vcd_status); + return false; + } + } else { + ERR("%s(): kernel_vaddr not found\n", __func__); + return false; + } +} +u32 vid_enc_set_recon_buffers(struct video_client_ctx *client_ctx, + struct venc_recon_addr *venc_recon) +{ + u32 vcd_status = VCD_ERR_FAIL; + u32 len, i, flags = 0; + struct file *file; + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_enc_recon_buffer *control = NULL; + struct msm_mapped_buffer *mapped_buffer = NULL; + int rc = -1; + unsigned long ionflag = 0; + unsigned long iova = 0; + unsigned long buffer_size = 0; + size_t ion_len = -1; + unsigned long phy_addr; + + if (!client_ctx || !venc_recon) { + pr_err("%s() Invalid params", __func__); + return false; + } + len = sizeof(client_ctx->recon_buffer)/ + sizeof(struct vcd_property_enc_recon_buffer); + for (i = 0; i < len; i++) { + if (!client_ctx->recon_buffer[i].kernel_virtual_addr) { + control = &client_ctx->recon_buffer[i]; + break; + } + } + if (!control) { + pr_err("Exceeded max recon buffer setting"); + return false; + } + control->buffer_size = venc_recon->buffer_size; + control->kernel_virtual_addr = NULL; + control->physical_addr = NULL; + control->pmem_fd = venc_recon->pmem_fd; + control->offset = venc_recon->offset; + control->user_virtual_addr = venc_recon->pbuffer; + + if (!vcd_get_ion_status()) { + if (get_pmem_file(control->pmem_fd, (unsigned long *) + (&(control->physical_addr)), (unsigned long *) + (&control->kernel_virtual_addr), + (unsigned long *) (&len), &file)) { + ERR("%s(): get_pmem_file failed\n", __func__); + return false; + } + put_pmem_file(file); + flags = MSM_SUBSYSTEM_MAP_IOVA; + mapped_buffer = msm_subsystem_map_buffer( + (unsigned long)control->physical_addr, len, + flags, vidc_mmu_subsystem, + sizeof(vidc_mmu_subsystem)/sizeof(unsigned int)); + if (IS_ERR(mapped_buffer)) { + pr_err("buffer map failed"); + return false; + } + control->client_data = (void *) mapped_buffer; + control->dev_addr = (u8 *)mapped_buffer->iova[0]; + } else { + client_ctx->recon_buffer_ion_handle[i] = ion_import_fd( + client_ctx->user_ion_client, control->pmem_fd); + if (IS_ERR_OR_NULL(client_ctx->recon_buffer_ion_handle[i])) { + ERR("%s(): get_ION_handle failed\n", __func__); + goto import_ion_error; + } + rc = ion_handle_get_flags(client_ctx->user_ion_client, + client_ctx->recon_buffer_ion_handle[i], + &ionflag); + if (rc) { + ERR("%s():get_ION_flags fail\n", + __func__); + goto import_ion_error; + } + control->kernel_virtual_addr = (u8 *) ion_map_kernel( + client_ctx->user_ion_client, + client_ctx->recon_buffer_ion_handle[i], + ionflag); + if (!control->kernel_virtual_addr) { + ERR("%s(): get_ION_kernel virtual addr fail\n", + __func__); + goto import_ion_error; + } + if (res_trk_check_for_sec_session()) { + rc = ion_phys(client_ctx->user_ion_client, + client_ctx->recon_buffer_ion_handle[i], + &phy_addr, &ion_len); + if (rc) { + ERR("%s():get_ION_kernel physical addr fail\n", + __func__); + goto map_ion_error; + } + control->physical_addr = (u8 *) phy_addr; + len = (unsigned long) ion_len; + control->client_data = NULL; + control->dev_addr = (u8 *)control->physical_addr; + } else { + rc = ion_map_iommu(client_ctx->user_ion_client, + client_ctx->recon_buffer_ion_handle[i], + VIDEO_DOMAIN, + VIDEO_MAIN_POOL, + SZ_4K, + 0, + (unsigned long *)&iova, + (unsigned long *)&buffer_size, + UNCACHED, 0); + if (rc) { + ERR("%s():ION map iommu addr fail\n", + __func__); + goto map_ion_error; + } + control->physical_addr = (u8 *) iova; + len = buffer_size; + control->client_data = NULL; + control->dev_addr = (u8 *)iova; + } + } + + vcd_property_hdr.prop_id = VCD_I_RECON_BUFFERS; + vcd_property_hdr.sz = + sizeof(struct vcd_property_enc_recon_buffer); + + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, control); + if (!vcd_status) { + DBG("vcd_set_property returned success\n"); + return true; + } else { + ERR("%s(): vid_enc_set_recon_buffers failed = %u\n", + __func__, vcd_status); + return false; + } +map_ion_error: + if (control->kernel_virtual_addr) + ion_unmap_kernel(client_ctx->user_ion_client, + client_ctx->recon_buffer_ion_handle[i]); + if (client_ctx->recon_buffer_ion_handle[i]) + ion_free(client_ctx->user_ion_client, + client_ctx->recon_buffer_ion_handle[i]); + client_ctx->recon_buffer_ion_handle[i] = NULL; +import_ion_error: + return false; +} + +u32 vid_enc_free_recon_buffers(struct video_client_ctx *client_ctx, + struct venc_recon_addr *venc_recon) +{ + u32 vcd_status = VCD_ERR_FAIL; + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_enc_recon_buffer *control = NULL; + u32 len = 0, i; + + if (!client_ctx || !venc_recon) { + pr_err("%s() Invalid params", __func__); + return false; + } + len = sizeof(client_ctx->recon_buffer)/ + sizeof(struct vcd_property_enc_recon_buffer); + pr_err(" %s() address %p", __func__, + venc_recon->pbuffer); + for (i = 0; i < len; i++) { + if (client_ctx->recon_buffer[i].user_virtual_addr + == venc_recon->pbuffer) { + control = &client_ctx->recon_buffer[i]; + break; + } + } + if (!control) { + pr_err(" %s() address not found %p", __func__, + venc_recon->pbuffer); + return false; + } + if (control->client_data) + msm_subsystem_unmap_buffer((struct msm_mapped_buffer *) + control->client_data); + + vcd_property_hdr.prop_id = VCD_I_FREE_RECON_BUFFERS; + vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size); + vcd_status = vcd_set_property(client_ctx->vcd_handle, + &vcd_property_hdr, control); + if (vcd_get_ion_status()) { + if (client_ctx->recon_buffer_ion_handle[i]) { + ion_unmap_kernel(client_ctx->user_ion_client, + client_ctx->recon_buffer_ion_handle[i]); + if (!res_trk_check_for_sec_session()) { + ion_unmap_iommu(client_ctx->user_ion_client, + client_ctx->recon_buffer_ion_handle[i], + VIDEO_DOMAIN, + VIDEO_MAIN_POOL); + } + ion_free(client_ctx->user_ion_client, + client_ctx->recon_buffer_ion_handle[i]); + client_ctx->recon_buffer_ion_handle[i] = NULL; + } + } + memset(control, 0, sizeof(struct vcd_property_enc_recon_buffer)); + return true; +} + +u32 vid_enc_get_recon_buffer_size(struct video_client_ctx *client_ctx, + struct venc_recon_buff_size *venc_recon_size) +{ + u32 vcd_status = VCD_ERR_FAIL; + struct vcd_property_hdr vcd_property_hdr; + struct vcd_property_buffer_size control; + + control.width = venc_recon_size->width; + control.height = venc_recon_size->height; + + vcd_property_hdr.prop_id = VCD_I_GET_RECON_BUFFER_SIZE; + vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size); + + vcd_status = vcd_get_property(client_ctx->vcd_handle, + &vcd_property_hdr, &control); + + venc_recon_size->width = control.width; + venc_recon_size->height = control.height; + venc_recon_size->size = control.size; + venc_recon_size->alignment = control.alignment; + DBG("W: %d, H: %d, S: %d, A: %d", venc_recon_size->width, + venc_recon_size->height, venc_recon_size->size, + venc_recon_size->alignment); + + if (!vcd_status) { + DBG("vcd_set_property returned success\n"); + return true; + } else { + ERR("%s(): vid_enc_get_recon_buffer_size failed = %u\n", + __func__, vcd_status); + return false; + } +} diff --git a/drivers/video/msm/vidc/common/enc/venc_internal.h b/drivers/video/msm/vidc/common/enc/venc_internal.h new file mode 100644 index 000000000000..324ed9e610eb --- /dev/null +++ b/drivers/video/msm/vidc/common/enc/venc_internal.h @@ -0,0 +1,154 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#ifndef VENC_INTERNAL_H +#define VENC_INTERNAL_H + +#include +#include +#include + +#define VID_ENC_MAX_NUM_OF_BUFF 100 + +enum venc_buffer_dir{ + VEN_BUFFER_TYPE_INPUT, + VEN_BUFFER_TYPE_OUTPUT +}; + +struct vid_enc_msg { + struct list_head list; + struct venc_msg venc_msg_info; +}; + +struct vid_enc_dev { + + struct cdev cdev; + struct device *device; + resource_size_t phys_base; + void __iomem *virt_base; + unsigned int irq; + struct clk *hclk; + struct clk *hclk_div2; + struct clk *pclk; + unsigned long hclk_rate; + struct mutex lock; + s32 device_handle; + struct video_client_ctx venc_clients[VIDC_MAX_NUM_CLIENTS]; + u32 num_clients; +}; + +u32 vid_enc_set_get_base_cfg(struct video_client_ctx *client_ctx, + struct venc_basecfg *base_config, u32 set_flag); + +u32 vid_enc_set_get_inputformat(struct video_client_ctx *client_ctx, + u32 *input_format, u32 set_flag); + +u32 vid_enc_set_get_codec(struct video_client_ctx *client_ctx, u32 *codec, + u32 set_flag); + +u32 vid_enc_set_get_framesize(struct video_client_ctx *client_ctx, + u32 *height, u32 *width, u32 set_flag); + +u32 vid_enc_set_get_bitrate(struct video_client_ctx *client_ctx, + struct venc_targetbitrate *venc_bitrate, u32 set_flag); + +u32 vid_enc_set_get_framerate(struct video_client_ctx *client_ctx, + struct venc_framerate *frame_rate, u32 set_flag); + +u32 vid_enc_set_get_live_mode(struct video_client_ctx *client_ctx, + struct venc_switch *encoder_switch, u32 set_flag); + +u32 vid_enc_set_get_extradata(struct video_client_ctx *client_ctx, + u32 *extradata_flag, u32 set_flag); + +u32 vid_enc_set_get_short_header(struct video_client_ctx *client_ctx, + struct venc_switch *encoder_switch, u32 set_flag); + +u32 vid_enc_set_get_profile(struct video_client_ctx *client_ctx, + struct venc_profile *profile, u32 set_flag); + +u32 vid_enc_set_get_profile_level(struct video_client_ctx *client_ctx, + struct ven_profilelevel *profile_level, u32 set_flag); + +u32 vid_enc_set_get_session_qp(struct video_client_ctx *client_ctx, + struct venc_sessionqp *session_qp, u32 set_flag); + +u32 vid_enc_set_get_intraperiod(struct video_client_ctx *client_ctx, + struct venc_intraperiod *intraperiod, u32 set_flag); + +u32 vid_enc_request_iframe(struct video_client_ctx *client_ctx); + +u32 vid_enc_get_sequence_header(struct video_client_ctx *client_ctx, + struct venc_seqheader *seq_header); + +u32 vid_enc_set_get_entropy_cfg(struct video_client_ctx *client_ctx, + struct venc_entropycfg *entropy_cfg, u32 set_flag); + +u32 vid_enc_set_get_dbcfg(struct video_client_ctx *client_ctx, + struct venc_dbcfg *dbcfg, u32 set_flag); + +u32 vid_enc_set_get_intrarefresh(struct video_client_ctx *client_ctx, + struct venc_intrarefresh *intrarefresh, u32 set_flag); + +u32 vid_enc_set_get_multiclicecfg(struct video_client_ctx *client_ctx, + struct venc_multiclicecfg *multiclicecfg, u32 set_flag); + +u32 vid_enc_set_get_ratectrlcfg(struct video_client_ctx *client_ctx, + struct venc_ratectrlcfg *ratectrlcfg, u32 set_flag); + +u32 vid_enc_set_get_voptimingcfg(struct video_client_ctx *client_ctx, + struct venc_voptimingcfg *voptimingcfg, u32 set_flag); + +u32 vid_enc_set_get_headerextension(struct video_client_ctx *client_ctx, + struct venc_headerextension *headerextension, u32 set_flag); + +u32 vid_enc_set_get_qprange(struct video_client_ctx *client_ctx, + struct venc_qprange *qprange, u32 set_flag); + +u32 vid_enc_start_stop(struct video_client_ctx *client_ctx, u32 start); + +u32 vid_enc_pause_resume(struct video_client_ctx *client_ctx, u32 pause); + +u32 vid_enc_flush(struct video_client_ctx *client_ctx, + struct venc_bufferflush *bufferflush); + +u32 vid_enc_get_buffer_req(struct video_client_ctx *client_ctx, + struct venc_allocatorproperty *venc_buf_req, u32 input_dir); + +u32 vid_enc_set_buffer_req(struct video_client_ctx *client_ctx, + struct venc_allocatorproperty *venc_buf_req, u32 input_dir); + +u32 vid_enc_set_buffer(struct video_client_ctx *client_ctx, + struct venc_bufferpayload *buffer_info, + enum venc_buffer_dir buffer); + +u32 vid_enc_free_buffer(struct video_client_ctx *client_ctx, + struct venc_bufferpayload *buffer_info, + enum venc_buffer_dir buffer); + +u32 vid_enc_encode_frame(struct video_client_ctx *client_ctx, + struct venc_buffer *input_frame_info); + +u32 vid_enc_fill_output_buffer(struct video_client_ctx *client_ctx, + struct venc_buffer *output_frame_info); + +u32 vid_enc_set_recon_buffers(struct video_client_ctx *client_ctx, + struct venc_recon_addr *venc_recon); + +u32 vid_enc_free_recon_buffers(struct video_client_ctx *client_ctx, + struct venc_recon_addr *venc_recon); + +u32 vid_enc_get_recon_buffer_size(struct video_client_ctx *client_ctx, + struct venc_recon_buff_size *venc_recon_size); + +#endif diff --git a/drivers/video/msm/vidc/common/init/vidc_init.c b/drivers/video/msm/vidc/common/init/vidc_init.c new file mode 100644 index 000000000000..97aa580ba1e9 --- /dev/null +++ b/drivers/video/msm/vidc/common/init/vidc_init.c @@ -0,0 +1,929 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "vidc_init_internal.h" +#include "vcd_res_tracker_api.h" + +#if DEBUG +#define DBG(x...) printk(KERN_DEBUG x) +#else +#define DBG(x...) +#endif + +#define VIDC_NAME "msm_vidc_reg" + +#define ERR(x...) printk(KERN_ERR x) + +static struct vidc_dev *vidc_device_p; +static dev_t vidc_dev_num; +static struct class *vidc_class; +static unsigned int vidc_mmu_subsystem[] = {MSM_SUBSYSTEM_VIDEO}; + +static const struct file_operations vidc_fops = { + .owner = THIS_MODULE, + .open = NULL, + .release = NULL, + .unlocked_ioctl = NULL, +}; + +struct workqueue_struct *vidc_wq; +struct workqueue_struct *vidc_timer_wq; +static irqreturn_t vidc_isr(int irq, void *dev); +static spinlock_t vidc_spin_lock; + +u32 vidc_msg_timing, vidc_msg_pmem, vidc_msg_register; + +#ifdef VIDC_ENABLE_DBGFS +struct dentry *vidc_debugfs_root; + +struct dentry *vidc_get_debugfs_root(void) +{ + if (vidc_debugfs_root == NULL) + vidc_debugfs_root = debugfs_create_dir("vidc", NULL); + return vidc_debugfs_root; +} + +void vidc_debugfs_file_create(struct dentry *root, const char *name, + u32 *var) +{ + struct dentry *vidc_debugfs_file = + debugfs_create_u32(name, S_IRUGO | S_IWUSR, root, var); + if (!vidc_debugfs_file) + ERR("%s(): Error creating/opening file %s\n", __func__, name); +} +#endif + +static void vidc_timer_fn(unsigned long data) +{ + unsigned long flag; + struct vidc_timer *hw_timer = NULL; + ERR("%s() Timer expired\n", __func__); + spin_lock_irqsave(&vidc_spin_lock, flag); + hw_timer = (struct vidc_timer *)data; + list_add_tail(&hw_timer->list, &vidc_device_p->vidc_timer_queue); + spin_unlock_irqrestore(&vidc_spin_lock, flag); + DBG("Queue the work for timer\n"); + queue_work(vidc_timer_wq, &vidc_device_p->vidc_timer_worker); +} + +static void vidc_timer_handler(struct work_struct *work) +{ + unsigned long flag = 0; + u32 islist_empty = 0; + struct vidc_timer *hw_timer = NULL; + + ERR("%s() Timer expired\n", __func__); + do { + spin_lock_irqsave(&vidc_spin_lock, flag); + islist_empty = list_empty(&vidc_device_p->vidc_timer_queue); + if (!islist_empty) { + hw_timer = list_first_entry( + &vidc_device_p->vidc_timer_queue, + struct vidc_timer, list); + list_del(&hw_timer->list); + } + spin_unlock_irqrestore(&vidc_spin_lock, flag); + if (!islist_empty && hw_timer && hw_timer->cb_func) + hw_timer->cb_func(hw_timer->userdata); + } while (!islist_empty); +} + +static void vidc_work_handler(struct work_struct *work) +{ + DBG("vidc_work_handler()"); + vcd_read_and_clear_interrupt(); + vcd_response_handler(); + enable_irq(vidc_device_p->irq); + DBG("vidc_work_handler() done"); +} + +static DECLARE_WORK(vidc_work, vidc_work_handler); + +static int vidc_720p_probe(struct platform_device *pdev) +{ + struct resource *resource; + DBG("Enter %s()\n", __func__); + + if (pdev->id) { + ERR("Invalid plaform device ID = %d\n", pdev->id); + return -EINVAL; + } + vidc_device_p->irq = platform_get_irq(pdev, 0); + if (unlikely(vidc_device_p->irq < 0)) { + ERR("%s(): Invalid irq = %d\n", __func__, + vidc_device_p->irq); + return -ENXIO; + } + + resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (unlikely(!resource)) { + ERR("%s(): Invalid resource\n", __func__); + return -ENXIO; + } + + vidc_device_p->phys_base = resource->start; + vidc_device_p->virt_base = ioremap(resource->start, + resource->end - resource->start + 1); + + if (!vidc_device_p->virt_base) { + ERR("%s() : ioremap failed\n", __func__); + return -ENOMEM; + } + vidc_device_p->device = &pdev->dev; + mutex_init(&vidc_device_p->lock); + + vidc_wq = create_singlethread_workqueue("vidc_worker_queue"); + if (!vidc_wq) { + ERR("%s: create workque failed\n", __func__); + return -ENOMEM; + } + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); + return 0; +} + +static int vidc_720p_remove(struct platform_device *pdev) +{ + if (pdev->id) { + ERR("Invalid plaform device ID = %d\n", pdev->id); + return -EINVAL; + } + pm_runtime_disable(&pdev->dev); + + return 0; +} + +static int vidc_runtime_suspend(struct device *dev) +{ + dev_dbg(dev, "pm_runtime: suspending...\n"); + return 0; +} + +static int vidc_runtime_resume(struct device *dev) +{ + dev_dbg(dev, "pm_runtime: resuming...\n"); + return 0; +} + +static const struct dev_pm_ops vidc_dev_pm_ops = { + .runtime_suspend = vidc_runtime_suspend, + .runtime_resume = vidc_runtime_resume, +}; + +static struct platform_driver msm_vidc_720p_platform_driver = { + .probe = vidc_720p_probe, + .remove = vidc_720p_remove, + .driver = { + .name = "msm_vidc", + .pm = &vidc_dev_pm_ops, + }, +}; + +static void __exit vidc_exit(void) +{ + platform_driver_unregister(&msm_vidc_720p_platform_driver); +} + +static irqreturn_t vidc_isr(int irq, void *dev) +{ + DBG("\n vidc_isr() %d ", irq); + disable_irq_nosync(irq); + queue_work(vidc_wq, &vidc_work); + return IRQ_HANDLED; +} + +static int __init vidc_init(void) +{ + int rc = 0; + struct device *class_devp; +#ifdef VIDC_ENABLE_DBGFS + struct dentry *root = NULL; +#endif + + vidc_device_p = kzalloc(sizeof(struct vidc_dev), GFP_KERNEL); + if (!vidc_device_p) { + ERR("%s Unable to allocate memory for vidc_dev\n", + __func__); + return -ENOMEM; + } + + rc = alloc_chrdev_region(&vidc_dev_num, 0, 1, VIDC_NAME); + if (rc < 0) { + ERR("%s: alloc_chrdev_region Failed rc = %d\n", + __func__, rc); + goto error_vidc_alloc_chrdev_region; + } + + vidc_class = class_create(THIS_MODULE, VIDC_NAME); + if (IS_ERR(vidc_class)) { + rc = PTR_ERR(vidc_class); + ERR("%s: couldn't create vidc_class rc = %d\n", + __func__, rc); + + goto error_vidc_class_create; + } + + class_devp = device_create(vidc_class, NULL, vidc_dev_num, NULL, + VIDC_NAME); + + if (IS_ERR(class_devp)) { + rc = PTR_ERR(class_devp); + ERR("%s: class device_create failed %d\n", + __func__, rc); + goto error_vidc_class_device_create; + } + + cdev_init(&vidc_device_p->cdev, &vidc_fops); + vidc_device_p->cdev.owner = THIS_MODULE; + rc = cdev_add(&(vidc_device_p->cdev), vidc_dev_num, 1); + + if (rc < 0) { + ERR("%s: cdev_add failed %d\n", __func__, rc); + goto error_vidc_cdev_add; + } + + rc = platform_driver_register(&msm_vidc_720p_platform_driver); + if (rc) { + ERR("%s failed to load\n", __func__); + goto error_vidc_platfom_register; + } + + rc = request_irq(vidc_device_p->irq, vidc_isr, IRQF_TRIGGER_HIGH, + "vidc", vidc_device_p->device); + + if (unlikely(rc)) { + ERR("%s() :request_irq failed\n", __func__); + goto error_vidc_request_irq; + } + res_trk_init(vidc_device_p->device, vidc_device_p->irq); + vidc_timer_wq = create_singlethread_workqueue("vidc_timer_wq"); + if (!vidc_timer_wq) { + ERR("%s: create workque failed\n", __func__); + rc = -ENOMEM; + goto error_vidc_create_workqueue; + } + DBG("Disabling IRQ in %s()\n", __func__); + disable_irq_nosync(vidc_device_p->irq); + INIT_WORK(&vidc_device_p->vidc_timer_worker, + vidc_timer_handler); + spin_lock_init(&vidc_spin_lock); + INIT_LIST_HEAD(&vidc_device_p->vidc_timer_queue); + + vidc_device_p->ref_count = 0; + vidc_device_p->firmware_refcount = 0; + vidc_device_p->get_firmware = 0; +#ifdef VIDC_ENABLE_DBGFS + root = vidc_get_debugfs_root(); + if (root) { + vidc_debugfs_file_create(root, "vidc_msg_timing", + (u32 *) &vidc_msg_timing); + vidc_debugfs_file_create(root, "vidc_msg_pmem", + (u32 *) &vidc_msg_pmem); + vidc_debugfs_file_create(root, "vidc_msg_register", + (u32 *) &vidc_msg_register); + } +#endif + return 0; + +error_vidc_create_workqueue: + free_irq(vidc_device_p->irq, vidc_device_p->device); +error_vidc_request_irq: + platform_driver_unregister(&msm_vidc_720p_platform_driver); +error_vidc_platfom_register: + cdev_del(&(vidc_device_p->cdev)); +error_vidc_cdev_add: + device_destroy(vidc_class, vidc_dev_num); +error_vidc_class_device_create: + class_destroy(vidc_class); +error_vidc_class_create: + unregister_chrdev_region(vidc_dev_num, 1); +error_vidc_alloc_chrdev_region: + kfree(vidc_device_p); + + return rc; +} + +void __iomem *vidc_get_ioaddr(void) +{ + return (u8 *)vidc_device_p->virt_base; +} +EXPORT_SYMBOL(vidc_get_ioaddr); + +int vidc_load_firmware(void) +{ + u32 status = true; + + if (!res_trk_check_for_sec_session()) { + mutex_lock(&vidc_device_p->lock); + if (!vidc_device_p->get_firmware) { + status = res_trk_download_firmware(); + if (!status) + goto error; + vidc_device_p->get_firmware = 1; + } + vidc_device_p->firmware_refcount++; +error: + mutex_unlock(&vidc_device_p->lock); + } + return status; +} +EXPORT_SYMBOL(vidc_load_firmware); + +void vidc_release_firmware(void) +{ + if (!res_trk_check_for_sec_session()) { + mutex_lock(&vidc_device_p->lock); + if (vidc_device_p->firmware_refcount > 0) + vidc_device_p->firmware_refcount--; + else + vidc_device_p->firmware_refcount = 0; + mutex_unlock(&vidc_device_p->lock); + } +} +EXPORT_SYMBOL(vidc_release_firmware); + +u32 vidc_get_fd_info(struct video_client_ctx *client_ctx, + enum buffer_dir buffer, int pmem_fd, + unsigned long kvaddr, int index, + struct ion_handle **buff_handle) +{ + struct buf_addr_table *buf_addr_table; + u32 rc = 0; + if (!client_ctx) + return false; + if (buffer == BUFFER_TYPE_INPUT) + buf_addr_table = client_ctx->input_buf_addr_table; + else + buf_addr_table = client_ctx->output_buf_addr_table; + if (buf_addr_table[index].pmem_fd == pmem_fd) { + if (buf_addr_table[index].kernel_vaddr == kvaddr) { + rc = buf_addr_table[index].buff_ion_flag; + *buff_handle = buf_addr_table[index].buff_ion_handle; + } else + *buff_handle = NULL; + } else + *buff_handle = NULL; + return rc; +} +EXPORT_SYMBOL(vidc_get_fd_info); + +void vidc_cleanup_addr_table(struct video_client_ctx *client_ctx, + enum buffer_dir buffer) +{ + u32 *num_of_buffers = NULL; + u32 i = 0; + struct buf_addr_table *buf_addr_table; + if (buffer == BUFFER_TYPE_INPUT) { + buf_addr_table = client_ctx->input_buf_addr_table; + num_of_buffers = &client_ctx->num_of_input_buffers; + DBG("%s(): buffer = INPUT\n", __func__); + + } else { + buf_addr_table = client_ctx->output_buf_addr_table; + num_of_buffers = &client_ctx->num_of_output_buffers; + DBG("%s(): buffer = OUTPUT\n", __func__); + } + + if (!*num_of_buffers) + goto bail_out_cleanup; + if (!client_ctx->user_ion_client) + goto bail_out_cleanup; + for (i = 0; i < *num_of_buffers; ++i) { + if (buf_addr_table[i].client_data) { + msm_subsystem_unmap_buffer( + (struct msm_mapped_buffer *) + buf_addr_table[i].client_data); + buf_addr_table[i].client_data = NULL; + } + if (!IS_ERR_OR_NULL(buf_addr_table[i].buff_ion_handle)) { + if (!IS_ERR_OR_NULL(client_ctx->user_ion_client)) { + ion_unmap_kernel(client_ctx->user_ion_client, + buf_addr_table[i]. + buff_ion_handle); + if (!res_trk_check_for_sec_session()) { + ion_unmap_iommu( + client_ctx->user_ion_client, + buf_addr_table[i]. + buff_ion_handle, + VIDEO_DOMAIN, + VIDEO_MAIN_POOL); + } + ion_free(client_ctx->user_ion_client, + buf_addr_table[i]. + buff_ion_handle); + buf_addr_table[i].buff_ion_handle = NULL; + } + } + } + if (client_ctx->vcd_h264_mv_buffer.client_data) { + msm_subsystem_unmap_buffer((struct msm_mapped_buffer *) + client_ctx->vcd_h264_mv_buffer.client_data); + client_ctx->vcd_h264_mv_buffer.client_data = NULL; + } + if (!IS_ERR_OR_NULL(client_ctx->h264_mv_ion_handle)) { + if (!IS_ERR_OR_NULL(client_ctx->user_ion_client)) { + ion_unmap_kernel(client_ctx->user_ion_client, + client_ctx->h264_mv_ion_handle); + if (!res_trk_check_for_sec_session()) { + ion_unmap_iommu(client_ctx->user_ion_client, + client_ctx->h264_mv_ion_handle, + VIDEO_DOMAIN, + VIDEO_MAIN_POOL); + } + ion_free(client_ctx->user_ion_client, + client_ctx->h264_mv_ion_handle); + client_ctx->h264_mv_ion_handle = NULL; + } + } +bail_out_cleanup: + return; +} +EXPORT_SYMBOL(vidc_cleanup_addr_table); + +u32 vidc_lookup_addr_table(struct video_client_ctx *client_ctx, + enum buffer_dir buffer, + u32 search_with_user_vaddr, + unsigned long *user_vaddr, + unsigned long *kernel_vaddr, + unsigned long *phy_addr, int *pmem_fd, + struct file **file, s32 *buffer_index) +{ + u32 num_of_buffers; + u32 i; + struct buf_addr_table *buf_addr_table; + u32 found = false; + + if (!client_ctx) + return false; + mutex_lock(&client_ctx->enrty_queue_lock); + if (buffer == BUFFER_TYPE_INPUT) { + buf_addr_table = client_ctx->input_buf_addr_table; + num_of_buffers = client_ctx->num_of_input_buffers; + DBG("%s(): buffer = INPUT\n", __func__); + + } else { + buf_addr_table = client_ctx->output_buf_addr_table; + num_of_buffers = client_ctx->num_of_output_buffers; + DBG("%s(): buffer = OUTPUT\n", __func__); + } + + for (i = 0; i < num_of_buffers; ++i) { + if (search_with_user_vaddr) { + if (*user_vaddr == buf_addr_table[i].user_vaddr) { + *kernel_vaddr = buf_addr_table[i].kernel_vaddr; + found = true; + DBG("%s() : client_ctx = %p." + " user_virt_addr = 0x%08lx is found", + __func__, client_ctx, *user_vaddr); + break; + } + } else { + if (*kernel_vaddr == buf_addr_table[i].kernel_vaddr) { + *user_vaddr = buf_addr_table[i].user_vaddr; + found = true; + DBG("%s() : client_ctx = %p." + " kernel_virt_addr = 0x%08lx is found", + __func__, client_ctx, *kernel_vaddr); + break; + } + } + } + + if (found) { + *phy_addr = buf_addr_table[i].dev_addr; + *pmem_fd = buf_addr_table[i].pmem_fd; + *file = buf_addr_table[i].file; + *buffer_index = i; + + if (search_with_user_vaddr) + DBG("kernel_vaddr = 0x%08lx, phy_addr = 0x%08lx " + " pmem_fd = %d, struct *file = %p " + "buffer_index = %d\n", *kernel_vaddr, + *phy_addr, *pmem_fd, *file, *buffer_index); + else + DBG("user_vaddr = 0x%08lx, phy_addr = 0x%08lx " + " pmem_fd = %d, struct *file = %p " + "buffer_index = %d\n", *user_vaddr, *phy_addr, + *pmem_fd, *file, *buffer_index); + mutex_unlock(&client_ctx->enrty_queue_lock); + return true; + } else { + if (search_with_user_vaddr) + DBG("%s() : client_ctx = %p user_virt_addr = 0x%08lx" + " Not Found.\n", __func__, client_ctx, *user_vaddr); + else + DBG("%s() : client_ctx = %p kernel_virt_addr = 0x%08lx" + " Not Found.\n", __func__, client_ctx, + *kernel_vaddr); + mutex_unlock(&client_ctx->enrty_queue_lock); + return false; + } +} +EXPORT_SYMBOL(vidc_lookup_addr_table); + +u32 vidc_insert_addr_table(struct video_client_ctx *client_ctx, + enum buffer_dir buffer, unsigned long user_vaddr, + unsigned long *kernel_vaddr, int pmem_fd, + unsigned long buffer_addr_offset, unsigned int max_num_buffers, + unsigned long length) +{ + unsigned long len, phys_addr; + struct file *file = NULL; + u32 *num_of_buffers = NULL; + u32 i, flags; + struct buf_addr_table *buf_addr_table; + struct msm_mapped_buffer *mapped_buffer = NULL; + struct ion_handle *buff_ion_handle = NULL; + unsigned long ionflag = 0; + unsigned long iova = 0; + int ret = 0; + unsigned long buffer_size = 0; + size_t ion_len; + + if (!client_ctx || !length) + return false; + mutex_lock(&client_ctx->enrty_queue_lock); + if (buffer == BUFFER_TYPE_INPUT) { + buf_addr_table = client_ctx->input_buf_addr_table; + num_of_buffers = &client_ctx->num_of_input_buffers; + DBG("%s(): buffer = INPUT #Buf = %d\n", + __func__, *num_of_buffers); + + } else { + buf_addr_table = client_ctx->output_buf_addr_table; + num_of_buffers = &client_ctx->num_of_output_buffers; + DBG("%s(): buffer = OUTPUT #Buf = %d\n", + __func__, *num_of_buffers); + length = length * 2; /* workaround for iommu video h/w bug */ + } + + if (*num_of_buffers == max_num_buffers) { + ERR("%s(): Num of buffers reached max value : %d", + __func__, max_num_buffers); + goto bail_out_add; + } + + i = 0; + while (i < *num_of_buffers && + user_vaddr != buf_addr_table[i].user_vaddr) + i++; + if (i < *num_of_buffers) { + DBG("%s() : client_ctx = %p." + " user_virt_addr = 0x%08lx already set", + __func__, client_ctx, user_vaddr); + goto bail_out_add; + } else { + if (!vcd_get_ion_status()) { + if (get_pmem_file(pmem_fd, &phys_addr, + kernel_vaddr, &len, &file)) { + ERR("%s(): get_pmem_file failed\n", __func__); + goto bail_out_add; + } + put_pmem_file(file); + flags = (buffer == BUFFER_TYPE_INPUT) + ? MSM_SUBSYSTEM_MAP_IOVA : + MSM_SUBSYSTEM_MAP_IOVA|MSM_SUBSYSTEM_ALIGN_IOVA_8K; + mapped_buffer = msm_subsystem_map_buffer(phys_addr, + length, flags, vidc_mmu_subsystem, + sizeof(vidc_mmu_subsystem)/sizeof(unsigned int)); + if (IS_ERR(mapped_buffer)) { + pr_err("buffer map failed"); + goto bail_out_add; + } + buf_addr_table[*num_of_buffers].client_data = (void *) + mapped_buffer; + buf_addr_table[*num_of_buffers].dev_addr = + mapped_buffer->iova[0]; + } else { + buff_ion_handle = ion_import_fd( + client_ctx->user_ion_client, pmem_fd); + if (IS_ERR_OR_NULL(buff_ion_handle)) { + ERR("%s(): get_ION_handle failed\n", + __func__); + goto bail_out_add; + } + if (ion_handle_get_flags(client_ctx->user_ion_client, + buff_ion_handle, + &ionflag)) { + ERR("%s():ION flags fail\n", + __func__); + goto bail_out_add; + } + *kernel_vaddr = (unsigned long) + ion_map_kernel( + client_ctx->user_ion_client, + buff_ion_handle, + ionflag); + if (IS_ERR_OR_NULL((void *)*kernel_vaddr)) { + ERR("%s():ION virtual addr fail\n", + __func__); + *kernel_vaddr = (unsigned long)NULL; + goto ion_free_error; + } + if (res_trk_check_for_sec_session()) { + if (ion_phys(client_ctx->user_ion_client, + buff_ion_handle, + &phys_addr, &ion_len)) { + ERR("%s():ION physical addr fail\n", + __func__); + goto ion_map_error; + } + len = (unsigned long) ion_len; + buf_addr_table[*num_of_buffers].client_data = + NULL; + buf_addr_table[*num_of_buffers].dev_addr = + phys_addr; + } else { + ret = ion_map_iommu(client_ctx->user_ion_client, + buff_ion_handle, + VIDEO_DOMAIN, + VIDEO_MAIN_POOL, + SZ_8K, + length, + (unsigned long *) &iova, + (unsigned long *) &buffer_size, + UNCACHED, + ION_IOMMU_UNMAP_DELAYED); + if (ret) { + ERR("%s():ION iommu map fail\n", + __func__); + goto ion_map_error; + } + phys_addr = iova; + buf_addr_table[*num_of_buffers].client_data = + NULL; + buf_addr_table[*num_of_buffers].dev_addr = + iova; + } + } + phys_addr += buffer_addr_offset; + (*kernel_vaddr) += buffer_addr_offset; + buf_addr_table[*num_of_buffers].user_vaddr = user_vaddr; + buf_addr_table[*num_of_buffers].kernel_vaddr = *kernel_vaddr; + buf_addr_table[*num_of_buffers].pmem_fd = pmem_fd; + buf_addr_table[*num_of_buffers].file = file; + buf_addr_table[*num_of_buffers].phy_addr = phys_addr; + buf_addr_table[*num_of_buffers].buff_ion_handle = + buff_ion_handle; + buf_addr_table[*num_of_buffers].buff_ion_flag = + ionflag; + *num_of_buffers = *num_of_buffers + 1; + DBG("%s() : client_ctx = %p, user_virt_addr = 0x%08lx, " + "kernel_vaddr = 0x%08lx phys_addr=%lu inserted!", + __func__, client_ctx, user_vaddr, *kernel_vaddr, + phys_addr); + } + mutex_unlock(&client_ctx->enrty_queue_lock); + return true; +ion_map_error: + if (*kernel_vaddr && buff_ion_handle) + ion_unmap_kernel(client_ctx->user_ion_client, buff_ion_handle); +ion_free_error: + if (!IS_ERR_OR_NULL(buff_ion_handle)) + ion_free(client_ctx->user_ion_client, buff_ion_handle); +bail_out_add: + mutex_unlock(&client_ctx->enrty_queue_lock); + return false; +} +EXPORT_SYMBOL(vidc_insert_addr_table); + +/* + * Similar to vidc_insert_addr_table except intended for in-kernel + * use where buffers have already been alloced and mapped properly + */ +u32 vidc_insert_addr_table_kernel(struct video_client_ctx *client_ctx, + enum buffer_dir buffer, unsigned long user_vaddr, + unsigned long kernel_vaddr, unsigned long phys_addr, + unsigned int max_num_buffers, + unsigned long length) +{ + u32 *num_of_buffers = NULL; + u32 i; + struct buf_addr_table *buf_addr_table; + struct msm_mapped_buffer *mapped_buffer = NULL; + + if (!client_ctx || !length || !kernel_vaddr || !phys_addr) + return false; + mutex_lock(&client_ctx->enrty_queue_lock); + if (buffer == BUFFER_TYPE_INPUT) { + buf_addr_table = client_ctx->input_buf_addr_table; + num_of_buffers = &client_ctx->num_of_input_buffers; + DBG("%s(): buffer = INPUT #Buf = %d\n", + __func__, *num_of_buffers); + + } else { + buf_addr_table = client_ctx->output_buf_addr_table; + num_of_buffers = &client_ctx->num_of_output_buffers; + DBG("%s(): buffer = OUTPUT #Buf = %d\n", + __func__, *num_of_buffers); + } + + if (*num_of_buffers == max_num_buffers) { + ERR("%s(): Num of buffers reached max value : %d", + __func__, max_num_buffers); + goto bail_out_add; + } + + i = 0; + while (i < *num_of_buffers && + user_vaddr != buf_addr_table[i].user_vaddr) { + i++; + } + if (i < *num_of_buffers) { + DBG("%s() : client_ctx = %p." + " user_virt_addr = 0x%08lx already set", + __func__, client_ctx, user_vaddr); + goto bail_out_add; + } else { + mapped_buffer = NULL; + buf_addr_table[*num_of_buffers].client_data = (void *) + mapped_buffer; + buf_addr_table[*num_of_buffers].dev_addr = phys_addr; + buf_addr_table[*num_of_buffers].user_vaddr = user_vaddr; + buf_addr_table[*num_of_buffers].kernel_vaddr = kernel_vaddr; + buf_addr_table[*num_of_buffers].pmem_fd = -1; + buf_addr_table[*num_of_buffers].file = NULL; + buf_addr_table[*num_of_buffers].phy_addr = phys_addr; + buf_addr_table[*num_of_buffers].buff_ion_handle = NULL; + *num_of_buffers = *num_of_buffers + 1; + DBG("%s() : client_ctx = %p, user_virt_addr = 0x%08lx, " + "kernel_vaddr = 0x%08lx inserted!", __func__, + client_ctx, user_vaddr, *kernel_vaddr); + } + mutex_unlock(&client_ctx->enrty_queue_lock); + return true; +bail_out_add: + mutex_unlock(&client_ctx->enrty_queue_lock); + return false; +} +EXPORT_SYMBOL(vidc_insert_addr_table_kernel); + +u32 vidc_delete_addr_table(struct video_client_ctx *client_ctx, + enum buffer_dir buffer, + unsigned long user_vaddr, + unsigned long *kernel_vaddr) +{ + u32 *num_of_buffers = NULL; + u32 i; + struct buf_addr_table *buf_addr_table; + + if (!client_ctx) + return false; + mutex_lock(&client_ctx->enrty_queue_lock); + if (buffer == BUFFER_TYPE_INPUT) { + buf_addr_table = client_ctx->input_buf_addr_table; + num_of_buffers = &client_ctx->num_of_input_buffers; + + } else { + buf_addr_table = client_ctx->output_buf_addr_table; + num_of_buffers = &client_ctx->num_of_output_buffers; + } + + if (!*num_of_buffers) + goto bail_out_del; + + i = 0; + while (i < *num_of_buffers && + user_vaddr != buf_addr_table[i].user_vaddr) + i++; + if (i == *num_of_buffers) { + pr_err("%s() : client_ctx = %p." + " user_virt_addr = 0x%08lx NOT found", + __func__, client_ctx, user_vaddr); + goto bail_out_del; + } + if (buf_addr_table[i].client_data) { + msm_subsystem_unmap_buffer( + (struct msm_mapped_buffer *)buf_addr_table[i].client_data); + buf_addr_table[i].client_data = NULL; + } + *kernel_vaddr = buf_addr_table[i].kernel_vaddr; + if (buf_addr_table[i].buff_ion_handle) { + ion_unmap_kernel(client_ctx->user_ion_client, + buf_addr_table[i].buff_ion_handle); + if (!res_trk_check_for_sec_session()) { + ion_unmap_iommu(client_ctx->user_ion_client, + buf_addr_table[i].buff_ion_handle, + VIDEO_DOMAIN, + VIDEO_MAIN_POOL); + } + ion_free(client_ctx->user_ion_client, + buf_addr_table[i].buff_ion_handle); + buf_addr_table[i].buff_ion_handle = NULL; + } + if (i < (*num_of_buffers - 1)) { + buf_addr_table[i].client_data = + buf_addr_table[*num_of_buffers - 1].client_data; + buf_addr_table[i].dev_addr = + buf_addr_table[*num_of_buffers - 1].dev_addr; + buf_addr_table[i].user_vaddr = + buf_addr_table[*num_of_buffers - 1].user_vaddr; + buf_addr_table[i].kernel_vaddr = + buf_addr_table[*num_of_buffers - 1].kernel_vaddr; + buf_addr_table[i].phy_addr = + buf_addr_table[*num_of_buffers - 1].phy_addr; + buf_addr_table[i].pmem_fd = + buf_addr_table[*num_of_buffers - 1].pmem_fd; + buf_addr_table[i].file = + buf_addr_table[*num_of_buffers - 1].file; + buf_addr_table[i].buff_ion_handle = + buf_addr_table[*num_of_buffers - 1].buff_ion_handle; + } + *num_of_buffers = *num_of_buffers - 1; + DBG("%s() : client_ctx = %p." + " user_virt_addr = 0x%08lx is found and deleted", + __func__, client_ctx, user_vaddr); + mutex_unlock(&client_ctx->enrty_queue_lock); + return true; +bail_out_del: + mutex_unlock(&client_ctx->enrty_queue_lock); + return false; +} +EXPORT_SYMBOL(vidc_delete_addr_table); + +u32 vidc_timer_create(void (*timer_handler)(void *), + void *user_data, void **timer_handle) +{ + struct vidc_timer *hw_timer = NULL; + if (!timer_handler || !timer_handle) { + DBG("%s(): timer creation failed\n ", __func__); + return false; + } + hw_timer = kzalloc(sizeof(struct vidc_timer), GFP_KERNEL); + if (!hw_timer) { + DBG("%s(): timer creation failed in allocation\n ", __func__); + return false; + } + init_timer(&hw_timer->hw_timeout); + hw_timer->hw_timeout.data = (unsigned long)hw_timer; + hw_timer->hw_timeout.function = vidc_timer_fn; + hw_timer->cb_func = timer_handler; + hw_timer->userdata = user_data; + *timer_handle = hw_timer; + return true; +} +EXPORT_SYMBOL(vidc_timer_create); + +void vidc_timer_release(void *timer_handle) +{ + kfree(timer_handle); +} +EXPORT_SYMBOL(vidc_timer_release); + +void vidc_timer_start(void *timer_handle, u32 time_out) +{ + struct vidc_timer *hw_timer = (struct vidc_timer *)timer_handle; + DBG("%s(): start timer\n ", __func__); + if (hw_timer) { + hw_timer->hw_timeout.expires = jiffies + 1*HZ; + add_timer(&hw_timer->hw_timeout); + } +} +EXPORT_SYMBOL(vidc_timer_start); + +void vidc_timer_stop(void *timer_handle) +{ + struct vidc_timer *hw_timer = (struct vidc_timer *)timer_handle; + DBG("%s(): stop timer\n ", __func__); + if (hw_timer) + del_timer(&hw_timer->hw_timeout); +} +EXPORT_SYMBOL(vidc_timer_stop); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Video decoder/encoder driver Init Module"); +MODULE_VERSION("1.0"); +module_init(vidc_init); +module_exit(vidc_exit); diff --git a/drivers/video/msm/vidc/common/init/vidc_init_internal.h b/drivers/video/msm/vidc/common/init/vidc_init_internal.h new file mode 100644 index 000000000000..b62280faebac --- /dev/null +++ b/drivers/video/msm/vidc/common/init/vidc_init_internal.h @@ -0,0 +1,41 @@ +/* Copyright (c) 2010, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#ifndef VIDC_INIT_INTERNAL_H +#define VIDC_INIT_INTERNAL_H + +#include + +struct vidc_timer { + struct list_head list; + struct timer_list hw_timeout; + void (*cb_func)(void *); + void *userdata; +}; + +struct vidc_dev { + struct cdev cdev; + struct device *device; + resource_size_t phys_base; + void __iomem *virt_base; + unsigned int irq; + unsigned int ref_count; + unsigned int firmware_refcount; + unsigned int get_firmware; + struct mutex lock; + s32 device_handle; + struct list_head vidc_timer_queue; + struct work_struct vidc_timer_worker; +}; + +#endif diff --git a/drivers/video/msm/vidc/common/vcd/vcd.h b/drivers/video/msm/vidc/common/vcd/vcd.h new file mode 100644 index 000000000000..9650193ddf47 --- /dev/null +++ b/drivers/video/msm/vidc/common/vcd/vcd.h @@ -0,0 +1,400 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#ifndef _VCD_H_ +#define _VCD_H_ + +#include +#include "vcd_util.h" +#include "vcd_ddl_api.h" +#include "vcd_res_tracker_api.h" +#include "vcd_client_sm.h" +#include "vcd_core.h" +#include "vcd_device_sm.h" + +void vcd_reset_device_channels(struct vcd_dev_ctxt *dev_ctxt); + +u32 vcd_get_command_channel + (struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc **transc); + +u32 vcd_get_command_channel_in_loop + (struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc **transc); + +void vcd_mark_command_channel + (struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc *transc); + +void vcd_release_command_channel + (struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc *transc); + +void vcd_release_multiple_command_channels(struct vcd_dev_ctxt *dev_ctxt, + u32 channels); + +void vcd_release_interim_command_channels(struct vcd_dev_ctxt *dev_ctxt); + +u32 vcd_get_frame_channel + (struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc **transc); + +u32 vcd_get_frame_channel_in_loop + (struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc **transc); + +void vcd_mark_frame_channel(struct vcd_dev_ctxt *dev_ctxt); + +void vcd_release_frame_channel + (struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc *transc); + +void vcd_release_multiple_frame_channels(struct vcd_dev_ctxt *dev_ctxt, + u32 channels); + +void vcd_release_interim_frame_channels(struct vcd_dev_ctxt *dev_ctxt); +u32 vcd_core_is_busy(struct vcd_dev_ctxt *dev_ctxt); + +void vcd_device_timer_start(struct vcd_dev_ctxt *dev_ctxt); +void vcd_device_timer_stop(struct vcd_dev_ctxt *dev_ctxt); + + +u32 vcd_init_device_context + (struct vcd_drv_ctxt *drv_ctxt, u32 ev_code); + +u32 vcd_deinit_device_context + (struct vcd_drv_ctxt *drv_ctxt, u32 ev_code); + +u32 vcd_init_client_context(struct vcd_clnt_ctxt *cctxt); + +void vcd_destroy_client_context(struct vcd_clnt_ctxt *cctxt); + +u32 vcd_check_for_client_context + (struct vcd_dev_ctxt *dev_ctxt, s32 driver_id); + +u32 vcd_validate_driver_handle + (struct vcd_dev_ctxt *dev_ctxt, s32 driver_handle); + +void vcd_handle_for_last_clnt_close + (struct vcd_dev_ctxt *dev_ctxt, u32 send_deinit); + +u32 vcd_common_allocate_set_buffer + (struct vcd_clnt_ctxt *cctxt, + enum vcd_buffer_type buffer, + u32 buf_size, struct vcd_buffer_pool **buf_pool); + +u32 vcd_set_buffer_internal + (struct vcd_clnt_ctxt *cctxt, + struct vcd_buffer_pool *buf_pool, u8 *buffer, u32 buf_size); + +u32 vcd_allocate_buffer_internal + (struct vcd_clnt_ctxt *cctxt, + struct vcd_buffer_pool *buf_pool, + u32 buf_size, u8 **vir_buf_addr, u8 **phy_buf_addr); + +u32 vcd_free_one_buffer_internal + (struct vcd_clnt_ctxt *cctxt, + enum vcd_buffer_type buffer_type, u8 *buffer); + +u32 vcd_free_buffers_internal + (struct vcd_clnt_ctxt *cctxt, + struct vcd_buffer_pool *buf_pool); + +u32 vcd_alloc_buffer_pool_entries + (struct vcd_buffer_pool *buf_pool, + struct vcd_buffer_requirement *buf_req); + +void vcd_free_buffer_pool_entries(struct vcd_buffer_pool *buf_pool); + +void vcd_flush_in_use_buffer_pool_entries(struct vcd_clnt_ctxt *cctxt, + struct vcd_buffer_pool *buf_pool, u32 event); + +void vcd_reset_buffer_pool_for_reuse(struct vcd_buffer_pool *buf_pool); + +struct vcd_buffer_entry *vcd_get_free_buffer_pool_entry + (struct vcd_buffer_pool *pool); + +struct vcd_buffer_entry *vcd_find_buffer_pool_entry + (struct vcd_buffer_pool *pool, u8 *v_addr); + +struct vcd_buffer_entry *vcd_buffer_pool_entry_de_q + (struct vcd_buffer_pool *pool); + +u32 vcd_buffer_pool_entry_en_q + (struct vcd_buffer_pool *pool, + struct vcd_buffer_entry *entry); + +u32 vcd_check_if_buffer_req_met(struct vcd_clnt_ctxt *cctxt, + enum vcd_buffer_type buffer_type); + +u32 vcd_client_cmd_en_q + (struct vcd_clnt_ctxt *cctxt, enum vcd_command command); + +void vcd_client_cmd_flush_and_en_q + (struct vcd_clnt_ctxt *cctxt, enum vcd_command command); + +u32 vcd_client_cmd_de_q + (struct vcd_clnt_ctxt *cctxt, enum vcd_command *command); + +u32 vcd_handle_recvd_eos + (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *input_frame, u32 * pb_eos_handled); + +u32 vcd_handle_first_decode_frame(struct vcd_clnt_ctxt *cctxt); + +u32 vcd_handle_input_frame + (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *input_frame); + +u32 vcd_store_seq_hdr + (struct vcd_clnt_ctxt *cctxt, + struct vcd_sequence_hdr *seq_hdr); + +u32 vcd_set_frame_size + (struct vcd_clnt_ctxt *cctxt, + struct vcd_property_frame_size *frm_size); + +u32 vcd_set_frame_rate + (struct vcd_clnt_ctxt *cctxt, + struct vcd_property_frame_rate *fps); + +u32 vcd_calculate_frame_delta + (struct vcd_clnt_ctxt *cctxt, struct vcd_frame_data *frame); + +struct vcd_buffer_entry *vcd_check_fill_output_buffer + (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *buffer); + +u32 vcd_handle_first_fill_output_buffer + (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *buffer, u32 *b_handled); + +u32 vcd_handle_first_fill_output_buffer_for_enc + (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *frm_entry, u32 *b_handled); + +u32 vcd_handle_first_fill_output_buffer_for_dec + (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *frm_entry, u32 *b_handled); + +u32 vcd_schedule_frame(struct vcd_dev_ctxt *dev_ctxt, + struct vcd_clnt_ctxt **cctxt, struct vcd_buffer_entry + **ip_buf_entry); + +u32 vcd_submit_command_in_continue + (struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc *transc); + +u32 vcd_submit_cmd_sess_start(struct vcd_transc *transc); + +u32 vcd_submit_cmd_sess_end(struct vcd_transc *transc); + +void vcd_submit_cmd_client_close(struct vcd_clnt_ctxt *cctxt); + +u32 vcd_submit_frame + (struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc *transc); + +u32 vcd_try_submit_frame_in_continue(struct vcd_dev_ctxt *dev_ctxt, + struct vcd_transc *transc); + +u32 vcd_process_cmd_sess_start(struct vcd_clnt_ctxt *cctxt); + +void vcd_try_submit_frame(struct vcd_dev_ctxt *dev_ctxt); + +u32 vcd_setup_with_ddl_capabilities(struct vcd_dev_ctxt *dev_ctxt); +void vcd_handle_submit_frame_failed(struct vcd_dev_ctxt *dev_ctxt, + struct vcd_transc *transc); + +struct vcd_transc *vcd_get_free_trans_tbl_entry + (struct vcd_dev_ctxt *dev_ctxt); + +void vcd_release_trans_tbl_entry(struct vcd_transc *trans_entry); + +void vcd_release_all_clnt_frm_transc(struct vcd_clnt_ctxt *cctxt); +void vcd_release_all_clnt_transc(struct vcd_clnt_ctxt *cctxt); + +u32 vcd_handle_input_done + (struct vcd_clnt_ctxt *cctxt, + void *payload, u32 event, u32 status); + +u32 vcd_handle_input_done_in_eos + (struct vcd_clnt_ctxt *cctxt, void *payload, u32 status); + +void vcd_handle_input_done_failed + (struct vcd_clnt_ctxt *cctxt, struct vcd_transc *transc); + +void vcd_handle_input_done_with_codec_config + (struct vcd_clnt_ctxt *cctxt, + struct vcd_transc *transc, + struct ddl_frame_data_tag *frm); + +void vcd_handle_input_done_for_interlacing + (struct vcd_clnt_ctxt *cctxt); + +void vcd_handle_input_done_with_trans_end + (struct vcd_clnt_ctxt *cctxt); + +u32 vcd_handle_frame_done + (struct vcd_clnt_ctxt *cctxt, + void *payload, u32 event, u32 status); + +void vcd_handle_frame_done_for_interlacing + (struct vcd_clnt_ctxt *cctxt, + struct vcd_transc *transc_ip1, + struct ddl_frame_data_tag *op_frm, u32 status); + + +u32 vcd_handle_frame_done_in_eos + (struct vcd_clnt_ctxt *cctxt, void *payload, u32 status); + +u32 vcd_handle_output_required(struct vcd_clnt_ctxt *cctxt, + void *payload, u32 status); + +u32 vcd_handle_output_required_in_flushing(struct vcd_clnt_ctxt *cctxt, + void *payload); + +u32 vcd_handle_output_req_tran_end_in_eos(struct vcd_clnt_ctxt *cctxt); + +u32 vcd_validate_io_done_pyld + (struct vcd_clnt_ctxt *cctxt, void *payload, u32 status); + +void vcd_handle_eos_trans_end(struct vcd_clnt_ctxt *cctxt); + + +void vcd_handle_eos_done + (struct vcd_clnt_ctxt *cctxt, + struct vcd_transc *transc, u32 status); + +void vcd_send_frame_done_in_eos + (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *input_frame, u32 valid_opbuf); + +void vcd_send_frame_done_in_eos_for_dec + (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *input_frame); + +void vcd_send_frame_done_in_eos_for_enc + (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *input_frame); + +void vcd_handle_start_done(struct vcd_clnt_ctxt *cctxt, + struct vcd_transc *transc, u32 status); + +void vcd_handle_stop_done(struct vcd_clnt_ctxt *cctxt, + struct vcd_transc *transc, u32 status); + +void vcd_handle_stop_done_in_starting(struct vcd_clnt_ctxt *cctxt, + struct vcd_transc *transc, u32 status); + +void vcd_handle_stop_done_in_invalid(struct vcd_clnt_ctxt *cctxt, + struct vcd_transc *transc, u32 status); + +void vcd_send_flush_done(struct vcd_clnt_ctxt *cctxt, u32 status); + +void vcd_process_pending_flush_in_eos(struct vcd_clnt_ctxt *cctxt); + +void vcd_process_pending_stop_in_eos(struct vcd_clnt_ctxt *cctxt); + +void vcd_handle_trans_pending(struct vcd_clnt_ctxt *cctxt); + +u32 vcd_handle_ind_output_reconfig + (struct vcd_clnt_ctxt *cctxt, void* payload, u32 status); + +u32 vcd_handle_ind_output_reconfig_in_flushing + (struct vcd_clnt_ctxt *cctxt, void* payload, u32 status); + +void vcd_flush_output_buffers(struct vcd_clnt_ctxt *cctxt); + +void vcd_flush_bframe_buffers(struct vcd_clnt_ctxt *cctxt, u32 mode); + +u32 vcd_flush_buffers(struct vcd_clnt_ctxt *cctxt, u32 mode); +void vcd_flush_buffers_in_err_fatal(struct vcd_clnt_ctxt *cctxt); + +u32 vcd_power_event + (struct vcd_dev_ctxt *dev_ctxt, + struct vcd_clnt_ctxt *cctxt, u32 event); + +u32 vcd_device_power_event(struct vcd_dev_ctxt *dev_ctxt, u32 event, + struct vcd_clnt_ctxt *cctxt); + +u32 vcd_client_power_event + (struct vcd_dev_ctxt *dev_ctxt, + struct vcd_clnt_ctxt *cctxt, u32 event); + +u32 vcd_enable_clock(struct vcd_dev_ctxt *dev_ctxt, + struct vcd_clnt_ctxt *cctxt); + +u32 vcd_disable_clock(struct vcd_dev_ctxt *dev_ctxt); + +u32 vcd_set_perf_level(struct vcd_dev_ctxt *dev_ctxt, u32 perf_lvl); + +u32 vcd_update_clnt_perf_lvl + (struct vcd_clnt_ctxt *cctxt, + struct vcd_property_frame_rate *fps, u32 frm_p_units); + +u32 vcd_gate_clock(struct vcd_dev_ctxt *dev_ctxt); + +u32 vcd_un_gate_clock(struct vcd_dev_ctxt *dev_ctxt); + +void vcd_handle_err_fatal(struct vcd_clnt_ctxt *cctxt, + u32 event, u32 status); + +void vcd_handle_device_err_fatal(struct vcd_dev_ctxt *dev_ctxt, + struct vcd_clnt_ctxt *cctxt); + +void vcd_clnt_handle_device_err_fatal(struct vcd_clnt_ctxt *cctxt, + u32 event); + +void vcd_handle_err_in_starting(struct vcd_clnt_ctxt *cctxt, + u32 status); + +void vcd_handle_ind_hw_err_fatal(struct vcd_clnt_ctxt *cctxt, + u32 event, u32 status); + +u32 vcd_return_op_buffer_to_hw(struct vcd_clnt_ctxt *cctxt, + struct vcd_buffer_entry *buf_entry); + +u32 vcd_sched_create(struct list_head *sched_list); + +void vcd_sched_destroy(struct list_head *sched_clnt_list); + +u32 vcd_sched_add_client(struct vcd_clnt_ctxt *cctxt); + +u32 vcd_sched_remove_client(struct vcd_sched_clnt_ctx *sched_cctxt); + +u32 vcd_sched_update_config(struct vcd_clnt_ctxt *cctxt); + +u32 vcd_sched_queue_buffer( + struct vcd_sched_clnt_ctx *sched_cctxt, + struct vcd_buffer_entry *buffer, u32 b_tail); + +u32 vcd_sched_dequeue_buffer( + struct vcd_sched_clnt_ctx *sched_cctxt, + struct vcd_buffer_entry **buffer); + +u32 vcd_sched_mark_client_eof(struct vcd_sched_clnt_ctx *sched_cctxt); + +u32 vcd_sched_suspend_resume_clnt( + struct vcd_clnt_ctxt *cctxt, u32 b_state); + +u32 vcd_sched_get_client_frame(struct list_head *sched_clnt_list, + struct vcd_clnt_ctxt **cctxt, + struct vcd_buffer_entry **buffer); + +void vcd_handle_clnt_fatal(struct vcd_clnt_ctxt *cctxt, u32 trans_end); + +void vcd_handle_clnt_fatal_input_done(struct vcd_clnt_ctxt *cctxt, + u32 trans_end); + +void vcd_handle_ind_info_output_reconfig + (struct vcd_clnt_ctxt *cctxt, u32 status); + +u32 vcd_req_perf_level(struct vcd_clnt_ctxt *cctxt, + struct vcd_property_perf_level *); + +u32 vcd_set_num_slices(struct vcd_clnt_ctxt *cctxt); + +u32 vcd_update_decoder_perf_level(struct vcd_dev_ctxt *dev_ctxt, u32 perf_lvl); + +#endif diff --git a/drivers/video/msm/vidc/common/vcd/vcd_api.c b/drivers/video/msm/vidc/common/vcd/vcd_api.c new file mode 100644 index 000000000000..facde348bab3 --- /dev/null +++ b/drivers/video/msm/vidc/common/vcd/vcd_api.c @@ -0,0 +1,986 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#include +#include +#include "vcd.h" + +u32 vcd_init(struct vcd_init_config *config, s32 *driver_handle) +{ + u32 rc = VCD_S_SUCCESS; + struct vcd_drv_ctxt *drv_ctxt; + + VCD_MSG_MED("vcd_init:"); + + if (!config || + !driver_handle || !config->map_dev_base_addr) { + VCD_MSG_ERROR("Bad parameters"); + + return VCD_ERR_ILLEGAL_PARM; + } + + drv_ctxt = vcd_get_drv_context(); + mutex_init(&drv_ctxt->dev_mutex); + mutex_lock(&drv_ctxt->dev_mutex); + + if (drv_ctxt->dev_state.state_table->ev_hdlr.init) { + rc = drv_ctxt->dev_state.state_table->ev_hdlr. + init(drv_ctxt, config, driver_handle); + } else { + VCD_MSG_ERROR("Unsupported API in device state %d", + drv_ctxt->dev_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_init); + +u32 vcd_term(s32 driver_handle) +{ + u32 rc = VCD_S_SUCCESS; + struct vcd_drv_ctxt *drv_ctxt; + + VCD_MSG_MED("vcd_term:"); + + drv_ctxt = vcd_get_drv_context(); + mutex_lock(&drv_ctxt->dev_mutex); + + if (drv_ctxt->dev_state.state_table->ev_hdlr.term) { + rc = drv_ctxt->dev_state.state_table->ev_hdlr. + term(drv_ctxt, driver_handle); + } else { + VCD_MSG_ERROR("Unsupported API in device state %d", + drv_ctxt->dev_state.state); + + rc = VCD_ERR_BAD_STATE; + } + mutex_unlock(&drv_ctxt->dev_mutex); + return rc; + +} +EXPORT_SYMBOL(vcd_term); + +struct client_security_info { + int secure_enc; + int secure_dec; + int non_secure_enc; + int non_secure_dec; +}; + +static int vcd_get_clients_security_info(struct client_security_info *sec_info) +{ + struct vcd_drv_ctxt *drv_ctxt; + struct vcd_clnt_ctxt *cctxt; + int count = 0; + if (!sec_info) { + VCD_MSG_ERROR("Invalid argument\n"); + return -EINVAL; + } + memset(sec_info, 0 , sizeof(*sec_info)); + drv_ctxt = vcd_get_drv_context(); + mutex_lock(&drv_ctxt->dev_mutex); + cctxt = drv_ctxt->dev_ctxt.cctxt_list_head; + while (cctxt) { + if (cctxt->secure && cctxt->decoding) + sec_info->secure_dec++; + else if (cctxt->secure && !cctxt->decoding) + sec_info->secure_enc++; + else if (!cctxt->secure && cctxt->decoding) + sec_info->non_secure_dec++; + else + sec_info->non_secure_enc++; + count++; + cctxt = cctxt->next; + } + mutex_unlock(&drv_ctxt->dev_mutex); + return count; +} + +static int is_session_invalid(u32 decoding, u32 flags) +{ + int is_secure; + struct client_security_info sec_info; + int client_count = 0; + int secure_session_running = 0; + is_secure = (flags & VCD_CP_SESSION) ? 1 : 0; + client_count = vcd_get_clients_security_info(&sec_info); + secure_session_running = (sec_info.secure_enc > 0) || + (sec_info.secure_dec > 0); + if (!decoding && is_secure) { + if ((sec_info.secure_dec == 1)) + VCD_MSG_LOW("SE-SD: SUCCESS\n"); + else { + VCD_MSG_LOW("SE is permitted only with SD: FAILURE\n"); + return -EACCES; + } + } else if (!decoding && !is_secure) { + if (secure_session_running) { + VCD_MSG_LOW("SD-NSE: FAILURE\n"); + VCD_MSG_LOW("SE-NSE: FAILURE\n"); + return -EACCES; + } + } else if (decoding && is_secure) { + if (client_count > 0) { + VCD_MSG_LOW("S/NS-SD: FAILURE\n"); + if (sec_info.secure_enc > 0 || + sec_info.non_secure_enc > 0) { + return -EAGAIN; + } + return -EACCES; + } + } else { + if (sec_info.secure_dec > 0) { + VCD_MSG_LOW("SD-NSD: FAILURE\n"); + return -EACCES; + } + } + return 0; +} + +u32 vcd_open(s32 driver_handle, u32 decoding, + void (*callback) (u32 event, u32 status, void *info, size_t sz, + void *handle, void *const client_data), + void *client_data, int flags) +{ + u32 rc = 0; + struct vcd_drv_ctxt *drv_ctxt; + struct vcd_clnt_ctxt *cctxt; + int is_secure = (flags & VCD_CP_SESSION) ? 1 : 0; + VCD_MSG_MED("vcd_open:"); + + if (!callback) { + VCD_MSG_ERROR("Bad parameters"); + return -EINVAL; + } + rc = is_session_invalid(decoding, flags); + if (rc) { + VCD_MSG_ERROR("Invalid Session: is_decoder: %d, secure: %d\n", + decoding, flags); + return rc; + } + if (is_secure) + res_trk_secure_set(); + drv_ctxt = vcd_get_drv_context(); + mutex_lock(&drv_ctxt->dev_mutex); + + if (drv_ctxt->dev_state.state_table->ev_hdlr.open) { + rc = drv_ctxt->dev_state.state_table->ev_hdlr. + open(drv_ctxt, driver_handle, decoding, callback, + client_data); + if (rc) { + rc = -ENODEV; + } + } else { + VCD_MSG_ERROR("Unsupported API in device state %d", + drv_ctxt->dev_state.state); + rc = -EPERM; + } + if (!rc) { + cctxt = drv_ctxt->dev_ctxt.cctxt_list_head; + cctxt->secure = is_secure; + } else if (is_secure) + res_trk_secure_unset(); + + mutex_unlock(&drv_ctxt->dev_mutex); + return rc; +} +EXPORT_SYMBOL(vcd_open); + +u32 vcd_close(void *handle) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + int is_secure = 0; + VCD_MSG_MED("vcd_close:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + is_secure = cctxt->secure; + drv_ctxt = vcd_get_drv_context(); + mutex_lock(&drv_ctxt->dev_mutex); + if (drv_ctxt->dev_state.state_table->ev_hdlr.close) { + rc = drv_ctxt->dev_state.state_table->ev_hdlr. + close(drv_ctxt, cctxt); + } else { + VCD_MSG_ERROR("Unsupported API in device state %d", + drv_ctxt->dev_state.state); + + rc = VCD_ERR_BAD_STATE; + } + mutex_unlock(&drv_ctxt->dev_mutex); + if (is_secure) + res_trk_secure_unset(); + return rc; + +} +EXPORT_SYMBOL(vcd_close); + +u32 vcd_encode_start(void *handle) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + + VCD_MSG_MED("vcd_encode_start:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr.encode_start && + drv_ctxt->dev_ctxt.pwr_state != VCD_PWR_STATE_SLEEP) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + encode_start(cctxt); + } else { + VCD_MSG_ERROR + ("Unsupported API in dev power state %d OR client state %d", + drv_ctxt->dev_ctxt.pwr_state, + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_encode_start); + +u32 vcd_encode_frame(void *handle, struct vcd_frame_data *input_frame) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + + VCD_MSG_MED("vcd_encode_frame:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + if (!input_frame) { + VCD_MSG_ERROR("Bad parameters"); + + return VCD_ERR_BAD_POINTER; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr.encode_frame) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + encode_frame(cctxt, input_frame); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_encode_frame); + +u32 vcd_decode_start(void *handle, struct vcd_sequence_hdr *seq_hdr) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + + VCD_MSG_MED("vcd_decode_start:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr.decode_start && + drv_ctxt->dev_ctxt.pwr_state != VCD_PWR_STATE_SLEEP) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + decode_start(cctxt, seq_hdr); + } else { + VCD_MSG_ERROR + ("Unsupported API in dev power state %d OR client state %d", + drv_ctxt->dev_ctxt.pwr_state, + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_decode_start); + +u32 vcd_decode_frame(void *handle, struct vcd_frame_data *input_frame) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + + VCD_MSG_MED("vcd_decode_frame:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + if (!input_frame) { + VCD_MSG_ERROR("Bad parameters"); + + return VCD_ERR_BAD_POINTER; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr.decode_frame) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + decode_frame(cctxt, input_frame); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_decode_frame); + +u32 vcd_pause(void *handle) +{ + struct vcd_drv_ctxt *drv_ctxt; + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + u32 rc; + + VCD_MSG_MED("vcd_pause:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr.pause) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + pause(cctxt); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_pause); + +u32 vcd_resume(void *handle) +{ + struct vcd_drv_ctxt *drv_ctxt; + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + u32 rc; + + VCD_MSG_MED("vcd_resume:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (drv_ctxt->dev_state.state_table->ev_hdlr.resume && + drv_ctxt->dev_ctxt.pwr_state != VCD_PWR_STATE_SLEEP) { + rc = drv_ctxt->dev_state.state_table->ev_hdlr. + resume(drv_ctxt, cctxt); + } else { + VCD_MSG_ERROR + ("Unsupported API in dev power state %d OR client state %d", + drv_ctxt->dev_ctxt.pwr_state, + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_resume); + +u32 vcd_flush(void *handle, u32 mode) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + + VCD_MSG_MED("vcd_flush:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr.flush) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + flush(cctxt, mode); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_flush); + +u32 vcd_stop(void *handle) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + + VCD_MSG_MED("vcd_stop:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr.stop && + drv_ctxt->dev_ctxt.pwr_state != VCD_PWR_STATE_SLEEP) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + stop(cctxt); + } else { + VCD_MSG_ERROR + ("Unsupported API in dev power state %d OR client state %d", + drv_ctxt->dev_ctxt.pwr_state, + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_stop); + +u32 vcd_set_property(void *handle, + struct vcd_property_hdr *prop_hdr, void *prop_val) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + + VCD_MSG_MED("vcd_set_property:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + if (!prop_hdr || !prop_val) { + VCD_MSG_ERROR("Bad parameters"); + + return VCD_ERR_BAD_POINTER; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr.set_property) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + set_property(cctxt, prop_hdr, prop_val); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_set_property); + +u32 vcd_get_property(void *handle, + struct vcd_property_hdr *prop_hdr, void *prop_val) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + + VCD_MSG_MED("vcd_get_property:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + if (!prop_hdr || !prop_val) { + VCD_MSG_ERROR("Bad parameters"); + + return VCD_ERR_BAD_POINTER; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr.get_property) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + get_property(cctxt, prop_hdr, prop_val); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_get_property); + +u32 vcd_set_buffer_requirements(void *handle, + enum vcd_buffer_type buffer, + struct vcd_buffer_requirement *buffer_req) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + + VCD_MSG_MED("vcd_set_buffer_requirements:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + if (!buffer_req) { + VCD_MSG_ERROR("Bad parameters"); + + return VCD_ERR_BAD_POINTER; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr. + set_buffer_requirements) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + set_buffer_requirements(cctxt, buffer, buffer_req); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_set_buffer_requirements); + +u32 vcd_get_buffer_requirements(void *handle, + enum vcd_buffer_type buffer, + struct vcd_buffer_requirement *buffer_req) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + + VCD_MSG_MED("vcd_get_buffer_requirements:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + if (!buffer_req) { + VCD_MSG_ERROR("Bad parameters"); + + return VCD_ERR_BAD_POINTER; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr. + get_buffer_requirements) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + get_buffer_requirements(cctxt, buffer, buffer_req); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_get_buffer_requirements); + +u32 vcd_set_buffer(void *handle, + enum vcd_buffer_type buffer_type, u8 *buffer, u32 buf_size) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + + VCD_MSG_MED("vcd_set_buffer:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + if (!buffer || !buf_size) { + VCD_MSG_ERROR("Bad parameters"); + + return VCD_ERR_BAD_POINTER; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr.set_buffer) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + set_buffer(cctxt, buffer_type, buffer, buf_size); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_set_buffer); + +u32 vcd_allocate_buffer(void *handle, + enum vcd_buffer_type buffer, + u32 buf_size, u8 **vir_buf_addr, u8 **phy_buf_addr) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + + VCD_MSG_MED("vcd_allocate_buffer:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + if (!vir_buf_addr || !phy_buf_addr + || !buf_size) { + VCD_MSG_ERROR("Bad parameters"); + + return VCD_ERR_BAD_POINTER; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr.allocate_buffer) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + allocate_buffer(cctxt, buffer, buf_size, + vir_buf_addr, phy_buf_addr); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_allocate_buffer); + +u32 vcd_free_buffer(void *handle, enum vcd_buffer_type buffer_type, u8 *buffer) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + + VCD_MSG_MED("vcd_free_buffer:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr.free_buffer) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + free_buffer(cctxt, buffer_type, buffer); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_free_buffer); + +u32 vcd_fill_output_buffer(void *handle, struct vcd_frame_data *buffer) +{ + struct vcd_clnt_ctxt *cctxt = + (struct vcd_clnt_ctxt *)handle; + struct vcd_drv_ctxt *drv_ctxt; + u32 rc; + + VCD_MSG_MED("vcd_fill_output_buffer:"); + + if (!cctxt || cctxt->signature != VCD_SIGNATURE) { + VCD_MSG_ERROR("Bad client handle"); + + return VCD_ERR_BAD_HANDLE; + } + + if (!buffer) { + VCD_MSG_ERROR("Bad parameters"); + + return VCD_ERR_BAD_POINTER; + } + + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (cctxt->clnt_state.state_table->ev_hdlr.fill_output_buffer) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + fill_output_buffer(cctxt, buffer); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_fill_output_buffer); + +u32 vcd_set_device_power(s32 driver_handle, + enum vcd_power_state pwr_state) +{ + u32 rc = VCD_S_SUCCESS; + struct vcd_drv_ctxt *drv_ctxt; + + VCD_MSG_MED("vcd_set_device_power:"); + + drv_ctxt = vcd_get_drv_context(); + mutex_lock(&drv_ctxt->dev_mutex); + + if (drv_ctxt->dev_state.state_table->ev_hdlr.set_dev_pwr) { + rc = drv_ctxt->dev_state.state_table->ev_hdlr. + set_dev_pwr(drv_ctxt, pwr_state); + } else { + VCD_MSG_ERROR("Unsupported API in device state %d", + drv_ctxt->dev_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + mutex_unlock(&drv_ctxt->dev_mutex); + + return rc; + +} +EXPORT_SYMBOL(vcd_set_device_power); + +void vcd_read_and_clear_interrupt(void) +{ + VCD_MSG_LOW("vcd_read_and_clear_interrupt:"); + ddl_read_and_clear_interrupt(); +} + + +void vcd_response_handler(void) +{ + struct vcd_drv_ctxt *drv_ctxt; + + VCD_MSG_LOW("vcd_response_handler:"); + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + + if (!ddl_process_core_response()) { + VCD_MSG_HIGH + ("ddl_process_core_response indicated no further" + "processing"); + mutex_unlock(&drv_ctxt->dev_mutex); + return; + } + + if (drv_ctxt->dev_ctxt.command_continue) + vcd_continue(); + mutex_unlock(&drv_ctxt->dev_mutex); +} +EXPORT_SYMBOL(vcd_response_handler); + +u8 vcd_get_num_of_clients(void) +{ + struct vcd_drv_ctxt *drv_ctxt; + struct vcd_clnt_ctxt *cctxt; + u8 count = 0; + + VCD_MSG_LOW("vcd_get_num_of_clients:"); + drv_ctxt = vcd_get_drv_context(); + + mutex_lock(&drv_ctxt->dev_mutex); + cctxt = drv_ctxt->dev_ctxt.cctxt_list_head; + while (cctxt) { + count++; + cctxt = cctxt->next; + } + mutex_unlock(&drv_ctxt->dev_mutex); + return count; +} +EXPORT_SYMBOL(vcd_get_num_of_clients); + +u32 vcd_get_ion_status(void) +{ + return res_trk_get_enable_ion(); +} +EXPORT_SYMBOL(vcd_get_ion_status); + +struct ion_client *vcd_get_ion_client(void) +{ + return res_trk_get_ion_client(); +} +EXPORT_SYMBOL(vcd_get_ion_client); + + + + diff --git a/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c new file mode 100644 index 000000000000..6c384cf509bb --- /dev/null +++ b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c @@ -0,0 +1,1884 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#include +#include "vcd.h" + +static const struct vcd_clnt_state_table *vcd_clnt_state_table[]; + +void vcd_clnt_handle_device_err_fatal(struct vcd_clnt_ctxt *cctxt, + u32 event) +{ + if (cctxt->clnt_state.state == VCD_CLIENT_STATE_NULL) { + cctxt->callback(VCD_EVT_RESP_OPEN, VCD_ERR_HW_FATAL, NULL, 0, + cctxt, cctxt->client_data); + vcd_destroy_client_context(cctxt); + return; + } + if (event == VCD_EVT_RESP_BASE) + event = VCD_EVT_IND_HWERRFATAL; + if (cctxt->clnt_state.state != VCD_CLIENT_STATE_INVALID) { + cctxt->callback(event, VCD_ERR_HW_FATAL, NULL, 0, + cctxt, cctxt->client_data); + vcd_flush_buffers_in_err_fatal(cctxt); + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_INVALID, + CLIENT_STATE_EVENT_NUMBER(clnt_cb)); + } +} + +static u32 vcd_close_in_open(struct vcd_clnt_ctxt *cctxt) +{ + u32 rc = VCD_S_SUCCESS; + + VCD_MSG_LOW("vcd_close_in_open:"); + if (cctxt->in_buf_pool.allocated || + cctxt->out_buf_pool.allocated) { + VCD_MSG_ERROR("\n Allocated buffers are not freed yet"); + return VCD_ERR_ILLEGAL_OP; + } + vcd_destroy_client_context(cctxt); + return rc; +} + +static u32 vcd_close_in_invalid(struct vcd_clnt_ctxt *cctxt) +{ + VCD_MSG_LOW("vcd_close_in_invalid:"); + if (cctxt->in_buf_pool.allocated || + cctxt->out_buf_pool.allocated){ + VCD_MSG_ERROR("Allocated buffers are not freed yet"); + return VCD_ERR_ILLEGAL_OP; + } + + if (cctxt->status.mask & VCD_CLEANING_UP) + cctxt->status.mask |= VCD_CLOSE_PENDING; + else + vcd_destroy_client_context(cctxt); + return VCD_S_SUCCESS; +} + +static u32 vcd_start_in_run_cmn(struct vcd_clnt_ctxt *cctxt) +{ + VCD_MSG_LOW("vcd_start_in_run_cmn:"); + cctxt->callback(VCD_EVT_RESP_START, VCD_S_SUCCESS, NULL, 0, + cctxt, cctxt->client_data); + return VCD_S_SUCCESS; + +} + +static u32 vcd_encode_start_in_open(struct vcd_clnt_ctxt *cctxt) +{ + u32 rc = VCD_S_SUCCESS; + struct vcd_property_hdr prop_hdr; + struct vcd_property_vop_timing timing; + + VCD_MSG_LOW("vcd_encode_start_in_open:"); + + if (cctxt->decoding) { + VCD_MSG_ERROR("vcd_encode_init for decoder client"); + + return VCD_ERR_ILLEGAL_OP; + } + + if ((!cctxt->meta_mode && !cctxt->in_buf_pool.entries) || + !cctxt->out_buf_pool.entries || + (!cctxt->meta_mode && + cctxt->in_buf_pool.validated != cctxt->in_buf_pool.count) || + cctxt->out_buf_pool.validated != + cctxt->out_buf_pool.count) { + VCD_MSG_HIGH("%s: Buffer pool is not completely setup yet", + __func__); + } + + rc = vcd_sched_add_client(cctxt); + VCD_FAILED_RETURN(rc, "Failed: vcd_sched_add_client"); + + prop_hdr.prop_id = VCD_I_VOP_TIMING; + prop_hdr.sz = sizeof(struct vcd_property_vop_timing); + rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr, &timing); + + VCD_FAILED_RETURN(rc, "Failed: Get VCD_I_VOP_TIMING"); + if (!timing.vop_time_resolution) { + VCD_MSG_ERROR("Vop_time_resolution value is zero"); + return VCD_ERR_FAIL; + } + cctxt->time_resoln = timing.vop_time_resolution; + + rc = vcd_process_cmd_sess_start(cctxt); + + if (!VCD_FAILED(rc)) { + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_STARTING, + CLIENT_STATE_EVENT_NUMBER + (encode_start)); + } + + return rc; +} + +static u32 vcd_encode_start_in_run(struct vcd_clnt_ctxt + *cctxt) +{ + VCD_MSG_LOW("vcd_encode_start_in_run:"); + (void) vcd_start_in_run_cmn(cctxt); + return VCD_S_SUCCESS; +} + + +static u32 vcd_encode_frame_cmn(struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *input_frame) +{ + VCD_MSG_LOW("vcd_encode_frame_cmn in %d:", cctxt->clnt_state.state); + + if (cctxt->decoding) { + VCD_MSG_ERROR("vcd_encode_frame for decoder client"); + + return VCD_ERR_ILLEGAL_OP; + } + + return vcd_handle_input_frame(cctxt, input_frame); +} + +static u32 vcd_decode_start_in_open + (struct vcd_clnt_ctxt *cctxt, + struct vcd_sequence_hdr *seq_hdr) +{ + u32 rc = VCD_S_SUCCESS; + + VCD_MSG_LOW("vcd_decode_start_in_open:"); + + if (!cctxt->decoding) { + VCD_MSG_ERROR("vcd_decode_init for encoder client"); + + return VCD_ERR_ILLEGAL_OP; + } + + if (seq_hdr) { + VCD_MSG_HIGH("Seq hdr supplied. len = %d", + seq_hdr->sequence_header_len); + + rc = vcd_store_seq_hdr(cctxt, seq_hdr); + + } else { + VCD_MSG_HIGH("Seq hdr not supplied"); + + cctxt->seq_hdr.sequence_header_len = 0; + cctxt->seq_hdr.sequence_header = NULL; + } + + VCD_FAILED_RETURN(rc, "Err processing seq hdr"); + + rc = vcd_process_cmd_sess_start(cctxt); + + if (!VCD_FAILED(rc)) { + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_STARTING, + CLIENT_STATE_EVENT_NUMBER + (decode_start)); + } + + return rc; +} + +static u32 vcd_decode_start_in_run(struct vcd_clnt_ctxt *cctxt, + struct vcd_sequence_hdr *seqhdr) +{ + VCD_MSG_LOW("vcd_decode_start_in_run:"); + (void) vcd_start_in_run_cmn(cctxt); + return VCD_S_SUCCESS; +} + +static u32 vcd_decode_frame_cmn + (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *input_frame) +{ + VCD_MSG_LOW("vcd_decode_frame_cmn in %d:", cctxt->clnt_state.state); + + if (!cctxt->decoding) { + VCD_MSG_ERROR("Decode_frame api called for Encoder client"); + + return VCD_ERR_ILLEGAL_OP; + } + + return vcd_handle_input_frame(cctxt, input_frame); +} + +static u32 vcd_pause_in_run(struct vcd_clnt_ctxt *cctxt) +{ + u32 rc = VCD_S_SUCCESS; + + VCD_MSG_LOW("vcd_pause_in_run:"); + + if (cctxt->sched_clnt_hdl) { + rc = vcd_sched_suspend_resume_clnt(cctxt, false); + VCD_FAILED_RETURN(rc, "Failed: vcd_sched_suspend_resume_clnt"); + } + + if (cctxt->status.frame_submitted > 0) { + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_PAUSING, + CLIENT_STATE_EVENT_NUMBER + (pause)); + + } else { + VCD_MSG_HIGH("No client frames are currently being processed"); + + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_PAUSED, + CLIENT_STATE_EVENT_NUMBER + (pause)); + + cctxt->callback(VCD_EVT_RESP_PAUSE, + VCD_S_SUCCESS, + NULL, 0, cctxt, cctxt->client_data); + + rc = vcd_power_event(cctxt->dev_ctxt, cctxt, + VCD_EVT_PWR_CLNT_PAUSE); + + if (VCD_FAILED(rc)) + VCD_MSG_ERROR("VCD_EVT_PWR_CLNT_PAUSE_END failed"); + + } + + return VCD_S_SUCCESS; +} + +static u32 vcd_resume_in_paused(struct vcd_clnt_ctxt *cctxt) +{ + struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; + u32 rc = VCD_S_SUCCESS; + + VCD_MSG_LOW("vcd_resume_in_paused:"); + + + if (cctxt->sched_clnt_hdl) { + rc = vcd_power_event(cctxt->dev_ctxt, + cctxt, VCD_EVT_PWR_CLNT_RESUME); + + if (VCD_FAILED(rc)) { + VCD_MSG_ERROR("VCD_EVT_PWR_CLNT_RESUME failed"); + } else { + rc = vcd_sched_suspend_resume_clnt(cctxt, true); + if (VCD_FAILED(rc)) { + VCD_MSG_ERROR + ("rc = 0x%x. Failed: " + "vcd_sched_suspend_resume_clnt", + rc); + } + + } + if (!VCD_FAILED(rc)) { + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_RUN, + CLIENT_STATE_EVENT_NUMBER + (resume)); + vcd_try_submit_frame(dev_ctxt); + } + } else { + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_RUN, + CLIENT_STATE_EVENT_NUMBER + (resume)); + } + + return rc; +} + +static u32 vcd_flush_cmn(struct vcd_clnt_ctxt *cctxt, u32 mode) +{ + u32 rc = VCD_S_SUCCESS; + + VCD_MSG_LOW("vcd_flush_cmn in %d:", cctxt->clnt_state.state); + + rc = vcd_flush_buffers(cctxt, mode); + + VCD_FAILED_RETURN(rc, "Failed: vcd_flush_buffers"); + + if (cctxt->status.frame_submitted > 0) { + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_FLUSHING, + CLIENT_STATE_EVENT_NUMBER + (flush)); + } else { + VCD_MSG_HIGH("All buffers are flushed"); + cctxt->status.mask |= (mode & VCD_FLUSH_ALL); + vcd_send_flush_done(cctxt, VCD_S_SUCCESS); + } + + return rc; +} + +static u32 vcd_flush_inopen(struct vcd_clnt_ctxt *cctxt, + u32 mode) +{ + VCD_MSG_LOW("vcd_flush_inopen:"); + cctxt->status.mask |= (mode & VCD_FLUSH_ALL); + vcd_send_flush_done(cctxt, VCD_S_SUCCESS); + return VCD_S_SUCCESS; +} + +static u32 vcd_flush_in_flushing + (struct vcd_clnt_ctxt *cctxt, u32 mode) +{ + u32 rc = VCD_S_SUCCESS; + + VCD_MSG_LOW("vcd_flush_in_flushing:"); + + rc = vcd_flush_buffers(cctxt, mode); + + return rc; +} + +static u32 vcd_flush_in_eos(struct vcd_clnt_ctxt *cctxt, + u32 mode) +{ + u32 rc = VCD_S_SUCCESS; + VCD_MSG_LOW("vcd_flush_in_eos:"); + + if (mode > VCD_FLUSH_ALL || !mode) { + VCD_MSG_ERROR("Invalid flush mode %d", mode); + + return VCD_ERR_ILLEGAL_PARM; + } + + VCD_MSG_MED("Flush mode requested %d", mode); + if (!(cctxt->status.frame_submitted) && + (!cctxt->decoding)) { + rc = vcd_flush_buffers(cctxt, mode); + if (!VCD_FAILED(rc)) { + VCD_MSG_HIGH("All buffers are flushed"); + cctxt->status.mask |= (mode & VCD_FLUSH_ALL); + vcd_send_flush_done(cctxt, VCD_S_SUCCESS); + } + } else + cctxt->status.mask |= (mode & VCD_FLUSH_ALL); + + return rc; +} + +static u32 vcd_flush_in_invalid(struct vcd_clnt_ctxt *cctxt, + u32 mode) +{ + u32 rc = VCD_S_SUCCESS; + VCD_MSG_LOW("vcd_flush_in_invalid:"); + if (!(cctxt->status.mask & VCD_CLEANING_UP)) { + rc = vcd_flush_buffers(cctxt, mode); + if (!VCD_FAILED(rc)) { + VCD_MSG_HIGH("All buffers are flushed"); + cctxt->status.mask |= (mode & VCD_FLUSH_ALL); + vcd_send_flush_done(cctxt, VCD_S_SUCCESS); + } + } else + cctxt->status.mask |= (mode & VCD_FLUSH_ALL); + return rc; +} + +static u32 vcd_stop_cmn(struct vcd_clnt_ctxt *cctxt) +{ + struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; + u32 rc = VCD_S_SUCCESS; + struct vcd_transc *transc; + + VCD_MSG_LOW("vcd_stop_cmn in %d:", cctxt->clnt_state.state); + + rc = vcd_flush_buffers(cctxt, VCD_FLUSH_ALL); + + VCD_FAILED_RETURN(rc, "Failed: vcd_flush_buffers"); + + if (!cctxt->status.frame_submitted) { + + if (vcd_get_command_channel(dev_ctxt, &transc)) { + rc = vcd_power_event(dev_ctxt, cctxt, + VCD_EVT_PWR_CLNT_CMD_BEGIN); + + if (!VCD_FAILED(rc)) { + transc->type = VCD_CMD_CODEC_STOP; + transc->cctxt = cctxt; + + rc = vcd_submit_cmd_sess_end(transc); + } else { + VCD_MSG_ERROR("Failed:" + " VCD_EVT_PWR_CLNT_CMD_BEGIN"); + } + + if (VCD_FAILED(rc)) { + vcd_release_command_channel(dev_ctxt, + transc); + } + + } else { + vcd_client_cmd_flush_and_en_q(cctxt, + VCD_CMD_CODEC_STOP); + } + } + + if (VCD_FAILED(rc)) { + (void)vcd_power_event(dev_ctxt, cctxt, + VCD_EVT_PWR_CLNT_CMD_FAIL); + } else { + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_STOPPING, + CLIENT_STATE_EVENT_NUMBER + (stop)); + } + + return rc; +} + + +static u32 vcd_stop_inopen(struct vcd_clnt_ctxt *cctxt) +{ + VCD_MSG_LOW("vcd_stop_inopen:"); + + cctxt->callback(VCD_EVT_RESP_STOP, VCD_S_SUCCESS, + NULL, 0, cctxt, + cctxt->client_data); + + return VCD_S_SUCCESS; +} + +static u32 vcd_stop_in_run(struct vcd_clnt_ctxt *cctxt) +{ + u32 rc = VCD_S_SUCCESS; + VCD_MSG_LOW("vcd_stop_in_run:"); + rc = vcd_stop_cmn(cctxt); + if (!VCD_FAILED(rc) && + (cctxt->status.mask & VCD_FIRST_IP_RCVD)) { + rc = vcd_power_event(cctxt->dev_ctxt, + cctxt, VCD_EVT_PWR_CLNT_LAST_FRAME); + } + return rc; +} + +static u32 vcd_stop_in_eos(struct vcd_clnt_ctxt *cctxt) +{ + u32 rc = VCD_S_SUCCESS; + VCD_MSG_LOW("vcd_stop_in_eos:"); + if (cctxt->status.mask & VCD_EOS_WAIT_OP_BUF) { + rc = vcd_stop_cmn(cctxt); + if (!VCD_FAILED(rc)) { + rc = vcd_power_event(cctxt->dev_ctxt, + cctxt, VCD_EVT_PWR_CLNT_LAST_FRAME); + cctxt->status.mask &= ~VCD_EOS_WAIT_OP_BUF; + } + } else + cctxt->status.mask |= VCD_STOP_PENDING; + return rc; +} + +static u32 vcd_stop_in_invalid(struct vcd_clnt_ctxt *cctxt) +{ + VCD_MSG_LOW("vcd_stop_in_invalid:"); + if (cctxt->status.mask & VCD_CLEANING_UP) { + cctxt->status.mask |= VCD_STOP_PENDING; + } else { + (void) vcd_flush_buffers(cctxt, VCD_FLUSH_ALL); + cctxt->callback(VCD_EVT_RESP_STOP, VCD_S_SUCCESS, NULL, + 0, cctxt, cctxt->client_data); + } + return VCD_S_SUCCESS; +} + +static u32 vcd_set_property_cmn + (struct vcd_clnt_ctxt *cctxt, + struct vcd_property_hdr *prop_hdr, void *prop_val) +{ + u32 rc; + VCD_MSG_LOW("vcd_set_property_cmn in %d:", cctxt->clnt_state.state); + VCD_MSG_LOW("property Id = %d", prop_hdr->prop_id); + if (!prop_hdr->sz || !prop_hdr->prop_id) { + VCD_MSG_MED("Bad parameters"); + return VCD_ERR_ILLEGAL_PARM; + } + + rc = ddl_set_property(cctxt->ddl_handle, prop_hdr, prop_val); + if (rc) { + /* Some properties aren't known to ddl that we can handle */ + if (prop_hdr->prop_id != VCD_I_VOP_TIMING_CONSTANT_DELTA) + VCD_FAILED_RETURN(rc, "Failed: ddl_set_property"); + } + + switch (prop_hdr->prop_id) { + case VCD_I_META_BUFFER_MODE: + { + struct vcd_property_live *live = + (struct vcd_property_live *)prop_val; + cctxt->meta_mode = live->live; + break; + } + case VCD_I_LIVE: + { + struct vcd_property_live *live = + (struct vcd_property_live *)prop_val; + cctxt->live = live->live; + break; + } + case VCD_I_FRAME_RATE: + { + if (cctxt->sched_clnt_hdl) { + rc = vcd_set_frame_rate(cctxt, + (struct vcd_property_frame_rate *) + prop_val); + } + break; + } + case VCD_I_FRAME_SIZE: + { + if (cctxt->sched_clnt_hdl) { + rc = vcd_set_frame_size(cctxt, + (struct vcd_property_frame_size *) + prop_val); + } + break; + } + case VCD_I_INTRA_PERIOD: + { + struct vcd_property_i_period *iperiod = + (struct vcd_property_i_period *)prop_val; + cctxt->bframe = iperiod->b_frames; + break; + } + case VCD_REQ_PERF_LEVEL: + rc = vcd_req_perf_level(cctxt, + (struct vcd_property_perf_level *)prop_val); + break; + case VCD_I_VOP_TIMING_CONSTANT_DELTA: + { + struct vcd_property_vop_timing_constant_delta *delta = + prop_val; + + if (delta->constant_delta > 0) { + cctxt->time_frame_delta = delta->constant_delta; + rc = VCD_S_SUCCESS; + } else { + VCD_MSG_ERROR("Frame delta must be positive"); + rc = VCD_ERR_ILLEGAL_PARM; + } + break; + } + default: + { + break; + } + } + return rc; +} + +static u32 vcd_get_property_cmn + (struct vcd_clnt_ctxt *cctxt, + struct vcd_property_hdr *prop_hdr, void *prop_val) +{ + int rc; + VCD_MSG_LOW("vcd_get_property_cmn in %d:", cctxt->clnt_state.state); + VCD_MSG_LOW("property Id = %d", prop_hdr->prop_id); + if (!prop_hdr->sz || !prop_hdr->prop_id) { + VCD_MSG_MED("Bad parameters"); + + return VCD_ERR_ILLEGAL_PARM; + } + rc = ddl_get_property(cctxt->ddl_handle, prop_hdr, prop_val); + if (rc) { + /* Some properties aren't known to ddl that we can handle */ + if (prop_hdr->prop_id != VCD_I_VOP_TIMING_CONSTANT_DELTA) + VCD_FAILED_RETURN(rc, "Failed: ddl_set_property"); + } + + switch (prop_hdr->prop_id) { + case VCD_I_VOP_TIMING_CONSTANT_DELTA: + { + struct vcd_property_vop_timing_constant_delta *delta = + (struct vcd_property_vop_timing_constant_delta *) + prop_val; + delta->constant_delta = cctxt->time_frame_delta; + rc = VCD_S_SUCCESS; + } + } + return rc; +} + +static u32 vcd_set_buffer_requirements_cmn + (struct vcd_clnt_ctxt *cctxt, + enum vcd_buffer_type buffer, + struct vcd_buffer_requirement *buffer_req) +{ + struct vcd_property_hdr Prop_hdr; + u32 rc = VCD_S_SUCCESS; + struct vcd_buffer_pool *buf_pool; + u32 first_frm_recvd = 0; + + VCD_MSG_LOW("vcd_set_buffer_requirements_cmn in %d:", + cctxt->clnt_state.state); + + if (!cctxt->decoding && + cctxt->clnt_state.state != VCD_CLIENT_STATE_OPEN) { + VCD_MSG_ERROR("Bad state (%d) for encoder", + cctxt->clnt_state.state); + + return VCD_ERR_BAD_STATE; + } + + VCD_MSG_MED("Buffer type = %d", buffer); + + if (buffer == VCD_BUFFER_INPUT) { + Prop_hdr.prop_id = DDL_I_INPUT_BUF_REQ; + buf_pool = &cctxt->in_buf_pool; + first_frm_recvd = VCD_FIRST_IP_RCVD; + } else if (buffer == VCD_BUFFER_OUTPUT) { + Prop_hdr.prop_id = DDL_I_OUTPUT_BUF_REQ; + buf_pool = &cctxt->out_buf_pool; + first_frm_recvd = VCD_FIRST_OP_RCVD; + } else { + rc = VCD_ERR_ILLEGAL_PARM; + } + + VCD_FAILED_RETURN(rc, "Invalid buffer type provided"); + + if (buf_pool->validated > 0) { + VCD_MSG_ERROR("Need to free allocated buffers"); + return VCD_ERR_ILLEGAL_OP; + } + + first_frm_recvd &= cctxt->status.mask; + if (first_frm_recvd) { + VCD_MSG_ERROR("VCD SetBufReq called when data path is active"); + return VCD_ERR_BAD_STATE; + } + Prop_hdr.sz = sizeof(*buffer_req); + rc = ddl_set_property(cctxt->ddl_handle, &Prop_hdr, buffer_req); + VCD_FAILED_RETURN(rc, "Failed: ddl_set_property"); + if (buf_pool->entries) { + VCD_MSG_MED("Resetting buffer requirements"); + vcd_free_buffer_pool_entries(buf_pool); + } + return rc; +} + +static u32 vcd_get_buffer_requirements_cmn + (struct vcd_clnt_ctxt *cctxt, + enum vcd_buffer_type buffer, + struct vcd_buffer_requirement *buffer_req) +{ + struct vcd_property_hdr Prop_hdr; + u32 rc = VCD_S_SUCCESS; + + VCD_MSG_LOW("vcd_get_buffer_requirements_cmn in %d:", + cctxt->clnt_state.state); + + VCD_MSG_MED("Buffer type = %d", buffer); + + if (buffer == VCD_BUFFER_INPUT) + Prop_hdr.prop_id = DDL_I_INPUT_BUF_REQ; + else if (buffer == VCD_BUFFER_OUTPUT) + Prop_hdr.prop_id = DDL_I_OUTPUT_BUF_REQ; + else + rc = VCD_ERR_ILLEGAL_PARM; + + VCD_FAILED_RETURN(rc, "Invalid buffer type provided"); + + Prop_hdr.sz = sizeof(*buffer_req); + + return ddl_get_property(cctxt->ddl_handle, &Prop_hdr, buffer_req); + +} + +static u32 vcd_set_buffer_cmn + (struct vcd_clnt_ctxt *cctxt, + enum vcd_buffer_type buffer_type, u8 *buffer, u32 buf_size) +{ + u32 rc; + struct vcd_buffer_pool *buf_pool; + + VCD_MSG_LOW("vcd_set_buffer_cmn in %d:", cctxt->clnt_state.state); + + rc = vcd_common_allocate_set_buffer(cctxt, buffer_type, buf_size, + &buf_pool); + + if (!VCD_FAILED(rc)) { + rc = vcd_set_buffer_internal(cctxt, buf_pool, buffer, + buf_size); + } + + return rc; +} + +static u32 vcd_allocate_buffer_cmn + (struct vcd_clnt_ctxt *cctxt, + enum vcd_buffer_type buffer, + u32 buf_size, u8 **vir_buf_addr, u8 **phy_buf_addr) +{ + u32 rc; + struct vcd_buffer_pool *buf_pool; + + VCD_MSG_LOW("vcd_allocate_buffer_cmn in %d:", + cctxt->clnt_state.state); + + rc = vcd_common_allocate_set_buffer(cctxt, buffer, buf_size, + &buf_pool); + + if (!VCD_FAILED(rc)) { + rc = vcd_allocate_buffer_internal(cctxt, + buf_pool, + buf_size, + vir_buf_addr, + phy_buf_addr); + } + + return rc; +} + +static u32 vcd_free_buffer_cmn + (struct vcd_clnt_ctxt *cctxt, + enum vcd_buffer_type buffer_type, u8 *buffer) +{ + + VCD_MSG_LOW("vcd_free_buffer_cmn in %d:", cctxt->clnt_state.state); + + return vcd_free_one_buffer_internal(cctxt, buffer_type, buffer); +} + +static u32 vcd_fill_output_buffer_cmn + (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *buffer) +{ + u32 rc = VCD_S_SUCCESS; + struct vcd_buffer_entry *buf_entry; + u32 result = true; + u32 handled = true; + if (!cctxt || !buffer) { + VCD_MSG_ERROR("%s(): Inavlid params cctxt %p buffer %p", + __func__, cctxt, buffer); + return VCD_ERR_BAD_POINTER; + } + VCD_MSG_LOW("vcd_fill_output_buffer_cmn in %d:", + cctxt->clnt_state.state); + if (cctxt->status.mask & VCD_IN_RECONFIG) { + buffer->time_stamp = 0; + buffer->data_len = 0; + VCD_MSG_LOW("In reconfig: Return output buffer"); + cctxt->callback(VCD_EVT_RESP_OUTPUT_DONE, + VCD_S_SUCCESS, + buffer, + sizeof(struct vcd_frame_data), + cctxt, cctxt->client_data); + return rc; + } + buf_entry = vcd_check_fill_output_buffer(cctxt, buffer); + if (!buf_entry) + return VCD_ERR_BAD_POINTER; + + if (!(cctxt->status.mask & VCD_FIRST_OP_RCVD)) { + rc = vcd_handle_first_fill_output_buffer(cctxt, buffer, + &handled); + VCD_FAILED_RETURN(rc, + "Failed: vcd_handle_first_fill_output_buffer"); + if (handled) + return rc ; + } + + result = + vcd_buffer_pool_entry_en_q(&cctxt->out_buf_pool, buf_entry); + + if (!result && !cctxt->decoding) { + VCD_MSG_ERROR("Failed: vcd_buffer_pool_entry_en_q"); + + return VCD_ERR_FAIL; + } + + buf_entry->frame = *buffer; + rc = vcd_return_op_buffer_to_hw(cctxt, buf_entry); + if (!VCD_FAILED(rc) && cctxt->sched_clnt_hdl) { + cctxt->sched_clnt_hdl->tkns++; + vcd_try_submit_frame(cctxt->dev_ctxt); + } + return rc; +} + +static u32 vcd_fill_output_buffer_in_eos + (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *buffer) +{ + u32 rc = VCD_S_SUCCESS; + struct vcd_buffer_entry *buf_entry; + + VCD_MSG_LOW("vcd_fill_output_buffer_in_eos:"); + + buf_entry = vcd_check_fill_output_buffer(cctxt, buffer); + if (!buf_entry) + return VCD_ERR_BAD_POINTER; + + if (cctxt->status.mask & VCD_EOS_WAIT_OP_BUF) { + VCD_MSG_HIGH("Got an output buffer we were waiting for"); + + buf_entry->frame = *buffer; + + buf_entry->frame.data_len = 0; + buf_entry->frame.flags |= VCD_FRAME_FLAG_EOS; + buf_entry->frame.ip_frm_tag = + cctxt->status.eos_trig_ip_frm.ip_frm_tag; + buf_entry->frame.time_stamp = + cctxt->status.eos_trig_ip_frm.time_stamp; + + cctxt->callback(VCD_EVT_RESP_OUTPUT_DONE, + VCD_S_SUCCESS, + &buf_entry->frame, + sizeof(struct vcd_frame_data), + cctxt, cctxt->client_data); + + cctxt->status.mask &= ~VCD_EOS_WAIT_OP_BUF; + + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_RUN, + CLIENT_STATE_EVENT_NUMBER + (fill_output_buffer)); + + } else { + rc = vcd_fill_output_buffer_cmn(cctxt, buffer); + } + + return rc; +} + +static void vcd_clnt_cb_in_starting + (struct vcd_clnt_ctxt *cctxt, + u32 event, u32 status, void *payload, size_t sz, + u32 *ddl_handle, void *const client_data) +{ + struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; + struct vcd_transc *transc = + (struct vcd_transc *)client_data; + VCD_MSG_LOW("vcd_clnt_cb_in_starting:"); + if (cctxt->ddl_handle != ddl_handle) { + VCD_MSG_ERROR("vcd_clnt_cb_in_initing: Wrong DDL handle %p", + ddl_handle); + return; + } + + switch (event) { + case VCD_EVT_RESP_START: + { + vcd_handle_start_done(cctxt, + (struct vcd_transc *)client_data, + status); + break; + } + case VCD_EVT_RESP_STOP: + { + vcd_handle_stop_done_in_starting(cctxt, + (struct vcd_transc *)client_data, + status); + break; + } + case VCD_EVT_IND_HWERRFATAL: + { + cctxt->status.cmd_submitted--; + vcd_mark_command_channel(cctxt->dev_ctxt, transc); + vcd_handle_err_fatal(cctxt, VCD_EVT_RESP_START, + status); + break; + } + default: + { + VCD_MSG_ERROR("Unexpected callback event=%d status=%d " + "from DDL", event, status); + dev_ctxt->command_continue = false; + break; + } + } +} + +static void vcd_clnt_cb_in_run + (struct vcd_clnt_ctxt *cctxt, + u32 event, + u32 status, + void *payload, size_t sz, u32 *ddl_handle, void *const client_data) +{ + struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; + u32 rc = VCD_S_SUCCESS; + + if (cctxt->ddl_handle != ddl_handle) { + VCD_MSG_ERROR("ddl_handle mismatch"); + + return; + } + + switch (event) { + case VCD_EVT_RESP_INPUT_DONE: + { + rc = vcd_handle_input_done(cctxt, payload, event, + status); + + break; + } + + case VCD_EVT_RESP_OUTPUT_DONE: + { + + rc = vcd_handle_frame_done(cctxt, payload, event, + status); + + break; + } + case VCD_EVT_RESP_OUTPUT_REQ: + { + rc = vcd_handle_output_required(cctxt, payload, + status); + break; + } + + case VCD_EVT_IND_OUTPUT_RECONFIG: + { + rc = vcd_handle_ind_output_reconfig(cctxt, payload, + status); + break; + } + case VCD_EVT_RESP_TRANSACTION_PENDING: + { + vcd_handle_trans_pending(cctxt); + break; + } + + case VCD_EVT_IND_HWERRFATAL: + { + vcd_handle_ind_hw_err_fatal(cctxt, + VCD_EVT_IND_HWERRFATAL, status); + break; + } + case VCD_EVT_IND_INFO_OUTPUT_RECONFIG: + { + vcd_handle_ind_info_output_reconfig(cctxt, status); + break; + } + default: + { + VCD_MSG_ERROR + ("Unexpected callback event=%d status=%d from DDL", + event, status); + dev_ctxt->command_continue = false; + + break; + } + } + + if (!VCD_FAILED(rc) && + (event == VCD_EVT_RESP_INPUT_DONE || + event == VCD_EVT_RESP_OUTPUT_DONE || + event == VCD_EVT_RESP_OUTPUT_REQ)) { + + if (((struct ddl_frame_data_tag *) + payload)->frm_trans_end) + vcd_mark_frame_channel(cctxt->dev_ctxt); + } +} + +static void vcd_clnt_cb_in_eos + (struct vcd_clnt_ctxt *cctxt, + u32 event, + u32 status, + void *payload, size_t sz, u32 *ddl_handle, void *const client_data) { + struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; + struct vcd_transc *transc = NULL; + u32 frm_trans_end = false, rc = VCD_S_SUCCESS; + + if (cctxt->ddl_handle != ddl_handle) { + VCD_MSG_ERROR("ddl_handle mismatch"); + + return; + } + + switch (event) { + case VCD_EVT_RESP_INPUT_DONE: + { + rc = vcd_handle_input_done_in_eos(cctxt, payload, + status); + + break; + } + + case VCD_EVT_RESP_OUTPUT_DONE: + { + rc = vcd_handle_frame_done_in_eos(cctxt, payload, + status); + + break; + } + case VCD_EVT_RESP_OUTPUT_REQ: + { + rc = vcd_handle_output_required(cctxt, payload, + status); + break; + } + case VCD_EVT_RESP_EOS_DONE: + { + transc = (struct vcd_transc *)client_data; + vcd_handle_eos_done(cctxt, transc, status); + vcd_mark_frame_channel(cctxt->dev_ctxt); + break; + } + case VCD_EVT_IND_OUTPUT_RECONFIG: + { + rc = vcd_handle_ind_output_reconfig(cctxt, + payload, status); + if (!VCD_FAILED(rc)) { + frm_trans_end = true; + payload = NULL; + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_RUN, + CLIENT_STATE_EVENT_NUMBER + (clnt_cb)); + VCD_MSG_LOW + ("RECONFIGinEOS:Suspending Client"); + rc = vcd_sched_suspend_resume_clnt(cctxt, + false); + if (VCD_FAILED(rc)) { + VCD_MSG_ERROR + ("Failed: suspend_resume_clnt. rc=0x%x", + rc); + } + } + break; + } + case VCD_EVT_IND_HWERRFATAL: + { + vcd_handle_ind_hw_err_fatal(cctxt, + VCD_EVT_IND_HWERRFATAL, status); + break; + } + case VCD_EVT_IND_INFO_OUTPUT_RECONFIG: + { + vcd_handle_ind_info_output_reconfig(cctxt, status); + break; + } + default: + { + VCD_MSG_ERROR + ("Unexpected callback event=%d status=%d from DDL", + event, status); + + dev_ctxt->command_continue = false; + + break; + } + + } + if (!VCD_FAILED(rc) && + (event == VCD_EVT_RESP_INPUT_DONE || + event == VCD_EVT_RESP_OUTPUT_DONE || + event == VCD_EVT_RESP_OUTPUT_REQ || + event == VCD_EVT_IND_OUTPUT_RECONFIG)) { + if (payload && ((struct ddl_frame_data_tag *) + payload)->frm_trans_end) { + vcd_mark_frame_channel(cctxt->dev_ctxt); + frm_trans_end = true; + } + if (frm_trans_end && !cctxt->status.frame_submitted) + vcd_handle_eos_trans_end(cctxt); + } +} + +static void vcd_clnt_cb_in_flushing + (struct vcd_clnt_ctxt *cctxt, + u32 event, + u32 status, + void *payload, size_t sz, u32 *ddl_handle, void *const client_data) { + struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; + u32 rc = VCD_S_SUCCESS; + u32 frm_trans_end = false; + + VCD_MSG_LOW("vcd_clnt_cb_in_flushing:"); + + if (cctxt->ddl_handle != ddl_handle) { + VCD_MSG_ERROR("ddl_handle mismatch"); + + return; + } + + switch (event) { + case VCD_EVT_RESP_INPUT_DONE: + { + rc = vcd_handle_input_done(cctxt, + payload, + VCD_EVT_RESP_INPUT_FLUSHED, + status); + + break; + } + + case VCD_EVT_RESP_OUTPUT_DONE: + { + + rc = vcd_handle_frame_done(cctxt, + payload, + VCD_EVT_RESP_OUTPUT_FLUSHED, + status); + + break; + } + case VCD_EVT_RESP_OUTPUT_REQ: + { + rc = vcd_handle_output_required_in_flushing(cctxt, + payload); + break; + } + case VCD_EVT_IND_OUTPUT_RECONFIG: + { + rc = vcd_handle_ind_output_reconfig(cctxt, + payload, status); + if (!VCD_FAILED(rc)) { + frm_trans_end = true; + payload = NULL; + } + break; + } + case VCD_EVT_IND_HWERRFATAL: + { + vcd_handle_ind_hw_err_fatal(cctxt, + VCD_EVT_IND_HWERRFATAL, status); + break; + } + default: + { + VCD_MSG_ERROR + ("Unexpected callback event=%d status=%d from DDL", + event, status); + + dev_ctxt->command_continue = false; + + break; + } + } + if (!VCD_FAILED(rc) && ((event == VCD_EVT_RESP_INPUT_DONE || + event == VCD_EVT_RESP_OUTPUT_DONE || + event == VCD_EVT_RESP_OUTPUT_REQ || + event == VCD_EVT_IND_OUTPUT_RECONFIG))) { + if (payload && + ((struct ddl_frame_data_tag *)\ + payload)->frm_trans_end) { + + vcd_mark_frame_channel(cctxt->dev_ctxt); + frm_trans_end = true; + } + if (frm_trans_end && !cctxt->status.frame_submitted) { + VCD_MSG_HIGH + ("All pending frames recvd from DDL"); + if (cctxt->status.mask & VCD_FLUSH_INPUT) + vcd_flush_bframe_buffers(cctxt, + VCD_FLUSH_INPUT); + if (cctxt->status.mask & VCD_FLUSH_OUTPUT) + vcd_flush_output_buffers(cctxt); + vcd_send_flush_done(cctxt, VCD_S_SUCCESS); + vcd_release_interim_frame_channels(dev_ctxt); + VCD_MSG_HIGH("Flush complete"); + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_RUN, + CLIENT_STATE_EVENT_NUMBER + (clnt_cb)); + } + } +} + +static void vcd_clnt_cb_in_stopping + (struct vcd_clnt_ctxt *cctxt, + u32 event, + u32 status, + void *payload, size_t sz, u32 *ddl_handle, void *const client_data) { + struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; + u32 rc = VCD_S_SUCCESS; + u32 frm_trans_end = false; + + VCD_MSG_LOW("vcd_clnt_cb_in_stopping:"); + + if (cctxt->ddl_handle != ddl_handle) { + VCD_MSG_ERROR("ddl_handle mismatch"); + + return; + } + + switch (event) { + + case VCD_EVT_RESP_INPUT_DONE: + { + rc = vcd_handle_input_done(cctxt, + payload, + VCD_EVT_RESP_INPUT_FLUSHED, + status); + + break; + } + + case VCD_EVT_RESP_OUTPUT_DONE: + { + + rc = vcd_handle_frame_done(cctxt, + payload, + VCD_EVT_RESP_OUTPUT_FLUSHED, + status); + + break; + } + case VCD_EVT_RESP_OUTPUT_REQ: + { + rc = vcd_handle_output_required_in_flushing(cctxt, + payload); + break; + } + case VCD_EVT_RESP_STOP: + { + vcd_handle_stop_done(cctxt, + (struct vcd_transc *) + client_data, status); + + break; + } + case VCD_EVT_IND_OUTPUT_RECONFIG: + { + (void) vcd_handle_ind_output_reconfig(cctxt, + payload, status); + + frm_trans_end = true; + payload = NULL; + + break; + } + case VCD_EVT_IND_HWERRFATAL: + { + vcd_handle_ind_hw_err_fatal(cctxt, VCD_EVT_RESP_STOP, + status); + break; + } + + default: + { + VCD_MSG_ERROR + ("Unexpected callback event=%d status=%d from DDL", + event, status); + + dev_ctxt->command_continue = false; + + break; + } + } + + if (!VCD_FAILED(rc) && ((event == VCD_EVT_RESP_INPUT_DONE || + event == VCD_EVT_RESP_OUTPUT_DONE) || + event == VCD_EVT_RESP_OUTPUT_REQ || + event == VCD_EVT_IND_OUTPUT_RECONFIG)) { + + if (payload && + ((struct ddl_frame_data_tag *)\ + payload)->frm_trans_end) { + + vcd_mark_frame_channel(cctxt->dev_ctxt); + frm_trans_end = true; + } + if (frm_trans_end && !cctxt->status.frame_submitted) { + VCD_MSG_HIGH + ("All pending frames recvd from DDL"); + vcd_flush_bframe_buffers(cctxt, + VCD_FLUSH_INPUT); + vcd_flush_output_buffers(cctxt); + cctxt->status.mask &= ~VCD_FLUSH_ALL; + vcd_release_all_clnt_frm_transc(cctxt); + VCD_MSG_HIGH + ("All buffers flushed. Enqueuing stop cmd"); + vcd_client_cmd_flush_and_en_q(cctxt, + VCD_CMD_CODEC_STOP); + } + } +} + +static void vcd_clnt_cb_in_pausing + (struct vcd_clnt_ctxt *cctxt, + u32 event, + u32 status, + void *payload, size_t sz, u32 *ddl_handle, void *const client_data) +{ + struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; + u32 rc = VCD_S_SUCCESS; + u32 frm_trans_end = false; + + VCD_MSG_LOW("vcd_clnt_cb_in_pausing:"); + + if (cctxt->ddl_handle != ddl_handle) { + VCD_MSG_ERROR("ddl_handle mismatch"); + + return; + } + + switch (event) { + case VCD_EVT_RESP_INPUT_DONE: + { + rc = vcd_handle_input_done(cctxt, payload, event, + status); + + break; + } + + case VCD_EVT_RESP_OUTPUT_DONE: + { + rc = vcd_handle_frame_done(cctxt, payload, event, + status); + break; + } + case VCD_EVT_RESP_OUTPUT_REQ: + { + rc = vcd_handle_output_required(cctxt, payload, + status); + break; + } + case VCD_EVT_IND_OUTPUT_RECONFIG: + { + rc = vcd_handle_ind_output_reconfig(cctxt, + payload, status); + if (!VCD_FAILED(rc)) { + frm_trans_end = true; + payload = NULL; + } + break; + } + case VCD_EVT_IND_HWERRFATAL: + { + vcd_handle_ind_hw_err_fatal(cctxt, + VCD_EVT_RESP_PAUSE, status); + rc = VCD_ERR_FAIL; + break; + } + default: + { + VCD_MSG_ERROR + ("Unexpected callback event=%d status=%d from DDL", + event, status); + + dev_ctxt->command_continue = false; + + break; + } + + } + + if (!VCD_FAILED(rc)) { + + if (payload && + ((struct ddl_frame_data_tag *)\ + payload)->frm_trans_end) { + + vcd_mark_frame_channel(cctxt->dev_ctxt); + frm_trans_end = true; + } + if (frm_trans_end && !cctxt->status.frame_submitted) { + VCD_MSG_HIGH + ("All pending frames recvd from DDL"); + + cctxt->callback(VCD_EVT_RESP_PAUSE, + VCD_S_SUCCESS, + NULL, + 0, + cctxt, + cctxt->client_data); + + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_PAUSED, + CLIENT_STATE_EVENT_NUMBER + (clnt_cb)); + + rc = vcd_power_event(cctxt->dev_ctxt, + cctxt, + VCD_EVT_PWR_CLNT_PAUSE); + + if (VCD_FAILED(rc)) { + VCD_MSG_ERROR + ("VCD_EVT_PWR_CLNT_PAUSE_END" + "failed"); + } + } + } +} + +static void vcd_clnt_cb_in_invalid( + struct vcd_clnt_ctxt *cctxt, u32 event, u32 status, + void *payload, size_t sz, u32 *ddl_handle, + void *const client_data +) +{ + struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; + VCD_MSG_LOW("vcd_clnt_cb_in_invalid:"); + if (cctxt->ddl_handle != ddl_handle) { + VCD_MSG_ERROR("ddl_handle mismatch"); + return; + } + switch (event) { + case VCD_EVT_RESP_STOP: + { + vcd_handle_stop_done_in_invalid(cctxt, + (struct vcd_transc *)client_data, + status); + break; + } + case VCD_EVT_RESP_INPUT_DONE: + case VCD_EVT_RESP_OUTPUT_REQ: + { + if (cctxt->status.frame_submitted) + cctxt->status.frame_submitted--; + if (payload && ((struct ddl_frame_data_tag *) + payload)->frm_trans_end) + vcd_mark_frame_channel(cctxt->dev_ctxt); + break; + } + case VCD_EVT_RESP_OUTPUT_DONE: + { + if (payload && ((struct ddl_frame_data_tag *) + payload)->frm_trans_end) + vcd_mark_frame_channel(cctxt->dev_ctxt); + break; + } + case VCD_EVT_RESP_TRANSACTION_PENDING: + { + if (cctxt->status.frame_submitted) + cctxt->status.frame_submitted--; + vcd_mark_frame_channel(cctxt->dev_ctxt); + break; + } + case VCD_EVT_IND_HWERRFATAL: + { + if (status == VCD_ERR_HW_FATAL) + vcd_handle_stop_done_in_invalid(cctxt, + (struct vcd_transc *)client_data, + status); + + break; + } + case VCD_EVT_RESP_EOS_DONE: + { + vcd_mark_frame_channel(cctxt->dev_ctxt); + break; + } + case VCD_EVT_IND_OUTPUT_RECONFIG: + { + if (cctxt->status.frame_submitted > 0) + cctxt->status.frame_submitted--; + else + cctxt->status.frame_delayed--; + vcd_mark_frame_channel(cctxt->dev_ctxt); + break; + } + default: + { + VCD_MSG_ERROR("Unexpected callback event=%d status=%d" + "from DDL", event, status); + dev_ctxt->command_continue = false; + break; + } + } +} + +static void vcd_clnt_enter_open + (struct vcd_clnt_ctxt *cctxt, s32 state_event) { + VCD_MSG_MED("Entering CLIENT_STATE_OPEN on api %d", state_event); +} + +static void vcd_clnt_enter_starting + (struct vcd_clnt_ctxt *cctxt, s32 state_event) { + VCD_MSG_MED("Entering CLIENT_STATE_STARTING on api %d", + state_event); + cctxt->status.last_evt = VCD_EVT_RESP_START; +} + +static void vcd_clnt_enter_run + (struct vcd_clnt_ctxt *cctxt, s32 state_event) { + VCD_MSG_MED("Entering CLIENT_STATE_RUN on api %d", state_event); +} + +static void vcd_clnt_enter_flushing + (struct vcd_clnt_ctxt *cctxt, s32 state_event) { + VCD_MSG_MED("Entering CLIENT_STATE_FLUSHING on api %d", + state_event); +} + +static void vcd_clnt_enter_stopping + (struct vcd_clnt_ctxt *cctxt, s32 state_event) { + VCD_MSG_MED("Entering CLIENT_STATE_STOPPING on api %d", + state_event); + cctxt->status.last_evt = VCD_EVT_RESP_STOP; +} + +static void vcd_clnt_enter_eos(struct vcd_clnt_ctxt *cctxt, + s32 state_event) +{ + u32 rc; + VCD_MSG_MED("Entering CLIENT_STATE_EOS on api %d", state_event); + rc = vcd_sched_suspend_resume_clnt(cctxt, false); + if (VCD_FAILED(rc)) + VCD_MSG_ERROR("Failed: vcd_sched_suspend_resume_clnt." + "rc=0x%x", rc); +} + +static void vcd_clnt_enter_pausing + (struct vcd_clnt_ctxt *cctxt, s32 state_event) { + VCD_MSG_MED("Entering CLIENT_STATE_PAUSING on api %d", + state_event); + cctxt->status.last_evt = VCD_EVT_RESP_PAUSE; +} + +static void vcd_clnt_enter_paused + (struct vcd_clnt_ctxt *cctxt, s32 state_event) +{ + VCD_MSG_MED("Entering CLIENT_STATE_PAUSED on api %d", + state_event); +} + +static void vcd_clnt_enter_invalid(struct vcd_clnt_ctxt *cctxt, + s32 state_event) +{ + VCD_MSG_MED("Entering CLIENT_STATE_INVALID on api %d", + state_event); + cctxt->ddl_hdl_valid = false; + cctxt->status.mask &= ~(VCD_FIRST_IP_RCVD | VCD_FIRST_OP_RCVD); + if (cctxt->sched_clnt_hdl) + vcd_sched_suspend_resume_clnt(cctxt, false); +} + +static void vcd_clnt_exit_open + (struct vcd_clnt_ctxt *cctxt, s32 state_event) +{ + VCD_MSG_MED("Exiting CLIENT_STATE_OPEN on api %d", state_event); +} + +static void vcd_clnt_exit_starting + (struct vcd_clnt_ctxt *cctxt, s32 state_event) { + VCD_MSG_MED("Exiting CLIENT_STATE_STARTING on api %d", + state_event); + cctxt->status.last_evt = VCD_EVT_RESP_BASE; +} + +static void vcd_clnt_exit_run + (struct vcd_clnt_ctxt *cctxt, s32 state_event) { + VCD_MSG_MED("Exiting CLIENT_STATE_RUN on api %d", state_event); +} + +static void vcd_clnt_exit_flushing + (struct vcd_clnt_ctxt *cctxt, s32 state_event) { + VCD_MSG_MED("Exiting CLIENT_STATE_FLUSHING on api %d", + state_event); +} + +static void vcd_clnt_exit_stopping + (struct vcd_clnt_ctxt *cctxt, s32 state_event) { + VCD_MSG_MED("Exiting CLIENT_STATE_STOPPING on api %d", + state_event); + cctxt->status.last_evt = VCD_EVT_RESP_BASE; +} + +static void vcd_clnt_exit_eos + (struct vcd_clnt_ctxt *cctxt, s32 state_event) +{ + u32 rc; + VCD_MSG_MED("Exiting CLIENT_STATE_EOS on api %d", state_event); + rc = vcd_sched_suspend_resume_clnt(cctxt, true); + if (VCD_FAILED(rc)) + VCD_MSG_ERROR("Failed: vcd_sched_suspend_resume_clnt. rc=0x%x", + rc); +} + +static void vcd_clnt_exit_pausing + (struct vcd_clnt_ctxt *cctxt, s32 state_event) { + VCD_MSG_MED("Exiting CLIENT_STATE_PAUSING on api %d", + state_event); + cctxt->status.last_evt = VCD_EVT_RESP_BASE; +} + +static void vcd_clnt_exit_paused + (struct vcd_clnt_ctxt *cctxt, s32 state_event) { + VCD_MSG_MED("Exiting CLIENT_STATE_PAUSED on api %d", + state_event); +} + +static void vcd_clnt_exit_invalid(struct vcd_clnt_ctxt *cctxt, + s32 state_event) +{ + VCD_MSG_MED("Exiting CLIENT_STATE_INVALID on api %d", + state_event); +} + +void vcd_do_client_state_transition(struct vcd_clnt_ctxt *cctxt, + enum vcd_clnt_state_enum to_state, u32 ev_code) +{ + struct vcd_clnt_state_ctxt *state_ctxt; + + if (!cctxt || to_state >= VCD_CLIENT_STATE_MAX) { + VCD_MSG_ERROR("Bad parameters. cctxt=%p, to_state=%d", + cctxt, to_state); + } + + state_ctxt = &cctxt->clnt_state; + + if (state_ctxt->state == to_state) { + VCD_MSG_HIGH("Client already in requested to_state=%d", + to_state); + + return; + } + + VCD_MSG_MED("vcd_do_client_state_transition: C%d -> C%d, for api %d", + (int)state_ctxt->state, (int)to_state, ev_code); + + if (state_ctxt->state_table->exit) + state_ctxt->state_table->exit(cctxt, ev_code); + + + state_ctxt->state = to_state; + state_ctxt->state_table = vcd_clnt_state_table[to_state]; + + if (state_ctxt->state_table->entry) + state_ctxt->state_table->entry(cctxt, ev_code); +} + +const struct vcd_clnt_state_table *vcd_get_client_state_table + (enum vcd_clnt_state_enum state) { + return vcd_clnt_state_table[state]; +} + +static const struct vcd_clnt_state_table vcd_clnt_table_open = { + { + vcd_close_in_open, + vcd_encode_start_in_open, + NULL, + vcd_decode_start_in_open, + NULL, + NULL, + NULL, + vcd_flush_inopen, + vcd_stop_inopen, + vcd_set_property_cmn, + vcd_get_property_cmn, + vcd_set_buffer_requirements_cmn, + vcd_get_buffer_requirements_cmn, + vcd_set_buffer_cmn, + vcd_allocate_buffer_cmn, + vcd_free_buffer_cmn, + vcd_fill_output_buffer_cmn, + NULL, + }, + vcd_clnt_enter_open, + vcd_clnt_exit_open +}; + +static const struct vcd_clnt_state_table vcd_clnt_table_starting = { + { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + vcd_get_property_cmn, + NULL, + vcd_get_buffer_requirements_cmn, + NULL, + NULL, + NULL, + NULL, + vcd_clnt_cb_in_starting, + }, + vcd_clnt_enter_starting, + vcd_clnt_exit_starting +}; + +static const struct vcd_clnt_state_table vcd_clnt_table_run = { + { + NULL, + vcd_encode_start_in_run, + vcd_encode_frame_cmn, + vcd_decode_start_in_run, + vcd_decode_frame_cmn, + vcd_pause_in_run, + NULL, + vcd_flush_cmn, + vcd_stop_in_run, + vcd_set_property_cmn, + vcd_get_property_cmn, + vcd_set_buffer_requirements_cmn, + vcd_get_buffer_requirements_cmn, + vcd_set_buffer_cmn, + vcd_allocate_buffer_cmn, + vcd_free_buffer_cmn, + vcd_fill_output_buffer_cmn, + vcd_clnt_cb_in_run, + }, + vcd_clnt_enter_run, + vcd_clnt_exit_run +}; + +static const struct vcd_clnt_state_table vcd_clnt_table_flushing = { + { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + vcd_flush_in_flushing, + NULL, + vcd_set_property_cmn, + vcd_get_property_cmn, + NULL, + vcd_get_buffer_requirements_cmn, + NULL, + NULL, + NULL, + vcd_fill_output_buffer_cmn, + vcd_clnt_cb_in_flushing, + }, + vcd_clnt_enter_flushing, + vcd_clnt_exit_flushing +}; + +static const struct vcd_clnt_state_table vcd_clnt_table_stopping = { + { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + vcd_get_property_cmn, + NULL, + vcd_get_buffer_requirements_cmn, + NULL, + NULL, + NULL, + NULL, + vcd_clnt_cb_in_stopping, + }, + vcd_clnt_enter_stopping, + vcd_clnt_exit_stopping +}; + +static const struct vcd_clnt_state_table vcd_clnt_table_eos = { + { + NULL, + NULL, + vcd_encode_frame_cmn, + NULL, + vcd_decode_frame_cmn, + NULL, + NULL, + vcd_flush_in_eos, + vcd_stop_in_eos, + NULL, + vcd_get_property_cmn, + NULL, + vcd_get_buffer_requirements_cmn, + NULL, + NULL, + NULL, + vcd_fill_output_buffer_in_eos, + vcd_clnt_cb_in_eos, + }, + vcd_clnt_enter_eos, + vcd_clnt_exit_eos +}; + +static const struct vcd_clnt_state_table vcd_clnt_table_pausing = { + { + NULL, + NULL, + vcd_encode_frame_cmn, + NULL, + vcd_decode_frame_cmn, + NULL, + NULL, + NULL, + NULL, + vcd_set_property_cmn, + vcd_get_property_cmn, + NULL, + vcd_get_buffer_requirements_cmn, + NULL, + NULL, + NULL, + vcd_fill_output_buffer_cmn, + vcd_clnt_cb_in_pausing, + }, + vcd_clnt_enter_pausing, + vcd_clnt_exit_pausing +}; + +static const struct vcd_clnt_state_table vcd_clnt_table_paused = { + { + NULL, + NULL, + vcd_encode_frame_cmn, + NULL, + vcd_decode_frame_cmn, + NULL, + vcd_resume_in_paused, + vcd_flush_cmn, + vcd_stop_cmn, + vcd_set_property_cmn, + vcd_get_property_cmn, + vcd_set_buffer_requirements_cmn, + vcd_get_buffer_requirements_cmn, + vcd_set_buffer_cmn, + vcd_allocate_buffer_cmn, + NULL, + vcd_fill_output_buffer_cmn, + NULL, + }, + vcd_clnt_enter_paused, + vcd_clnt_exit_paused +}; +static const struct vcd_clnt_state_table vcd_clnt_table_invalid = { + { + vcd_close_in_invalid, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + vcd_flush_in_invalid, + vcd_stop_in_invalid, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + vcd_free_buffer_cmn, + NULL, + vcd_clnt_cb_in_invalid, + }, + vcd_clnt_enter_invalid, + vcd_clnt_exit_invalid +}; + +static const struct vcd_clnt_state_table *vcd_clnt_state_table[] = { + NULL, + &vcd_clnt_table_open, + &vcd_clnt_table_starting, + &vcd_clnt_table_run, + &vcd_clnt_table_flushing, + &vcd_clnt_table_pausing, + &vcd_clnt_table_paused, + &vcd_clnt_table_stopping, + &vcd_clnt_table_eos, + &vcd_clnt_table_invalid +}; diff --git a/drivers/video/msm/vidc/common/vcd/vcd_client_sm.h b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.h new file mode 100644 index 000000000000..ba1884dd601d --- /dev/null +++ b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.h @@ -0,0 +1,110 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#ifndef _VCD_CLIENT_SM_H_ +#define _VCD_CLIENT_SM_H_ +#include +#include "vcd_ddl_api.h" + +struct vcd_clnt_state_table; +struct vcd_clnt_state_ctxt; +struct vcd_clnt_ctxt; + +enum vcd_clnt_state_enum { + VCD_CLIENT_STATE_NULL = 0, + VCD_CLIENT_STATE_OPEN, + VCD_CLIENT_STATE_STARTING, + VCD_CLIENT_STATE_RUN, + VCD_CLIENT_STATE_FLUSHING, + VCD_CLIENT_STATE_PAUSING, + VCD_CLIENT_STATE_PAUSED, + VCD_CLIENT_STATE_STOPPING, + VCD_CLIENT_STATE_EOS, + VCD_CLIENT_STATE_INVALID, + VCD_CLIENT_STATE_MAX, + VCD_CLIENT_STATE_32BIT = 0x7FFFFFFF +}; + +#define CLIENT_STATE_EVENT_NUMBER(ppf) \ + ((u32 *) (&(((struct vcd_clnt_state_table*)0)->ev_hdlr.ppf)) - \ + (u32 *) (&(((struct vcd_clnt_state_table*)0)->ev_hdlr.close)) \ + + 1) + +struct vcd_clnt_state_table { + struct { + u32(*close) (struct vcd_clnt_ctxt *cctxt); + u32(*encode_start) (struct vcd_clnt_ctxt *cctxt); + u32(*encode_frame) (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *input_frame); + u32(*decode_start) (struct vcd_clnt_ctxt *cctxt, + struct vcd_sequence_hdr *seq_hdr); + u32(*decode_frame) (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *input_frame); + u32(*pause) (struct vcd_clnt_ctxt *cctxt); + u32(*resume) (struct vcd_clnt_ctxt *cctxt); + u32(*flush) (struct vcd_clnt_ctxt *cctxt, + u32 mode); + u32(*stop) (struct vcd_clnt_ctxt *cctxt); + u32(*set_property) (struct vcd_clnt_ctxt *cctxt, + struct vcd_property_hdr *prop_hdr, + void *prop); + u32(*get_property) (struct vcd_clnt_ctxt *cctxt, + struct vcd_property_hdr *prop_hdr, + void *prop); + u32(*set_buffer_requirements) (struct vcd_clnt_ctxt * + cctxt, + enum vcd_buffer_type buffer, + struct + vcd_buffer_requirement * + buffer_req); + u32(*get_buffer_requirements) (struct vcd_clnt_ctxt * + cctxt, + enum vcd_buffer_type buffer, + struct + vcd_buffer_requirement * + buffer_req); + u32(*set_buffer) (struct vcd_clnt_ctxt *cctxt, + enum vcd_buffer_type buffer_type, u8 *buffer, + u32 buf_size); + u32(*allocate_buffer) (struct vcd_clnt_ctxt *cctxt, + enum vcd_buffer_type buffer, u32 buf_size, + u8 **vir_buf_addr, u8 **phy_buf_addr); + u32(*free_buffer) (struct vcd_clnt_ctxt *cctxt, + enum vcd_buffer_type buffer_type, u8 *buffer); + u32(*fill_output_buffer) ( + struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *buffer); + void (*clnt_cb) (struct vcd_clnt_ctxt *cctxt, + u32 event, u32 status, void *payload, + size_t sz, u32 *ddl_handle, + void *const client_data); + } ev_hdlr; + + void (*entry) (struct vcd_clnt_ctxt *cctxt, + s32 state_event); + void (*exit) (struct vcd_clnt_ctxt *cctxt, + s32 state_event); +}; + +struct vcd_clnt_state_ctxt { + const struct vcd_clnt_state_table *state_table; + enum vcd_clnt_state_enum state; +}; + +extern void vcd_do_client_state_transition + (struct vcd_clnt_ctxt *cctxt, + enum vcd_clnt_state_enum to_state, u32 ev_code); + +extern const struct vcd_clnt_state_table *vcd_get_client_state_table( + enum vcd_clnt_state_enum state); + +#endif diff --git a/drivers/video/msm/vidc/common/vcd/vcd_core.h b/drivers/video/msm/vidc/common/vcd/vcd_core.h new file mode 100644 index 000000000000..1ffedf7ca545 --- /dev/null +++ b/drivers/video/msm/vidc/common/vcd/vcd_core.h @@ -0,0 +1,228 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#ifndef _VCD_CORE_H_ +#define _VCD_CORE_H_ + +#include +#include +#include "vcd_ddl_api.h" + +#include "vcd_util.h" +#include "vcd_client_sm.h" +#include "vcd_power_sm.h" + +#define VCD_SIGNATURE 0x75017591U + +#define VCD_MIN_PERF_LEVEL 37900 + +#define VCD_DRIVER_INSTANCE_MAX 4 + +#define VCD_MAX_CLIENT_TRANSACTIONS 32 + +#define VCD_MAX_BUFFER_ENTRIES 32 + +#define VCD_SEQ_HDR_PADDING_BYTES 256 + +#define VCD_DEC_NUM_INTERLACED_FIELDS 2 + +#define VCD_TIMESTAMP_RESOLUTION 1000000 +#define VCD_DEC_INITIAL_FRAME_RATE 30 + +#define VCD_FIRST_IP_RCVD 0x00000004 +#define VCD_FIRST_OP_RCVD 0x00000008 +#define VCD_EOS_PREV_VALID 0x00000010 +#define VCD_EOS_WAIT_OP_BUF 0x00000020 +#define VCD_CLEANING_UP 0x00000040 +#define VCD_STOP_PENDING 0x00000080 +#define VCD_CLOSE_PENDING 0x00000100 +#define VCD_IN_RECONFIG 0x00000200 +#define VCD_FIRST_IP_DONE 0x00000400 + +enum vcd_command { + VCD_CMD_NONE, + VCD_CMD_DEVICE_INIT, + VCD_CMD_DEVICE_TERM, + VCD_CMD_DEVICE_RESET, + VCD_CMD_CODEC_START, + VCD_CMD_CODEC_STOP, + VCD_CMD_CODE_FRAME, + VCD_CMD_OUTPUT_FLUSH, + VCD_CMD_CLIENT_CLOSE +}; + +enum vcd_core_type { + VCD_CORE_1080P, + VCD_CORE_720P +}; + +struct vcd_cmd_q_element { + enum vcd_command pending_cmd; +}; + +struct vcd_buffer_entry { + struct list_head sched_list; + struct list_head list; + u32 valid; + u8 *alloc; + u8 *virtual; + u8 *physical; + size_t sz; + u32 allocated; + u32 in_use; + struct vcd_frame_data frame; + +}; + +struct vcd_buffer_pool { + struct vcd_buffer_entry *entries; + u32 count; + struct vcd_buffer_requirement buf_req; + u32 validated; + u32 allocated; + u32 in_use; + struct list_head queue; + u16 q_len; +}; + +struct vcd_transc { + u32 in_use; + enum vcd_command type; + struct vcd_clnt_ctxt *cctxt; + + struct vcd_buffer_entry *ip_buf_entry; + + s64 time_stamp; + u32 flags; + u32 ip_frm_tag; + enum vcd_frame frame; + + struct vcd_buffer_entry *op_buf_entry; + + u32 input_done; + u32 frame_done; +}; + +struct vcd_dev_ctxt { + u32 ddl_cmd_concurrency; + u32 ddl_frame_ch_depth; + u32 ddl_cmd_ch_depth; + u32 ddl_frame_ch_interim; + u32 ddl_cmd_ch_interim; + u32 ddl_frame_ch_free; + u32 ddl_cmd_ch_free; + + struct list_head sched_clnt_list; + + struct vcd_init_config config; + + u32 driver_ids[VCD_DRIVER_INSTANCE_MAX]; + u32 refs; + u8 *device_base_addr; + void *hw_timer_handle; + u32 hw_time_out; + struct vcd_clnt_ctxt *cctxt_list_head; + + enum vcd_command pending_cmd; + + u32 command_continue; + + struct vcd_transc *trans_tbl; + u32 trans_tbl_size; + + enum vcd_power_state pwr_state; + enum vcd_pwr_clk_state pwr_clk_state; + u32 active_clnts; + u32 max_perf_lvl; + u32 reqd_perf_lvl; + u32 curr_perf_lvl; + u32 set_perf_lvl_pending; + +}; + +struct vcd_clnt_status { + u32 req_perf_lvl; + u32 frame_submitted; + u32 frame_delayed; + u32 cmd_submitted; + u32 int_field_cnt; + s64 first_ts; + s64 prev_ts; + u64 time_elapsed; + struct vcd_frame_data eos_trig_ip_frm; + struct ddl_frame_data_tag eos_prev_op_frm; + u32 eos_prev_op_frm_status; + u32 last_err; + u32 last_evt; + u32 mask; +}; + +struct vcd_sched_clnt_ctx { + struct list_head list; + u32 clnt_active; + void *clnt_data; + u32 tkns; + u32 round_perfrm; + u32 rounds; + struct list_head ip_frm_list; +}; + +struct vcd_clnt_ctxt { + u32 signature; + struct vcd_clnt_state_ctxt clnt_state; + + s32 driver_id; + + u32 live; + u32 decoding; + u32 bframe; + u32 num_slices; + + struct vcd_property_frame_rate frm_rate; + u32 frm_p_units; + u32 reqd_perf_lvl; + u32 time_resoln; + u32 time_frame_delta; + + struct vcd_buffer_pool in_buf_pool; + struct vcd_buffer_pool out_buf_pool; + + void (*callback) (u32 event, u32 status, void *info, size_t sz, + void *handle, void *const client_data); + void *client_data; + struct vcd_sched_clnt_ctx *sched_clnt_hdl; + u32 ddl_hdl_valid; + u32 *ddl_handle; + struct vcd_dev_ctxt *dev_ctxt; + struct vcd_cmd_q_element cmd_q; + struct vcd_sequence_hdr seq_hdr; + u8 *seq_hdr_phy_addr; + struct vcd_clnt_status status; + struct ion_client *vcd_ion_client; + u32 vcd_enable_ion; + struct vcd_clnt_ctxt *next; + u32 meta_mode; + int perf_set_by_client; + int secure; +}; + +#define VCD_BUFFERPOOL_INUSE_DECREMENT(val) \ +do { \ + if ((val) > 0) \ + val--; \ + else { \ + VCD_MSG_ERROR("%s(): Inconsistent val given in " \ + " VCD_BUFFERPOOL_INUSE_DECREMENT\n", __func__); \ + } \ +} while (0) + +#endif diff --git a/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c new file mode 100644 index 000000000000..5f2343db67b8 --- /dev/null +++ b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.c @@ -0,0 +1,1218 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#include +#include "vcd.h" + +static const struct vcd_dev_state_table *vcd_dev_state_table[]; +static const struct vcd_dev_state_table vcd_dev_table_null; + +struct vcd_drv_ctxt *vcd_get_drv_context(void) +{ + static struct vcd_drv_ctxt drv_context = { + {&vcd_dev_table_null, VCD_DEVICE_STATE_NULL}, + {0}, + }; + + return &drv_context; + +} + +void vcd_do_device_state_transition(struct vcd_drv_ctxt *drv_ctxt, + enum vcd_dev_state_enum to_state, u32 ev_code) +{ + struct vcd_dev_state_ctxt *state_ctxt; + + if (!drv_ctxt || to_state >= VCD_DEVICE_STATE_MAX) { + VCD_MSG_ERROR("Bad parameters. drv_ctxt=%p, to_state=%d", + drv_ctxt, to_state); + } + + state_ctxt = &drv_ctxt->dev_state; + + if (state_ctxt->state == to_state) { + VCD_MSG_HIGH("Device already in requested to_state=%d", + to_state); + + return; + } + + VCD_MSG_MED("vcd_do_device_state_transition: D%d -> D%d, for api %d", + (int)state_ctxt->state, (int)to_state, ev_code); + + if (state_ctxt->state_table->exit) + state_ctxt->state_table->exit(drv_ctxt, ev_code); + + + state_ctxt->state = to_state; + state_ctxt->state_table = vcd_dev_state_table[to_state]; + + if (state_ctxt->state_table->entry) + state_ctxt->state_table->entry(drv_ctxt, ev_code); +} + +void vcd_hw_timeout_handler(void *user_data) +{ + struct vcd_drv_ctxt *drv_ctxt; + + VCD_MSG_HIGH("vcd_hw_timeout_handler:"); + user_data = NULL; + drv_ctxt = vcd_get_drv_context(); + mutex_lock(&drv_ctxt->dev_mutex); + if (drv_ctxt->dev_state.state_table->ev_hdlr.timeout) + drv_ctxt->dev_state.state_table->ev_hdlr. + timeout(drv_ctxt, user_data); + else + VCD_MSG_ERROR("hw_timeout unsupported in device state %d", + drv_ctxt->dev_state.state); + mutex_unlock(&drv_ctxt->dev_mutex); +} + +void vcd_ddl_callback(u32 event, u32 status, void *payload, + size_t sz, u32 *ddl_handle, void *const client_data) +{ + struct vcd_drv_ctxt *drv_ctxt; + struct vcd_dev_ctxt *dev_ctxt; + struct vcd_dev_state_ctxt *dev_state; + struct vcd_clnt_ctxt *cctxt; + struct vcd_transc *transc; + + VCD_MSG_LOW("vcd_ddl_callback:"); + + VCD_MSG_LOW("event=0x%x status=0x%x", event, status); + + drv_ctxt = vcd_get_drv_context(); + dev_ctxt = &drv_ctxt->dev_ctxt; + dev_state = &drv_ctxt->dev_state; + + dev_ctxt->command_continue = true; + vcd_device_timer_stop(dev_ctxt); + + switch (dev_state->state) { + case VCD_DEVICE_STATE_NULL: + { + VCD_MSG_HIGH("Callback unexpected in NULL state"); + break; + } + + case VCD_DEVICE_STATE_NOT_INIT: + { + VCD_MSG_HIGH("Callback unexpected in NOT_INIT state"); + break; + } + + case VCD_DEVICE_STATE_INITING: + { + if (dev_state->state_table->ev_hdlr.dev_cb) { + dev_state->state_table->ev_hdlr. + dev_cb(drv_ctxt, event, status, + payload, sz, ddl_handle, + client_data); + } else { + VCD_MSG_HIGH("No device handler in %d state", + dev_state->state); + } + break; + } + + case VCD_DEVICE_STATE_READY: + { + transc = (struct vcd_transc *)client_data; + + if (!transc || !transc->in_use || !transc->cctxt) { + VCD_MSG_ERROR("Invalid clientdata " + "received from DDL, transc = 0x%x\n", + (u32)transc); + if (transc) { + VCD_MSG_ERROR("transc->in_use = %u, " + "transc->cctxt = 0x%x\n", + transc->in_use, + (u32)transc->cctxt); + } + } else { + cctxt = transc->cctxt; + + if (cctxt->clnt_state.state_table->ev_hdlr. + clnt_cb) { + cctxt->clnt_state.state_table-> + ev_hdlr.clnt_cb(cctxt, + event, status, payload, + sz, ddl_handle, + client_data); + } else { + VCD_MSG_HIGH + ("No client handler in" + " (dsm:READY, csm:%d) state", + (int)cctxt->clnt_state.state); + + if (VCD_FAILED(status)) { + VCD_MSG_FATAL("DDL callback" + " returned failure 0x%x", + status); + } + } + } + break; + } + + default: + { + VCD_MSG_ERROR("Unknown state"); + break; + } + + } + +} + +u32 vcd_init_device_context(struct vcd_drv_ctxt *drv_ctxt, + u32 ev_code) +{ + struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt; + u32 rc; + struct ddl_init_config ddl_init; + + VCD_MSG_LOW("vcd_init_device_context:"); + + dev_ctxt->pending_cmd = VCD_CMD_NONE; + + rc = vcd_power_event(dev_ctxt, NULL, VCD_EVT_PWR_DEV_INIT_BEGIN); + VCD_FAILED_RETURN(rc, "VCD_EVT_PWR_DEV_INIT_BEGIN failed"); + + VCD_MSG_HIGH("Device powered ON and clocked"); + rc = vcd_sched_create(&dev_ctxt->sched_clnt_list); + if (VCD_FAILED(rc)) { + VCD_MSG_ERROR("rc = 0x%x. Failed: vcd_sched_create", rc); + + (void)vcd_power_event(dev_ctxt, NULL, + VCD_EVT_PWR_DEV_INIT_FAIL); + + return rc; + } + + VCD_MSG_HIGH("Created scheduler instance."); + + ddl_init.core_virtual_base_addr = dev_ctxt->device_base_addr; + ddl_init.interrupt_clr = dev_ctxt->config.interrupt_clr; + ddl_init.ddl_callback = vcd_ddl_callback; + + rc = ddl_device_init(&ddl_init, NULL); + + if (VCD_FAILED(rc)) { + VCD_MSG_ERROR("rc = 0x%x. Failed: ddl_device_init", rc); + vcd_sched_destroy(&dev_ctxt->sched_clnt_list); + (void)vcd_power_event(dev_ctxt, NULL, + VCD_EVT_PWR_DEV_INIT_FAIL); + } else { + vcd_device_timer_start(dev_ctxt); + vcd_do_device_state_transition(drv_ctxt, + VCD_DEVICE_STATE_INITING, + ev_code); + } + + return rc; +} + +void vcd_handle_device_init_failed(struct vcd_drv_ctxt *drv_ctxt, + u32 status) +{ + struct vcd_clnt_ctxt *client; + struct vcd_clnt_ctxt *tmp_client; + + VCD_MSG_ERROR("Device init failed. status = %d", status); + + client = drv_ctxt->dev_ctxt.cctxt_list_head; + while (client) { + client->callback(VCD_EVT_RESP_OPEN, + status, NULL, 0, 0, client->client_data); + + tmp_client = client; + client = client->next; + + vcd_destroy_client_context(tmp_client); + } + if (ddl_device_release(NULL)) + VCD_MSG_ERROR("Failed: ddl_device_release"); + + vcd_sched_destroy(&drv_ctxt->dev_ctxt.sched_clnt_list); + if (vcd_power_event(&drv_ctxt->dev_ctxt, + NULL, VCD_EVT_PWR_DEV_INIT_FAIL)) + VCD_MSG_ERROR("VCD_EVT_PWR_DEV_INIT_FAIL failed"); + + vcd_do_device_state_transition(drv_ctxt, + VCD_DEVICE_STATE_NOT_INIT, + DEVICE_STATE_EVENT_NUMBER(dev_cb)); +} + +u32 vcd_deinit_device_context(struct vcd_drv_ctxt *drv_ctxt, + u32 ev_code) +{ + struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt; + u32 rc = VCD_S_SUCCESS; + + VCD_MSG_LOW("vcd_deinit_device_context:"); + + rc = vcd_power_event(&drv_ctxt->dev_ctxt, NULL, + VCD_EVT_PWR_DEV_TERM_BEGIN); + + VCD_FAILED_RETURN(rc, "VCD_EVT_PWR_DEV_TERM_BEGIN failed"); + + rc = ddl_device_release(NULL); + + if (VCD_FAILED(rc)) { + VCD_MSG_ERROR("rc = 0x%x. Failed: ddl_device_release", rc); + + (void)vcd_power_event(dev_ctxt, NULL, + VCD_EVT_PWR_DEV_TERM_FAIL); + } else { + vcd_sched_destroy(&dev_ctxt->sched_clnt_list); + (void) vcd_power_event(dev_ctxt, NULL, + VCD_EVT_PWR_DEV_TERM_END); + + vcd_do_device_state_transition(drv_ctxt, + VCD_DEVICE_STATE_NOT_INIT, ev_code); + } + return rc; +} + +void vcd_term_driver_context(struct vcd_drv_ctxt *drv_ctxt) +{ + struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt; + + VCD_MSG_HIGH("All driver instances terminated"); + + if (dev_ctxt->config.deregister_isr) + dev_ctxt->config.deregister_isr(); + + if (dev_ctxt->config.un_map_dev_base_addr) + dev_ctxt->config.un_map_dev_base_addr(); + + if (dev_ctxt->config.timer_release) + dev_ctxt->config.timer_release( + dev_ctxt->hw_timer_handle); + + kfree(dev_ctxt->trans_tbl); + + memset(dev_ctxt, 0, sizeof(struct vcd_dev_ctxt)); + + vcd_do_device_state_transition(drv_ctxt, + VCD_DEVICE_STATE_NULL, + DEVICE_STATE_EVENT_NUMBER(term)); + +} + +u32 vcd_reset_device_context(struct vcd_drv_ctxt *drv_ctxt, + u32 ev_code) +{ + struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt; + u32 rc = VCD_S_SUCCESS; + + VCD_MSG_LOW("vcd_reset_device_context:"); + vcd_reset_device_channels(dev_ctxt); + rc = vcd_power_event(&drv_ctxt->dev_ctxt, NULL, + VCD_EVT_PWR_DEV_TERM_BEGIN); + VCD_FAILED_RETURN(rc, "VCD_EVT_PWR_DEV_TERM_BEGIN failed"); + if (ddl_reset_hw(0)) + VCD_MSG_HIGH("HW Reset done"); + else + VCD_MSG_FATAL("HW Reset failed"); + + (void)vcd_power_event(dev_ctxt, NULL, VCD_EVT_PWR_DEV_TERM_END); + + return VCD_S_SUCCESS; +} + +void vcd_handle_device_err_fatal(struct vcd_dev_ctxt *dev_ctxt, + struct vcd_clnt_ctxt *trig_clnt) +{ + struct vcd_clnt_ctxt *cctxt = dev_ctxt->cctxt_list_head; + struct vcd_clnt_ctxt *tmp_clnt = NULL; + VCD_MSG_LOW("vcd_handle_device_err_fatal:"); + while (cctxt) { + tmp_clnt = cctxt; + cctxt = cctxt->next; + if (tmp_clnt != trig_clnt) + vcd_clnt_handle_device_err_fatal(tmp_clnt, + tmp_clnt->status.last_evt); + } + dev_ctxt->pending_cmd = VCD_CMD_DEVICE_RESET; + if (!dev_ctxt->cctxt_list_head) + vcd_do_device_state_transition(vcd_get_drv_context(), + VCD_DEVICE_STATE_NOT_INIT, + DEVICE_STATE_EVENT_NUMBER(timeout)); + else + vcd_do_device_state_transition(vcd_get_drv_context(), + VCD_DEVICE_STATE_INVALID, + DEVICE_STATE_EVENT_NUMBER(dev_cb)); +} + +void vcd_handle_for_last_clnt_close( + struct vcd_dev_ctxt *dev_ctxt, u32 send_deinit) +{ + if (!dev_ctxt->cctxt_list_head) { + VCD_MSG_HIGH("All clients are closed"); + if (send_deinit) + (void) vcd_deinit_device_context( + vcd_get_drv_context(), + DEVICE_STATE_EVENT_NUMBER(close)); + else + dev_ctxt->pending_cmd = + VCD_CMD_DEVICE_TERM; + } +} +void vcd_continue(void) +{ + struct vcd_drv_ctxt *drv_ctxt; + struct vcd_dev_ctxt *dev_ctxt; + u32 command_continue; + struct vcd_transc *transc; + u32 rc; + VCD_MSG_LOW("vcd_continue:"); + + drv_ctxt = vcd_get_drv_context(); + dev_ctxt = &drv_ctxt->dev_ctxt; + + dev_ctxt->command_continue = false; + + if (dev_ctxt->pending_cmd == VCD_CMD_DEVICE_INIT) { + VCD_MSG_HIGH("VCD_CMD_DEVICE_INIT is pending"); + + dev_ctxt->pending_cmd = VCD_CMD_NONE; + + (void)vcd_init_device_context(drv_ctxt, + DEVICE_STATE_EVENT_NUMBER(open)); + } else if (dev_ctxt->pending_cmd == VCD_CMD_DEVICE_TERM) { + VCD_MSG_HIGH("VCD_CMD_DEVICE_TERM is pending"); + + dev_ctxt->pending_cmd = VCD_CMD_NONE; + + (void)vcd_deinit_device_context(drv_ctxt, + DEVICE_STATE_EVENT_NUMBER(close)); + } else if (dev_ctxt->pending_cmd == VCD_CMD_DEVICE_RESET) { + VCD_MSG_HIGH("VCD_CMD_DEVICE_RESET is pending"); + dev_ctxt->pending_cmd = VCD_CMD_NONE; + (void)vcd_reset_device_context(drv_ctxt, + DEVICE_STATE_EVENT_NUMBER(dev_cb)); + } else { + if (dev_ctxt->set_perf_lvl_pending) { + rc = vcd_power_event(dev_ctxt, NULL, + VCD_EVT_PWR_DEV_SET_PERFLVL); + + if (VCD_FAILED(rc)) { + VCD_MSG_ERROR + ("VCD_EVT_PWR_CLNT_SET_PERFLVL failed"); + VCD_MSG_HIGH + ("Not running at desired perf level." + "curr=%d, reqd=%d", + dev_ctxt->curr_perf_lvl, + dev_ctxt->reqd_perf_lvl); + } else { + dev_ctxt->set_perf_lvl_pending = false; + } + } + + do { + command_continue = false; + + if (vcd_get_command_channel_in_loop + (dev_ctxt, &transc)) { + if (vcd_submit_command_in_continue(dev_ctxt, + transc)) + command_continue = true; + else { + VCD_MSG_MED + ("No more commands to submit"); + + vcd_release_command_channel(dev_ctxt, + transc); + + vcd_release_interim_command_channels + (dev_ctxt); + } + } + } while (command_continue); + + do { + command_continue = false; + + if (vcd_get_frame_channel_in_loop + (dev_ctxt, &transc)) { + if (vcd_try_submit_frame_in_continue(dev_ctxt, + transc)) { + command_continue = true; + } else { + VCD_MSG_MED("No more frames to submit"); + + vcd_release_frame_channel(dev_ctxt, + transc); + + vcd_release_interim_frame_channels + (dev_ctxt); + } + } + + } while (command_continue); + + if (!vcd_core_is_busy(dev_ctxt)) { + rc = vcd_power_event(dev_ctxt, NULL, + VCD_EVT_PWR_CLNT_CMD_END); + + if (VCD_FAILED(rc)) + VCD_MSG_ERROR("Failed:" + "VCD_EVT_PWR_CLNT_CMD_END"); + } + } +} + +static void vcd_pause_all_sessions(struct vcd_dev_ctxt *dev_ctxt) +{ + struct vcd_clnt_ctxt *cctxt = dev_ctxt->cctxt_list_head; + u32 rc; + + while (cctxt) { + if (cctxt->clnt_state.state_table->ev_hdlr.pause) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + pause(cctxt); + + if (VCD_FAILED(rc)) + VCD_MSG_ERROR("Client pause failed"); + + } + + cctxt = cctxt->next; + } +} + +static void vcd_resume_all_sessions(struct vcd_dev_ctxt *dev_ctxt) +{ + struct vcd_clnt_ctxt *cctxt = dev_ctxt->cctxt_list_head; + u32 rc; + + while (cctxt) { + if (cctxt->clnt_state.state_table->ev_hdlr.resume) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + resume(cctxt); + + if (VCD_FAILED(rc)) + VCD_MSG_ERROR("Client resume failed"); + + } + + cctxt = cctxt->next; + } +} + +static u32 vcd_init_cmn + (struct vcd_drv_ctxt *drv_ctxt, + struct vcd_init_config *config, s32 *driver_handle) +{ + struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt; + s32 driver_id; + + if (dev_ctxt->config.interrupt_clr != + config->interrupt_clr + || dev_ctxt->config.register_isr != + config->register_isr + || dev_ctxt->config.deregister_isr != + config->deregister_isr + || dev_ctxt->config.map_dev_base_addr != + config->map_dev_base_addr + || dev_ctxt->config.un_map_dev_base_addr != + config->un_map_dev_base_addr) { + VCD_MSG_HIGH("Device config mismatch. " + "VCD will be using config from 1st vcd_init"); + } + + *driver_handle = 0; + + driver_id = 0; + while (driver_id < VCD_DRIVER_INSTANCE_MAX && + dev_ctxt->driver_ids[driver_id]) { + ++driver_id; + } + + if (driver_id == VCD_DRIVER_INSTANCE_MAX) { + VCD_MSG_ERROR("Max driver instances reached"); + + return VCD_ERR_FAIL; + } + + ++dev_ctxt->refs; + dev_ctxt->driver_ids[driver_id] = true; + *driver_handle = driver_id + 1; + + VCD_MSG_HIGH("Driver_id = %d. No of driver instances = %d", + driver_id, dev_ctxt->refs); + + return VCD_S_SUCCESS; + +} + +static u32 vcd_init_in_null + (struct vcd_drv_ctxt *drv_ctxt, + struct vcd_init_config *config, s32 *driver_handle) { + u32 rc = VCD_S_SUCCESS; + struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt; + u32 done_create_timer = false; + VCD_MSG_LOW("vcd_init_in_dev_null:"); + + + dev_ctxt->config = *config; + + dev_ctxt->device_base_addr = + (u8 *)config->map_dev_base_addr( + dev_ctxt->config.device_name); + + if (!dev_ctxt->device_base_addr) { + VCD_MSG_ERROR("NULL Device_base_addr"); + + return VCD_ERR_FAIL; + } + + if (config->register_isr) { + config->register_isr(dev_ctxt->config. + device_name); + } + + if (config->timer_create) { + if (config->timer_create(vcd_hw_timeout_handler, + NULL, &dev_ctxt->hw_timer_handle)) + done_create_timer = true; + else { + VCD_MSG_ERROR("timercreate failed"); + return VCD_ERR_FAIL; + } + } + + + rc = vcd_init_cmn(drv_ctxt, config, driver_handle); + + if (!VCD_FAILED(rc)) { + vcd_do_device_state_transition(drv_ctxt, + VCD_DEVICE_STATE_NOT_INIT, + DEVICE_STATE_EVENT_NUMBER + (init)); + } else { + if (dev_ctxt->config.un_map_dev_base_addr) + dev_ctxt->config.un_map_dev_base_addr(); + + if (dev_ctxt->config.deregister_isr) + dev_ctxt->config.deregister_isr(); + + if (done_create_timer && dev_ctxt->config.timer_release) + dev_ctxt->config.timer_release(dev_ctxt-> + hw_timer_handle); + + } + + return rc; + +} + +static u32 vcd_init_in_not_init + (struct vcd_drv_ctxt *drv_ctxt, + struct vcd_init_config *config, s32 *driver_handle) +{ + + VCD_MSG_LOW("vcd_init_in_dev_not_init:"); + + return vcd_init_cmn(drv_ctxt, config, driver_handle); + +} + +static u32 vcd_init_in_initing + (struct vcd_drv_ctxt *drv_ctxt, + struct vcd_init_config *config, s32 *driver_handle) { + + VCD_MSG_LOW("vcd_init_in_dev_initing:"); + + return vcd_init_cmn(drv_ctxt, config, driver_handle); + +} + +static u32 vcd_init_in_ready + (struct vcd_drv_ctxt *drv_ctxt, + struct vcd_init_config *config, s32 *driver_handle) +{ + VCD_MSG_LOW("vcd_init_in_dev_ready:"); + + return vcd_init_cmn(drv_ctxt, config, driver_handle); +} + +static u32 vcd_term_cmn + (struct vcd_drv_ctxt *drv_ctxt, s32 driver_handle) +{ + struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt; + + if (!vcd_validate_driver_handle(dev_ctxt, driver_handle)) { + VCD_MSG_ERROR("Invalid driver handle = %d", driver_handle); + + return VCD_ERR_BAD_HANDLE; + } + + if (vcd_check_for_client_context(dev_ctxt, + driver_handle - 1)) { + VCD_MSG_ERROR("Driver has active client"); + + return VCD_ERR_BAD_STATE; + } + + --dev_ctxt->refs; + dev_ctxt->driver_ids[driver_handle - 1] = false; + + VCD_MSG_HIGH("Driver_id %d terminated. No of driver instances = %d", + driver_handle - 1, dev_ctxt->refs); + + return VCD_S_SUCCESS; +} + +static u32 vcd_term_in_not_init + (struct vcd_drv_ctxt *drv_ctxt, s32 driver_handle) +{ + struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt; + u32 rc; + + VCD_MSG_LOW("vcd_term_in_dev_not_init:"); + + rc = vcd_term_cmn(drv_ctxt, driver_handle); + + if (!VCD_FAILED(rc) && !dev_ctxt->refs) + vcd_term_driver_context(drv_ctxt); + + return rc; +} + +static u32 vcd_term_in_initing + (struct vcd_drv_ctxt *drv_ctxt, s32 driver_handle) +{ + VCD_MSG_LOW("vcd_term_in_dev_initing:"); + + return vcd_term_cmn(drv_ctxt, driver_handle); +} + +static u32 vcd_term_in_ready + (struct vcd_drv_ctxt *drv_ctxt, s32 driver_handle) +{ + VCD_MSG_LOW("vcd_term_in_dev_ready:"); + + return vcd_term_cmn(drv_ctxt, driver_handle); +} + +static u32 vcd_term_in_invalid(struct vcd_drv_ctxt *drv_ctxt, + s32 driver_handle) +{ + u32 rc; + VCD_MSG_LOW("vcd_term_in_invalid:"); + rc = vcd_term_cmn(drv_ctxt, driver_handle); + if (!VCD_FAILED(rc) && !drv_ctxt->dev_ctxt.refs) + vcd_term_driver_context(drv_ctxt); + + return rc; +} + +static u32 vcd_open_cmn + (struct vcd_drv_ctxt *drv_ctxt, + s32 driver_handle, + u32 decoding, + void (*callback) (u32 event, u32 status, void *info, size_t sz, + void *handle, void *const client_data), + void *client_data, struct vcd_clnt_ctxt ** clnt_cctxt) +{ + struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt; + struct vcd_clnt_ctxt *cctxt; + struct vcd_clnt_ctxt *client; + + if (!vcd_validate_driver_handle(dev_ctxt, driver_handle)) { + VCD_MSG_ERROR("Invalid driver handle = %d", driver_handle); + + return VCD_ERR_BAD_HANDLE; + } + + cctxt = (struct vcd_clnt_ctxt *) + kmalloc(sizeof(struct vcd_clnt_ctxt), GFP_KERNEL); + if (!cctxt) { + VCD_MSG_ERROR("No memory for client ctxt"); + + return VCD_ERR_ALLOC_FAIL; + } + + memset(cctxt, 0, sizeof(struct vcd_clnt_ctxt)); + cctxt->dev_ctxt = dev_ctxt; + cctxt->driver_id = driver_handle - 1; + cctxt->decoding = decoding; + cctxt->callback = callback; + cctxt->client_data = client_data; + cctxt->status.last_evt = VCD_EVT_RESP_OPEN; + INIT_LIST_HEAD(&cctxt->in_buf_pool.queue); + INIT_LIST_HEAD(&cctxt->out_buf_pool.queue); + client = dev_ctxt->cctxt_list_head; + dev_ctxt->cctxt_list_head = cctxt; + cctxt->next = client; + + *clnt_cctxt = cctxt; + + return VCD_S_SUCCESS; + +} + +static u32 vcd_open_in_not_init + (struct vcd_drv_ctxt *drv_ctxt, + s32 driver_handle, + u32 decoding, + void (*callback) (u32 event, u32 status, void *info, size_t sz, + void *handle, void *const client_data), + void *client_data) +{ + struct vcd_clnt_ctxt *cctxt; + u32 rc; + + VCD_MSG_LOW("vcd_open_in_dev_not_init:"); + + rc = vcd_open_cmn(drv_ctxt, driver_handle, decoding, callback, + client_data, &cctxt); + + VCD_FAILED_RETURN(rc, "Failed: vcd_open_cmn"); + + rc = vcd_init_device_context(drv_ctxt, + DEVICE_STATE_EVENT_NUMBER(open)); + + if (VCD_FAILED(rc)) + vcd_destroy_client_context(cctxt); + + return rc; +} + +static u32 vcd_open_in_initing(struct vcd_drv_ctxt *drv_ctxt, + s32 driver_handle, u32 decoding, + void (*callback) (u32 event, u32 status, void *info, size_t sz, + void *handle, void *const client_data), + void *client_data) +{ + struct vcd_clnt_ctxt *cctxt; + + VCD_MSG_LOW("vcd_open_in_dev_initing:"); + + return vcd_open_cmn(drv_ctxt, driver_handle, decoding, callback, + client_data, &cctxt); +} + +static u32 vcd_open_in_ready + (struct vcd_drv_ctxt *drv_ctxt, + s32 driver_handle, + u32 decoding, + void (*callback) (u32 event, u32 status, void *info, size_t sz, + void *handle, void *const client_data), + void *client_data) +{ + struct vcd_clnt_ctxt *cctxt; + struct vcd_handle_container container; + u32 rc; + + VCD_MSG_LOW("vcd_open_in_dev_ready:"); + + rc = vcd_open_cmn(drv_ctxt, driver_handle, decoding, callback, + client_data, &cctxt); + + VCD_FAILED_RETURN(rc, "Failed: vcd_open_cmn"); + + rc = vcd_init_client_context(cctxt); + + if (!VCD_FAILED(rc)) { + container.handle = (void *)cctxt; + + callback(VCD_EVT_RESP_OPEN, + VCD_S_SUCCESS, + &container, + sizeof(container), container.handle, client_data); + } else { + VCD_MSG_ERROR("rc = 0x%x. Failed: vcd_init_client_context", rc); + + vcd_destroy_client_context(cctxt); + } + + return rc; +} + +static u32 vcd_close_in_ready + (struct vcd_drv_ctxt *drv_ctxt, + struct vcd_clnt_ctxt *cctxt) { + u32 rc; + + VCD_MSG_LOW("vcd_close_in_dev_ready:"); + + if (cctxt->clnt_state.state_table->ev_hdlr.close) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + close(cctxt); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + if (!VCD_FAILED(rc)) + vcd_handle_for_last_clnt_close(&drv_ctxt->dev_ctxt, true); + + return rc; +} + +static u32 vcd_close_in_dev_invalid(struct vcd_drv_ctxt *drv_ctxt, + struct vcd_clnt_ctxt *cctxt) +{ + u32 rc; + VCD_MSG_LOW("vcd_close_in_dev_invalid:"); + if (cctxt->clnt_state.state_table->ev_hdlr.close) { + rc = cctxt->clnt_state.state_table-> + ev_hdlr.close(cctxt); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + rc = VCD_ERR_BAD_STATE; + } + if (!VCD_FAILED(rc) && !drv_ctxt->dev_ctxt. + cctxt_list_head) { + VCD_MSG_HIGH("All INVALID clients are closed"); + vcd_do_device_state_transition(drv_ctxt, + VCD_DEVICE_STATE_NOT_INIT, + DEVICE_STATE_EVENT_NUMBER(close)); + } + return rc; +} + +static u32 vcd_resume_in_ready + (struct vcd_drv_ctxt *drv_ctxt, + struct vcd_clnt_ctxt *cctxt) { + u32 rc = VCD_S_SUCCESS; + + VCD_MSG_LOW("vcd_resume_in_ready:"); + + if (cctxt->clnt_state.state_table->ev_hdlr.resume) { + rc = cctxt->clnt_state.state_table->ev_hdlr. + resume(cctxt); + } else { + VCD_MSG_ERROR("Unsupported API in client state %d", + cctxt->clnt_state.state); + + rc = VCD_ERR_BAD_STATE; + } + + return rc; +} + +static u32 vcd_set_dev_pwr_in_ready + (struct vcd_drv_ctxt *drv_ctxt, + enum vcd_power_state pwr_state) +{ + u32 rc = VCD_S_SUCCESS; + struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt; + + VCD_MSG_LOW("vcd_set_dev_pwr_in_ready:"); + + switch (pwr_state) { + case VCD_PWR_STATE_SLEEP: + { + if (dev_ctxt->pwr_state == VCD_PWR_STATE_ON) + vcd_pause_all_sessions(dev_ctxt); + dev_ctxt->pwr_state = VCD_PWR_STATE_SLEEP; + break; + } + + case VCD_PWR_STATE_ON: + { + if (dev_ctxt->pwr_state == VCD_PWR_STATE_SLEEP) + vcd_resume_all_sessions(dev_ctxt); + dev_ctxt->pwr_state = VCD_PWR_STATE_ON; + break; + } + + default: + { + VCD_MSG_ERROR("Invalid power state requested %d", + pwr_state); + break; + } + + } + + return rc; +} + +static void vcd_dev_cb_in_initing + (struct vcd_drv_ctxt *drv_ctxt, + u32 event, + u32 status, + void *payload, size_t sz, u32 *ddl_handle, void *const client_data) +{ + struct vcd_dev_ctxt *dev_ctxt; + struct vcd_clnt_ctxt *client; + struct vcd_clnt_ctxt *tmp_client; + struct vcd_handle_container container; + u32 rc = VCD_S_SUCCESS; + u32 client_inited = false; + u32 fail_all_open = false; + struct ddl_context *ddl_context; + + ddl_context = ddl_get_context(); + + VCD_MSG_LOW("vcd_dev_cb_in_initing:"); + + if (event != VCD_EVT_RESP_DEVICE_INIT) { + VCD_MSG_ERROR("vcd_dev_cb_in_initing: Unexpected event %d", + (int)event); + return; + } + + dev_ctxt = &drv_ctxt->dev_ctxt; + + dev_ctxt->command_continue = false; + + if (VCD_FAILED(status)) { + vcd_handle_device_init_failed(drv_ctxt, status); + + return; + } + + vcd_do_device_state_transition(drv_ctxt, + VCD_DEVICE_STATE_READY, + DEVICE_STATE_EVENT_NUMBER(open)); + + if (!dev_ctxt->cctxt_list_head) { + VCD_MSG_HIGH("All clients are closed"); + + dev_ctxt->pending_cmd = VCD_CMD_DEVICE_TERM; + + return; + } + + if (!dev_ctxt->ddl_cmd_ch_depth + || !dev_ctxt->trans_tbl) + rc = vcd_setup_with_ddl_capabilities(dev_ctxt); + + + if (VCD_FAILED(rc)) { + VCD_MSG_ERROR + ("rc = 0x%x: Failed vcd_setup_with_ddl_capabilities", + rc); + + fail_all_open = true; + } + + client = dev_ctxt->cctxt_list_head; + while (client) { + if (!fail_all_open) + rc = vcd_init_client_context(client); + + + if (!VCD_FAILED(rc)) { + container.handle = (void *)client; + client->callback(VCD_EVT_RESP_OPEN, + VCD_S_SUCCESS, + &container, + sizeof(container), + container.handle, + client->client_data); + + client = client->next; + + client_inited = true; + } else { + VCD_MSG_ERROR + ("rc = 0x%x, Failed: vcd_init_client_context", + rc); + + client->callback(VCD_EVT_RESP_OPEN, + rc, + NULL, 0, 0, client->client_data); + + tmp_client = client; + client = client->next; + if (tmp_client == dev_ctxt->cctxt_list_head) + fail_all_open = true; + + vcd_destroy_client_context(tmp_client); + } + } + + if (!client_inited || fail_all_open) { + VCD_MSG_ERROR("All client open requests failed"); + + DDL_IDLE(ddl_context); + + vcd_handle_device_init_failed(drv_ctxt, + DEVICE_STATE_EVENT_NUMBER(close)); + dev_ctxt->pending_cmd = VCD_CMD_DEVICE_TERM; + } else { + if (vcd_power_event(dev_ctxt, NULL, + VCD_EVT_PWR_DEV_INIT_END)) { + VCD_MSG_ERROR("VCD_EVT_PWR_DEV_INIT_END failed"); + } + } +} + +static void vcd_hw_timeout_cmn(struct vcd_drv_ctxt *drv_ctxt, + void *user_data) +{ + struct vcd_dev_ctxt *dev_ctxt = &drv_ctxt->dev_ctxt; + VCD_MSG_LOW("vcd_hw_timeout_cmn:"); + vcd_device_timer_stop(dev_ctxt); + + vcd_handle_device_err_fatal(dev_ctxt, NULL); + + /* Reset HW. */ + (void) vcd_reset_device_context(drv_ctxt, + DEVICE_STATE_EVENT_NUMBER(timeout)); +} + +static void vcd_dev_enter_null + (struct vcd_drv_ctxt *drv_ctxt, s32 state_event) { + VCD_MSG_MED("Entering DEVICE_STATE_NULL on api %d", state_event); + +} + +static void vcd_dev_enter_not_init + (struct vcd_drv_ctxt *drv_ctxt, s32 state_event) { + VCD_MSG_MED("Entering DEVICE_STATE_NOT_INIT on api %d", + state_event); + +} + +static void vcd_dev_enter_initing + (struct vcd_drv_ctxt *drv_ctxt, s32 state_event) { + VCD_MSG_MED("Entering DEVICE_STATE_INITING on api %d", + state_event); + +} + +static void vcd_dev_enter_ready + (struct vcd_drv_ctxt *drv_ctxt, s32 state_event) { + VCD_MSG_MED("Entering DEVICE_STATE_READY on api %d", + state_event); +} + +static void vcd_dev_enter_invalid(struct vcd_drv_ctxt *drv_ctxt, + s32 state_event) +{ + VCD_MSG_MED("Entering DEVICE_STATE_INVALID on api %d", state_event); +} + +static void vcd_dev_exit_null + (struct vcd_drv_ctxt *drv_ctxt, s32 state_event) { + VCD_MSG_MED("Exiting DEVICE_STATE_NULL on api %d", state_event); +} + +static void vcd_dev_exit_not_init + (struct vcd_drv_ctxt *drv_ctxt, s32 state_event) { + VCD_MSG_MED("Exiting DEVICE_STATE_NOT_INIT on api %d", + state_event); + +} + +static void vcd_dev_exit_initing + (struct vcd_drv_ctxt *drv_ctxt, s32 state_event) { + VCD_MSG_MED("Exiting DEVICE_STATE_INITING on api %d", + state_event); +} + +static void vcd_dev_exit_ready + (struct vcd_drv_ctxt *drv_ctxt, s32 state_event) { + VCD_MSG_MED("Exiting DEVICE_STATE_READY on api %d", state_event); +} + +static void vcd_dev_exit_invalid(struct vcd_drv_ctxt *drv_ctxt, + s32 state_event) +{ + VCD_MSG_MED("Exiting DEVICE_STATE_INVALID on api %d", state_event); +} + +static const struct vcd_dev_state_table vcd_dev_table_null = { + { + vcd_init_in_null, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + }, + vcd_dev_enter_null, + vcd_dev_exit_null +}; + +static const struct vcd_dev_state_table vcd_dev_table_not_init = { + { + vcd_init_in_not_init, + vcd_term_in_not_init, + vcd_open_in_not_init, + NULL, + NULL, + NULL, + NULL, + NULL, + }, + vcd_dev_enter_not_init, + vcd_dev_exit_not_init +}; + +static const struct vcd_dev_state_table vcd_dev_table_initing = { + { + vcd_init_in_initing, + vcd_term_in_initing, + vcd_open_in_initing, + NULL, + NULL, + NULL, + vcd_dev_cb_in_initing, + vcd_hw_timeout_cmn, + }, + vcd_dev_enter_initing, + vcd_dev_exit_initing +}; + +static const struct vcd_dev_state_table vcd_dev_table_ready = { + { + vcd_init_in_ready, + vcd_term_in_ready, + vcd_open_in_ready, + vcd_close_in_ready, + vcd_resume_in_ready, + vcd_set_dev_pwr_in_ready, + NULL, + vcd_hw_timeout_cmn, + }, + vcd_dev_enter_ready, + vcd_dev_exit_ready +}; + +static const struct vcd_dev_state_table vcd_dev_table_in_invalid = { + { + NULL, + vcd_term_in_invalid, + NULL, + vcd_close_in_dev_invalid, + NULL, + NULL, + NULL, + NULL, + }, + vcd_dev_enter_invalid, + vcd_dev_exit_invalid +}; + +static const struct vcd_dev_state_table *vcd_dev_state_table[] = { + &vcd_dev_table_null, + &vcd_dev_table_not_init, + &vcd_dev_table_initing, + &vcd_dev_table_ready, + &vcd_dev_table_in_invalid +}; diff --git a/drivers/video/msm/vidc/common/vcd/vcd_device_sm.h b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.h new file mode 100644 index 000000000000..898f284bee8e --- /dev/null +++ b/drivers/video/msm/vidc/common/vcd/vcd_device_sm.h @@ -0,0 +1,96 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#ifndef _VCD_DEVICE_SM_H_ +#define _VCD_DEVICE_SM_H_ + +#include +#include "vcd_ddl_api.h" +#include "vcd_core.h" + +struct vcd_dev_state_table; +struct vcd_dev_state_ctxt; +struct vcd_drv_ctxt; + +enum vcd_dev_state_enum { + VCD_DEVICE_STATE_NULL = 0, + VCD_DEVICE_STATE_NOT_INIT, + VCD_DEVICE_STATE_INITING, + VCD_DEVICE_STATE_READY, + VCD_DEVICE_STATE_INVALID, + VCD_DEVICE_STATE_MAX, + VCD_DEVICE_STATE_32BIT = 0x7FFFFFFF +}; + +struct vcd_dev_state_table { + struct { + u32(*init) (struct vcd_drv_ctxt *drv_ctxt, + struct vcd_init_config *config, + s32 *driver_handle); + + u32(*term) (struct vcd_drv_ctxt *drv_ctxt, + s32 driver_handle); + + u32(*open) (struct vcd_drv_ctxt *drv_ctxt, + s32 driver_handle, u32 decoding, + void (*callback) (u32 event, u32 status, + void *info, size_t sz, void *handle, + void *const client_data), + void *client_data); + + u32(*close) (struct vcd_drv_ctxt *drv_ctxt, + struct vcd_clnt_ctxt *cctxt); + + u32(*resume) (struct vcd_drv_ctxt *drv_ctxt, + struct vcd_clnt_ctxt *cctxt); + + u32(*set_dev_pwr) (struct vcd_drv_ctxt *drv_ctxt, + enum vcd_power_state pwr_state); + + void (*dev_cb) (struct vcd_drv_ctxt *drv_ctxt, + u32 event, u32 status, void *payload, + size_t sz, u32 *ddl_handle, + void *const client_data); + + void (*timeout) (struct vcd_drv_ctxt *drv_ctxt, + void *user_data); + } ev_hdlr; + + void (*entry) (struct vcd_drv_ctxt *drv_ctxt, + s32 state_event); + void (*exit) (struct vcd_drv_ctxt *drv_ctxt, + s32 state_event); +}; + +#define DEVICE_STATE_EVENT_NUMBER(ppf) \ + ((u32 *) (&(((struct vcd_dev_state_table*)0)->ev_hdlr.ppf)) - \ + (u32 *) (&(((struct vcd_dev_state_table*)0)->ev_hdlr.init)) \ + + 1) + +struct vcd_dev_state_ctxt { + const struct vcd_dev_state_table *state_table; + + enum vcd_dev_state_enum state; +}; + +struct vcd_drv_ctxt { + struct vcd_dev_state_ctxt dev_state; + struct vcd_dev_ctxt dev_ctxt; + struct mutex dev_mutex; +}; + + +extern struct vcd_drv_ctxt *vcd_get_drv_context(void); + +void vcd_continue(void); + +#endif diff --git a/drivers/video/msm/vidc/common/vcd/vcd_power_sm.c b/drivers/video/msm/vidc/common/vcd/vcd_power_sm.c new file mode 100644 index 000000000000..c69cff3c283a --- /dev/null +++ b/drivers/video/msm/vidc/common/vcd/vcd_power_sm.c @@ -0,0 +1,366 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#include +#include "vcd_power_sm.h" +#include "vcd_core.h" +#include "vcd.h" + +u32 vcd_power_event( + struct vcd_dev_ctxt *dev_ctxt, + struct vcd_clnt_ctxt *cctxt, u32 event) +{ + u32 rc = VCD_S_SUCCESS; + + VCD_MSG_MED("Device power state = %d", dev_ctxt->pwr_clk_state); + VCD_MSG_MED("event = 0x%x", event); + switch (event) { + + case VCD_EVT_PWR_DEV_INIT_BEGIN: + case VCD_EVT_PWR_DEV_INIT_END: + case VCD_EVT_PWR_DEV_INIT_FAIL: + case VCD_EVT_PWR_DEV_TERM_BEGIN: + case VCD_EVT_PWR_DEV_TERM_END: + case VCD_EVT_PWR_DEV_TERM_FAIL: + case VCD_EVT_PWR_DEV_SLEEP_BEGIN: + case VCD_EVT_PWR_DEV_SLEEP_END: + case VCD_EVT_PWR_DEV_SET_PERFLVL: + case VCD_EVT_PWR_DEV_HWTIMEOUT: + { + rc = vcd_device_power_event(dev_ctxt, event, + cctxt); + break; + } + + case VCD_EVT_PWR_CLNT_CMD_BEGIN: + case VCD_EVT_PWR_CLNT_CMD_END: + case VCD_EVT_PWR_CLNT_CMD_FAIL: + case VCD_EVT_PWR_CLNT_PAUSE: + case VCD_EVT_PWR_CLNT_RESUME: + case VCD_EVT_PWR_CLNT_FIRST_FRAME: + case VCD_EVT_PWR_CLNT_LAST_FRAME: + case VCD_EVT_PWR_CLNT_ERRFATAL: + { + rc = vcd_client_power_event(dev_ctxt, cctxt, event); + break; + } + + } + + if (VCD_FAILED(rc)) + VCD_MSG_ERROR("vcd_power_event: event 0x%x failed", event); + + + return rc; + +} + +u32 vcd_device_power_event(struct vcd_dev_ctxt *dev_ctxt, u32 event, + struct vcd_clnt_ctxt *cctxt) +{ + u32 rc = VCD_ERR_FAIL; + u32 set_perf_lvl; + + switch (event) { + + case VCD_EVT_PWR_DEV_INIT_BEGIN: + { + if (dev_ctxt->pwr_clk_state == + VCD_PWRCLK_STATE_OFF) { + if (res_trk_get_max_perf_level(&dev_ctxt-> + max_perf_lvl)) { + if (res_trk_power_up()) { + dev_ctxt->pwr_clk_state = + VCD_PWRCLK_STATE_ON_NOTCLOCKED; + dev_ctxt->curr_perf_lvl = 0; + dev_ctxt->reqd_perf_lvl = 0; + dev_ctxt->active_clnts = 0; + dev_ctxt-> + set_perf_lvl_pending = false; + rc = vcd_enable_clock(dev_ctxt, + cctxt); + if (VCD_FAILED(rc)) { + (void)res_trk_power_down(); + dev_ctxt->pwr_clk_state = + VCD_PWRCLK_STATE_OFF; + } + } + } + } + + break; + } + + case VCD_EVT_PWR_DEV_INIT_END: + case VCD_EVT_PWR_DEV_TERM_FAIL: + case VCD_EVT_PWR_DEV_SLEEP_BEGIN: + case VCD_EVT_PWR_DEV_HWTIMEOUT: + { + rc = vcd_gate_clock(dev_ctxt); + + break; + } + + case VCD_EVT_PWR_DEV_INIT_FAIL: + case VCD_EVT_PWR_DEV_TERM_END: + { + if (dev_ctxt->pwr_clk_state != + VCD_PWRCLK_STATE_OFF) { + (void)vcd_disable_clock(dev_ctxt); + (void)res_trk_power_down(); + + dev_ctxt->pwr_clk_state = + VCD_PWRCLK_STATE_OFF; + dev_ctxt->curr_perf_lvl = 0; + dev_ctxt->reqd_perf_lvl = 0; + dev_ctxt->active_clnts = 0; + dev_ctxt->set_perf_lvl_pending = false; + rc = VCD_S_SUCCESS; + } + + break; + } + + case VCD_EVT_PWR_DEV_TERM_BEGIN: + case VCD_EVT_PWR_DEV_SLEEP_END: + { + rc = vcd_un_gate_clock(dev_ctxt); + + break; + } + + case VCD_EVT_PWR_DEV_SET_PERFLVL: + { + set_perf_lvl = + dev_ctxt->reqd_perf_lvl > + 0 ? dev_ctxt-> + reqd_perf_lvl : VCD_MIN_PERF_LEVEL; + rc = vcd_set_perf_level(dev_ctxt, set_perf_lvl); + break; + } + } + return rc; +} + +u32 vcd_client_power_event( + struct vcd_dev_ctxt *dev_ctxt, + struct vcd_clnt_ctxt *cctxt, u32 event) +{ + u32 rc = VCD_ERR_FAIL; + + switch (event) { + + case VCD_EVT_PWR_CLNT_CMD_BEGIN: + { + rc = vcd_un_gate_clock(dev_ctxt); + break; + } + + case VCD_EVT_PWR_CLNT_CMD_END: + { + rc = vcd_gate_clock(dev_ctxt); + break; + } + + case VCD_EVT_PWR_CLNT_CMD_FAIL: + { + if (!vcd_core_is_busy(dev_ctxt)) + rc = vcd_gate_clock(dev_ctxt); + + break; + } + + case VCD_EVT_PWR_CLNT_PAUSE: + case VCD_EVT_PWR_CLNT_LAST_FRAME: + case VCD_EVT_PWR_CLNT_ERRFATAL: + { + if (cctxt) { + rc = VCD_S_SUCCESS; + if (cctxt->status.req_perf_lvl) { + dev_ctxt->reqd_perf_lvl -= + cctxt->reqd_perf_lvl; + cctxt->status.req_perf_lvl = false; + rc = vcd_set_perf_level(dev_ctxt, + dev_ctxt->reqd_perf_lvl); + } + } + + break; + } + + case VCD_EVT_PWR_CLNT_RESUME: + case VCD_EVT_PWR_CLNT_FIRST_FRAME: + { + if (cctxt) { + rc = VCD_S_SUCCESS; + if (!cctxt->status.req_perf_lvl) { + dev_ctxt->reqd_perf_lvl += + cctxt->reqd_perf_lvl; + cctxt->status.req_perf_lvl = true; + + rc = vcd_set_perf_level(dev_ctxt, + dev_ctxt->reqd_perf_lvl); + } + } + break; + } + } + + return rc; +} + +u32 vcd_enable_clock(struct vcd_dev_ctxt *dev_ctxt, + struct vcd_clnt_ctxt *cctxt) +{ + u32 rc = VCD_S_SUCCESS; + u32 set_perf_lvl; + + if (dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_OFF) { + VCD_MSG_ERROR("vcd_enable_clock(): Already in state " + "VCD_PWRCLK_STATE_OFF\n"); + rc = VCD_ERR_FAIL; + } else if (dev_ctxt->pwr_clk_state == + VCD_PWRCLK_STATE_ON_NOTCLOCKED) { + set_perf_lvl = + dev_ctxt->reqd_perf_lvl > + 0 ? dev_ctxt-> + reqd_perf_lvl : VCD_MIN_PERF_LEVEL; + rc = vcd_set_perf_level(dev_ctxt, set_perf_lvl); + if (!VCD_FAILED(rc)) { + if (res_trk_enable_clocks()) { + dev_ctxt->pwr_clk_state = + VCD_PWRCLK_STATE_ON_CLOCKED; + } + } else { + rc = VCD_ERR_FAIL; + } + + } + + if (!VCD_FAILED(rc)) + dev_ctxt->active_clnts++; + + return rc; +} + +u32 vcd_disable_clock(struct vcd_dev_ctxt *dev_ctxt) +{ + u32 rc = VCD_S_SUCCESS; + + if (dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_OFF) { + VCD_MSG_ERROR("vcd_disable_clock(): Already in state " + "VCD_PWRCLK_STATE_OFF\n"); + rc = VCD_ERR_FAIL; + } else if (dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_ON_CLOCKED || + dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_ON_CLOCKGATED) { + dev_ctxt->active_clnts--; + + if (!dev_ctxt->active_clnts) { + if (!res_trk_disable_clocks()) + rc = VCD_ERR_FAIL; + + dev_ctxt->pwr_clk_state = + VCD_PWRCLK_STATE_ON_NOTCLOCKED; + dev_ctxt->curr_perf_lvl = 0; + } + } + + return rc; +} + +u32 vcd_set_perf_level(struct vcd_dev_ctxt *dev_ctxt, u32 perf_lvl) +{ + u32 rc = VCD_S_SUCCESS; + if (!vcd_core_is_busy(dev_ctxt)) { + if (res_trk_set_perf_level(perf_lvl, + &dev_ctxt->curr_perf_lvl, dev_ctxt)) { + dev_ctxt->set_perf_lvl_pending = false; + } else { + rc = VCD_ERR_FAIL; + dev_ctxt->set_perf_lvl_pending = true; + } + + } else { + dev_ctxt->set_perf_lvl_pending = true; + } + + return rc; +} + +u32 vcd_update_decoder_perf_level(struct vcd_dev_ctxt *dev_ctxt, u32 perf_lvl) +{ + u32 rc = VCD_S_SUCCESS; + + if (res_trk_set_perf_level(perf_lvl, + &dev_ctxt->curr_perf_lvl, dev_ctxt)) { + dev_ctxt->set_perf_lvl_pending = false; + } else { + rc = VCD_ERR_FAIL; + dev_ctxt->set_perf_lvl_pending = true; + } + + return rc; +} + +u32 vcd_update_clnt_perf_lvl( + struct vcd_clnt_ctxt *cctxt, + struct vcd_property_frame_rate *fps, u32 frm_p_units) +{ + u32 rc = VCD_S_SUCCESS; + struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; + u32 new_perf_lvl; + new_perf_lvl = frm_p_units *\ + (fps->fps_numerator / fps->fps_denominator); + if (cctxt->status.req_perf_lvl) { + dev_ctxt->reqd_perf_lvl = + dev_ctxt->reqd_perf_lvl - cctxt->reqd_perf_lvl + + new_perf_lvl; + rc = vcd_set_perf_level(cctxt->dev_ctxt, + dev_ctxt->reqd_perf_lvl); + } + cctxt->reqd_perf_lvl = new_perf_lvl; + return rc; +} + +u32 vcd_gate_clock(struct vcd_dev_ctxt *dev_ctxt) +{ + u32 rc = VCD_S_SUCCESS; + if (dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_OFF || + dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_ON_NOTCLOCKED) { + VCD_MSG_ERROR("%s(): Clk is Off or Not Clked yet\n", __func__); + rc = VCD_ERR_FAIL; + } else if (dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_ON_CLOCKGATED) + rc = VCD_S_SUCCESS; + else if (res_trk_disable_clocks()) + dev_ctxt->pwr_clk_state = VCD_PWRCLK_STATE_ON_CLOCKGATED; + else + rc = VCD_ERR_FAIL; + return rc; +} + +u32 vcd_un_gate_clock(struct vcd_dev_ctxt *dev_ctxt) +{ + u32 rc = VCD_S_SUCCESS; + if (dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_OFF || + dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_ON_NOTCLOCKED) { + VCD_MSG_ERROR("%s(): Clk is Off or Not Clked yet\n", __func__); + rc = VCD_ERR_FAIL; + } else if (dev_ctxt->pwr_clk_state == VCD_PWRCLK_STATE_ON_CLOCKED) + rc = VCD_S_SUCCESS; + else if (res_trk_enable_clocks()) + dev_ctxt->pwr_clk_state = VCD_PWRCLK_STATE_ON_CLOCKED; + else + rc = VCD_ERR_FAIL; + return rc; +} + diff --git a/drivers/video/msm/vidc/common/vcd/vcd_power_sm.h b/drivers/video/msm/vidc/common/vcd/vcd_power_sm.h new file mode 100644 index 000000000000..aecbc8d58f28 --- /dev/null +++ b/drivers/video/msm/vidc/common/vcd/vcd_power_sm.h @@ -0,0 +1,43 @@ +/* Copyright (c) 2010, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#ifndef _VCD_POWERSM_H_ +#define _VCD_POWERSM_H_ + +#define VCD_EVT_PWR_BASE 0x5000 +#define VCD_EVT_PWR_DEV_INIT_BEGIN (VCD_EVT_PWR_BASE + 0x1) +#define VCD_EVT_PWR_DEV_INIT_END (VCD_EVT_PWR_BASE + 0x2) +#define VCD_EVT_PWR_DEV_INIT_FAIL (VCD_EVT_PWR_BASE + 0x3) +#define VCD_EVT_PWR_DEV_TERM_BEGIN (VCD_EVT_PWR_BASE + 0x4) +#define VCD_EVT_PWR_DEV_TERM_END (VCD_EVT_PWR_BASE + 0x5) +#define VCD_EVT_PWR_DEV_TERM_FAIL (VCD_EVT_PWR_BASE + 0x6) +#define VCD_EVT_PWR_DEV_SLEEP_BEGIN (VCD_EVT_PWR_BASE + 0x7) +#define VCD_EVT_PWR_DEV_SLEEP_END (VCD_EVT_PWR_BASE + 0x8) +#define VCD_EVT_PWR_DEV_SET_PERFLVL (VCD_EVT_PWR_BASE + 0x9) +#define VCD_EVT_PWR_DEV_HWTIMEOUT (VCD_EVT_PWR_BASE + 0xa) +#define VCD_EVT_PWR_CLNT_CMD_BEGIN (VCD_EVT_PWR_BASE + 0xb) +#define VCD_EVT_PWR_CLNT_CMD_END (VCD_EVT_PWR_BASE + 0xc) +#define VCD_EVT_PWR_CLNT_CMD_FAIL (VCD_EVT_PWR_BASE + 0xd) +#define VCD_EVT_PWR_CLNT_PAUSE (VCD_EVT_PWR_BASE + 0xe) +#define VCD_EVT_PWR_CLNT_RESUME (VCD_EVT_PWR_BASE + 0xf) +#define VCD_EVT_PWR_CLNT_FIRST_FRAME (VCD_EVT_PWR_BASE + 0x10) +#define VCD_EVT_PWR_CLNT_LAST_FRAME (VCD_EVT_PWR_BASE + 0x11) +#define VCD_EVT_PWR_CLNT_ERRFATAL (VCD_EVT_PWR_BASE + 0x12) + +enum vcd_pwr_clk_state { + VCD_PWRCLK_STATE_OFF = 0, + VCD_PWRCLK_STATE_ON_NOTCLOCKED, + VCD_PWRCLK_STATE_ON_CLOCKED, + VCD_PWRCLK_STATE_ON_CLOCKGATED +}; + +#endif diff --git a/drivers/video/msm/vidc/common/vcd/vcd_scheduler.c b/drivers/video/msm/vidc/common/vcd/vcd_scheduler.c new file mode 100644 index 000000000000..e3924143962a --- /dev/null +++ b/drivers/video/msm/vidc/common/vcd/vcd_scheduler.c @@ -0,0 +1,287 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#include +#include "vcd.h" + +#define NORMALIZATION_FACTOR 3600 +#define ADJUST_CLIENT_ROUNDS(client, round_adjustment) \ +do {\ + if ((client)->rounds < round_adjustment) {\ + (client)->rounds = 0;\ + VCD_MSG_HIGH("%s(): WARNING: Scheduler list unsorted",\ + __func__);\ + } else\ + (client)->rounds -= round_adjustment;\ +} while (0) + +u32 vcd_sched_create(struct list_head *sched_list) +{ + u32 rc = VCD_S_SUCCESS; + if (!sched_list) { + VCD_MSG_ERROR("%s(): Invalid parameter", __func__); + rc = VCD_ERR_ILLEGAL_PARM; + } else + INIT_LIST_HEAD(sched_list); + return rc; +} + +void vcd_sched_destroy(struct list_head *sched_clnt_list) +{ + struct vcd_sched_clnt_ctx *sched_clnt, *sched_clnt_next; + if (sched_clnt_list) + list_for_each_entry_safe(sched_clnt, + sched_clnt_next, sched_clnt_list, list) { + list_del_init(&sched_clnt->list); + sched_clnt->clnt_active = false; + } +} + +void insert_client_in_list(struct list_head *sched_clnt_list, + struct vcd_sched_clnt_ctx *sched_new_clnt, bool tail) +{ + struct vcd_sched_clnt_ctx *sched_clnt; + if (!list_empty(sched_clnt_list)) { + if (tail) + sched_clnt = list_entry(sched_clnt_list->prev, + struct vcd_sched_clnt_ctx, list); + else + sched_clnt = list_first_entry(sched_clnt_list, + struct vcd_sched_clnt_ctx, list); + sched_new_clnt->rounds = sched_clnt->rounds; + } else + sched_new_clnt->rounds = 0; + if (tail) + list_add_tail(&sched_new_clnt->list, sched_clnt_list); + else + list_add(&sched_new_clnt->list, sched_clnt_list); +} + +u32 vcd_sched_add_client(struct vcd_clnt_ctxt *cctxt) +{ + struct vcd_property_hdr prop_hdr; + struct vcd_sched_clnt_ctx *sched_cctxt; + u32 rc = VCD_S_SUCCESS; + if (!cctxt) { + VCD_MSG_ERROR("%s(): Invalid parameter", __func__); + rc = VCD_ERR_ILLEGAL_PARM; + } else if (cctxt->sched_clnt_hdl) + VCD_MSG_HIGH( + "%s(): Scheduler client already exists!", __func__); + else { + sched_cctxt = (struct vcd_sched_clnt_ctx *) + kmalloc(sizeof(struct vcd_sched_clnt_ctx), + GFP_KERNEL); + if (sched_cctxt) { + + prop_hdr.prop_id = DDL_I_FRAME_PROC_UNITS; + prop_hdr.sz = sizeof(cctxt->frm_p_units); + rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr, + &cctxt->frm_p_units); + VCD_FAILED_RETURN(rc, + "Failed: Get DDL_I_FRAME_PROC_UNITS"); + if (cctxt->decoding) { + cctxt->frm_rate.fps_numerator = + VCD_DEC_INITIAL_FRAME_RATE; + cctxt->frm_rate.fps_denominator = 1; + } else { + prop_hdr.prop_id = VCD_I_FRAME_RATE; + prop_hdr.sz = sizeof(cctxt->frm_rate); + rc = ddl_get_property(cctxt->ddl_handle, + &prop_hdr, &cctxt->frm_rate); + VCD_FAILED_RETURN(rc, + "Failed: Get VCD_I_FRAME_RATE"); + } + if (!cctxt->perf_set_by_client) + cctxt->reqd_perf_lvl = cctxt->frm_p_units * + cctxt->frm_rate.fps_numerator / + cctxt->frm_rate.fps_denominator; + + cctxt->sched_clnt_hdl = sched_cctxt; + memset(sched_cctxt, 0, + sizeof(struct vcd_sched_clnt_ctx)); + sched_cctxt->tkns = 0; + sched_cctxt->round_perfrm = NORMALIZATION_FACTOR * + cctxt->frm_rate.fps_denominator / + cctxt->frm_rate.fps_numerator; + sched_cctxt->clnt_active = true; + sched_cctxt->clnt_data = cctxt; + INIT_LIST_HEAD(&sched_cctxt->ip_frm_list); + + insert_client_in_list( + &cctxt->dev_ctxt->sched_clnt_list, + sched_cctxt, false); + } + } + return rc; +} + +u32 vcd_sched_remove_client(struct vcd_sched_clnt_ctx *sched_cctxt) +{ + u32 rc = VCD_S_SUCCESS; + struct vcd_clnt_ctxt *cctxt; + if (!sched_cctxt) { + VCD_MSG_ERROR("%s(): Invalid handle ptr", __func__); + rc = VCD_ERR_ILLEGAL_PARM; + } else if (!list_empty(&sched_cctxt->ip_frm_list)) { + VCD_MSG_ERROR( + "%s(): Cannot remove client, queue no empty", __func__); + rc = VCD_ERR_ILLEGAL_OP; + } else { + cctxt = sched_cctxt->clnt_data; + list_del(&sched_cctxt->list); + memset(sched_cctxt, 0, + sizeof(struct vcd_sched_clnt_ctx)); + kfree(sched_cctxt); + } + return rc; +} + +u32 vcd_sched_update_config(struct vcd_clnt_ctxt *cctxt) +{ + u32 rc = VCD_S_SUCCESS; + if (!cctxt || !cctxt->sched_clnt_hdl) { + VCD_MSG_ERROR("%s(): Invalid parameter", __func__); + rc = VCD_ERR_ILLEGAL_PARM; + } else { + cctxt->sched_clnt_hdl->rounds /= + cctxt->sched_clnt_hdl->round_perfrm; + cctxt->sched_clnt_hdl->round_perfrm = + NORMALIZATION_FACTOR * + cctxt->frm_rate.fps_denominator / + cctxt->frm_rate.fps_numerator; + cctxt->sched_clnt_hdl->rounds *= + cctxt->sched_clnt_hdl->round_perfrm; + } + return rc; +} + +u32 vcd_sched_queue_buffer( + struct vcd_sched_clnt_ctx *sched_cctxt, + struct vcd_buffer_entry *buffer, u32 tail) +{ + u32 rc = VCD_S_SUCCESS; + if (!sched_cctxt || !buffer) { + VCD_MSG_ERROR("%s(): Invalid parameter", __func__); + rc = VCD_ERR_ILLEGAL_PARM; + } else if (tail) + list_add_tail(&buffer->sched_list, + &sched_cctxt->ip_frm_list); + else + list_add(&buffer->sched_list, &sched_cctxt->ip_frm_list); + return rc; +} + +u32 vcd_sched_dequeue_buffer( + struct vcd_sched_clnt_ctx *sched_cctxt, + struct vcd_buffer_entry **buffer) +{ + u32 rc = VCD_ERR_QEMPTY; + if (!sched_cctxt || !buffer) { + VCD_MSG_ERROR("%s(): Invalid parameter", __func__); + rc = VCD_ERR_ILLEGAL_PARM; + } else { + *buffer = NULL; + if (!list_empty(&sched_cctxt->ip_frm_list)) { + *buffer = list_first_entry( + &sched_cctxt->ip_frm_list, + struct vcd_buffer_entry, + sched_list); + list_del(&(*buffer)->sched_list); + rc = VCD_S_SUCCESS; + } + } + return rc; +} + +u32 vcd_sched_mark_client_eof(struct vcd_sched_clnt_ctx *sched_cctxt) +{ + u32 rc = VCD_S_SUCCESS; + struct vcd_buffer_entry *buffer = NULL; + if (!sched_cctxt) { + VCD_MSG_ERROR("%s(): Invalid parameter", __func__); + rc = VCD_ERR_ILLEGAL_PARM; + } else if (!list_empty(&sched_cctxt->ip_frm_list)) { + buffer = list_entry(sched_cctxt->ip_frm_list.prev, + struct vcd_buffer_entry, sched_list); + buffer->frame.flags |= VCD_FRAME_FLAG_EOS; + } else + rc = VCD_ERR_QEMPTY; + return rc; +} + +u32 vcd_sched_suspend_resume_clnt( + struct vcd_clnt_ctxt *cctxt, u32 state) +{ + u32 rc = VCD_S_SUCCESS; + struct vcd_sched_clnt_ctx *sched_cctxt; + if (!cctxt || !cctxt->sched_clnt_hdl) { + VCD_MSG_ERROR("%s(): Invalid parameter", __func__); + rc = VCD_ERR_ILLEGAL_PARM; + } else { + sched_cctxt = cctxt->sched_clnt_hdl; + if (state != sched_cctxt->clnt_active) { + sched_cctxt->clnt_active = state; + if (state) + insert_client_in_list(&cctxt->dev_ctxt->\ + sched_clnt_list, sched_cctxt, false); + else + list_del_init(&sched_cctxt->list); + } + } + return rc; +} + +u32 vcd_sched_get_client_frame(struct list_head *sched_clnt_list, + struct vcd_clnt_ctxt **cctxt, + struct vcd_buffer_entry **buffer) +{ + u32 rc = VCD_ERR_QEMPTY, round_adjustment = 0; + struct vcd_sched_clnt_ctx *sched_clnt, *clnt_nxt; + if (!sched_clnt_list || !cctxt || !buffer) { + VCD_MSG_ERROR("%s(): Invalid parameter", __func__); + rc = VCD_ERR_ILLEGAL_PARM; + } else if (!list_empty(sched_clnt_list)) { + *cctxt = NULL; + *buffer = NULL; + list_for_each_entry_safe(sched_clnt, + clnt_nxt, sched_clnt_list, list) { + if (&sched_clnt->list == sched_clnt_list->next) + round_adjustment = sched_clnt->rounds; + if (*cctxt) { + if ((*cctxt)->sched_clnt_hdl->rounds >= + sched_clnt->rounds) + list_move(&(*cctxt)->sched_clnt_hdl\ + ->list, &sched_clnt->list); + ADJUST_CLIENT_ROUNDS(sched_clnt, + round_adjustment); + } else if (sched_clnt->tkns && + !list_empty(&sched_clnt->ip_frm_list)) { + *cctxt = sched_clnt->clnt_data; + sched_clnt->rounds += sched_clnt->round_perfrm; + } else + ADJUST_CLIENT_ROUNDS(sched_clnt, + round_adjustment); + } + if (*cctxt) { + rc = vcd_sched_dequeue_buffer( + (*cctxt)->sched_clnt_hdl, buffer); + if (rc == VCD_S_SUCCESS) { + (*cctxt)->sched_clnt_hdl->tkns--; + ADJUST_CLIENT_ROUNDS((*cctxt)->\ + sched_clnt_hdl, round_adjustment); + } + } + } + return rc; +} diff --git a/drivers/video/msm/vidc/common/vcd/vcd_sub.c b/drivers/video/msm/vidc/common/vcd/vcd_sub.c new file mode 100644 index 000000000000..9cbf7d5b92f9 --- /dev/null +++ b/drivers/video/msm/vidc/common/vcd/vcd_sub.c @@ -0,0 +1,3433 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#include +#include +#include +#include +#include "vcd.h" +#include "vdec_internal.h" + +#define MAX(x, y) (((x) > (y)) ? (x) : (y)) +#define MAP_TABLE_SZ 64 +#define VCD_ENC_MAX_OUTBFRS_PER_FRAME 8 +#define MAX_DEC_TIME 33 + +struct vcd_msm_map_buffer { + phys_addr_t phy_addr; + struct msm_mapped_buffer *mapped_buffer; + struct ion_handle *alloc_handle; + u32 in_use; +}; +static struct vcd_msm_map_buffer msm_mapped_buffer_table[MAP_TABLE_SZ]; +static unsigned int vidc_mmu_subsystem[] = {MSM_SUBSYSTEM_VIDEO}; + +static int vcd_pmem_alloc(size_t sz, u8 **kernel_vaddr, u8 **phy_addr, + struct vcd_clnt_ctxt *cctxt) +{ + u32 memtype, i = 0, flags = 0; + struct vcd_msm_map_buffer *map_buffer = NULL; + struct msm_mapped_buffer *mapped_buffer = NULL; + unsigned long iova = 0; + unsigned long buffer_size = 0; + int ret = 0; + unsigned long ionflag = 0; + + if (!kernel_vaddr || !phy_addr || !cctxt) { + pr_err("\n%s: Invalid parameters", __func__); + goto bailout; + } + *phy_addr = NULL; + *kernel_vaddr = NULL; + for (i = 0; i < MAP_TABLE_SZ; i++) { + if (!msm_mapped_buffer_table[i].in_use) { + map_buffer = &msm_mapped_buffer_table[i]; + map_buffer->in_use = 1; + break; + } + } + if (!map_buffer) { + pr_err("%s() map table is full", __func__); + goto bailout; + } + res_trk_set_mem_type(DDL_MM_MEM); + memtype = res_trk_get_mem_type(); + if (!cctxt->vcd_enable_ion) { + map_buffer->phy_addr = (phys_addr_t) + allocate_contiguous_memory_nomap(sz, memtype, SZ_4K); + if (!map_buffer->phy_addr) { + pr_err("%s() acm alloc failed", __func__); + goto free_map_table; + } + flags = MSM_SUBSYSTEM_MAP_IOVA | MSM_SUBSYSTEM_MAP_KADDR; + map_buffer->mapped_buffer = + msm_subsystem_map_buffer((unsigned long)map_buffer->phy_addr, + sz, flags, vidc_mmu_subsystem, + sizeof(vidc_mmu_subsystem)/sizeof(unsigned int)); + if (IS_ERR(map_buffer->mapped_buffer)) { + pr_err(" %s() buffer map failed", __func__); + goto free_acm_alloc; + } + mapped_buffer = map_buffer->mapped_buffer; + if (!mapped_buffer->vaddr || !mapped_buffer->iova[0]) { + pr_err("%s() map buffers failed", __func__); + goto free_map_buffers; + } + *phy_addr = (u8 *) mapped_buffer->iova[0]; + *kernel_vaddr = (u8 *) mapped_buffer->vaddr; + } else { + map_buffer->alloc_handle = ion_alloc( + cctxt->vcd_ion_client, sz, SZ_4K, + memtype); + if (!map_buffer->alloc_handle) { + pr_err("%s() ION alloc failed", __func__); + goto bailout; + } + if (ion_handle_get_flags(cctxt->vcd_ion_client, + map_buffer->alloc_handle, + &ionflag)) { + pr_err("%s() ION get flag failed", __func__); + goto bailout; + } + *kernel_vaddr = (u8 *) ion_map_kernel( + cctxt->vcd_ion_client, + map_buffer->alloc_handle, + ionflag); + if (!(*kernel_vaddr)) { + pr_err("%s() ION map failed", __func__); + goto ion_free_bailout; + } + ret = ion_map_iommu(cctxt->vcd_ion_client, + map_buffer->alloc_handle, + VIDEO_DOMAIN, + VIDEO_MAIN_POOL, + SZ_4K, + 0, + (unsigned long *)&iova, + (unsigned long *)&buffer_size, + UNCACHED, 0); + if (ret) { + pr_err("%s() ION iommu map failed", __func__); + goto ion_map_bailout; + } + map_buffer->phy_addr = iova; + if (!map_buffer->phy_addr) { + pr_err("%s() acm alloc failed", __func__); + goto free_map_table; + } + *phy_addr = (u8 *)iova; + mapped_buffer = NULL; + map_buffer->mapped_buffer = NULL; + } + + return 0; + +free_map_buffers: + if (map_buffer->mapped_buffer) + msm_subsystem_unmap_buffer(map_buffer->mapped_buffer); +free_acm_alloc: + if (!cctxt->vcd_enable_ion) { + free_contiguous_memory_by_paddr( + (unsigned long)map_buffer->phy_addr); + } + return -ENOMEM; +ion_map_bailout: + ion_unmap_kernel(cctxt->vcd_ion_client, map_buffer->alloc_handle); +ion_free_bailout: + ion_free(cctxt->vcd_ion_client, map_buffer->alloc_handle); +free_map_table: + map_buffer->in_use = 0; +bailout: + return -ENOMEM; +} + +static int vcd_pmem_free(u8 *kernel_vaddr, u8 *phy_addr, + struct vcd_clnt_ctxt *cctxt) +{ + u32 i = 0; + struct vcd_msm_map_buffer *map_buffer = NULL; + + if (!kernel_vaddr || !phy_addr || !cctxt) { + pr_err("\n%s: Invalid parameters", __func__); + goto bailout; + } + for (i = 0; i < MAP_TABLE_SZ; i++) { + if (msm_mapped_buffer_table[i].in_use && + (msm_mapped_buffer_table[i] + .mapped_buffer->vaddr == kernel_vaddr)) { + map_buffer = &msm_mapped_buffer_table[i]; + map_buffer->in_use = 0; + break; + } + } + if (!map_buffer) { + pr_err("%s() Entry not found", __func__); + goto bailout; + } + if (map_buffer->mapped_buffer) + msm_subsystem_unmap_buffer(map_buffer->mapped_buffer); + if (cctxt->vcd_enable_ion) { + if (map_buffer->alloc_handle) { + ion_unmap_kernel(cctxt->vcd_ion_client, + map_buffer->alloc_handle); + ion_unmap_iommu(cctxt->vcd_ion_client, + map_buffer->alloc_handle, + VIDEO_DOMAIN, + VIDEO_MAIN_POOL); + ion_free(cctxt->vcd_ion_client, + map_buffer->alloc_handle); + } + } else { + free_contiguous_memory_by_paddr( + (unsigned long)map_buffer->phy_addr); + } +bailout: + kernel_vaddr = NULL; + phy_addr = NULL; + return 0; +} + + +u8 *vcd_pmem_get_physical(struct video_client_ctx *client_ctx, + unsigned long kernel_vaddr) +{ + unsigned long phy_addr, user_vaddr; + int pmem_fd; + struct file *file; + s32 buffer_index = -1; + + if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_INPUT, + false, &user_vaddr, &kernel_vaddr, + &phy_addr, &pmem_fd, &file, + &buffer_index)) { + + return (u8 *) phy_addr; + } else if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT, + false, &user_vaddr, &kernel_vaddr, &phy_addr, &pmem_fd, &file, + &buffer_index)) { + return (u8 *) phy_addr; + } else { + VCD_MSG_ERROR("Couldn't get physical address"); + + return NULL; + } + +} + +u32 vcd_get_ion_flag(struct video_client_ctx *client_ctx, + unsigned long kernel_vaddr, + struct ion_handle **buff_ion_handle) +{ + unsigned long phy_addr, user_vaddr; + int pmem_fd; + struct file *file; + s32 buffer_index = -1; + u32 ion_flag = 0; + struct ion_handle *buff_handle = NULL; + + if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_INPUT, + false, &user_vaddr, &kernel_vaddr, + &phy_addr, &pmem_fd, &file, + &buffer_index)) { + + ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_INPUT, + pmem_fd, kernel_vaddr, buffer_index, + &buff_handle); + *buff_ion_handle = buff_handle; + return ion_flag; + } else if (vidc_lookup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT, + false, &user_vaddr, &kernel_vaddr, &phy_addr, &pmem_fd, &file, + &buffer_index)) { + ion_flag = vidc_get_fd_info(client_ctx, BUFFER_TYPE_OUTPUT, + pmem_fd, kernel_vaddr, buffer_index, + &buff_handle); + *buff_ion_handle = buff_handle; + return ion_flag; + } else { + VCD_MSG_ERROR("Couldn't get ion flag"); + return 0; + } + +} + +void vcd_reset_device_channels(struct vcd_dev_ctxt *dev_ctxt) +{ + dev_ctxt->ddl_frame_ch_free = dev_ctxt->ddl_frame_ch_depth; + dev_ctxt->ddl_cmd_ch_free = dev_ctxt->ddl_cmd_ch_depth; + dev_ctxt->ddl_frame_ch_interim = 0; + dev_ctxt->ddl_cmd_ch_interim = 0; +} + +u32 vcd_get_command_channel( + struct vcd_dev_ctxt *dev_ctxt, + struct vcd_transc **transc) +{ + u32 result = false; + + *transc = NULL; + + if (dev_ctxt->ddl_cmd_ch_free > 0) { + if (dev_ctxt->ddl_cmd_concurrency) { + --dev_ctxt->ddl_cmd_ch_free; + result = true; + } else if ((dev_ctxt->ddl_frame_ch_free + + dev_ctxt->ddl_frame_ch_interim) + == dev_ctxt->ddl_frame_ch_depth) { + --dev_ctxt->ddl_cmd_ch_free; + result = true; + } + } + + if (result) { + *transc = vcd_get_free_trans_tbl_entry(dev_ctxt); + + if (!*transc) { + result = false; + + vcd_release_command_channel(dev_ctxt, *transc); + } + + } + return result; +} + +u32 vcd_get_command_channel_in_loop( + struct vcd_dev_ctxt *dev_ctxt, + struct vcd_transc **transc) +{ + u32 result = false; + + *transc = NULL; + + if (dev_ctxt->ddl_cmd_ch_interim > 0) { + if (dev_ctxt->ddl_cmd_concurrency) { + --dev_ctxt->ddl_cmd_ch_interim; + result = true; + } else if ((dev_ctxt->ddl_frame_ch_free + + dev_ctxt->ddl_frame_ch_interim) + == dev_ctxt->ddl_frame_ch_depth) { + --dev_ctxt->ddl_cmd_ch_interim; + result = true; + } + } else { + result = vcd_get_command_channel(dev_ctxt, transc); + } + + if (result && !*transc) { + *transc = vcd_get_free_trans_tbl_entry(dev_ctxt); + + if (!*transc) { + result = false; + + ++dev_ctxt->ddl_cmd_ch_interim; + } + + } + + return result; +} + +void vcd_mark_command_channel(struct vcd_dev_ctxt *dev_ctxt, + struct vcd_transc *transc) +{ + ++dev_ctxt->ddl_cmd_ch_interim; + + vcd_release_trans_tbl_entry(transc); + if (dev_ctxt->ddl_cmd_ch_interim + + dev_ctxt->ddl_cmd_ch_free > + dev_ctxt->ddl_cmd_ch_depth) { + VCD_MSG_ERROR("\n Command channel access counters messed up"); + } +} + +void vcd_release_command_channel( + struct vcd_dev_ctxt *dev_ctxt, struct vcd_transc *transc) +{ + ++dev_ctxt->ddl_cmd_ch_free; + + vcd_release_trans_tbl_entry(transc); + if (dev_ctxt->ddl_cmd_ch_interim + dev_ctxt->ddl_cmd_ch_free > + dev_ctxt->ddl_cmd_ch_depth) { + VCD_MSG_ERROR("\n Command channel access counters messed up"); + } +} + +void vcd_release_multiple_command_channels(struct vcd_dev_ctxt + *dev_ctxt, u32 channels) +{ + dev_ctxt->ddl_cmd_ch_free += channels; + + if (dev_ctxt->ddl_cmd_ch_interim + + dev_ctxt->ddl_cmd_ch_free > + dev_ctxt->ddl_cmd_ch_depth) { + VCD_MSG_ERROR("\n Command channel access counters messed up"); + } +} + +void vcd_release_interim_command_channels(struct vcd_dev_ctxt *dev_ctxt) +{ + dev_ctxt->ddl_cmd_ch_free += dev_ctxt->ddl_cmd_ch_interim; + dev_ctxt->ddl_cmd_ch_interim = 0; + + if (dev_ctxt->ddl_cmd_ch_interim + dev_ctxt->ddl_cmd_ch_free > + dev_ctxt->ddl_cmd_ch_depth) { + VCD_MSG_ERROR("\n Command channel access counters messed up"); + } +} + +u32 vcd_get_frame_channel(struct vcd_dev_ctxt *dev_ctxt, + struct vcd_transc **transc) +{ + u32 result = false; + + if (dev_ctxt->ddl_frame_ch_free > 0) { + if (dev_ctxt->ddl_cmd_concurrency) { + --dev_ctxt->ddl_frame_ch_free; + result = true; + } else if ((dev_ctxt->ddl_cmd_ch_free + + dev_ctxt->ddl_cmd_ch_interim) + == dev_ctxt->ddl_cmd_ch_depth) { + --dev_ctxt->ddl_frame_ch_free; + result = true; + } + } + + if (result) { + *transc = vcd_get_free_trans_tbl_entry(dev_ctxt); + + if (!*transc) { + result = false; + + vcd_release_frame_channel(dev_ctxt, *transc); + } else { + (*transc)->type = VCD_CMD_CODE_FRAME; + } + + } + + return result; +} + +u32 vcd_get_frame_channel_in_loop( + struct vcd_dev_ctxt *dev_ctxt, + struct vcd_transc **transc) +{ + u32 result = false; + + *transc = NULL; + + if (dev_ctxt->ddl_frame_ch_interim > 0) { + if (dev_ctxt->ddl_cmd_concurrency) { + --dev_ctxt->ddl_frame_ch_interim; + result = true; + } else if ((dev_ctxt->ddl_cmd_ch_free + + dev_ctxt->ddl_cmd_ch_interim) + == dev_ctxt->ddl_cmd_ch_depth) { + --dev_ctxt->ddl_frame_ch_interim; + result = true; + } + } else { + result = vcd_get_frame_channel(dev_ctxt, transc); + } + + if (result && !*transc) { + *transc = vcd_get_free_trans_tbl_entry(dev_ctxt); + + if (!*transc) { + result = false; + VCD_MSG_FATAL("\n%s: All transactions are busy;" + "Couldnt find free one\n", __func__); + ++dev_ctxt->ddl_frame_ch_interim; + } else + (*transc)->type = VCD_CMD_CODE_FRAME; + } + + return result; +} + +void vcd_mark_frame_channel(struct vcd_dev_ctxt *dev_ctxt) +{ + ++dev_ctxt->ddl_frame_ch_interim; + + if (dev_ctxt->ddl_frame_ch_interim + + dev_ctxt->ddl_frame_ch_free > + dev_ctxt->ddl_cmd_ch_depth) { + VCD_MSG_FATAL("Frame channel access counters messed up"); + } +} + +void vcd_release_frame_channel(struct vcd_dev_ctxt *dev_ctxt, + struct vcd_transc *transc) +{ + ++dev_ctxt->ddl_frame_ch_free; + + vcd_release_trans_tbl_entry(transc); + + if (dev_ctxt->ddl_frame_ch_interim + + dev_ctxt->ddl_frame_ch_free > + dev_ctxt->ddl_cmd_ch_depth) { + VCD_MSG_FATAL("Frame channel access counters messed up"); + } +} + +void vcd_release_multiple_frame_channels(struct vcd_dev_ctxt + *dev_ctxt, u32 channels) +{ + dev_ctxt->ddl_frame_ch_free += channels; + + if (dev_ctxt->ddl_frame_ch_interim + + dev_ctxt->ddl_frame_ch_free > + dev_ctxt->ddl_frame_ch_depth) { + VCD_MSG_FATAL("Frame channel access counters messed up"); + } +} + +void vcd_release_interim_frame_channels(struct vcd_dev_ctxt + *dev_ctxt) +{ + dev_ctxt->ddl_frame_ch_free += + dev_ctxt->ddl_frame_ch_interim; + dev_ctxt->ddl_frame_ch_interim = 0; + + if (dev_ctxt->ddl_frame_ch_free > + dev_ctxt->ddl_cmd_ch_depth) { + VCD_MSG_FATAL("Frame channel access counters messed up"); + } +} + +u32 vcd_core_is_busy(struct vcd_dev_ctxt *dev_ctxt) +{ + if (((dev_ctxt->ddl_cmd_ch_free + + dev_ctxt->ddl_cmd_ch_interim) != + dev_ctxt->ddl_cmd_ch_depth) + || + ((dev_ctxt->ddl_frame_ch_free + + dev_ctxt->ddl_frame_ch_interim) != + dev_ctxt->ddl_frame_ch_depth) + ) { + return true; + } else { + return false; + } +} + +void vcd_device_timer_start(struct vcd_dev_ctxt *dev_ctxt) +{ + if (dev_ctxt->config.timer_start) + dev_ctxt->config.timer_start(dev_ctxt->hw_timer_handle, + dev_ctxt->hw_time_out); +} + +void vcd_device_timer_stop(struct vcd_dev_ctxt *dev_ctxt) +{ + if (dev_ctxt->config.timer_stop) + dev_ctxt->config.timer_stop(dev_ctxt->hw_timer_handle); +} + + +u32 vcd_common_allocate_set_buffer( + struct vcd_clnt_ctxt *cctxt, + enum vcd_buffer_type buffer, + u32 buf_size, struct vcd_buffer_pool **buffer_pool) +{ + u32 rc = VCD_S_SUCCESS; + struct vcd_buffer_requirement Buf_req; + struct vcd_property_hdr Prop_hdr; + struct vcd_buffer_pool *buf_pool; + + if (buffer == VCD_BUFFER_INPUT) { + Prop_hdr.prop_id = DDL_I_INPUT_BUF_REQ; + buf_pool = &cctxt->in_buf_pool; + } else if (buffer == VCD_BUFFER_OUTPUT) { + Prop_hdr.prop_id = DDL_I_OUTPUT_BUF_REQ; + buf_pool = &cctxt->out_buf_pool; + } else { + rc = VCD_ERR_ILLEGAL_PARM; + } + VCD_FAILED_RETURN(rc, "Invalid buffer type provided"); + + *buffer_pool = buf_pool; + + if (buf_pool->count > 0 && + buf_pool->validated == buf_pool->count) { + VCD_MSG_ERROR("Buffer pool is full"); + return VCD_ERR_FAIL; + } + + if (!buf_pool->entries) { + Prop_hdr.sz = sizeof(Buf_req); + rc = ddl_get_property(cctxt->ddl_handle, &Prop_hdr, &Buf_req); + if (!VCD_FAILED(rc)) { + rc = vcd_alloc_buffer_pool_entries(buf_pool, + &Buf_req); + } else { + VCD_MSG_ERROR("rc = 0x%x. Failed: ddl_get_property", + rc); + } + } + + if (!VCD_FAILED(rc)) { + if (buf_pool->buf_req.sz > buf_size) { + VCD_MSG_ERROR("\n required buffer sz %u " + "allocated sz %u", buf_pool->buf_req. + sz, buf_size); + + rc = VCD_ERR_ILLEGAL_PARM; + } + } + + return rc; +} + +u32 vcd_set_buffer_internal( + struct vcd_clnt_ctxt *cctxt, + struct vcd_buffer_pool *buf_pool, u8 *buffer, u32 buf_size) +{ + struct vcd_buffer_entry *buf_entry; + u8 *physical; + u32 ion_flag = 0; + struct ion_handle *buff_handle = NULL; + + buf_entry = vcd_find_buffer_pool_entry(buf_pool, buffer); + if (buf_entry) { + VCD_MSG_ERROR("This buffer address already exists"); + + return VCD_ERR_ILLEGAL_OP; + } + + physical = (u8 *) vcd_pmem_get_physical( + cctxt->client_data, (unsigned long)buffer); + + ion_flag = vcd_get_ion_flag(cctxt->client_data, + (unsigned long)buffer, + &buff_handle); + if (!physical) { + VCD_MSG_ERROR("Couldn't get physical address"); + return VCD_ERR_BAD_POINTER; + } + if (((u32) physical % buf_pool->buf_req.align)) { + VCD_MSG_ERROR("Physical addr is not aligned"); + return VCD_ERR_BAD_POINTER; + } + + buf_entry = vcd_get_free_buffer_pool_entry(buf_pool); + if (!buf_entry) { + VCD_MSG_ERROR("Can't allocate buffer pool is full"); + return VCD_ERR_FAIL; + } + buf_entry->virtual = buffer; + buf_entry->physical = physical; + buf_entry->sz = buf_size; + buf_entry->frame.alloc_len = buf_size; + buf_entry->allocated = false; + + buf_entry->frame.virtual = buf_entry->virtual; + buf_entry->frame.physical = buf_entry->physical; + buf_entry->frame.ion_flag = ion_flag; + buf_entry->frame.buff_ion_handle = buff_handle; + + buf_pool->validated++; + + return VCD_S_SUCCESS; + +} + +u32 vcd_allocate_buffer_internal( + struct vcd_clnt_ctxt *cctxt, + struct vcd_buffer_pool *buf_pool, + u32 buf_size, u8 **vir_buf_addr, u8 **phy_buf_addr) +{ + struct vcd_buffer_entry *buf_entry; + struct vcd_buffer_requirement *buf_req; + u32 addr; + int rc = 0; + + buf_entry = vcd_get_free_buffer_pool_entry(buf_pool); + if (!buf_entry) { + VCD_MSG_ERROR("Can't allocate buffer pool is full"); + + return VCD_ERR_FAIL; + } + + buf_req = &buf_pool->buf_req; + + buf_size += buf_req->align; + + rc = vcd_pmem_alloc(buf_size, &buf_entry->alloc, + &buf_entry->physical, cctxt); + + if (rc < 0) { + VCD_MSG_ERROR("Buffer allocation failed"); + + return VCD_ERR_ALLOC_FAIL; + } + + buf_entry->sz = buf_size; + buf_entry->frame.alloc_len = buf_size; + + if (!buf_entry->physical) { + VCD_MSG_ERROR("Couldn't get physical address"); + + return VCD_ERR_BAD_POINTER; + } + + buf_entry->allocated = true; + + if (buf_req->align > 0) { + + addr = (u32) buf_entry->physical; + addr += buf_req->align; + addr -= (addr % buf_req->align); + buf_entry->virtual = buf_entry->alloc; + buf_entry->virtual += (u32) (addr - (u32) + buf_entry->physical); + buf_entry->physical = (u8 *) addr; + } else { + VCD_MSG_LOW("No buffer alignment required"); + + buf_entry->virtual = buf_entry->alloc; + + } + + buf_entry->frame.virtual = buf_entry->virtual; + buf_entry->frame.physical = buf_entry->physical; + + *vir_buf_addr = buf_entry->virtual; + *phy_buf_addr = buf_entry->physical; + + buf_pool->allocated++; + buf_pool->validated++; + + return VCD_S_SUCCESS; +} + +u32 vcd_free_one_buffer_internal( + struct vcd_clnt_ctxt *cctxt, + enum vcd_buffer_type buffer_type, u8 *buffer) +{ + struct vcd_buffer_pool *buf_pool; + u32 rc = VCD_S_SUCCESS; + struct vcd_buffer_entry *buf_entry; + u32 first_frm_recvd = 0; + + if (buffer_type == VCD_BUFFER_INPUT) { + buf_pool = &cctxt->in_buf_pool; + first_frm_recvd = VCD_FIRST_IP_RCVD; + } else if (buffer_type == VCD_BUFFER_OUTPUT) { + buf_pool = &cctxt->out_buf_pool; + first_frm_recvd = VCD_FIRST_OP_RCVD; + } else + rc = VCD_ERR_ILLEGAL_PARM; + + VCD_FAILED_RETURN(rc, "Invalid buffer type provided"); + + first_frm_recvd &= cctxt->status.mask; + if (first_frm_recvd && !cctxt->meta_mode) { + VCD_MSG_ERROR( + "VCD free buffer called when data path is active"); + return VCD_ERR_BAD_STATE; + } + + buf_entry = vcd_find_buffer_pool_entry(buf_pool, buffer); + if (!buf_entry) { + VCD_MSG_ERROR("Buffer addr %p not found. Can't free buffer", + buffer); + + return VCD_ERR_ILLEGAL_PARM; + } + if (buf_entry->in_use) { + VCD_MSG_ERROR("\n Buffer is in use and is not flushed"); + return VCD_ERR_ILLEGAL_OP; + } + + VCD_MSG_LOW("Freeing buffer %p. Allocated %d", + buf_entry->virtual, buf_entry->allocated); + + if (buf_entry->allocated) { + vcd_pmem_free(buf_entry->alloc, buf_entry->physical, cctxt); + buf_pool->allocated--; + } + + memset(buf_entry, 0, sizeof(struct vcd_buffer_entry)); + buf_pool->validated--; + if (buf_pool->validated == 0) + vcd_free_buffer_pool_entries(buf_pool); + + return VCD_S_SUCCESS; +} + +u32 vcd_free_buffers_internal( + struct vcd_clnt_ctxt *cctxt, + struct vcd_buffer_pool *buf_pool) +{ + u32 rc = VCD_S_SUCCESS; + u32 i; + + VCD_MSG_LOW("vcd_free_buffers_internal:"); + + if (buf_pool->entries) { + for (i = 1; i <= buf_pool->count; i++) { + if (buf_pool->entries[i].valid && + buf_pool->entries[i].allocated) { + vcd_pmem_free(buf_pool->entries[i].alloc, + buf_pool->entries[i]. + physical, cctxt); + } + } + + } + + vcd_reset_buffer_pool_for_reuse(buf_pool); + + return rc; +} + +u32 vcd_alloc_buffer_pool_entries( + struct vcd_buffer_pool *buf_pool, + struct vcd_buffer_requirement *buf_req) +{ + + VCD_MSG_LOW("vcd_alloc_buffer_pool_entries:"); + + buf_pool->buf_req = *buf_req; + + buf_pool->count = buf_req->actual_count; + buf_pool->entries = (struct vcd_buffer_entry *) + kzalloc((sizeof(struct vcd_buffer_entry) * + (VCD_MAX_BUFFER_ENTRIES + 1)), GFP_KERNEL); + + if (!buf_pool->entries) { + VCD_MSG_ERROR("Buf_pool entries alloc failed"); + return VCD_ERR_ALLOC_FAIL; + } + + INIT_LIST_HEAD(&buf_pool->queue); + buf_pool->entries[0].valid = true; + buf_pool->q_len = 0; + + buf_pool->validated = 0; + buf_pool->allocated = 0; + buf_pool->in_use = 0; + + return VCD_S_SUCCESS; +} + +void vcd_free_buffer_pool_entries(struct vcd_buffer_pool *buf_pool) +{ + VCD_MSG_LOW("vcd_free_buffer_pool_entries:"); + kfree(buf_pool->entries); + memset(buf_pool, 0, sizeof(struct vcd_buffer_pool)); + INIT_LIST_HEAD(&buf_pool->queue); +} + +void vcd_flush_in_use_buffer_pool_entries(struct vcd_clnt_ctxt *cctxt, + struct vcd_buffer_pool *buf_pool, u32 event) +{ + u32 i; + VCD_MSG_LOW("vcd_flush_buffer_pool_entries: event=0x%x", event); + + if (buf_pool->entries) { + for (i = 0; i <= buf_pool->count; i++) { + if (buf_pool->entries[i].virtual && + buf_pool->entries[i].in_use) { + cctxt->callback(event, VCD_S_SUCCESS, + &buf_pool->entries[i].frame, + sizeof(struct vcd_frame_data), + cctxt, cctxt->client_data); + buf_pool->entries[i].in_use = false; + VCD_BUFFERPOOL_INUSE_DECREMENT( + buf_pool->in_use); + } + } + } +} + + +void vcd_reset_buffer_pool_for_reuse(struct vcd_buffer_pool *buf_pool) +{ + VCD_MSG_LOW("vcd_reset_buffer_pool_for_reuse:"); + + if (buf_pool->entries) { + memset(&buf_pool->entries[1], 0, + sizeof(struct vcd_buffer_entry) * + VCD_MAX_BUFFER_ENTRIES); + } + buf_pool->q_len = 0; + + buf_pool->validated = 0; + buf_pool->allocated = 0; + buf_pool->in_use = 0; + INIT_LIST_HEAD(&buf_pool->queue); +} + +struct vcd_buffer_entry *vcd_get_free_buffer_pool_entry + (struct vcd_buffer_pool *pool) { + u32 i; + + i = 1; + while (i <= pool->count && pool->entries[i].valid) + i++; + + + if (i <= pool->count) { + pool->entries[i].valid = true; + + return &pool->entries[i]; + } else { + return NULL; + } +} + +struct vcd_buffer_entry *vcd_find_buffer_pool_entry + (struct vcd_buffer_pool *pool, u8 *addr) +{ + u32 i; + u32 found = false; + + for (i = 0; i <= pool->count && !found; i++) { + if (pool->entries[i].virtual == addr) + found = true; + + } + + if (found) + return &pool->entries[i - 1]; + else + return NULL; + +} + +u32 vcd_buffer_pool_entry_en_q( + struct vcd_buffer_pool *pool, + struct vcd_buffer_entry *entry) +{ + struct vcd_buffer_entry *list_itr; + + if (pool->q_len == pool->count) + return false; + + list_for_each_entry(list_itr, &pool->queue, list) + if (list_itr == entry) { + VCD_MSG_HIGH("\n this output buffer is already present" + " in queue"); + VCD_MSG_HIGH("\n Vir Addr %p Phys Addr %p", + entry->virtual, entry->physical); + return false; + } + + list_add_tail(&entry->list, &pool->queue); + pool->q_len++; + + return true; +} + +struct vcd_buffer_entry *vcd_buffer_pool_entry_de_q + (struct vcd_buffer_pool *pool) { + struct vcd_buffer_entry *entry; + + if (!pool || !pool->q_len) + return NULL; + + entry = list_first_entry(&pool->queue, + struct vcd_buffer_entry, list); + + if (entry) { + list_del(&entry->list); + pool->q_len--; + } + return entry; +} + +void vcd_flush_bframe_buffers(struct vcd_clnt_ctxt *cctxt, u32 mode) +{ + int i; + struct vcd_buffer_pool *buf_pool; + + if (!cctxt->decoding && cctxt->bframe) { + buf_pool = (mode == VCD_FLUSH_INPUT) ? + &cctxt->in_buf_pool : &cctxt->out_buf_pool; + if (buf_pool->entries != NULL) { + for (i = 1; i <= buf_pool->count; i++) { + if ((buf_pool->entries[i].in_use) && + (buf_pool->entries[i].frame.virtual + != NULL)) { + if (mode == VCD_FLUSH_INPUT) { + cctxt->callback( + VCD_EVT_RESP_INPUT_FLUSHED, + VCD_S_SUCCESS, + &(buf_pool->entries[i].frame), + sizeof(struct vcd_frame_data), + cctxt, cctxt->client_data); + } else { + buf_pool->entries[i]. + frame.data_len = 0; + cctxt->callback( + VCD_EVT_RESP_OUTPUT_FLUSHED, + VCD_S_SUCCESS, + &(buf_pool->entries[i].frame), + sizeof(struct vcd_frame_data), + cctxt, + cctxt->client_data); + } + VCD_BUFFERPOOL_INUSE_DECREMENT( + buf_pool->in_use); + buf_pool->entries[i].in_use = false; + } + } + } + } +} + +void vcd_flush_output_buffers(struct vcd_clnt_ctxt *cctxt) +{ + struct vcd_buffer_pool *buf_pool; + struct vcd_buffer_entry *buf_entry; + u32 count = 0; + struct vcd_property_hdr prop_hdr; + + VCD_MSG_LOW("vcd_flush_output_buffers:"); + buf_pool = &cctxt->out_buf_pool; + buf_entry = vcd_buffer_pool_entry_de_q(buf_pool); + while (buf_entry) { + if (!cctxt->decoding || buf_entry->in_use) { + buf_entry->frame.data_len = 0; + cctxt->callback(VCD_EVT_RESP_OUTPUT_FLUSHED, + VCD_S_SUCCESS, + &buf_entry->frame, + sizeof(struct vcd_frame_data), + cctxt, cctxt->client_data); + if (buf_entry->in_use) { + VCD_BUFFERPOOL_INUSE_DECREMENT( + buf_pool->in_use); + buf_entry->in_use = false; + } + count++; + } + buf_entry = vcd_buffer_pool_entry_de_q(buf_pool); + } + vcd_flush_bframe_buffers(cctxt, VCD_FLUSH_OUTPUT); + if (buf_pool->in_use || buf_pool->q_len) { + VCD_MSG_ERROR("%s(): WARNING in_use(%u) or q_len(%u) not zero!", + __func__, buf_pool->in_use, buf_pool->q_len); + buf_pool->in_use = buf_pool->q_len = 0; + } + if (cctxt->sched_clnt_hdl) { + if (count > cctxt->sched_clnt_hdl->tkns) + cctxt->sched_clnt_hdl->tkns = 0; + else + cctxt->sched_clnt_hdl->tkns -= count; + } + + if (cctxt->ddl_hdl_valid && cctxt->decoding) { + prop_hdr.prop_id = DDL_I_REQ_OUTPUT_FLUSH; + prop_hdr.sz = sizeof(u32); + count = 0x1; + + (void)ddl_set_property(cctxt->ddl_handle, &prop_hdr, + &count); + } + vcd_release_all_clnt_frm_transc(cctxt); + cctxt->status.mask &= ~VCD_IN_RECONFIG; +} + +u32 vcd_flush_buffers(struct vcd_clnt_ctxt *cctxt, u32 mode) +{ + u32 rc = VCD_S_SUCCESS; + struct vcd_buffer_entry *buf_entry; + + VCD_MSG_LOW("vcd_flush_buffers:"); + + if (mode > VCD_FLUSH_ALL || !(mode & VCD_FLUSH_ALL)) { + VCD_MSG_ERROR("Invalid flush mode %d", mode); + return VCD_ERR_ILLEGAL_PARM; + } + + VCD_MSG_MED("Flush mode %d requested", mode); + if ((mode & VCD_FLUSH_INPUT) && + cctxt->sched_clnt_hdl) { + + rc = vcd_sched_dequeue_buffer( + cctxt->sched_clnt_hdl, &buf_entry); + while (!VCD_FAILED(rc) && buf_entry) { + if (buf_entry->virtual) { + cctxt->callback(VCD_EVT_RESP_INPUT_FLUSHED, + VCD_S_SUCCESS, + &buf_entry->frame, + sizeof(struct + vcd_frame_data), + cctxt, + cctxt->client_data); + } + + buf_entry->in_use = false; + VCD_BUFFERPOOL_INUSE_DECREMENT( + cctxt->in_buf_pool.in_use); + buf_entry = NULL; + rc = vcd_sched_dequeue_buffer( + cctxt->sched_clnt_hdl, &buf_entry); + } + } + if (rc != VCD_ERR_QEMPTY) + VCD_FAILED_RETURN(rc, "Failed: vcd_sched_dequeue_buffer"); + if (cctxt->status.frame_submitted > 0) + cctxt->status.mask |= mode; + else { + if (mode & VCD_FLUSH_INPUT) + vcd_flush_bframe_buffers(cctxt, VCD_FLUSH_INPUT); + if (mode & VCD_FLUSH_OUTPUT) + vcd_flush_output_buffers(cctxt); + } + return VCD_S_SUCCESS; +} + +void vcd_flush_buffers_in_err_fatal(struct vcd_clnt_ctxt *cctxt) +{ + VCD_MSG_LOW("\n vcd_flush_buffers_in_err_fatal:"); + (void) vcd_flush_buffers(cctxt, VCD_FLUSH_ALL); + vcd_flush_in_use_buffer_pool_entries(cctxt, + &cctxt->in_buf_pool, VCD_EVT_RESP_INPUT_FLUSHED); + vcd_flush_in_use_buffer_pool_entries(cctxt, + &cctxt->out_buf_pool, VCD_EVT_RESP_OUTPUT_FLUSHED); + vcd_send_flush_done(cctxt, VCD_S_SUCCESS); +} + +u32 vcd_init_client_context(struct vcd_clnt_ctxt *cctxt) +{ + u32 rc; + VCD_MSG_LOW("vcd_init_client_context:"); + rc = ddl_open(&cctxt->ddl_handle, cctxt->decoding); + VCD_FAILED_RETURN(rc, "Failed: ddl_open"); + cctxt->vcd_enable_ion = res_trk_get_enable_ion(); + if (cctxt->vcd_enable_ion) { + cctxt->vcd_ion_client = res_trk_get_ion_client(); + if (!cctxt->vcd_ion_client) { + VCD_MSG_LOW("vcd_init_ion_get_client_failed:"); + return -EINVAL; + } + } + cctxt->ddl_hdl_valid = true; + cctxt->clnt_state.state = VCD_CLIENT_STATE_OPEN; + cctxt->clnt_state.state_table = + vcd_get_client_state_table(VCD_CLIENT_STATE_OPEN); + cctxt->signature = VCD_SIGNATURE; + cctxt->live = true; + cctxt->bframe = 0; + cctxt->cmd_q.pending_cmd = VCD_CMD_NONE; + cctxt->status.last_evt = VCD_EVT_RESP_BASE; + cctxt->num_slices = 1; + return rc; +} + +void vcd_destroy_client_context(struct vcd_clnt_ctxt *cctxt) +{ + struct vcd_dev_ctxt *dev_ctxt; + struct vcd_clnt_ctxt *client; + struct vcd_buffer_entry *buf_entry; + u32 rc = VCD_S_SUCCESS; + VCD_MSG_LOW("vcd_destroy_client_context:"); + + dev_ctxt = cctxt->dev_ctxt; + + if (cctxt == dev_ctxt->cctxt_list_head) { + VCD_MSG_MED("Clnt list head clnt being removed"); + + dev_ctxt->cctxt_list_head = cctxt->next; + } else { + client = dev_ctxt->cctxt_list_head; + while (client && cctxt != client->next) + client = client->next; + if (client) + client->next = cctxt->next; + if (!client) { + rc = VCD_ERR_FAIL; + VCD_MSG_ERROR("Client not found in client list"); + } + } + + if (VCD_FAILED(rc)) + return; + + if (cctxt->sched_clnt_hdl) { + rc = VCD_S_SUCCESS; + while (!VCD_FAILED(rc)) { + rc = vcd_sched_dequeue_buffer( + cctxt->sched_clnt_hdl, &buf_entry); + if (rc != VCD_ERR_QEMPTY && VCD_FAILED(rc)) + VCD_MSG_ERROR("\n Failed: " + "vcd_sched_de_queue_buffer"); + } + rc = vcd_sched_remove_client(cctxt->sched_clnt_hdl); + if (VCD_FAILED(rc)) + VCD_MSG_ERROR("\n Failed: sched_remove_client"); + cctxt->sched_clnt_hdl = NULL; + } + + if (cctxt->seq_hdr.sequence_header) { + vcd_pmem_free(cctxt->seq_hdr.sequence_header, + cctxt->seq_hdr_phy_addr, cctxt); + cctxt->seq_hdr.sequence_header = NULL; + } + + vcd_free_buffers_internal(cctxt, &cctxt->in_buf_pool); + vcd_free_buffers_internal(cctxt, &cctxt->out_buf_pool); + vcd_free_buffer_pool_entries(&cctxt->in_buf_pool); + vcd_free_buffer_pool_entries(&cctxt->out_buf_pool); + vcd_release_all_clnt_transc(cctxt); + + if (cctxt->ddl_hdl_valid) { + (void)ddl_close(&cctxt->ddl_handle); + cctxt->ddl_hdl_valid = false; + } + + cctxt->signature = 0; + cctxt->clnt_state.state = VCD_CLIENT_STATE_NULL; + cctxt->clnt_state.state_table = NULL; + cctxt->vcd_ion_client = NULL; + kfree(cctxt); +} + +u32 vcd_check_for_client_context( + struct vcd_dev_ctxt *dev_ctxt, s32 driver_id) +{ + struct vcd_clnt_ctxt *client; + + client = dev_ctxt->cctxt_list_head; + while (client && client->driver_id != driver_id) + client = client->next; + + if (!client) + return false; + else + return true; +} + +u32 vcd_validate_driver_handle( + struct vcd_dev_ctxt *dev_ctxt, s32 driver_handle) +{ + driver_handle--; + + if (driver_handle < 0 || + driver_handle >= VCD_DRIVER_INSTANCE_MAX || + !dev_ctxt->driver_ids[driver_handle]) { + return false; + } else { + return true; + } +} + +u32 vcd_client_cmd_en_q( + struct vcd_clnt_ctxt *cctxt, enum vcd_command command) +{ + u32 result; + + if (cctxt->cmd_q.pending_cmd == VCD_CMD_NONE) { + cctxt->cmd_q.pending_cmd = command; + result = true; + } else { + result = false; + } + + return result; +} + +void vcd_client_cmd_flush_and_en_q( + struct vcd_clnt_ctxt *cctxt, enum vcd_command command) +{ + cctxt->cmd_q.pending_cmd = command; +} + +u32 vcd_client_cmd_de_q(struct vcd_clnt_ctxt *cctxt, + enum vcd_command *command) +{ + if (cctxt->cmd_q.pending_cmd == VCD_CMD_NONE) + return false; + + *command = cctxt->cmd_q.pending_cmd; + cctxt->cmd_q.pending_cmd = VCD_CMD_NONE; + + return true; +} + +u32 vcd_get_next_queued_client_cmd(struct vcd_dev_ctxt *dev_ctxt, + struct vcd_clnt_ctxt **cctxt, enum vcd_command *command) +{ + struct vcd_clnt_ctxt *client = dev_ctxt->cctxt_list_head; + u32 result = false; + + while (client && !result) { + *cctxt = client; + result = vcd_client_cmd_de_q(client, command); + client = client->next; + } + return result; +} + +u32 vcd_submit_cmd_sess_start(struct vcd_transc *transc) +{ + u32 rc; + struct vcd_sequence_hdr Seq_hdr; + + VCD_MSG_LOW("vcd_submit_cmd_sess_start:"); + + if (transc->cctxt->decoding) { + + if (transc->cctxt->seq_hdr.sequence_header) { + Seq_hdr.sequence_header_len = + transc->cctxt->seq_hdr. + sequence_header_len; + Seq_hdr.sequence_header = + transc->cctxt->seq_hdr_phy_addr; + + rc = ddl_decode_start(transc->cctxt->ddl_handle, + &Seq_hdr, (void *)transc); + } else { + rc = ddl_decode_start(transc->cctxt->ddl_handle, + NULL, (void *)transc); + } + + } else { + vcd_set_num_slices(transc->cctxt); + rc = ddl_encode_start(transc->cctxt->ddl_handle, + (void *)transc); + } + if (!VCD_FAILED(rc)) { + transc->cctxt->status.cmd_submitted++; + vcd_device_timer_start(transc->cctxt->dev_ctxt); + } else + VCD_MSG_ERROR("rc = 0x%x. Failed: ddl start", rc); + + return rc; +} + +u32 vcd_submit_cmd_sess_end(struct vcd_transc *transc) +{ + u32 rc; + + VCD_MSG_LOW("vcd_submit_cmd_sess_end:"); + + if (transc->cctxt->decoding) { + rc = ddl_decode_end(transc->cctxt->ddl_handle, + (void *)transc); + } else { + rc = ddl_encode_end(transc->cctxt->ddl_handle, + (void *)transc); + } + if (!VCD_FAILED(rc)) { + transc->cctxt->status.cmd_submitted++; + vcd_device_timer_start(transc->cctxt->dev_ctxt); + } else + VCD_MSG_ERROR("rc = 0x%x. Failed: ddl end", rc); + + return rc; +} + +void vcd_submit_cmd_client_close(struct vcd_clnt_ctxt *cctxt) +{ + (void) ddl_close(&cctxt->ddl_handle); + cctxt->ddl_hdl_valid = false; + cctxt->status.mask &= ~VCD_CLEANING_UP; + if (cctxt->status.mask & VCD_CLOSE_PENDING) { + vcd_destroy_client_context(cctxt); + vcd_handle_for_last_clnt_close(cctxt->dev_ctxt, true); + } +} + +u32 vcd_submit_command_in_continue(struct vcd_dev_ctxt + *dev_ctxt, struct vcd_transc *transc) +{ + struct vcd_property_hdr prop_hdr; + struct vcd_clnt_ctxt *client = NULL; + enum vcd_command cmd = VCD_CMD_NONE; + u32 rc = VCD_ERR_FAIL; + u32 result = false, flush = 0, event = 0; + u32 command_break = false; + + VCD_MSG_LOW("\n vcd_submit_command_in_continue:"); + + while (!command_break) { + result = vcd_get_next_queued_client_cmd(dev_ctxt, + &client, &cmd); + + if (!result) + command_break = true; + else { + transc->type = cmd; + transc->cctxt = client; + + switch (cmd) { + case VCD_CMD_CODEC_START: + { + rc = vcd_submit_cmd_sess_start(transc); + event = VCD_EVT_RESP_START; + break; + } + case VCD_CMD_CODEC_STOP: + { + rc = vcd_submit_cmd_sess_end(transc); + event = VCD_EVT_RESP_STOP; + break; + } + case VCD_CMD_OUTPUT_FLUSH: + { + prop_hdr.prop_id = DDL_I_REQ_OUTPUT_FLUSH; + prop_hdr.sz = sizeof(u32); + flush = 0x1; + (void) ddl_set_property(client->ddl_handle, + &prop_hdr, &flush); + vcd_release_command_channel(dev_ctxt, + transc); + rc = VCD_S_SUCCESS; + break; + } + case VCD_CMD_CLIENT_CLOSE: + { + vcd_submit_cmd_client_close(client); + vcd_release_command_channel(dev_ctxt, + transc); + rc = VCD_S_SUCCESS; + break; + } + default: + { + VCD_MSG_ERROR("\n vcd_submit_command: Unknown" + "command %d", (int)cmd); + break; + } + } + + if (!VCD_FAILED(rc)) { + command_break = true; + } else { + VCD_MSG_ERROR("vcd_submit_command %d: failed 0x%x", + cmd, rc); + client->callback(event, rc, NULL, 0, client, + client->client_data); + } + } + } + return result; +} + +u32 vcd_schedule_frame(struct vcd_dev_ctxt *dev_ctxt, + struct vcd_clnt_ctxt **cctxt, struct vcd_buffer_entry + **ip_buf_entry) +{ + u32 rc = VCD_S_SUCCESS; + VCD_MSG_LOW("vcd_schedule_frame:"); + + if (!dev_ctxt->cctxt_list_head) { + VCD_MSG_HIGH("Client list empty"); + return false; + } + rc = vcd_sched_get_client_frame(&dev_ctxt->sched_clnt_list, + cctxt, ip_buf_entry); + if (rc == VCD_ERR_QEMPTY) { + VCD_MSG_HIGH("No frame available. Sched queues are empty"); + return false; + } + if (VCD_FAILED(rc)) { + VCD_MSG_FATAL("vcd_submit_frame: sched_de_queue_frame" + "failed 0x%x", rc); + return false; + } + if (!*cctxt || !*ip_buf_entry) { + VCD_MSG_FATAL("Sched returned invalid values. ctxt=%p," + "ipbuf=%p", *cctxt, *ip_buf_entry); + return false; + } + return true; +} + +void vcd_try_submit_frame(struct vcd_dev_ctxt *dev_ctxt) +{ + struct vcd_transc *transc; + u32 rc = VCD_S_SUCCESS; + struct vcd_clnt_ctxt *cctxt = NULL; + struct vcd_buffer_entry *ip_buf_entry = NULL; + u32 result = false; + + VCD_MSG_LOW("vcd_try_submit_frame:"); + + if (!vcd_get_frame_channel(dev_ctxt, &transc)) + return; + + if (!vcd_schedule_frame(dev_ctxt, &cctxt, &ip_buf_entry)) { + vcd_release_frame_channel(dev_ctxt, transc); + return; + } + + rc = vcd_power_event(dev_ctxt, cctxt, VCD_EVT_PWR_CLNT_CMD_BEGIN); + + if (!VCD_FAILED(rc)) { + transc->cctxt = cctxt; + transc->ip_buf_entry = ip_buf_entry; + + result = vcd_submit_frame(dev_ctxt, transc); + } else { + VCD_MSG_ERROR("Failed: VCD_EVT_PWR_CLNT_CMD_BEGIN"); + (void) vcd_sched_queue_buffer( + cctxt->sched_clnt_hdl, ip_buf_entry, false); + cctxt->sched_clnt_hdl->tkns++; + } + + if (!result) { + vcd_release_frame_channel(dev_ctxt, transc); + (void) vcd_power_event(dev_ctxt, cctxt, + VCD_EVT_PWR_CLNT_CMD_FAIL); + } +} + +u32 vcd_submit_frame(struct vcd_dev_ctxt *dev_ctxt, + struct vcd_transc *transc) +{ + struct vcd_clnt_ctxt *cctxt = NULL; + struct vcd_frame_data *ip_frm_entry; + struct vcd_buffer_entry *op_buf_entry = NULL; + u32 rc = VCD_S_SUCCESS; + u32 evcode = 0; + u32 perf_level = 0; + int decodeTime = 0; + struct ddl_frame_data_tag ddl_ip_frm; + struct ddl_frame_data_tag *ddl_op_frm; + u32 out_buf_cnt = 0; + + VCD_MSG_LOW("vcd_submit_frame:"); + cctxt = transc->cctxt; + ip_frm_entry = &transc->ip_buf_entry->frame; + + transc->op_buf_entry = op_buf_entry; + transc->ip_frm_tag = ip_frm_entry->ip_frm_tag; + transc->time_stamp = ip_frm_entry->time_stamp; + transc->flags = ip_frm_entry->flags; + ip_frm_entry->ip_frm_tag = (u32) transc; + memset(&ddl_ip_frm, 0, sizeof(ddl_ip_frm)); + if (cctxt->decoding) { + decodeTime = ddl_get_core_decode_proc_time(cctxt->ddl_handle); + if (decodeTime > MAX_DEC_TIME) { + if (res_trk_get_curr_perf_level(&perf_level)) { + vcd_update_decoder_perf_level(dev_ctxt, + res_trk_estimate_perf_level(perf_level)); + ddl_reset_avg_dec_time(cctxt->ddl_handle); + } else + VCD_MSG_ERROR("%s(): retrieve curr_perf_level" + "returned FALSE\n", __func__); + } + evcode = CLIENT_STATE_EVENT_NUMBER(decode_frame); + ddl_ip_frm.vcd_frm = *ip_frm_entry; + rc = ddl_decode_frame(cctxt->ddl_handle, &ddl_ip_frm, + (void *) transc); + } else { + ddl_op_frm = (struct ddl_frame_data_tag *) + kmalloc((sizeof(struct ddl_frame_data_tag) * + VCD_ENC_MAX_OUTBFRS_PER_FRAME), GFP_KERNEL); + if (!ddl_op_frm) { + VCD_MSG_ERROR("Memory allocation failure"); + return VCD_ERR_ALLOC_FAIL; + } + memset(ddl_op_frm, 0, (sizeof(struct ddl_frame_data_tag) * + VCD_ENC_MAX_OUTBFRS_PER_FRAME)); + for (out_buf_cnt = 0; out_buf_cnt < cctxt->num_slices ; + out_buf_cnt++) { + op_buf_entry = vcd_buffer_pool_entry_de_q( + &cctxt->out_buf_pool); + if (!op_buf_entry) { + VCD_MSG_ERROR("Sched provided frame when no" + "op buffer was present"); + rc = VCD_ERR_FAIL; + break; + } + op_buf_entry->in_use = true; + cctxt->out_buf_pool.in_use++; + ddl_op_frm[out_buf_cnt].vcd_frm = op_buf_entry->frame; + VCD_MSG_LOW("%s : buffer_cnt = %d framebfr(virtual)" + " 0x%p", __func__, out_buf_cnt, + op_buf_entry->frame.virtual); + VCD_MSG_LOW("framebfr(physical) 0x%p bfrlength %d", + op_buf_entry->frame.physical, + op_buf_entry->frame.alloc_len); + } + ddl_ip_frm.vcd_frm = *ip_frm_entry; + ddl_ip_frm.frm_delta = + vcd_calculate_frame_delta(cctxt, + ip_frm_entry); + evcode = CLIENT_STATE_EVENT_NUMBER(encode_frame); + + if (!VCD_FAILED(rc)) { + rc = ddl_encode_frame(cctxt->ddl_handle, + &ddl_ip_frm, &ddl_op_frm[0], (void *) transc); + } + kfree(ddl_op_frm); + } + ip_frm_entry->ip_frm_tag = transc->ip_frm_tag; + if (!VCD_FAILED(rc)) { + vcd_device_timer_start(dev_ctxt); + cctxt->status.frame_submitted++; + if (ip_frm_entry->flags & VCD_FRAME_FLAG_EOS) + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_EOS, evcode); + } else { + VCD_MSG_ERROR("Frame submission failed. rc = 0x%x", rc); + vcd_handle_submit_frame_failed(dev_ctxt, transc); + } + return true; +} + +u32 vcd_try_submit_frame_in_continue(struct vcd_dev_ctxt *dev_ctxt, + struct vcd_transc *transc) +{ + struct vcd_clnt_ctxt *cctxt = NULL; + struct vcd_buffer_entry *ip_buf_entry = NULL; + + VCD_MSG_LOW("vcd_try_submit_frame_in_continue:"); + + if (!vcd_schedule_frame(dev_ctxt, &cctxt, &ip_buf_entry)) + return false; + + transc->cctxt = cctxt; + transc->ip_buf_entry = ip_buf_entry; + + return vcd_submit_frame(dev_ctxt, transc); +} + +u32 vcd_process_cmd_sess_start(struct vcd_clnt_ctxt *cctxt) +{ + struct vcd_transc *transc; + u32 rc = VCD_S_SUCCESS; + + VCD_MSG_LOW("vcd_process_cmd_sess_start:"); + if (vcd_get_command_channel(cctxt->dev_ctxt, &transc)) { + rc = vcd_power_event(cctxt->dev_ctxt, + cctxt, VCD_EVT_PWR_CLNT_CMD_BEGIN); + + if (!VCD_FAILED(rc)) { + transc->type = VCD_CMD_CODEC_START; + transc->cctxt = cctxt; + rc = vcd_submit_cmd_sess_start(transc); + } else { + VCD_MSG_ERROR("Failed: VCD_EVT_PWR_CLNT_CMD_BEGIN"); + } + + if (VCD_FAILED(rc)) { + vcd_release_command_channel(cctxt->dev_ctxt, + transc); + } + } else { + u32 result; + + result = vcd_client_cmd_en_q(cctxt, VCD_CMD_CODEC_START); + if (!result) { + rc = VCD_ERR_BUSY; + VCD_MSG_ERROR("%s(): vcd_client_cmd_en_q() " + "failed\n", __func__); + } + } + + if (VCD_FAILED(rc)) { + (void)vcd_power_event(cctxt->dev_ctxt, + cctxt, VCD_EVT_PWR_CLNT_CMD_FAIL); + } + + return rc; +} + +void vcd_send_frame_done_in_eos(struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *input_frame, u32 valid_opbuf) +{ + VCD_MSG_LOW("vcd_send_frame_done_in_eos:"); + + if (!input_frame->virtual && !valid_opbuf) { + VCD_MSG_MED("Sending NULL output with EOS"); + + cctxt->out_buf_pool.entries[0].frame.flags = + VCD_FRAME_FLAG_EOS; + cctxt->out_buf_pool.entries[0].frame.data_len = 0; + cctxt->out_buf_pool.entries[0].frame.time_stamp = + input_frame->time_stamp; + cctxt->out_buf_pool.entries[0].frame.ip_frm_tag = + input_frame->ip_frm_tag; + + cctxt->callback(VCD_EVT_RESP_OUTPUT_DONE, + VCD_S_SUCCESS, + &cctxt->out_buf_pool.entries[0].frame, + sizeof(struct vcd_frame_data), + cctxt, cctxt->client_data); + + memset(&cctxt->out_buf_pool.entries[0].frame, + 0, sizeof(struct vcd_frame_data)); + } else if (!input_frame->data_len) { + if (cctxt->decoding) { + vcd_send_frame_done_in_eos_for_dec(cctxt, + input_frame); + } else { + vcd_send_frame_done_in_eos_for_enc(cctxt, + input_frame); + } + + } +} + +void vcd_send_frame_done_in_eos_for_dec( + struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *input_frame) +{ + struct vcd_buffer_entry *buf_entry; + struct vcd_property_hdr prop_hdr; + u32 rc; + struct ddl_frame_data_tag ddl_frm; + + prop_hdr.prop_id = DDL_I_DPB_RETRIEVE; + prop_hdr.sz = sizeof(struct ddl_frame_data_tag); + memset(&ddl_frm, 0, sizeof(ddl_frm)); + rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr, &ddl_frm); + + if (VCD_FAILED(rc) || !ddl_frm.vcd_frm.virtual) { + cctxt->status.eos_trig_ip_frm = *input_frame; + cctxt->status.mask |= VCD_EOS_WAIT_OP_BUF; + return; + } + + buf_entry = vcd_find_buffer_pool_entry(&cctxt->out_buf_pool, + ddl_frm.vcd_frm.virtual); + if (!buf_entry) { + VCD_MSG_ERROR("Unrecognized buffer address provided = %p", + ddl_frm.vcd_frm.virtual); + return; + } else { + if (cctxt->sched_clnt_hdl->tkns) + cctxt->sched_clnt_hdl->tkns--; + + VCD_MSG_MED("Sending non-NULL output with EOS"); + + buf_entry->frame.data_len = 0; + buf_entry->frame.offset = 0; + buf_entry->frame.flags |= VCD_FRAME_FLAG_EOS; + buf_entry->frame.ip_frm_tag = input_frame->ip_frm_tag; + buf_entry->frame.time_stamp = input_frame->time_stamp; + + cctxt->callback(VCD_EVT_RESP_OUTPUT_DONE, + VCD_S_SUCCESS, + &buf_entry->frame, + sizeof(struct vcd_frame_data), + cctxt, cctxt->client_data); + + buf_entry->in_use = false; + VCD_BUFFERPOOL_INUSE_DECREMENT(cctxt->out_buf_pool.in_use); + } +} + +void vcd_send_frame_done_in_eos_for_enc( + struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *input_frame) +{ + struct vcd_buffer_entry *op_buf_entry; + + if (!cctxt->out_buf_pool.q_len) { + cctxt->status.eos_trig_ip_frm = *input_frame; + + cctxt->status.mask |= VCD_EOS_WAIT_OP_BUF; + + return; + } + + op_buf_entry = vcd_buffer_pool_entry_de_q(&cctxt->out_buf_pool); + if (!op_buf_entry) { + VCD_MSG_ERROR("%s(): vcd_buffer_pool_entry_de_q() " + "failed\n", __func__); + } else { + if (cctxt->sched_clnt_hdl->tkns) + cctxt->sched_clnt_hdl->tkns--; + + VCD_MSG_MED("Sending non-NULL output with EOS"); + + op_buf_entry->frame.data_len = 0; + op_buf_entry->frame.flags |= VCD_FRAME_FLAG_EOS; + op_buf_entry->frame.ip_frm_tag = + input_frame->ip_frm_tag; + op_buf_entry->frame.time_stamp = input_frame->time_stamp; + + cctxt->callback(VCD_EVT_RESP_OUTPUT_DONE, + VCD_S_SUCCESS, + &op_buf_entry->frame, + sizeof(struct vcd_frame_data), + cctxt, cctxt->client_data); + } +} + +u32 vcd_handle_recvd_eos( + struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *input_frame, u32 *pb_eos_handled) +{ + u32 rc; + + VCD_MSG_LOW("vcd_handle_recvd_eos:"); + + *pb_eos_handled = false; + + if (input_frame->virtual && + input_frame->data_len) + return VCD_S_SUCCESS; + + input_frame->data_len = 0; + rc = vcd_sched_mark_client_eof(cctxt->sched_clnt_hdl); + if (VCD_FAILED(rc) && rc != VCD_ERR_QEMPTY) + return rc; + + if (rc == VCD_S_SUCCESS) + *pb_eos_handled = true; + else if (cctxt->decoding && !input_frame->virtual) + cctxt->sched_clnt_hdl->tkns++; + else if (!cctxt->decoding) { + vcd_send_frame_done_in_eos(cctxt, input_frame, false); + if (cctxt->status.mask & VCD_EOS_WAIT_OP_BUF) { + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_EOS, + CLIENT_STATE_EVENT_NUMBER + (encode_frame)); + } + *pb_eos_handled = true; + } + + if (*pb_eos_handled && + input_frame->virtual && + !input_frame->data_len) { + cctxt->callback(VCD_EVT_RESP_INPUT_DONE, + VCD_S_SUCCESS, + input_frame, + sizeof(struct vcd_frame_data), + cctxt, cctxt->client_data); + } + return VCD_S_SUCCESS; +} + +u32 vcd_handle_first_decode_frame(struct vcd_clnt_ctxt *cctxt) +{ + u32 rc = VCD_ERR_BAD_STATE; + + VCD_MSG_LOW("vcd_handle_first_decode_frame:"); + if (!cctxt->in_buf_pool.entries || + !cctxt->out_buf_pool.entries || + cctxt->in_buf_pool.validated != + cctxt->in_buf_pool.count || + cctxt->out_buf_pool.validated != + cctxt->out_buf_pool.count) + VCD_MSG_ERROR("Buffer pool is not completely setup yet"); + else if (!cctxt->sched_clnt_hdl) { + rc = vcd_sched_add_client(cctxt); + VCD_FAILED_RETURN(rc, "Failed: vcd_add_client_to_sched"); + cctxt->sched_clnt_hdl->tkns = + cctxt->out_buf_pool.q_len; + } else + rc = vcd_sched_suspend_resume_clnt(cctxt, true); + return rc; +} + +u32 vcd_setup_with_ddl_capabilities(struct vcd_dev_ctxt *dev_ctxt) +{ + struct vcd_property_hdr Prop_hdr; + struct ddl_property_capability capability; + u32 rc = VCD_S_SUCCESS; + + VCD_MSG_LOW("vcd_setup_with_ddl_capabilities:"); + + if (!dev_ctxt->ddl_cmd_ch_depth) { + Prop_hdr.prop_id = DDL_I_CAPABILITY; + Prop_hdr.sz = sizeof(capability); + + /* + ** Since this is underlying core's property we don't need a + ** ddl client handle. + */ + rc = ddl_get_property(NULL, &Prop_hdr, &capability); + + if (!VCD_FAILED(rc)) { + /* + ** Allocate the transaction table. + */ + dev_ctxt->trans_tbl_size = + (VCD_MAX_CLIENT_TRANSACTIONS * + capability.max_num_client) + + capability.general_command_depth; + + dev_ctxt->trans_tbl = (struct vcd_transc *) + kzalloc((sizeof(struct vcd_transc) * + dev_ctxt->trans_tbl_size), GFP_KERNEL); + + if (!dev_ctxt->trans_tbl) { + VCD_MSG_ERROR("Transaction table alloc failed"); + rc = VCD_ERR_ALLOC_FAIL; + } else { + dev_ctxt->ddl_cmd_concurrency = + !capability.exclusive; + dev_ctxt->ddl_frame_ch_depth = + capability.frame_command_depth; + dev_ctxt->ddl_cmd_ch_depth = + capability.general_command_depth; + + vcd_reset_device_channels(dev_ctxt); + + dev_ctxt->hw_time_out = + capability.ddl_time_out_in_ms; + + } + } + } + return rc; +} + +struct vcd_transc *vcd_get_free_trans_tbl_entry + (struct vcd_dev_ctxt *dev_ctxt) { + u32 i; + + if (!dev_ctxt->trans_tbl) + return NULL; + + i = 0; + while (i < dev_ctxt->trans_tbl_size && + dev_ctxt->trans_tbl[i].in_use) + i++; + + if (i == dev_ctxt->trans_tbl_size) { + return NULL; + } else { + memset(&dev_ctxt->trans_tbl[i], 0, + sizeof(struct vcd_transc)); + dev_ctxt->trans_tbl[i].in_use = true; + VCD_MSG_LOW("%s: Get transc = 0x%x, in_use = %u\n", + __func__, (u32)(&dev_ctxt->trans_tbl[i]), + dev_ctxt->trans_tbl[i].in_use); + return &dev_ctxt->trans_tbl[i]; + } +} + +void vcd_release_trans_tbl_entry(struct vcd_transc *trans_entry) +{ + if (trans_entry) { + trans_entry->in_use = false; + VCD_MSG_LOW("%s: Free transc = 0x%x, in_use = %u\n", + __func__, (u32)trans_entry, trans_entry->in_use); + } +} + +u32 vcd_handle_input_done( + struct vcd_clnt_ctxt *cctxt, + void *payload, u32 event, u32 status) +{ + struct vcd_transc *transc; + struct ddl_frame_data_tag *frame = + (struct ddl_frame_data_tag *) payload; + struct vcd_buffer_entry *orig_frame = NULL; + u32 rc; + VCD_MSG_LOW("%s\n", __func__); + + if (!cctxt->status.frame_submitted && + !cctxt->status.frame_delayed) { + VCD_MSG_ERROR("Input done was not expected"); + return VCD_ERR_BAD_STATE; + } + + rc = vcd_validate_io_done_pyld(cctxt, payload, status); + if (rc == VCD_ERR_CLIENT_FATAL) + vcd_handle_clnt_fatal_input_done(cctxt, frame->frm_trans_end); + VCD_FAILED_RETURN(rc, "Bad input done payload"); + + transc = (struct vcd_transc *)frame->vcd_frm.ip_frm_tag; + orig_frame = vcd_find_buffer_pool_entry(&cctxt->in_buf_pool, + transc->ip_buf_entry->virtual); + + if ((transc->ip_buf_entry->frame.virtual != + frame->vcd_frm.virtual) + || !transc->ip_buf_entry->in_use) { + VCD_MSG_ERROR("Bad frm transaction state"); + vcd_handle_clnt_fatal_input_done(cctxt, frame->frm_trans_end); + return VCD_ERR_BAD_POINTER; + } + + frame->vcd_frm.ip_frm_tag = transc->ip_frm_tag; + transc->frame = frame->vcd_frm.frame; + + cctxt->callback(event, + status, + &frame->vcd_frm, + sizeof(struct vcd_frame_data), + cctxt, cctxt->client_data); + + orig_frame->in_use--; + VCD_BUFFERPOOL_INUSE_DECREMENT(cctxt->in_buf_pool.in_use); + + if (cctxt->decoding && orig_frame->in_use) { + VCD_MSG_ERROR("When decoding same input buffer not " + "supposed to be queued multiple times"); + return VCD_ERR_FAIL; + } + + if (orig_frame != transc->ip_buf_entry) + kfree(transc->ip_buf_entry); + transc->ip_buf_entry = NULL; + transc->input_done = true; + + if (transc->input_done && transc->frame_done) { + VCD_MSG_LOW("%s Calling vcd_release_trans_tbl_entry\n", + __func__); + vcd_release_trans_tbl_entry(transc); + } + + if (VCD_FAILED(status)) { + VCD_MSG_ERROR("INPUT_DONE returned err = 0x%x", status); + vcd_handle_input_done_failed(cctxt, transc); + } else + cctxt->status.mask |= VCD_FIRST_IP_DONE; + + if (cctxt->status.frame_submitted > 0) + cctxt->status.frame_submitted--; + else + cctxt->status.frame_delayed--; + + if (!VCD_FAILED(status) && + cctxt->decoding) { + if (frame->vcd_frm.flags & VCD_FRAME_FLAG_CODECCONFIG) { + VCD_MSG_HIGH( + "INPUT_DONE with VCD_FRAME_FLAG_CODECCONFIG"); + vcd_handle_input_done_with_codec_config(cctxt, + transc, frame); + frame->vcd_frm.flags &= ~VCD_FRAME_FLAG_CODECCONFIG; + } + if (frame->vcd_frm.interlaced) + vcd_handle_input_done_for_interlacing(cctxt); + if (frame->frm_trans_end) + vcd_handle_input_done_with_trans_end(cctxt); + } + + return VCD_S_SUCCESS; +} + +u32 vcd_handle_input_done_in_eos( + struct vcd_clnt_ctxt *cctxt, void *payload, u32 status) +{ + struct vcd_transc *transc; + struct ddl_frame_data_tag *frame = + (struct ddl_frame_data_tag *) payload; + u32 rc = VCD_ERR_FAIL, codec_config = false; + u32 core_type = res_trk_get_core_type(); + VCD_MSG_LOW("%s\n", __func__); + rc = vcd_validate_io_done_pyld(cctxt, payload, status); + if (rc == VCD_ERR_CLIENT_FATAL) + vcd_handle_clnt_fatal_input_done(cctxt, frame->frm_trans_end); + VCD_FAILED_RETURN(rc, "Failed: vcd_validate_io_done_pyld"); + transc = (struct vcd_transc *)frame->vcd_frm.ip_frm_tag; + codec_config = frame->vcd_frm.flags & VCD_FRAME_FLAG_CODECCONFIG; + rc = vcd_handle_input_done(cctxt, + payload, VCD_EVT_RESP_INPUT_DONE, status); + VCD_FAILED_RETURN(rc, "Failed: vcd_handle_input_done"); + if (frame->vcd_frm.flags & VCD_FRAME_FLAG_EOS) { + VCD_MSG_HIGH("Got input done for EOS initiator"); + transc->input_done = false; + transc->in_use = true; + if ((codec_config && + (status != VCD_ERR_BITSTREAM_ERR)) || + ((status == VCD_ERR_BITSTREAM_ERR) && + !(cctxt->status.mask & VCD_FIRST_IP_DONE) && + (core_type == VCD_CORE_720P))) + vcd_handle_eos_done(cctxt, transc, VCD_S_SUCCESS); + } + return rc; +} + +u32 vcd_validate_io_done_pyld( + struct vcd_clnt_ctxt *cctxt, void *payload, u32 status) +{ + struct ddl_frame_data_tag *frame = + (struct ddl_frame_data_tag *) payload; + struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; + struct vcd_transc *transc = NULL; + u32 rc = VCD_S_SUCCESS, i = 0; + + if (!frame) { + VCD_MSG_ERROR("Bad payload from DDL"); + return VCD_ERR_BAD_POINTER; + } + + transc = (struct vcd_transc *)frame->vcd_frm.ip_frm_tag; + if (dev_ctxt->trans_tbl) { + while (i < dev_ctxt->trans_tbl_size && + transc != &dev_ctxt->trans_tbl[i]) + i++; + if (i == dev_ctxt->trans_tbl_size || + !dev_ctxt->trans_tbl[i].in_use) + rc = VCD_ERR_CLIENT_FATAL; + } else + rc = VCD_ERR_CLIENT_FATAL; + + if (VCD_FAILED(rc)) { + VCD_MSG_FATAL("vcd_validate_io_done_pyld: "\ + "invalid transaction 0x%x", (u32)transc); + } else if (!frame->vcd_frm.virtual && + status != VCD_ERR_INTRLCD_FIELD_DROP) + rc = VCD_ERR_BAD_POINTER; + + return rc; +} + +void vcd_handle_input_done_failed( + struct vcd_clnt_ctxt *cctxt, struct vcd_transc *transc) +{ + if (cctxt->decoding) { + cctxt->sched_clnt_hdl->tkns++; + vcd_release_trans_tbl_entry(transc); + } +} + +void vcd_handle_input_done_with_codec_config( + struct vcd_clnt_ctxt *cctxt, struct vcd_transc *transc, + struct ddl_frame_data_tag *frm) +{ + cctxt->sched_clnt_hdl->tkns++; + if (frm->frm_trans_end) + vcd_release_trans_tbl_entry(transc); +} + +void vcd_handle_input_done_for_interlacing(struct vcd_clnt_ctxt *cctxt) +{ + cctxt->status.int_field_cnt++; + if (cctxt->status.int_field_cnt == 1) + cctxt->sched_clnt_hdl->tkns++; + else if (cctxt->status.int_field_cnt == + VCD_DEC_NUM_INTERLACED_FIELDS) + cctxt->status.int_field_cnt = 0; +} + +void vcd_handle_input_done_with_trans_end( + struct vcd_clnt_ctxt *cctxt) +{ + if (!cctxt->decoding) + return; + if (cctxt->out_buf_pool.in_use < + cctxt->out_buf_pool.buf_req.min_count) + return; + if (!cctxt->sched_clnt_hdl->tkns) + cctxt->sched_clnt_hdl->tkns++; +} + +u32 vcd_handle_output_required(struct vcd_clnt_ctxt + *cctxt, void *payload, u32 status) +{ + struct vcd_transc *transc; + struct ddl_frame_data_tag *frame = + (struct ddl_frame_data_tag *)payload; + u32 rc = VCD_S_SUCCESS; + VCD_MSG_LOW("%s\n", __func__); + + if (!cctxt->status.frame_submitted && + !cctxt->status.frame_delayed) { + VCD_MSG_ERROR("\n Input done was not expected"); + return VCD_ERR_BAD_STATE; + } + + rc = vcd_validate_io_done_pyld(cctxt, payload, status); + if (rc == VCD_ERR_CLIENT_FATAL) + vcd_handle_clnt_fatal_input_done(cctxt, frame->frm_trans_end); + VCD_FAILED_RETURN(rc, "\n Bad input done payload"); + + transc = (struct vcd_transc *)frame-> + vcd_frm.ip_frm_tag; + + if ((transc->ip_buf_entry->frame.virtual != + frame->vcd_frm.virtual) || + !transc->ip_buf_entry->in_use) { + VCD_MSG_ERROR("\n Bad frm transaction state"); + vcd_handle_clnt_fatal_input_done(cctxt, frame->frm_trans_end); + return VCD_ERR_BAD_STATE; + } + rc = vcd_sched_queue_buffer(cctxt->sched_clnt_hdl, + transc->ip_buf_entry, false); + VCD_FAILED_RETURN(rc, "Failed: vcd_sched_queue_buffer"); + + transc->ip_buf_entry = NULL; + vcd_release_trans_tbl_entry(transc); + frame->frm_trans_end = true; + + if (VCD_FAILED(status)) + VCD_MSG_ERROR("\n OUTPUT_REQ returned err = 0x%x", + status); + + if (cctxt->status.frame_submitted > 0) + cctxt->status.frame_submitted--; + else + cctxt->status.frame_delayed--; + + + if (!VCD_FAILED(status) && + cctxt->decoding && + frame->vcd_frm.interlaced) { + if (cctxt->status.int_field_cnt > 0) { + VCD_MSG_ERROR("\n Not expected: OUTPUT_REQ" + "for 2nd interlace field"); + rc = VCD_ERR_FAIL; + } + } + + return rc; +} + +u32 vcd_handle_output_required_in_flushing( +struct vcd_clnt_ctxt *cctxt, void *payload) +{ + u32 rc; + struct vcd_transc *transc; + struct ddl_frame_data_tag *frame = + (struct ddl_frame_data_tag *)payload; + VCD_MSG_LOW("%s\n", __func__); + + rc = vcd_validate_io_done_pyld(cctxt, payload, VCD_S_SUCCESS); + if (rc == VCD_ERR_CLIENT_FATAL) + vcd_handle_clnt_fatal_input_done(cctxt, frame->frm_trans_end); + VCD_FAILED_RETURN(rc, "Bad input done payload"); + + transc = (struct vcd_transc *) + (((struct ddl_frame_data_tag *)payload)-> + vcd_frm.ip_frm_tag); + + ((struct ddl_frame_data_tag *)payload)-> + vcd_frm.interlaced = false; + + rc = vcd_handle_input_done(cctxt, payload, + VCD_EVT_RESP_INPUT_FLUSHED, VCD_S_SUCCESS); + VCD_FAILED_RETURN(rc, "Failed: vcd_handle_input_done"); + + vcd_release_trans_tbl_entry(transc); + ((struct ddl_frame_data_tag *)payload)->frm_trans_end = true; + + return rc; +} + +u32 vcd_handle_frame_done( + struct vcd_clnt_ctxt *cctxt, + void *payload, u32 event, u32 status) +{ + struct vcd_buffer_entry *op_buf_entry = NULL; + struct ddl_frame_data_tag *op_frm = + (struct ddl_frame_data_tag *) payload; + struct vcd_transc *transc; + u32 rc; + s64 time_stamp; + VCD_MSG_LOW("%s\n", __func__); + + rc = vcd_validate_io_done_pyld(cctxt, payload, status); + if (rc == VCD_ERR_CLIENT_FATAL) + vcd_handle_clnt_fatal(cctxt, op_frm->frm_trans_end); + VCD_FAILED_RETURN(rc, "Bad payload recvd"); + + transc = (struct vcd_transc *)op_frm->vcd_frm.ip_frm_tag; + + if (op_frm->vcd_frm.virtual) { + + if (!transc->op_buf_entry) { + op_buf_entry = + vcd_find_buffer_pool_entry( + &cctxt->out_buf_pool, + op_frm->vcd_frm. + virtual); + } else { + op_buf_entry = transc->op_buf_entry; + } + + if (!op_buf_entry) { + VCD_MSG_ERROR("Invalid output buffer returned" + "from DDL"); + vcd_handle_clnt_fatal(cctxt, op_frm->frm_trans_end); + rc = VCD_ERR_BAD_POINTER; + } else if (!op_buf_entry->in_use) { + VCD_MSG_ERROR("Bad output buffer 0x%p recvd from DDL", + op_buf_entry->frame.virtual); + vcd_handle_clnt_fatal(cctxt, op_frm->frm_trans_end); + rc = VCD_ERR_BAD_POINTER; + } else { + op_buf_entry->in_use = false; + VCD_BUFFERPOOL_INUSE_DECREMENT( + cctxt->out_buf_pool.in_use); + VCD_MSG_LOW("outBufPool.InUse = %d", + cctxt->out_buf_pool.in_use); + } + } + VCD_FAILED_RETURN(rc, "Bad output buffer pointer"); + op_frm->vcd_frm.time_stamp = transc->time_stamp; + op_frm->vcd_frm.ip_frm_tag = transc->ip_frm_tag; + + if (transc->flags & VCD_FRAME_FLAG_EOSEQ) + op_frm->vcd_frm.flags |= VCD_FRAME_FLAG_EOSEQ; + else + op_frm->vcd_frm.flags &= ~VCD_FRAME_FLAG_EOSEQ; + + if (cctxt->decoding) + op_frm->vcd_frm.frame = transc->frame; + else + transc->frame = op_frm->vcd_frm.frame; + transc->frame_done = true; + + if (transc->input_done && transc->frame_done) { + time_stamp = transc->time_stamp; + vcd_release_trans_tbl_entry(transc); + } + + if (status == VCD_ERR_INTRLCD_FIELD_DROP || + (op_frm->vcd_frm.intrlcd_ip_frm_tag != + VCD_FRAMETAG_INVALID && + op_frm->vcd_frm.intrlcd_ip_frm_tag)) { + vcd_handle_frame_done_for_interlacing(cctxt, transc, + op_frm, status); + if (status == VCD_ERR_INTRLCD_FIELD_DROP) { + cctxt->callback(VCD_EVT_IND_INFO_FIELD_DROPPED, + VCD_S_SUCCESS, + &time_stamp, + sizeof(time_stamp), + cctxt, cctxt->client_data); + } + } + + if (status != VCD_ERR_INTRLCD_FIELD_DROP) { + cctxt->callback(event, + status, + &op_frm->vcd_frm, + sizeof(struct vcd_frame_data), + cctxt, cctxt->client_data); + } + return rc; +} + +u32 vcd_handle_frame_done_in_eos( + struct vcd_clnt_ctxt *cctxt, void *payload, u32 status) +{ + struct ddl_frame_data_tag *frame = + (struct ddl_frame_data_tag *) payload; + u32 rc = VCD_S_SUCCESS; + VCD_MSG_LOW("%s\n", __func__); + rc = vcd_validate_io_done_pyld(cctxt, payload, status); + if (rc == VCD_ERR_CLIENT_FATAL) + vcd_handle_clnt_fatal(cctxt, frame->frm_trans_end); + VCD_FAILED_RETURN(rc, "Bad payload received"); + + if (cctxt->status.mask & VCD_EOS_PREV_VALID) { + rc = vcd_handle_frame_done(cctxt, + (void *)&cctxt->status. + eos_prev_op_frm, + VCD_EVT_RESP_OUTPUT_DONE, + cctxt->status.eos_prev_op_frm_status); + VCD_FAILED_RETURN(rc, "Failed: vcd_handle_frame_done"); + } + + cctxt->status.eos_prev_op_frm = *frame; + cctxt->status.eos_prev_op_frm_status = status; + cctxt->status.mask |= VCD_EOS_PREV_VALID; + return rc; +} + +void vcd_handle_frame_done_for_interlacing( + struct vcd_clnt_ctxt *cctxt, + struct vcd_transc *transc_ip1, + struct ddl_frame_data_tag *op_frm, u32 status) +{ + struct vcd_transc *transc_ip2 = + (struct vcd_transc *)op_frm->\ + vcd_frm.intrlcd_ip_frm_tag; + + if (status == VCD_ERR_INTRLCD_FIELD_DROP) { + cctxt->status.int_field_cnt = 0; + return; + } + + op_frm->vcd_frm.intrlcd_ip_frm_tag = transc_ip2->ip_frm_tag; + + transc_ip2->frame_done = true; + + if (transc_ip2->input_done && transc_ip2->frame_done) + vcd_release_trans_tbl_entry(transc_ip2); + + if (!transc_ip1->frame || !transc_ip2->frame) { + VCD_MSG_ERROR("DDL didn't provided frame type"); + return; + } +} + +u32 vcd_handle_first_fill_output_buffer( + struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *buffer, + u32 *handled) +{ + u32 rc = VCD_S_SUCCESS; + rc = vcd_check_if_buffer_req_met(cctxt, VCD_BUFFER_OUTPUT); + VCD_FAILED_RETURN(rc, "Output buffer requirements not met"); + if (cctxt->out_buf_pool.q_len > 0) { + VCD_MSG_ERROR("Old output buffers were not flushed out"); + return VCD_ERR_BAD_STATE; + } + cctxt->status.mask |= VCD_FIRST_OP_RCVD; + if (cctxt->sched_clnt_hdl) + rc = vcd_sched_suspend_resume_clnt(cctxt, true); + VCD_FAILED_RETURN(rc, "Failed: vcd_sched_suspend_resume_clnt"); + if (cctxt->decoding) + rc = vcd_handle_first_fill_output_buffer_for_dec( + cctxt, buffer, handled); + else + rc = vcd_handle_first_fill_output_buffer_for_enc( + cctxt, buffer, handled); + return rc; +} + +u32 vcd_handle_first_fill_output_buffer_for_enc( + struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *frm_entry, + u32 *handled) +{ + u32 rc, seqhdr_present = 0; + struct vcd_property_hdr prop_hdr; + struct vcd_sequence_hdr seq_hdr; + struct vcd_property_sps_pps_for_idr_enable idr_enable; + struct vcd_property_codec codec; + *handled = true; + prop_hdr.prop_id = DDL_I_SEQHDR_PRESENT; + prop_hdr.sz = sizeof(seqhdr_present); + rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr, &seqhdr_present); + VCD_FAILED_RETURN(rc, "Failed: DDL_I_SEQHDR_PRESENT"); + if (!seqhdr_present) { + *handled = false; + return VCD_S_SUCCESS; + } + + prop_hdr.prop_id = VCD_I_CODEC; + prop_hdr.sz = sizeof(struct vcd_property_codec); + rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr, &codec); + if (!VCD_FAILED(rc)) { + if (codec.codec != VCD_CODEC_H263) { + /* + * The seq. header is stored in a seperate internal + * buffer and is memcopied into the output buffer + * that we provide. In secure sessions, we aren't + * allowed to touch these buffers. In these cases + * seq. headers are returned to client as part of + * I-frames. So for secure session, just return + * empty buffer. + */ + if (!cctxt->secure) { + prop_hdr.prop_id = VCD_I_SEQ_HEADER; + prop_hdr.sz = sizeof(struct vcd_sequence_hdr); + seq_hdr.sequence_header = frm_entry->virtual; + seq_hdr.sequence_header_len = + frm_entry->alloc_len; + rc = ddl_get_property(cctxt->ddl_handle, + &prop_hdr, &seq_hdr); + if (!VCD_FAILED(rc)) { + frm_entry->data_len = + seq_hdr.sequence_header_len; + frm_entry->time_stamp = 0; + frm_entry->flags |= + VCD_FRAME_FLAG_CODECCONFIG; + } else + VCD_MSG_ERROR("rc = 0x%x. Failed:" + "ddl_get_property: VCD_I_SEQ_HEADER", + rc); + } else { + /* + * First check that the proper props are enabled + * so client can get the proper info eventually + */ + prop_hdr.prop_id = VCD_I_ENABLE_SPS_PPS_FOR_IDR; + prop_hdr.sz = sizeof(idr_enable); + rc = ddl_get_property(cctxt->ddl_handle, + &prop_hdr, &idr_enable); + if (!VCD_FAILED(rc)) { + if (!idr_enable. + sps_pps_for_idr_enable_flag) { + VCD_MSG_ERROR("SPS/PPS per IDR " + "needs to be enabled"); + rc = VCD_ERR_BAD_STATE; + } else { + /* Send zero len frame */ + frm_entry->data_len = 0; + frm_entry->time_stamp = 0; + frm_entry->flags = 0; + } + } + + } + + if (!VCD_FAILED(rc)) + cctxt->callback(VCD_EVT_RESP_OUTPUT_DONE, + VCD_S_SUCCESS, frm_entry, + sizeof(struct vcd_frame_data), + cctxt, + cctxt->client_data); + } else + VCD_MSG_LOW("Codec Type is H.263\n"); + } else + VCD_MSG_ERROR( + "rc = 0x%x. Failed: ddl_get_property:VCD_I_CODEC", + rc); + return rc; +} + +u32 vcd_handle_first_fill_output_buffer_for_dec( + struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *frm_entry, + u32 *handled) +{ + u32 rc; + struct vcd_property_hdr prop_hdr; + struct vcd_buffer_pool *out_buf_pool; + struct ddl_property_dec_pic_buffers dpb; + struct ddl_frame_data_tag *dpb_list; + u8 i; + + (void)frm_entry; + *handled = true; + prop_hdr.prop_id = DDL_I_DPB; + prop_hdr.sz = sizeof(dpb); + out_buf_pool = &cctxt->out_buf_pool; + + dpb_list = (struct ddl_frame_data_tag *) + kmalloc((sizeof(struct ddl_frame_data_tag) * + out_buf_pool->count), GFP_KERNEL); + + if (!dpb_list) { + VCD_MSG_ERROR("Memory allocation failure"); + return VCD_ERR_ALLOC_FAIL; + } + + for (i = 1; i <= out_buf_pool->count; i++) + dpb_list[i - 1].vcd_frm = out_buf_pool->entries[i].frame; + + dpb.dec_pic_buffers = dpb_list; + dpb.no_of_dec_pic_buf = out_buf_pool->count; + rc = ddl_set_property(cctxt->ddl_handle, &prop_hdr, &dpb); + + kfree(dpb_list); + *handled = false; + + return VCD_S_SUCCESS; +} + +void vcd_handle_eos_trans_end(struct vcd_clnt_ctxt *cctxt) +{ + u32 rc = VCD_S_SUCCESS; + if (cctxt->status.mask & VCD_EOS_PREV_VALID) { + rc = vcd_handle_frame_done(cctxt, + (void *)&cctxt->status.eos_prev_op_frm, + VCD_EVT_RESP_OUTPUT_DONE, + cctxt->status.eos_prev_op_frm_status); + cctxt->status.mask &= ~VCD_EOS_PREV_VALID; + } + if (VCD_FAILED(rc)) + return; + + if (cctxt->status.mask & VCD_FLUSH_ALL) + vcd_process_pending_flush_in_eos(cctxt); + + if (cctxt->status.mask & VCD_STOP_PENDING) + vcd_process_pending_stop_in_eos(cctxt); + else { + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_RUN, + CLIENT_STATE_EVENT_NUMBER(clnt_cb)); + } +} + +void vcd_handle_eos_done(struct vcd_clnt_ctxt *cctxt, + struct vcd_transc *transc, u32 status) +{ + struct vcd_frame_data vcd_frm; + u32 rc = VCD_S_SUCCESS, sent_eos_frm = false; + VCD_MSG_LOW("vcd_handle_eos_done:"); + + if (VCD_FAILED(status)) + VCD_MSG_ERROR("EOS DONE returned error = 0x%x", status); + + if (cctxt->status.mask & VCD_EOS_PREV_VALID) { + cctxt->status.eos_prev_op_frm.vcd_frm.flags |= + VCD_FRAME_FLAG_EOS; + + rc = vcd_handle_frame_done(cctxt, + (void *)&cctxt->status. + eos_prev_op_frm, + VCD_EVT_RESP_OUTPUT_DONE, + cctxt->status. + eos_prev_op_frm_status); + cctxt->status.mask &= ~VCD_EOS_PREV_VALID; + if (!VCD_FAILED(rc) && + cctxt->status.eos_prev_op_frm_status != + VCD_ERR_INTRLCD_FIELD_DROP) + sent_eos_frm = true; + } + if (!sent_eos_frm) { + if (transc->ip_buf_entry) { + transc->ip_buf_entry->frame.ip_frm_tag = + transc->ip_frm_tag; + + vcd_send_frame_done_in_eos(cctxt, + &transc->ip_buf_entry->frame, false); + } else { + memset(&vcd_frm, 0, sizeof(struct vcd_frame_data)); + vcd_frm.ip_frm_tag = transc->ip_frm_tag; + vcd_frm.time_stamp = transc->time_stamp; + vcd_frm.flags = VCD_FRAME_FLAG_EOS; + vcd_send_frame_done_in_eos(cctxt, &vcd_frm, true); + } + } + if (VCD_FAILED(rc)) + return; + if (transc->ip_buf_entry) { + if (transc->ip_buf_entry->frame.virtual) { + transc->ip_buf_entry->frame.ip_frm_tag = + transc->ip_frm_tag; + cctxt->callback(VCD_EVT_RESP_INPUT_DONE, + VCD_S_SUCCESS, + &transc->ip_buf_entry->frame, + sizeof(struct vcd_frame_data), + cctxt, cctxt->client_data); + } + transc->ip_buf_entry->in_use = false; + VCD_BUFFERPOOL_INUSE_DECREMENT(cctxt->in_buf_pool.in_use); + transc->ip_buf_entry = NULL; + if (cctxt->status.frame_submitted) + cctxt->status.frame_submitted--; + else + cctxt->status.frame_delayed--; + } + + vcd_release_trans_tbl_entry(transc); + if (cctxt->status.mask & VCD_FLUSH_ALL) + vcd_process_pending_flush_in_eos(cctxt); + + if (cctxt->status.mask & VCD_STOP_PENDING) { + vcd_process_pending_stop_in_eos(cctxt); + } else if (!(cctxt->status.mask & VCD_EOS_WAIT_OP_BUF)) { + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_RUN, + CLIENT_STATE_EVENT_NUMBER + (clnt_cb)); + } +} + +void vcd_handle_start_done(struct vcd_clnt_ctxt *cctxt, + struct vcd_transc *transc, u32 status) +{ + cctxt->status.cmd_submitted--; + vcd_mark_command_channel(cctxt->dev_ctxt, transc); + + if (!VCD_FAILED(status)) { + cctxt->callback(VCD_EVT_RESP_START, status, NULL, + 0, cctxt, cctxt->client_data); + + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_RUN, + CLIENT_STATE_EVENT_NUMBER(clnt_cb)); + } else { + VCD_MSG_ERROR("ddl callback returned failure." + "status = 0x%x", status); + vcd_handle_err_in_starting(cctxt, status); + } +} + +void vcd_handle_stop_done(struct vcd_clnt_ctxt *cctxt, + struct vcd_transc *transc, u32 status) +{ + + VCD_MSG_LOW("vcd_handle_stop_done:"); + cctxt->status.cmd_submitted--; + vcd_mark_command_channel(cctxt->dev_ctxt, transc); + + if (!VCD_FAILED(status)) { + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_OPEN, + CLIENT_STATE_EVENT_NUMBER(clnt_cb)); + } else { + VCD_MSG_FATAL("STOP_DONE returned error = 0x%x", status); + status = VCD_ERR_HW_FATAL; + vcd_handle_device_err_fatal(cctxt->dev_ctxt, cctxt); + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_INVALID, + CLIENT_STATE_EVENT_NUMBER(clnt_cb)); + } + + cctxt->callback(VCD_EVT_RESP_STOP, status, NULL, 0, cctxt, + cctxt->client_data); + + memset(&cctxt->status, 0, sizeof(struct vcd_clnt_status)); +} + +void vcd_handle_stop_done_in_starting(struct vcd_clnt_ctxt + *cctxt, struct vcd_transc *transc, u32 status) +{ + VCD_MSG_LOW("vcd_handle_stop_done_in_starting:"); + cctxt->status.cmd_submitted--; + vcd_mark_command_channel(cctxt->dev_ctxt, transc); + if (!VCD_FAILED(status)) { + cctxt->callback(VCD_EVT_RESP_START, cctxt->status. + last_err, NULL, 0, cctxt, cctxt->client_data); + vcd_do_client_state_transition(cctxt, VCD_CLIENT_STATE_OPEN, + CLIENT_STATE_EVENT_NUMBER(clnt_cb)); + } else { + VCD_MSG_FATAL("VCD Cleanup: STOP_DONE returned error " + "= 0x%x", status); + vcd_handle_err_fatal(cctxt, VCD_EVT_RESP_START, + VCD_ERR_HW_FATAL); + } +} + +void vcd_handle_stop_done_in_invalid(struct vcd_clnt_ctxt *cctxt, + struct vcd_transc *transc, u32 status) +{ + u32 rc; + VCD_MSG_LOW("vcd_handle_stop_done_in_invalid:"); + + cctxt->status.cmd_submitted--; + vcd_mark_command_channel(cctxt->dev_ctxt, transc); + + if (!VCD_FAILED(status)) { + vcd_client_cmd_flush_and_en_q(cctxt, VCD_CMD_CLIENT_CLOSE); + if (cctxt->status.frame_submitted) { + vcd_release_multiple_frame_channels(cctxt->dev_ctxt, + cctxt->status.frame_submitted); + + cctxt->status.frame_submitted = 0; + cctxt->status.frame_delayed = 0; + } + if (cctxt->status.cmd_submitted) { + vcd_release_multiple_command_channels( + cctxt->dev_ctxt, + cctxt->status.cmd_submitted); + cctxt->status.cmd_submitted = 0; + } + } else { + VCD_MSG_FATAL("VCD Cleanup: STOP_DONE returned error " + "= 0x%x", status); + vcd_handle_device_err_fatal(cctxt->dev_ctxt, cctxt); + cctxt->status.mask &= ~VCD_CLEANING_UP; + } + vcd_flush_buffers_in_err_fatal(cctxt); + VCD_MSG_HIGH("VCD cleanup: All buffers are returned"); + if (cctxt->status.mask & VCD_STOP_PENDING) { + cctxt->callback(VCD_EVT_RESP_STOP, VCD_S_SUCCESS, NULL, 0, + cctxt, cctxt->client_data); + cctxt->status.mask &= ~VCD_STOP_PENDING; + } + rc = vcd_power_event(cctxt->dev_ctxt, cctxt, + VCD_EVT_PWR_CLNT_ERRFATAL); + if (VCD_FAILED(rc)) + VCD_MSG_ERROR("VCD_EVT_PWR_CLNT_ERRFATAL failed"); + if (!(cctxt->status.mask & VCD_CLEANING_UP) && + cctxt->status.mask & VCD_CLOSE_PENDING) { + vcd_destroy_client_context(cctxt); + vcd_handle_for_last_clnt_close(cctxt->dev_ctxt, false); + } +} + +u32 vcd_handle_input_frame( + struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *input_frame) +{ + struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; + struct vcd_buffer_entry *buf_entry, *orig_frame; + struct vcd_frame_data *frm_entry; + u32 rc = VCD_S_SUCCESS; + u32 eos_handled = false; + + VCD_MSG_LOW("vcd_handle_input_frame:"); + + VCD_MSG_LOW("input buffer: addr=(0x%p), sz=(%d), len=(%d)", + input_frame->virtual, input_frame->alloc_len, + input_frame->data_len); + + if (!input_frame->virtual && + !(input_frame->flags & VCD_FRAME_FLAG_EOS)) { + VCD_MSG_ERROR("Bad frame ptr/len/EOS combination"); + return VCD_ERR_ILLEGAL_PARM; + } + + + if (!input_frame->data_len && + !(input_frame->flags & VCD_FRAME_FLAG_EOS)) { + VCD_MSG_MED("data_len = 0, returning INPUT DONE"); + cctxt->callback(VCD_EVT_RESP_INPUT_DONE, + VCD_ERR_INPUT_NOT_PROCESSED, + input_frame, + sizeof(struct vcd_frame_data), + cctxt, cctxt->client_data); + return VCD_S_SUCCESS; + } + + if (!(cctxt->status.mask & VCD_FIRST_IP_RCVD)) { + if (cctxt->decoding) + rc = vcd_handle_first_decode_frame(cctxt); + + if (!VCD_FAILED(rc)) { + cctxt->status.first_ts = input_frame->time_stamp; + cctxt->status.prev_ts = cctxt->status.first_ts; + + cctxt->status.mask |= VCD_FIRST_IP_RCVD; + + (void)vcd_power_event(cctxt->dev_ctxt, + cctxt, + VCD_EVT_PWR_CLNT_FIRST_FRAME); + } + } + VCD_FAILED_RETURN(rc, "Failed: First frame handling"); + + orig_frame = vcd_find_buffer_pool_entry(&cctxt->in_buf_pool, + input_frame->virtual); + if (!orig_frame) { + VCD_MSG_ERROR("Bad buffer addr: %p", input_frame->virtual); + return VCD_ERR_FAIL; + } + + if (orig_frame->in_use) { + /* + * This path only allowed for enc., dec. not allowed + * to queue same buffer multiple times + */ + if (cctxt->decoding) { + VCD_MSG_ERROR("An inuse input frame is being " + "re-queued to scheduler"); + return VCD_ERR_FAIL; + } + + buf_entry = kzalloc(sizeof(*buf_entry), GFP_KERNEL); + if (!buf_entry) { + VCD_MSG_ERROR("Unable to alloc memory"); + return VCD_ERR_FAIL; + } + + INIT_LIST_HEAD(&buf_entry->sched_list); + /* + * Pre-emptively poisoning this, as these dupe entries + * shouldn't get added to any list + */ + INIT_LIST_HEAD(&buf_entry->list); + buf_entry->list.next = LIST_POISON1; + buf_entry->list.prev = LIST_POISON2; + + buf_entry->valid = orig_frame->valid; + buf_entry->alloc = orig_frame->alloc; + buf_entry->virtual = orig_frame->virtual; + buf_entry->physical = orig_frame->physical; + buf_entry->sz = orig_frame->sz; + buf_entry->allocated = orig_frame->allocated; + buf_entry->in_use = 1; /* meaningless for the dupe buffers */ + buf_entry->frame = orig_frame->frame; + } else + buf_entry = orig_frame; + + if (input_frame->alloc_len > buf_entry->sz) { + VCD_MSG_ERROR("Bad buffer Alloc_len %d, Actual sz=%d", + input_frame->alloc_len, buf_entry->sz); + + return VCD_ERR_ILLEGAL_PARM; + } + + frm_entry = &buf_entry->frame; + + *frm_entry = *input_frame; + frm_entry->physical = buf_entry->physical; + + if (input_frame->flags & VCD_FRAME_FLAG_EOS) { + rc = vcd_handle_recvd_eos(cctxt, input_frame, + &eos_handled); + } + + if (VCD_FAILED(rc) || eos_handled) { + VCD_MSG_HIGH("rc = 0x%x, eos_handled = %d", rc, + eos_handled); + + return rc; + } + rc = vcd_sched_queue_buffer( + cctxt->sched_clnt_hdl, buf_entry, true); + VCD_FAILED_RETURN(rc, "Failed: vcd_sched_queue_buffer"); + + orig_frame->in_use++; + cctxt->in_buf_pool.in_use++; + vcd_try_submit_frame(dev_ctxt); + return rc; +} + +void vcd_release_all_clnt_frm_transc(struct vcd_clnt_ctxt *cctxt) +{ + struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; + u32 i, cntr = 0; + VCD_MSG_LOW("vcd_release_all_clnt_frm_transc:"); + for (i = 0; i < dev_ctxt->trans_tbl_size; i++) { + if (dev_ctxt->trans_tbl[i].in_use && + cctxt == dev_ctxt->trans_tbl[i].cctxt) { + if (dev_ctxt->trans_tbl[i]. + type == VCD_CMD_CODE_FRAME || + dev_ctxt->trans_tbl[i]. + type == VCD_CMD_NONE) { + vcd_release_trans_tbl_entry(&dev_ctxt-> + trans_tbl[i]); + } else { + VCD_MSG_LOW("vcd_transaction in use type(%u)", + dev_ctxt->trans_tbl[i].type); + cntr++; + } + } + } + if (cntr) + VCD_MSG_ERROR("vcd_transactions still in use: (%d)", cntr); +} + +void vcd_release_all_clnt_transc(struct vcd_clnt_ctxt *cctxt) +{ + struct vcd_dev_ctxt *dev_ctxt = cctxt->dev_ctxt; + u32 i; + + VCD_MSG_LOW("vcd_release_all_clnt_transc:"); + + for (i = 0; i < dev_ctxt->trans_tbl_size; i++) { + if (dev_ctxt->trans_tbl[i].in_use && + cctxt == dev_ctxt->trans_tbl[i].cctxt) { + vcd_release_trans_tbl_entry( + &dev_ctxt->trans_tbl[i]); + } + } +} + +void vcd_send_flush_done(struct vcd_clnt_ctxt *cctxt, u32 status) +{ + VCD_MSG_LOW("vcd_send_flush_done:"); + + if (cctxt->status.mask & VCD_FLUSH_INPUT) { + cctxt->callback(VCD_EVT_RESP_FLUSH_INPUT_DONE, + status, NULL, 0, cctxt, cctxt->client_data); + cctxt->status.mask &= ~VCD_FLUSH_INPUT; + } + + if (cctxt->status.mask & VCD_FLUSH_OUTPUT) { + cctxt->callback(VCD_EVT_RESP_FLUSH_OUTPUT_DONE, + status, NULL, 0, cctxt, cctxt->client_data); + cctxt->status.mask &= ~VCD_FLUSH_OUTPUT; + } +} + +u32 vcd_store_seq_hdr( + struct vcd_clnt_ctxt *cctxt, + struct vcd_sequence_hdr *seq_hdr) +{ + u32 rc; + struct vcd_property_hdr prop_hdr; + u32 align; + u8 *virtual_aligned; + u32 addr; + int ret = 0; + + if (!seq_hdr->sequence_header_len + || !seq_hdr->sequence_header) { + VCD_MSG_ERROR("Bad seq hdr"); + + return VCD_ERR_BAD_POINTER; + } + + if (cctxt->seq_hdr.sequence_header) { + VCD_MSG_HIGH("Old seq hdr detected"); + + vcd_pmem_free(cctxt->seq_hdr.sequence_header, + cctxt->seq_hdr_phy_addr, cctxt); + cctxt->seq_hdr.sequence_header = NULL; + } + + cctxt->seq_hdr.sequence_header_len = + seq_hdr->sequence_header_len; + + prop_hdr.prop_id = DDL_I_SEQHDR_ALIGN_BYTES; + prop_hdr.sz = sizeof(u32); + + rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr, &align); + + VCD_FAILED_RETURN(rc, + "Failed: ddl_get_property DDL_I_SEQHDR_ALIGN_BYTES"); + + VCD_MSG_MED("Seq hdr alignment bytes = %d", align); + + ret = vcd_pmem_alloc(cctxt->seq_hdr.sequence_header_len + align + + VCD_SEQ_HDR_PADDING_BYTES, + &(cctxt->seq_hdr.sequence_header), + &(cctxt->seq_hdr_phy_addr), cctxt); + + if (ret < 0) { + VCD_MSG_ERROR("Seq hdr allocation failed"); + + return VCD_ERR_ALLOC_FAIL; + } + + if (!cctxt->seq_hdr_phy_addr) { + VCD_MSG_ERROR("Couldn't get physical address"); + + return VCD_ERR_BAD_POINTER; + } + + if (align > 0) { + addr = (u32) cctxt->seq_hdr_phy_addr; + addr += align; + addr -= (addr % align); + virtual_aligned = cctxt->seq_hdr.sequence_header; + virtual_aligned += (u32) (addr - + (u32) cctxt->seq_hdr_phy_addr); + cctxt->seq_hdr_phy_addr = (u8 *) addr; + } else { + virtual_aligned = cctxt->seq_hdr.sequence_header; + } + + memcpy(virtual_aligned, seq_hdr->sequence_header, + seq_hdr->sequence_header_len); + + return VCD_S_SUCCESS; +} + +u32 vcd_set_frame_rate( + struct vcd_clnt_ctxt *cctxt, + struct vcd_property_frame_rate *fps) +{ + u32 rc; + cctxt->frm_rate = *fps; + rc = vcd_update_clnt_perf_lvl(cctxt, &cctxt->frm_rate, + cctxt->frm_p_units); + if (VCD_FAILED(rc)) { + VCD_MSG_ERROR("rc = 0x%x. Failed: vcd_update_clnt_perf_lvl", + rc); + } + rc = vcd_sched_update_config(cctxt); + return rc; +} + +u32 vcd_req_perf_level( + struct vcd_clnt_ctxt *cctxt, + struct vcd_property_perf_level *perf_level) +{ + u32 rc; + u32 res_trk_perf_level; + if (!perf_level) { + VCD_MSG_ERROR("Invalid parameters\n"); + return -EINVAL; + } + res_trk_perf_level = get_res_trk_perf_level(perf_level->level); + if (res_trk_perf_level < 0) { + rc = -ENOTSUPP; + goto perf_level_not_supp; + } + rc = vcd_set_perf_level(cctxt->dev_ctxt, res_trk_perf_level); + if (!rc) { + cctxt->reqd_perf_lvl = res_trk_perf_level; + cctxt->perf_set_by_client = 1; + } +perf_level_not_supp: + return rc; +} + +u32 vcd_set_frame_size( + struct vcd_clnt_ctxt *cctxt, + struct vcd_property_frame_size *frm_size) +{ + struct vcd_property_hdr prop_hdr; + u32 rc; + u32 frm_p_units; + (void)frm_size; + if (res_trk_get_disable_fullhd() && frm_size && + (frm_size->width * frm_size->height > 1280 * 720)) { + VCD_MSG_ERROR("Frame size = %dX%d greater than 1280X720 not" + "supported", frm_size->width, frm_size->height); + return VCD_ERR_FAIL; + } + prop_hdr.prop_id = DDL_I_FRAME_PROC_UNITS; + prop_hdr.sz = sizeof(frm_p_units); + rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr, &frm_p_units); + VCD_FAILED_RETURN(rc, "Failed: Get DDL_I_FRAME_PROC_UNITS"); + + cctxt->frm_p_units = frm_p_units; + + rc = vcd_update_clnt_perf_lvl(cctxt, &cctxt->frm_rate, + frm_p_units); + if (VCD_FAILED(rc)) { + VCD_MSG_ERROR("rc = 0x%x. Failed: vcd_update_clnt_perf_lvl", + rc); + } + return rc; +} + +void vcd_process_pending_flush_in_eos(struct vcd_clnt_ctxt *cctxt) +{ + u32 rc = VCD_S_SUCCESS; + VCD_MSG_HIGH("Buffer flush is pending"); + rc = vcd_flush_buffers(cctxt, cctxt->status.mask & VCD_FLUSH_ALL); + if (VCD_FAILED(rc)) + VCD_MSG_ERROR("rc = 0x%x. Failed: vcd_flush_buffers", rc); + cctxt->status.mask &= ~VCD_EOS_WAIT_OP_BUF; + vcd_send_flush_done(cctxt, VCD_S_SUCCESS); +} + +void vcd_process_pending_stop_in_eos(struct vcd_clnt_ctxt *cctxt) +{ + u32 rc = VCD_S_SUCCESS; + rc = vcd_flush_buffers(cctxt, VCD_FLUSH_ALL); + if (VCD_FAILED(rc)) + VCD_MSG_ERROR("rc = 0x%x. Failed: vcd_flush_buffers", rc); + VCD_MSG_HIGH("All buffers are returned. Enqueuing stop cmd"); + vcd_client_cmd_flush_and_en_q(cctxt, VCD_CMD_CODEC_STOP); + cctxt->status.mask &= ~VCD_STOP_PENDING; + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_STOPPING, + CLIENT_STATE_EVENT_NUMBER(stop)); +} + +u32 vcd_calculate_frame_delta( + struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *frame) +{ + u32 frm_delta; + u64 temp, max = ~((u64)0); + + if (cctxt->time_frame_delta) + temp = cctxt->time_frame_delta; + else if (frame->time_stamp >= cctxt->status.prev_ts) + temp = frame->time_stamp - cctxt->status.prev_ts; + else + temp = (max - cctxt->status.prev_ts) + + frame->time_stamp; + + VCD_MSG_LOW("Curr_ts=%lld Prev_ts=%lld Diff=%llu\n", + frame->time_stamp, cctxt->status.prev_ts, temp); + + temp *= cctxt->time_resoln; + (void)do_div(temp, VCD_TIMESTAMP_RESOLUTION); + frm_delta = temp; + cctxt->status.time_elapsed += frm_delta; + + temp = (cctxt->status.time_elapsed * VCD_TIMESTAMP_RESOLUTION); + (void)do_div(temp, cctxt->time_resoln); + cctxt->status.prev_ts = cctxt->status.first_ts + temp; + + VCD_MSG_LOW("Time_elapsed=%llu, Drift=%llu, new Prev_ts=%lld", + cctxt->status.time_elapsed, temp, + cctxt->status.prev_ts); + + return frm_delta; +} + +struct vcd_buffer_entry *vcd_check_fill_output_buffer + (struct vcd_clnt_ctxt *cctxt, + struct vcd_frame_data *buffer) { + struct vcd_buffer_pool *buf_pool = &cctxt->out_buf_pool; + struct vcd_buffer_entry *buf_entry; + + if (!buf_pool->entries) { + VCD_MSG_ERROR("Buffers not set or allocated yet"); + + return NULL; + } + + if (!buffer->virtual) { + VCD_MSG_ERROR("NULL buffer address provided"); + return NULL; + } + + buf_entry = + vcd_find_buffer_pool_entry(buf_pool, buffer->virtual); + if (!buf_entry) { + VCD_MSG_ERROR("Unrecognized buffer address provided = %p", + buffer->virtual); + return NULL; + } + + if (buf_entry->in_use) { + VCD_MSG_ERROR + ("An inuse output frame is being provided for reuse"); + return NULL; + } + + if ((buffer->alloc_len < buf_pool->buf_req.sz || + buffer->alloc_len > buf_entry->sz) && + !(cctxt->status.mask & VCD_IN_RECONFIG)) { + VCD_MSG_ERROR + ("Bad buffer Alloc_len = %d, Actual sz = %d, " + " Min sz = %u", + buffer->alloc_len, buf_entry->sz, + buf_pool->buf_req.sz); + return NULL; + } + + return buf_entry; +} + +void vcd_handle_ind_hw_err_fatal(struct vcd_clnt_ctxt *cctxt, + u32 event, u32 status) +{ + if (cctxt->status.frame_submitted) { + cctxt->status.frame_submitted--; + vcd_mark_frame_channel(cctxt->dev_ctxt); + } + vcd_handle_err_fatal(cctxt, event, status); +} + +void vcd_handle_err_fatal(struct vcd_clnt_ctxt *cctxt, u32 event, + u32 status) +{ + VCD_MSG_LOW("vcd_handle_err_fatal: event=%x, err=%x", event, status); + if (!VCD_FAILED_FATAL(status)) + return; + + if (VCD_FAILED_DEVICE_FATAL(status)) { + vcd_clnt_handle_device_err_fatal(cctxt, event); + vcd_handle_device_err_fatal(cctxt->dev_ctxt, cctxt); + } else if (VCD_FAILED_CLIENT_FATAL(status)) { + cctxt->status.last_evt = event; + cctxt->callback(event, VCD_ERR_HW_FATAL, NULL, 0, cctxt, + cctxt->client_data); + cctxt->status.mask |= VCD_CLEANING_UP; + vcd_client_cmd_flush_and_en_q(cctxt, VCD_CMD_CODEC_STOP); + vcd_do_client_state_transition(cctxt, + VCD_CLIENT_STATE_INVALID, + CLIENT_STATE_EVENT_NUMBER(clnt_cb)); + } +} + +void vcd_handle_err_in_starting(struct vcd_clnt_ctxt *cctxt, + u32 status) +{ + VCD_MSG_LOW("\n vcd_handle_err_in_starting:"); + if (VCD_FAILED_FATAL(status)) { + vcd_handle_err_fatal(cctxt, VCD_EVT_RESP_START, status); + } else { + cctxt->status.last_err = status; + VCD_MSG_HIGH("\n VCD cleanup: Enqueuing stop cmd"); + vcd_client_cmd_flush_and_en_q(cctxt, VCD_CMD_CODEC_STOP); + } +} + +void vcd_handle_trans_pending(struct vcd_clnt_ctxt *cctxt) +{ + if (!cctxt->status.frame_submitted) { + VCD_MSG_ERROR("Transaction pending response was not expected"); + return; + } + cctxt->status.frame_submitted--; + cctxt->status.frame_delayed++; + vcd_mark_frame_channel(cctxt->dev_ctxt); +} +void vcd_handle_submit_frame_failed(struct vcd_dev_ctxt + *dev_ctxt, struct vcd_transc *transc) +{ + struct vcd_clnt_ctxt *cctxt = transc->cctxt; + u32 rc; + + vcd_mark_frame_channel(dev_ctxt); + vcd_release_trans_tbl_entry(transc); + + vcd_handle_err_fatal(cctxt, VCD_EVT_IND_HWERRFATAL, + VCD_ERR_CLIENT_FATAL); + + if (vcd_get_command_channel(dev_ctxt, &transc)) { + transc->type = VCD_CMD_CODEC_STOP; + transc->cctxt = cctxt; + rc = vcd_submit_cmd_sess_end(transc); + if (VCD_FAILED(rc)) { + vcd_release_command_channel(dev_ctxt, transc); + VCD_MSG_ERROR("rc = 0x%x. Failed: VCD_SubmitCmdSessEnd", + rc); + } + } +} + +u32 vcd_check_if_buffer_req_met(struct vcd_clnt_ctxt *cctxt, + enum vcd_buffer_type buffer) +{ + struct vcd_property_hdr prop_hdr; + struct vcd_buffer_pool *buf_pool; + struct vcd_buffer_requirement buf_req; + u32 rc; + u8 i; + + if (buffer == VCD_BUFFER_INPUT) { + prop_hdr.prop_id = DDL_I_INPUT_BUF_REQ; + buf_pool = &cctxt->in_buf_pool; + } else { + prop_hdr.prop_id = DDL_I_OUTPUT_BUF_REQ; + buf_pool = &cctxt->out_buf_pool; + } + + prop_hdr.sz = sizeof(buf_req); + rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr, &buf_req); + VCD_FAILED_RETURN(rc, "Failed: ddl_GetProperty"); + + buf_pool->buf_req = buf_req; + if (buf_pool->count < buf_req.actual_count) { + VCD_MSG_ERROR("Buf requirement count not met"); + return VCD_ERR_FAIL; + } + + if (buf_pool->count > buf_req.actual_count) + buf_pool->count = buf_req.actual_count; + + if (!buf_pool->entries || + buf_pool->validated != buf_pool->count) { + VCD_MSG_ERROR("Buffer pool is not completely setup yet"); + return VCD_ERR_BAD_STATE; + } + for (i = 1; (rc == VCD_S_SUCCESS && i <= buf_pool->count); i++) { + if (buf_pool->entries[i].sz < + buf_pool->buf_req.sz) { + VCD_MSG_ERROR( + "BufReq sz not met:\ + addr=(0x%p) sz=%d ReqSize=%d", + buf_pool->entries[i].virtual, + buf_pool->entries[i].sz, + buf_pool->buf_req.sz); + rc = VCD_ERR_FAIL; + } + } + return rc; +} + +u32 vcd_handle_ind_output_reconfig( + struct vcd_clnt_ctxt *cctxt, void* payload, u32 status) +{ + struct ddl_frame_data_tag *frame = + (struct ddl_frame_data_tag *)payload; + struct vcd_property_hdr prop_hdr; + u32 rc = VCD_S_SUCCESS; + struct vcd_buffer_pool *out_buf_pool; + struct vcd_buffer_requirement buf_req; + + if (frame) + rc = vcd_handle_output_required(cctxt, payload, status); + VCD_FAILED_RETURN(rc, "Failed: vcd_handle_output_required in reconfig"); + vcd_mark_frame_channel(cctxt->dev_ctxt); + + rc = vcd_sched_suspend_resume_clnt(cctxt, false); + VCD_FAILED_RETURN(rc, "Failed: vcd_sched_suspend_resume_clnt"); + out_buf_pool = &cctxt->out_buf_pool; + prop_hdr.prop_id = DDL_I_OUTPUT_BUF_REQ; + prop_hdr.sz = sizeof(buf_req); + rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr, &buf_req); + VCD_FAILED_RETURN(rc, "Failed: ddl_GetProperty"); + + out_buf_pool->buf_req = buf_req; + + if (out_buf_pool->count < buf_req.actual_count) { + VCD_MSG_HIGH("Output buf requirement count increased"); + out_buf_pool->count = buf_req.actual_count; + } + + if (buf_req.actual_count > VCD_MAX_BUFFER_ENTRIES) { + VCD_MSG_ERROR("\n New act count exceeds Max count(32)"); + return VCD_ERR_FAIL; + } + + if (!VCD_FAILED(rc)) { + rc = vcd_set_frame_size(cctxt, NULL); + VCD_FAILED_RETURN(rc, "Failed: set_frame_size in reconfig"); + cctxt->status.mask &= ~VCD_FIRST_OP_RCVD; + cctxt->status.mask |= VCD_IN_RECONFIG; + cctxt->callback(VCD_EVT_IND_OUTPUT_RECONFIG, + status, NULL, 0, cctxt, + cctxt->client_data); + } + return rc; +} + +u32 vcd_handle_ind_output_reconfig_in_flushing( + struct vcd_clnt_ctxt *cctxt, void* payload, u32 status) +{ + u32 rc = VCD_S_SUCCESS; + if (cctxt->status.mask & VCD_FLUSH_INPUT && payload) { + (void)vcd_handle_input_done(cctxt, payload, + VCD_EVT_RESP_INPUT_FLUSHED, status); + payload = NULL; + } + rc = vcd_handle_ind_output_reconfig(cctxt, payload, status); + return rc; +} + +u32 vcd_return_op_buffer_to_hw(struct vcd_clnt_ctxt *cctxt, + struct vcd_buffer_entry *buf_entry) +{ + u32 rc = VCD_S_SUCCESS; + struct vcd_frame_data *frm_entry = &buf_entry->frame; + + VCD_MSG_LOW("vcd_return_op_buffer_to_hw in %d:", + cctxt->clnt_state.state); + frm_entry->physical = buf_entry->physical; + frm_entry->ip_frm_tag = VCD_FRAMETAG_INVALID; + frm_entry->intrlcd_ip_frm_tag = VCD_FRAMETAG_INVALID; + frm_entry->data_len = 0; + + if (cctxt->decoding) { + struct vcd_property_hdr Prop_hdr; + struct ddl_frame_data_tag ddl_frm; + Prop_hdr.prop_id = DDL_I_DPB_RELEASE; + Prop_hdr.sz = + sizeof(struct ddl_frame_data_tag); + memset(&ddl_frm, 0, sizeof(ddl_frm)); + ddl_frm.vcd_frm = *frm_entry; + rc = ddl_set_property(cctxt->ddl_handle, &Prop_hdr, + &ddl_frm); + if (VCD_FAILED(rc)) { + VCD_MSG_ERROR("Error returning output buffer to" + " HW. rc = 0x%x", rc); + buf_entry->in_use = false; + } else { + cctxt->out_buf_pool.in_use++; + buf_entry->in_use = true; + } + } + return rc; +} + +void vcd_handle_clnt_fatal(struct vcd_clnt_ctxt *cctxt, u32 trans_end) +{ + if (trans_end) + vcd_mark_frame_channel(cctxt->dev_ctxt); + vcd_handle_err_fatal(cctxt, + VCD_EVT_IND_HWERRFATAL, VCD_ERR_CLIENT_FATAL); +} + +void vcd_handle_clnt_fatal_input_done(struct vcd_clnt_ctxt *cctxt, + u32 trans_end) +{ + if (cctxt->status.frame_submitted > 0) + cctxt->status.frame_submitted--; + vcd_handle_clnt_fatal(cctxt, trans_end); +} + +void vcd_handle_ind_info_output_reconfig( + struct vcd_clnt_ctxt *cctxt, u32 status) +{ + if (cctxt) { + cctxt->callback(VCD_EVT_IND_INFO_OUTPUT_RECONFIG, status, NULL, + 0, cctxt, cctxt->client_data); + } +} + +u32 vcd_set_num_slices(struct vcd_clnt_ctxt *cctxt) +{ + struct vcd_property_hdr prop_hdr; + struct vcd_property_slice_delivery_info slice_delivery_info; + u32 rc = VCD_S_SUCCESS; + prop_hdr.prop_id = VCD_I_SLICE_DELIVERY_MODE; + prop_hdr.sz = prop_hdr.sz = + sizeof(struct vcd_property_slice_delivery_info); + rc = ddl_get_property(cctxt->ddl_handle, &prop_hdr, + &slice_delivery_info); + VCD_FAILED_RETURN(rc, "Failed: Get VCD_I_SLICE_DELIVERY_MODE"); + if (slice_delivery_info.enable) { + cctxt->num_slices = slice_delivery_info.num_slices; + VCD_MSG_LOW("%s slice delivery mode num_slices = %u\n", + __func__, cctxt->num_slices); + } else { + cctxt->num_slices = 1; + } + return rc; +} diff --git a/drivers/video/msm/vidc/common/vcd/vcd_util.c b/drivers/video/msm/vidc/common/vcd/vcd_util.c new file mode 100644 index 000000000000..98bc7f553e96 --- /dev/null +++ b/drivers/video/msm/vidc/common/vcd/vcd_util.c @@ -0,0 +1,106 @@ +/* Copyright (c) 2010, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#include "vidc_type.h" +#include "vcd_util.h" + +u32 vcd_critical_section_create(u32 **p_cs) +{ + struct mutex *lock; + if (!p_cs) { + VCD_MSG_ERROR("Bad critical section ptr"); + return VCD_ERR_BAD_POINTER; + } else { + lock = kmalloc(sizeof(struct mutex), GFP_KERNEL); + if (!lock) { + VCD_MSG_ERROR("Failed: vcd_critical_section_create"); + return VCD_ERR_ALLOC_FAIL; + } + mutex_init(lock); + *p_cs = (u32 *) lock; + return VCD_S_SUCCESS; + } +} + +u32 vcd_critical_section_release(u32 *cs) +{ + struct mutex *lock = (struct mutex *)cs; + if (!lock) { + VCD_MSG_ERROR("Bad critical section object"); + return VCD_ERR_BAD_POINTER; + } + + mutex_destroy(lock); + kfree(cs); + return VCD_S_SUCCESS; +} + +u32 vcd_critical_section_enter(u32 *cs) +{ + struct mutex *lock = (struct mutex *)cs; + if (!lock) { + VCD_MSG_ERROR("Bad critical section object"); + return VCD_ERR_BAD_POINTER; + } else + mutex_lock(lock); + + return VCD_S_SUCCESS; +} + +u32 vcd_critical_section_leave(u32 *cs) +{ + struct mutex *lock = (struct mutex *)cs; + + if (!lock) { + VCD_MSG_ERROR("Bad critical section object"); + + return VCD_ERR_BAD_POINTER; + } else + mutex_unlock(lock); + + return VCD_S_SUCCESS; +} + +int vcd_pmem_alloc(u32 size, u8 **kernel_vaddr, u8 **phy_addr) +{ + *phy_addr = + (u8 *) pmem_kalloc(size, PMEM_MEMTYPE | PMEM_ALIGNMENT_4K); + + if (!IS_ERR((void *)*phy_addr)) { + + *kernel_vaddr = ioremap((unsigned long)*phy_addr, size); + + if (!*kernel_vaddr) { + pr_err("%s: could not ioremap in kernel pmem buffers\n", + __func__); + pmem_kfree((s32) *phy_addr); + return -ENOMEM; + } + pr_debug("write buf: phy addr 0x%08x kernel addr 0x%08x\n", + (u32) *phy_addr, (u32) *kernel_vaddr); + return 0; + } else { + pr_err("%s: could not allocte in kernel pmem buffers\n", + __func__); + return -ENOMEM; + } + +} + +int vcd_pmem_free(u8 *kernel_vaddr, u8 *phy_addr) +{ + iounmap((void *)kernel_vaddr); + pmem_kfree((s32) phy_addr); + + return 0; +} diff --git a/drivers/video/msm/vidc/common/vcd/vcd_util.h b/drivers/video/msm/vidc/common/vcd/vcd_util.h new file mode 100644 index 000000000000..7571b25fceba --- /dev/null +++ b/drivers/video/msm/vidc/common/vcd/vcd_util.h @@ -0,0 +1,52 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#ifndef _VCD_UTIL_H_ +#define _VCD_UTIL_H_ +#include +#include + +#if DEBUG + +#define VCD_MSG_LOW(xx_fmt...) printk(KERN_INFO "\n\t* " xx_fmt) +#define VCD_MSG_MED(xx_fmt...) printk(KERN_INFO "\n * " xx_fmt) +#define VCD_MSG_HIGH(xx_fmt...) printk(KERN_WARNING "\n" xx_fmt) + +#else + +#define VCD_MSG_LOW(xx_fmt...) +#define VCD_MSG_MED(xx_fmt...) +#define VCD_MSG_HIGH(xx_fmt...) + +#endif + +#define VCD_MSG_ERROR(xx_fmt...) printk(KERN_ERR "\n err: " xx_fmt) +#define VCD_MSG_FATAL(xx_fmt...) printk(KERN_ERR "\n " xx_fmt) + +#define VCD_FAILED_RETURN(rc, xx_fmt...) \ + do { \ + if (VCD_FAILED(rc)) { \ + printk(KERN_ERR xx_fmt); \ + return rc; \ + } \ + } while (0) + +#define VCD_FAILED_DEVICE_FATAL(rc) \ + (rc == VCD_ERR_HW_FATAL ? true : false) +#define VCD_FAILED_CLIENT_FATAL(rc) \ + (rc == VCD_ERR_CLIENT_FATAL ? true : false) + +#define VCD_FAILED_FATAL(rc) \ + ((VCD_FAILED_DEVICE_FATAL(rc) || VCD_FAILED_CLIENT_FATAL(rc)) \ + ? true : false) + +#endif diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h index fe722c1fb61d..b4821a2b4d69 100644 --- a/include/linux/msm_mdp.h +++ b/include/linux/msm_mdp.h @@ -1,6 +1,7 @@ /* include/linux/msm_mdp.h * * Copyright (C) 2007 Google Incorporated + * Copyright (c) 2012 The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -14,66 +15,19 @@ #ifndef _MSM_MDP_H_ #define _MSM_MDP_H_ -#include - -#define MSMFB_IOCTL_MAGIC 'm' -#define MSMFB_GRP_DISP _IOW(MSMFB_IOCTL_MAGIC, 1, unsigned int) -#define MSMFB_BLIT _IOW(MSMFB_IOCTL_MAGIC, 2, unsigned int) - -enum { - MDP_RGB_565, /* RGB 565 planar */ - MDP_XRGB_8888, /* RGB 888 padded */ - MDP_Y_CBCR_H2V2, /* Y and CbCr, pseudo planar w/ Cb is in MSB */ - MDP_ARGB_8888, /* ARGB 888 */ - MDP_RGB_888, /* RGB 888 planar */ - MDP_Y_CRCB_H2V2, /* Y and CrCb, pseudo planar w/ Cr is in MSB */ - MDP_YCRYCB_H2V1, /* YCrYCb interleave */ - MDP_Y_CRCB_H2V1, /* Y and CrCb, pseduo planar w/ Cr is in MSB */ - MDP_Y_CBCR_H2V1, /* Y and CrCb, pseduo planar w/ Cr is in MSB */ - MDP_RGBA_8888, /* ARGB 888 */ - MDP_BGRA_8888, /* ABGR 888 */ - MDP_RGBX_8888, /* RGBX 888 */ - MDP_IMGTYPE_LIMIT /* Non valid image type after this enum */ -}; - -enum { - PMEM_IMG, - FB_IMG, -}; - -/* flag values */ -#define MDP_ROT_NOP 0 -#define MDP_FLIP_LR 0x1 -#define MDP_FLIP_UD 0x2 -#define MDP_ROT_90 0x4 -#define MDP_ROT_180 (MDP_FLIP_UD|MDP_FLIP_LR) -#define MDP_ROT_270 (MDP_ROT_90|MDP_FLIP_UD|MDP_FLIP_LR) -#define MDP_DITHER 0x8 -#define MDP_BLUR 0x10 - -#define MDP_TRANSP_NOP 0xffffffff -#define MDP_ALPHA_NOP 0xff - -struct mdp_rect { - u32 x, y, w, h; -}; - -struct mdp_img { - u32 width, height, format, offset; - int memory_id; /* the file descriptor */ -}; - -struct mdp_blit_req { - struct mdp_img src; - struct mdp_img dst; - struct mdp_rect src_rect; - struct mdp_rect dst_rect; - u32 alpha, transp_mask, flags; -}; - -struct mdp_blit_req_list { - u32 count; - struct mdp_blit_req req[]; -}; - -#endif /* _MSM_MDP_H_ */ +#include + +/* get the framebuffer physical address information */ +int get_fb_phys_info(unsigned long *start, unsigned long *len, int fb_num, + int subsys_id); +struct fb_info *msm_fb_get_writeback_fb(void); +int msm_fb_writeback_init(struct fb_info *info); +int msm_fb_writeback_start(struct fb_info *info); +int msm_fb_writeback_queue_buffer(struct fb_info *info, + struct msmfb_data *data); +int msm_fb_writeback_dequeue_buffer(struct fb_info *info, + struct msmfb_data *data); +int msm_fb_writeback_stop(struct fb_info *info); +int msm_fb_writeback_terminate(struct fb_info *info); + +#endif /*_MSM_MDP_H_*/ diff --git a/include/linux/msm_vidc_dec.h b/include/linux/msm_vidc_dec.h new file mode 100644 index 000000000000..0c03e136c3c9 --- /dev/null +++ b/include/linux/msm_vidc_dec.h @@ -0,0 +1,568 @@ +#ifndef _MSM_VIDC_DEC_H_ +#define _MSM_VIDC_DEC_H_ + +#include +#include + +/* STATUS CODES */ +/* Base value for status codes */ +#define VDEC_S_BASE 0x40000000 +/* Success */ +#define VDEC_S_SUCCESS (VDEC_S_BASE) +/* General failure */ +#define VDEC_S_EFAIL (VDEC_S_BASE + 1) +/* Fatal irrecoverable failure. Need to tear down session. */ +#define VDEC_S_EFATAL (VDEC_S_BASE + 2) +/* Error detected in the passed parameters */ +#define VDEC_S_EBADPARAM (VDEC_S_BASE + 3) +/* Command called in invalid state. */ +#define VDEC_S_EINVALSTATE (VDEC_S_BASE + 4) + /* Insufficient OS resources - thread, memory etc. */ +#define VDEC_S_ENOSWRES (VDEC_S_BASE + 5) + /* Insufficient HW resources - core capacity maxed out. */ +#define VDEC_S_ENOHWRES (VDEC_S_BASE + 6) +/* Invalid command called */ +#define VDEC_S_EINVALCMD (VDEC_S_BASE + 7) +/* Command timeout. */ +#define VDEC_S_ETIMEOUT (VDEC_S_BASE + 8) +/* Pre-requirement is not met for API. */ +#define VDEC_S_ENOPREREQ (VDEC_S_BASE + 9) +/* Command queue is full. */ +#define VDEC_S_ECMDQFULL (VDEC_S_BASE + 10) +/* Command is not supported by this driver */ +#define VDEC_S_ENOTSUPP (VDEC_S_BASE + 11) +/* Command is not implemented by thedriver. */ +#define VDEC_S_ENOTIMPL (VDEC_S_BASE + 12) +/* Command is not implemented by the driver. */ +#define VDEC_S_BUSY (VDEC_S_BASE + 13) +#define VDEC_S_INPUT_BITSTREAM_ERR (VDEC_S_BASE + 14) + +#define VDEC_INTF_VER 1 +#define VDEC_MSG_BASE 0x0000000 +/* Codes to identify asynchronous message responses and events that driver + wants to communicate to the app.*/ +#define VDEC_MSG_INVALID (VDEC_MSG_BASE + 0) +#define VDEC_MSG_RESP_INPUT_BUFFER_DONE (VDEC_MSG_BASE + 1) +#define VDEC_MSG_RESP_OUTPUT_BUFFER_DONE (VDEC_MSG_BASE + 2) +#define VDEC_MSG_RESP_INPUT_FLUSHED (VDEC_MSG_BASE + 3) +#define VDEC_MSG_RESP_OUTPUT_FLUSHED (VDEC_MSG_BASE + 4) +#define VDEC_MSG_RESP_FLUSH_INPUT_DONE (VDEC_MSG_BASE + 5) +#define VDEC_MSG_RESP_FLUSH_OUTPUT_DONE (VDEC_MSG_BASE + 6) +#define VDEC_MSG_RESP_START_DONE (VDEC_MSG_BASE + 7) +#define VDEC_MSG_RESP_STOP_DONE (VDEC_MSG_BASE + 8) +#define VDEC_MSG_RESP_PAUSE_DONE (VDEC_MSG_BASE + 9) +#define VDEC_MSG_RESP_RESUME_DONE (VDEC_MSG_BASE + 10) +#define VDEC_MSG_RESP_RESOURCE_LOADED (VDEC_MSG_BASE + 11) +#define VDEC_EVT_RESOURCES_LOST (VDEC_MSG_BASE + 12) +#define VDEC_MSG_EVT_CONFIG_CHANGED (VDEC_MSG_BASE + 13) +#define VDEC_MSG_EVT_HW_ERROR (VDEC_MSG_BASE + 14) +#define VDEC_MSG_EVT_INFO_CONFIG_CHANGED (VDEC_MSG_BASE + 15) +#define VDEC_MSG_EVT_INFO_FIELD_DROPPED (VDEC_MSG_BASE + 16) + +/*Buffer flags bits masks.*/ +#define VDEC_BUFFERFLAG_EOS 0x00000001 +#define VDEC_BUFFERFLAG_DECODEONLY 0x00000004 +#define VDEC_BUFFERFLAG_DATACORRUPT 0x00000008 +#define VDEC_BUFFERFLAG_ENDOFFRAME 0x00000010 +#define VDEC_BUFFERFLAG_SYNCFRAME 0x00000020 +#define VDEC_BUFFERFLAG_EXTRADATA 0x00000040 +#define VDEC_BUFFERFLAG_CODECCONFIG 0x00000080 + +/*Post processing flags bit masks*/ +#define VDEC_EXTRADATA_NONE 0x001 +#define VDEC_EXTRADATA_QP 0x004 +#define VDEC_EXTRADATA_MB_ERROR_MAP 0x008 +#define VDEC_EXTRADATA_SEI 0x010 +#define VDEC_EXTRADATA_VUI 0x020 +#define VDEC_EXTRADATA_VC1 0x040 + +#define VDEC_CMDBASE 0x800 +#define VDEC_CMD_SET_INTF_VERSION (VDEC_CMDBASE) + +#define VDEC_IOCTL_MAGIC 'v' + +struct vdec_ioctl_msg { + void __user *in; + void __user *out; +}; + +/* CMD params: InputParam:enum vdec_codec + OutputParam: struct vdec_profile_level*/ +#define VDEC_IOCTL_GET_PROFILE_LEVEL_SUPPORTED \ + _IOWR(VDEC_IOCTL_MAGIC, 0, struct vdec_ioctl_msg) + +/*CMD params:InputParam: NULL + OutputParam: uint32_t(bitmask)*/ +#define VDEC_IOCTL_GET_INTERLACE_FORMAT \ + _IOR(VDEC_IOCTL_MAGIC, 1, struct vdec_ioctl_msg) + +/* CMD params: InputParam: enum vdec_codec + OutputParam: struct vdec_profile_level*/ +#define VDEC_IOCTL_GET_CURRENT_PROFILE_LEVEL \ + _IOWR(VDEC_IOCTL_MAGIC, 2, struct vdec_ioctl_msg) + +/*CMD params: SET: InputParam: enum vdec_output_fromat OutputParam: NULL + GET: InputParam: NULL OutputParam: enum vdec_output_fromat*/ +#define VDEC_IOCTL_SET_OUTPUT_FORMAT \ + _IOWR(VDEC_IOCTL_MAGIC, 3, struct vdec_ioctl_msg) +#define VDEC_IOCTL_GET_OUTPUT_FORMAT \ + _IOWR(VDEC_IOCTL_MAGIC, 4, struct vdec_ioctl_msg) + +/*CMD params: SET: InputParam: enum vdec_codec OutputParam: NULL + GET: InputParam: NULL OutputParam: enum vdec_codec*/ +#define VDEC_IOCTL_SET_CODEC \ + _IOW(VDEC_IOCTL_MAGIC, 5, struct vdec_ioctl_msg) +#define VDEC_IOCTL_GET_CODEC \ + _IOR(VDEC_IOCTL_MAGIC, 6, struct vdec_ioctl_msg) + +/*CMD params: SET: InputParam: struct vdec_picsize outputparam: NULL + GET: InputParam: NULL outputparam: struct vdec_picsize*/ +#define VDEC_IOCTL_SET_PICRES \ + _IOW(VDEC_IOCTL_MAGIC, 7, struct vdec_ioctl_msg) +#define VDEC_IOCTL_GET_PICRES \ + _IOR(VDEC_IOCTL_MAGIC, 8, struct vdec_ioctl_msg) + +#define VDEC_IOCTL_SET_EXTRADATA \ + _IOW(VDEC_IOCTL_MAGIC, 9, struct vdec_ioctl_msg) +#define VDEC_IOCTL_GET_EXTRADATA \ + _IOR(VDEC_IOCTL_MAGIC, 10, struct vdec_ioctl_msg) + +#define VDEC_IOCTL_SET_SEQUENCE_HEADER \ + _IOW(VDEC_IOCTL_MAGIC, 11, struct vdec_ioctl_msg) + +/* CMD params: SET: InputParam - vdec_allocatorproperty, OutputParam - NULL + GET: InputParam - NULL, OutputParam - vdec_allocatorproperty*/ +#define VDEC_IOCTL_SET_BUFFER_REQ \ + _IOW(VDEC_IOCTL_MAGIC, 12, struct vdec_ioctl_msg) +#define VDEC_IOCTL_GET_BUFFER_REQ \ + _IOR(VDEC_IOCTL_MAGIC, 13, struct vdec_ioctl_msg) +/* CMD params: InputParam - vdec_buffer, OutputParam - uint8_t** */ +#define VDEC_IOCTL_ALLOCATE_BUFFER \ + _IOWR(VDEC_IOCTL_MAGIC, 14, struct vdec_ioctl_msg) +/* CMD params: InputParam - uint8_t *, OutputParam - NULL.*/ +#define VDEC_IOCTL_FREE_BUFFER \ + _IOW(VDEC_IOCTL_MAGIC, 15, struct vdec_ioctl_msg) + +/*CMD params: CMD: InputParam - struct vdec_setbuffer_cmd, OutputParam - NULL*/ +#define VDEC_IOCTL_SET_BUFFER \ + _IOW(VDEC_IOCTL_MAGIC, 16, struct vdec_ioctl_msg) + +/* CMD params: InputParam - struct vdec_fillbuffer_cmd, OutputParam - NULL*/ +#define VDEC_IOCTL_FILL_OUTPUT_BUFFER \ + _IOW(VDEC_IOCTL_MAGIC, 17, struct vdec_ioctl_msg) + +/*CMD params: InputParam - struct vdec_frameinfo , OutputParam - NULL*/ +#define VDEC_IOCTL_DECODE_FRAME \ + _IOW(VDEC_IOCTL_MAGIC, 18, struct vdec_ioctl_msg) + +#define VDEC_IOCTL_LOAD_RESOURCES _IO(VDEC_IOCTL_MAGIC, 19) +#define VDEC_IOCTL_CMD_START _IO(VDEC_IOCTL_MAGIC, 20) +#define VDEC_IOCTL_CMD_STOP _IO(VDEC_IOCTL_MAGIC, 21) +#define VDEC_IOCTL_CMD_PAUSE _IO(VDEC_IOCTL_MAGIC, 22) +#define VDEC_IOCTL_CMD_RESUME _IO(VDEC_IOCTL_MAGIC, 23) + +/*CMD params: InputParam - enum vdec_bufferflush , OutputParam - NULL */ +#define VDEC_IOCTL_CMD_FLUSH _IOW(VDEC_IOCTL_MAGIC, 24, struct vdec_ioctl_msg) + +/* ======================================================== + * IOCTL for getting asynchronous notification from driver + * ========================================================*/ + +/*IOCTL params: InputParam - NULL, OutputParam - struct vdec_msginfo*/ +#define VDEC_IOCTL_GET_NEXT_MSG \ + _IOR(VDEC_IOCTL_MAGIC, 25, struct vdec_ioctl_msg) + +#define VDEC_IOCTL_STOP_NEXT_MSG _IO(VDEC_IOCTL_MAGIC, 26) + +#define VDEC_IOCTL_GET_NUMBER_INSTANCES \ + _IOR(VDEC_IOCTL_MAGIC, 27, struct vdec_ioctl_msg) + +#define VDEC_IOCTL_SET_PICTURE_ORDER \ + _IOW(VDEC_IOCTL_MAGIC, 28, struct vdec_ioctl_msg) + +#define VDEC_IOCTL_SET_FRAME_RATE \ + _IOW(VDEC_IOCTL_MAGIC, 29, struct vdec_ioctl_msg) + +#define VDEC_IOCTL_SET_H264_MV_BUFFER \ + _IOW(VDEC_IOCTL_MAGIC, 30, struct vdec_ioctl_msg) + +#define VDEC_IOCTL_FREE_H264_MV_BUFFER \ + _IOW(VDEC_IOCTL_MAGIC, 31, struct vdec_ioctl_msg) + +#define VDEC_IOCTL_GET_MV_BUFFER_SIZE \ + _IOR(VDEC_IOCTL_MAGIC, 32, struct vdec_ioctl_msg) + +#define VDEC_IOCTL_SET_IDR_ONLY_DECODING \ + _IO(VDEC_IOCTL_MAGIC, 33) + +#define VDEC_IOCTL_SET_CONT_ON_RECONFIG \ + _IO(VDEC_IOCTL_MAGIC, 34) + +#define VDEC_IOCTL_SET_DISABLE_DMX \ + _IOW(VDEC_IOCTL_MAGIC, 35, struct vdec_ioctl_msg) + +#define VDEC_IOCTL_GET_DISABLE_DMX \ + _IOR(VDEC_IOCTL_MAGIC, 36, struct vdec_ioctl_msg) + +#define VDEC_IOCTL_GET_DISABLE_DMX_SUPPORT \ + _IOR(VDEC_IOCTL_MAGIC, 37, struct vdec_ioctl_msg) + +enum vdec_picture { + PICTURE_TYPE_I, + PICTURE_TYPE_P, + PICTURE_TYPE_B, + PICTURE_TYPE_BI, + PICTURE_TYPE_SKIP, + PICTURE_TYPE_IDR, + PICTURE_TYPE_UNKNOWN +}; + +enum vdec_buffer { + VDEC_BUFFER_TYPE_INPUT, + VDEC_BUFFER_TYPE_OUTPUT +}; + +struct vdec_allocatorproperty { + enum vdec_buffer buffer_type; + uint32_t mincount; + uint32_t maxcount; + uint32_t actualcount; + size_t buffer_size; + uint32_t alignment; + uint32_t buf_poolid; +}; + +struct vdec_bufferpayload { + void __user *bufferaddr; + size_t buffer_len; + int pmem_fd; + size_t offset; + size_t mmaped_size; +}; + +struct vdec_setbuffer_cmd { + enum vdec_buffer buffer_type; + struct vdec_bufferpayload buffer; +}; + +struct vdec_fillbuffer_cmd { + struct vdec_bufferpayload buffer; + void *client_data; +}; + +enum vdec_bufferflush { + VDEC_FLUSH_TYPE_INPUT, + VDEC_FLUSH_TYPE_OUTPUT, + VDEC_FLUSH_TYPE_ALL +}; + +enum vdec_codec { + VDEC_CODECTYPE_H264 = 0x1, + VDEC_CODECTYPE_H263 = 0x2, + VDEC_CODECTYPE_MPEG4 = 0x3, + VDEC_CODECTYPE_DIVX_3 = 0x4, + VDEC_CODECTYPE_DIVX_4 = 0x5, + VDEC_CODECTYPE_DIVX_5 = 0x6, + VDEC_CODECTYPE_DIVX_6 = 0x7, + VDEC_CODECTYPE_XVID = 0x8, + VDEC_CODECTYPE_MPEG1 = 0x9, + VDEC_CODECTYPE_MPEG2 = 0xa, + VDEC_CODECTYPE_VC1 = 0xb, + VDEC_CODECTYPE_VC1_RCV = 0xc +}; + +enum vdec_mpeg2_profile { + VDEC_MPEG2ProfileSimple = 0x1, + VDEC_MPEG2ProfileMain = 0x2, + VDEC_MPEG2Profile422 = 0x4, + VDEC_MPEG2ProfileSNR = 0x8, + VDEC_MPEG2ProfileSpatial = 0x10, + VDEC_MPEG2ProfileHigh = 0x20, + VDEC_MPEG2ProfileKhronosExtensions = 0x6F000000, + VDEC_MPEG2ProfileVendorStartUnused = 0x7F000000, + VDEC_MPEG2ProfileMax = 0x7FFFFFFF +}; + +enum vdec_mpeg2_level { + + VDEC_MPEG2LevelLL = 0x1, + VDEC_MPEG2LevelML = 0x2, + VDEC_MPEG2LevelH14 = 0x4, + VDEC_MPEG2LevelHL = 0x8, + VDEC_MPEG2LevelKhronosExtensions = 0x6F000000, + VDEC_MPEG2LevelVendorStartUnused = 0x7F000000, + VDEC_MPEG2LevelMax = 0x7FFFFFFF +}; + +enum vdec_mpeg4_profile { + VDEC_MPEG4ProfileSimple = 0x01, + VDEC_MPEG4ProfileSimpleScalable = 0x02, + VDEC_MPEG4ProfileCore = 0x04, + VDEC_MPEG4ProfileMain = 0x08, + VDEC_MPEG4ProfileNbit = 0x10, + VDEC_MPEG4ProfileScalableTexture = 0x20, + VDEC_MPEG4ProfileSimpleFace = 0x40, + VDEC_MPEG4ProfileSimpleFBA = 0x80, + VDEC_MPEG4ProfileBasicAnimated = 0x100, + VDEC_MPEG4ProfileHybrid = 0x200, + VDEC_MPEG4ProfileAdvancedRealTime = 0x400, + VDEC_MPEG4ProfileCoreScalable = 0x800, + VDEC_MPEG4ProfileAdvancedCoding = 0x1000, + VDEC_MPEG4ProfileAdvancedCore = 0x2000, + VDEC_MPEG4ProfileAdvancedScalable = 0x4000, + VDEC_MPEG4ProfileAdvancedSimple = 0x8000, + VDEC_MPEG4ProfileKhronosExtensions = 0x6F000000, + VDEC_MPEG4ProfileVendorStartUnused = 0x7F000000, + VDEC_MPEG4ProfileMax = 0x7FFFFFFF +}; + +enum vdec_mpeg4_level { + VDEC_MPEG4Level0 = 0x01, + VDEC_MPEG4Level0b = 0x02, + VDEC_MPEG4Level1 = 0x04, + VDEC_MPEG4Level2 = 0x08, + VDEC_MPEG4Level3 = 0x10, + VDEC_MPEG4Level4 = 0x20, + VDEC_MPEG4Level4a = 0x40, + VDEC_MPEG4Level5 = 0x80, + VDEC_MPEG4LevelKhronosExtensions = 0x6F000000, + VDEC_MPEG4LevelVendorStartUnused = 0x7F000000, + VDEC_MPEG4LevelMax = 0x7FFFFFFF +}; + +enum vdec_avc_profile { + VDEC_AVCProfileBaseline = 0x01, + VDEC_AVCProfileMain = 0x02, + VDEC_AVCProfileExtended = 0x04, + VDEC_AVCProfileHigh = 0x08, + VDEC_AVCProfileHigh10 = 0x10, + VDEC_AVCProfileHigh422 = 0x20, + VDEC_AVCProfileHigh444 = 0x40, + VDEC_AVCProfileKhronosExtensions = 0x6F000000, + VDEC_AVCProfileVendorStartUnused = 0x7F000000, + VDEC_AVCProfileMax = 0x7FFFFFFF +}; + +enum vdec_avc_level { + VDEC_AVCLevel1 = 0x01, + VDEC_AVCLevel1b = 0x02, + VDEC_AVCLevel11 = 0x04, + VDEC_AVCLevel12 = 0x08, + VDEC_AVCLevel13 = 0x10, + VDEC_AVCLevel2 = 0x20, + VDEC_AVCLevel21 = 0x40, + VDEC_AVCLevel22 = 0x80, + VDEC_AVCLevel3 = 0x100, + VDEC_AVCLevel31 = 0x200, + VDEC_AVCLevel32 = 0x400, + VDEC_AVCLevel4 = 0x800, + VDEC_AVCLevel41 = 0x1000, + VDEC_AVCLevel42 = 0x2000, + VDEC_AVCLevel5 = 0x4000, + VDEC_AVCLevel51 = 0x8000, + VDEC_AVCLevelKhronosExtensions = 0x6F000000, + VDEC_AVCLevelVendorStartUnused = 0x7F000000, + VDEC_AVCLevelMax = 0x7FFFFFFF +}; + +enum vdec_divx_profile { + VDEC_DIVXProfile_qMobile = 0x01, + VDEC_DIVXProfile_Mobile = 0x02, + VDEC_DIVXProfile_HD = 0x04, + VDEC_DIVXProfile_Handheld = 0x08, + VDEC_DIVXProfile_Portable = 0x10, + VDEC_DIVXProfile_HomeTheater = 0x20 +}; + +enum vdec_xvid_profile { + VDEC_XVIDProfile_Simple = 0x1, + VDEC_XVIDProfile_Advanced_Realtime_Simple = 0x2, + VDEC_XVIDProfile_Advanced_Simple = 0x4 +}; + +enum vdec_xvid_level { + VDEC_XVID_LEVEL_S_L0 = 0x1, + VDEC_XVID_LEVEL_S_L1 = 0x2, + VDEC_XVID_LEVEL_S_L2 = 0x4, + VDEC_XVID_LEVEL_S_L3 = 0x8, + VDEC_XVID_LEVEL_ARTS_L1 = 0x10, + VDEC_XVID_LEVEL_ARTS_L2 = 0x20, + VDEC_XVID_LEVEL_ARTS_L3 = 0x40, + VDEC_XVID_LEVEL_ARTS_L4 = 0x80, + VDEC_XVID_LEVEL_AS_L0 = 0x100, + VDEC_XVID_LEVEL_AS_L1 = 0x200, + VDEC_XVID_LEVEL_AS_L2 = 0x400, + VDEC_XVID_LEVEL_AS_L3 = 0x800, + VDEC_XVID_LEVEL_AS_L4 = 0x1000 +}; + +enum vdec_h263profile { + VDEC_H263ProfileBaseline = 0x01, + VDEC_H263ProfileH320Coding = 0x02, + VDEC_H263ProfileBackwardCompatible = 0x04, + VDEC_H263ProfileISWV2 = 0x08, + VDEC_H263ProfileISWV3 = 0x10, + VDEC_H263ProfileHighCompression = 0x20, + VDEC_H263ProfileInternet = 0x40, + VDEC_H263ProfileInterlace = 0x80, + VDEC_H263ProfileHighLatency = 0x100, + VDEC_H263ProfileKhronosExtensions = 0x6F000000, + VDEC_H263ProfileVendorStartUnused = 0x7F000000, + VDEC_H263ProfileMax = 0x7FFFFFFF +}; + +enum vdec_h263level { + VDEC_H263Level10 = 0x01, + VDEC_H263Level20 = 0x02, + VDEC_H263Level30 = 0x04, + VDEC_H263Level40 = 0x08, + VDEC_H263Level45 = 0x10, + VDEC_H263Level50 = 0x20, + VDEC_H263Level60 = 0x40, + VDEC_H263Level70 = 0x80, + VDEC_H263LevelKhronosExtensions = 0x6F000000, + VDEC_H263LevelVendorStartUnused = 0x7F000000, + VDEC_H263LevelMax = 0x7FFFFFFF +}; + +enum vdec_wmv_format { + VDEC_WMVFormatUnused = 0x01, + VDEC_WMVFormat7 = 0x02, + VDEC_WMVFormat8 = 0x04, + VDEC_WMVFormat9 = 0x08, + VDEC_WMFFormatKhronosExtensions = 0x6F000000, + VDEC_WMFFormatVendorStartUnused = 0x7F000000, + VDEC_WMVFormatMax = 0x7FFFFFFF +}; + +enum vdec_vc1_profile { + VDEC_VC1ProfileSimple = 0x1, + VDEC_VC1ProfileMain = 0x2, + VDEC_VC1ProfileAdvanced = 0x4 +}; + +enum vdec_vc1_level { + VDEC_VC1_LEVEL_S_Low = 0x1, + VDEC_VC1_LEVEL_S_Medium = 0x2, + VDEC_VC1_LEVEL_M_Low = 0x4, + VDEC_VC1_LEVEL_M_Medium = 0x8, + VDEC_VC1_LEVEL_M_High = 0x10, + VDEC_VC1_LEVEL_A_L0 = 0x20, + VDEC_VC1_LEVEL_A_L1 = 0x40, + VDEC_VC1_LEVEL_A_L2 = 0x80, + VDEC_VC1_LEVEL_A_L3 = 0x100, + VDEC_VC1_LEVEL_A_L4 = 0x200 +}; + +struct vdec_profile_level { + uint32_t profiles; + uint32_t levels; +}; + +enum vdec_interlaced_format { + VDEC_InterlaceFrameProgressive = 0x1, + VDEC_InterlaceInterleaveFrameTopFieldFirst = 0x2, + VDEC_InterlaceInterleaveFrameBottomFieldFirst = 0x4 +}; + +enum vdec_output_fromat { + VDEC_YUV_FORMAT_NV12 = 0x1, + VDEC_YUV_FORMAT_TILE_4x2 = 0x2 +}; + +enum vdec_output_order { + VDEC_ORDER_DISPLAY = 0x1, + VDEC_ORDER_DECODE = 0x2 +}; + +struct vdec_picsize { + uint32_t frame_width; + uint32_t frame_height; + uint32_t stride; + uint32_t scan_lines; +}; + +struct vdec_seqheader { + void __user *ptr_seqheader; + size_t seq_header_len; + int pmem_fd; + size_t pmem_offset; +}; + +struct vdec_mberror { + void __user *ptr_errormap; + size_t err_mapsize; +}; + +struct vdec_input_frameinfo { + void __user *bufferaddr; + size_t offset; + size_t datalen; + uint32_t flags; + int64_t timestamp; + void *client_data; + int pmem_fd; + size_t pmem_offset; + void __user *desc_addr; + uint32_t desc_size; +}; + +struct vdec_framesize { + uint32_t left; + uint32_t top; + uint32_t right; + uint32_t bottom; +}; + +struct vdec_aspectratioinfo { + uint32_t aspect_ratio; + uint32_t par_width; + uint32_t par_height; +}; + +struct vdec_output_frameinfo { + void __user *bufferaddr; + size_t offset; + size_t len; + uint32_t flags; + int64_t time_stamp; + enum vdec_picture pic_type; + void *client_data; + void *input_frame_clientdata; + struct vdec_framesize framesize; + enum vdec_interlaced_format interlaced_format; + struct vdec_aspectratioinfo aspect_ratio_info; +}; + +union vdec_msgdata { + struct vdec_output_frameinfo output_frame; + void *input_frame_clientdata; +}; + +struct vdec_msginfo { + uint32_t status_code; + uint32_t msgcode; + union vdec_msgdata msgdata; + size_t msgdatasize; +}; + +struct vdec_framerate { + unsigned long fps_denominator; + unsigned long fps_numerator; +}; + +struct vdec_h264_mv{ + size_t size; + int count; + int pmem_fd; + int offset; +}; + +struct vdec_mv_buff_size{ + int width; + int height; + int size; + int alignment; +}; + +#endif /* end of macro _VDECDECODER_H_ */ diff --git a/include/linux/msm_vidc_enc.h b/include/linux/msm_vidc_enc.h new file mode 100644 index 000000000000..519c537c722a --- /dev/null +++ b/include/linux/msm_vidc_enc.h @@ -0,0 +1,617 @@ +#ifndef _MSM_VIDC_ENC_H_ +#define _MSM_VIDC_ENC_H_ + +#include +#include + +/** STATUS CODES*/ +/* Base value for status codes */ +#define VEN_S_BASE 0x00000000 +#define VEN_S_SUCCESS (VEN_S_BASE)/* Success */ +#define VEN_S_EFAIL (VEN_S_BASE+1)/* General failure */ +#define VEN_S_EFATAL (VEN_S_BASE+2)/* Fatal irrecoverable failure*/ +#define VEN_S_EBADPARAM (VEN_S_BASE+3)/* Error passed parameters*/ +/*Command called in invalid state*/ +#define VEN_S_EINVALSTATE (VEN_S_BASE+4) +#define VEN_S_ENOSWRES (VEN_S_BASE+5)/* Insufficient OS resources*/ +#define VEN_S_ENOHWRES (VEN_S_BASE+6)/*Insufficient HW resources */ +#define VEN_S_EBUFFREQ (VEN_S_BASE+7)/* Buffer requirements were not met*/ +#define VEN_S_EINVALCMD (VEN_S_BASE+8)/* Invalid command called */ +#define VEN_S_ETIMEOUT (VEN_S_BASE+9)/* Command timeout. */ +/*Re-attempt was made when multiple invocation not supported for API.*/ +#define VEN_S_ENOREATMPT (VEN_S_BASE+10) +#define VEN_S_ENOPREREQ (VEN_S_BASE+11)/*Pre-requirement is not met for API*/ +#define VEN_S_ECMDQFULL (VEN_S_BASE+12)/*Command queue is full*/ +#define VEN_S_ENOTSUPP (VEN_S_BASE+13)/*Command not supported*/ +#define VEN_S_ENOTIMPL (VEN_S_BASE+14)/*Command not implemented.*/ +#define VEN_S_ENOTPMEM (VEN_S_BASE+15)/*Buffer is not from PMEM*/ +#define VEN_S_EFLUSHED (VEN_S_BASE+16)/*returned buffer was flushed*/ +#define VEN_S_EINSUFBUF (VEN_S_BASE+17)/*provided buffer size insufficient*/ +#define VEN_S_ESAMESTATE (VEN_S_BASE+18) +#define VEN_S_EINVALTRANS (VEN_S_BASE+19) + +#define VEN_INTF_VER 1 + +/*Asynchronous messages from driver*/ +#define VEN_MSG_INDICATION 0 +#define VEN_MSG_INPUT_BUFFER_DONE 1 +#define VEN_MSG_OUTPUT_BUFFER_DONE 2 +#define VEN_MSG_NEED_OUTPUT_BUFFER 3 +#define VEN_MSG_FLUSH_INPUT_DONE 4 +#define VEN_MSG_FLUSH_OUPUT_DONE 5 +#define VEN_MSG_START 6 +#define VEN_MSG_STOP 7 +#define VEN_MSG_PAUSE 8 +#define VEN_MSG_RESUME 9 +#define VEN_MSG_STOP_READING_MSG 10 + +/*Buffer flags bits masks*/ +#define VEN_BUFFLAG_EOS 0x00000001 +#define VEN_BUFFLAG_ENDOFFRAME 0x00000010 +#define VEN_BUFFLAG_SYNCFRAME 0x00000020 +#define VEN_BUFFLAG_EXTRADATA 0x00000040 +#define VEN_BUFFLAG_CODECCONFIG 0x00000080 + +/*Post processing flags bit masks*/ +#define VEN_EXTRADATA_NONE 0x001 +#define VEN_EXTRADATA_QCOMFILLER 0x002 +#define VEN_EXTRADATA_SLICEINFO 0x100 + +/*ENCODER CONFIGURATION CONSTANTS*/ + +/*Encoded video frame types*/ +#define VEN_FRAME_TYPE_I 1/* I frame type */ +#define VEN_FRAME_TYPE_P 2/* P frame type */ +#define VEN_FRAME_TYPE_B 3/* B frame type */ + +/*Video codec types*/ +#define VEN_CODEC_MPEG4 1/* MPEG4 Codec */ +#define VEN_CODEC_H264 2/* H.264 Codec */ +#define VEN_CODEC_H263 3/* H.263 Codec */ + +/*Video codec profile types.*/ +#define VEN_PROFILE_MPEG4_SP 1/* 1 - MPEG4 SP profile */ +#define VEN_PROFILE_MPEG4_ASP 2/* 2 - MPEG4 ASP profile */ +#define VEN_PROFILE_H264_BASELINE 3/* 3 - H264 Baseline profile */ +#define VEN_PROFILE_H264_MAIN 4/* 4 - H264 Main profile */ +#define VEN_PROFILE_H264_HIGH 5/* 5 - H264 High profile */ +#define VEN_PROFILE_H263_BASELINE 6/* 6 - H263 Baseline profile */ + +/*Video codec profile level types.*/ +#define VEN_LEVEL_MPEG4_0 0x1/* MPEG4 Level 0 */ +#define VEN_LEVEL_MPEG4_1 0x2/* MPEG4 Level 1 */ +#define VEN_LEVEL_MPEG4_2 0x3/* MPEG4 Level 2 */ +#define VEN_LEVEL_MPEG4_3 0x4/* MPEG4 Level 3 */ +#define VEN_LEVEL_MPEG4_4 0x5/* MPEG4 Level 4 */ +#define VEN_LEVEL_MPEG4_5 0x6/* MPEG4 Level 5 */ +#define VEN_LEVEL_MPEG4_3b 0x7/* MPEG4 Level 3b */ +#define VEN_LEVEL_MPEG4_6 0x8/* MPEG4 Level 6 */ + +#define VEN_LEVEL_H264_1 0x9/* H.264 Level 1 */ +#define VEN_LEVEL_H264_1b 0xA/* H.264 Level 1b */ +#define VEN_LEVEL_H264_1p1 0xB/* H.264 Level 1.1 */ +#define VEN_LEVEL_H264_1p2 0xC/* H.264 Level 1.2 */ +#define VEN_LEVEL_H264_1p3 0xD/* H.264 Level 1.3 */ +#define VEN_LEVEL_H264_2 0xE/* H.264 Level 2 */ +#define VEN_LEVEL_H264_2p1 0xF/* H.264 Level 2.1 */ +#define VEN_LEVEL_H264_2p2 0x10/* H.264 Level 2.2 */ +#define VEN_LEVEL_H264_3 0x11/* H.264 Level 3 */ +#define VEN_LEVEL_H264_3p1 0x12/* H.264 Level 3.1 */ +#define VEN_LEVEL_H264_3p2 0x13/* H.264 Level 3.2 */ +#define VEN_LEVEL_H264_4 0x14/* H.264 Level 4 */ + +#define VEN_LEVEL_H263_10 0x15/* H.263 Level 10 */ +#define VEN_LEVEL_H263_20 0x16/* H.263 Level 20 */ +#define VEN_LEVEL_H263_30 0x17/* H.263 Level 30 */ +#define VEN_LEVEL_H263_40 0x18/* H.263 Level 40 */ +#define VEN_LEVEL_H263_45 0x19/* H.263 Level 45 */ +#define VEN_LEVEL_H263_50 0x1A/* H.263 Level 50 */ +#define VEN_LEVEL_H263_60 0x1B/* H.263 Level 60 */ +#define VEN_LEVEL_H263_70 0x1C/* H.263 Level 70 */ + +/*Entropy coding model selection for H.264 encoder.*/ +#define VEN_ENTROPY_MODEL_CAVLC 1 +#define VEN_ENTROPY_MODEL_CABAC 2 +/*Cabac model number (0,1,2) for encoder.*/ +#define VEN_CABAC_MODEL_0 1/* CABAC Model 0. */ +#define VEN_CABAC_MODEL_1 2/* CABAC Model 1. */ +#define VEN_CABAC_MODEL_2 3/* CABAC Model 2. */ + +/*Deblocking filter control type for encoder.*/ +#define VEN_DB_DISABLE 1/* 1 - Disable deblocking filter*/ +#define VEN_DB_ALL_BLKG_BNDRY 2/* 2 - All blocking boundary filtering*/ +#define VEN_DB_SKIP_SLICE_BNDRY 3/* 3 - Filtering except sliceboundary*/ + +/*Different methods of Multi slice selection.*/ +#define VEN_MSLICE_OFF 1 +#define VEN_MSLICE_CNT_MB 2 /*number of MBscount per slice*/ +#define VEN_MSLICE_CNT_BYTE 3 /*number of bytes count per slice.*/ +#define VEN_MSLICE_GOB 4 /*Multi slice by GOB for H.263 only.*/ + +/*Different modes for Rate Control.*/ +#define VEN_RC_OFF 1 +#define VEN_RC_VBR_VFR 2 +#define VEN_RC_VBR_CFR 3 +#define VEN_RC_CBR_VFR 4 +#define VEN_RC_CBR_CFR 5 + +/*Different modes for flushing buffers*/ +#define VEN_FLUSH_INPUT 1 +#define VEN_FLUSH_OUTPUT 2 +#define VEN_FLUSH_ALL 3 + +/*Different input formats for YUV data.*/ +#define VEN_INPUTFMT_NV12 1/* NV12 Linear */ +#define VEN_INPUTFMT_NV21 2/* NV21 Linear */ +#define VEN_INPUTFMT_NV12_16M2KA 3/* NV12 Linear */ + +/*Different allowed rotation modes.*/ +#define VEN_ROTATION_0 1/* 0 degrees */ +#define VEN_ROTATION_90 2/* 90 degrees */ +#define VEN_ROTATION_180 3/* 180 degrees */ +#define VEN_ROTATION_270 4/* 270 degrees */ + +/*IOCTL timeout values*/ +#define VEN_TIMEOUT_INFINITE 0xffffffff + +/*Different allowed intra refresh modes.*/ +#define VEN_IR_OFF 1 +#define VEN_IR_CYCLIC 2 +#define VEN_IR_RANDOM 3 + +/*IOCTL BASE CODES Not to be used directly by the client.*/ +/* Base value for ioctls that are not related to encoder configuration.*/ +#define VEN_IOCTLBASE_NENC 0x800 +/* Base value for encoder configuration ioctls*/ +#define VEN_IOCTLBASE_ENC 0x850 + +struct venc_ioctl_msg{ + void __user *in; + void __user *out; +}; + +/*NON ENCODER CONFIGURATION IOCTLs*/ + +/*IOCTL params:SET: InputData - unsigned long, OutputData - NULL*/ +#define VEN_IOCTL_SET_INTF_VERSION \ + _IOW(VEN_IOCTLBASE_NENC, 0, struct venc_ioctl_msg) + +/*IOCTL params:CMD: InputData - venc_timeout, OutputData - venc_msg*/ +#define VEN_IOCTL_CMD_READ_NEXT_MSG \ + _IOWR(VEN_IOCTLBASE_NENC, 1, struct venc_ioctl_msg) + +/*IOCTL params:CMD: InputData - NULL, OutputData - NULL*/ +#define VEN_IOCTL_CMD_STOP_READ_MSG _IO(VEN_IOCTLBASE_NENC, 2) + +/*IOCTL params:SET: InputData - venc_allocatorproperty, OutputData - NULL + GET: InputData - NULL, OutputData - venc_allocatorproperty*/ +#define VEN_IOCTL_SET_INPUT_BUFFER_REQ \ + _IOW(VEN_IOCTLBASE_NENC, 3, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_INPUT_BUFFER_REQ \ + _IOR(VEN_IOCTLBASE_NENC, 4, struct venc_ioctl_msg) + +/*IOCTL params:CMD: InputData - venc_bufferpayload, OutputData - NULL*/ +#define VEN_IOCTL_CMD_ALLOC_INPUT_BUFFER \ + _IOW(VEN_IOCTLBASE_NENC, 5, struct venc_ioctl_msg) + +/*IOCTL params:CMD: InputData - venc_bufferpayload, OutputData - NULL*/ +#define VEN_IOCTL_SET_INPUT_BUFFER \ + _IOW(VEN_IOCTLBASE_NENC, 6, struct venc_ioctl_msg) + +/*IOCTL params: CMD: InputData - venc_bufferpayload, OutputData - NULL*/ +#define VEN_IOCTL_CMD_FREE_INPUT_BUFFER \ + _IOW(VEN_IOCTLBASE_NENC, 7, struct venc_ioctl_msg) + +/*IOCTL params:SET: InputData - venc_allocatorproperty, OutputData - NULL + GET: InputData - NULL, OutputData - venc_allocatorproperty*/ +#define VEN_IOCTL_SET_OUTPUT_BUFFER_REQ \ + _IOW(VEN_IOCTLBASE_NENC, 8, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_OUTPUT_BUFFER_REQ \ + _IOR(VEN_IOCTLBASE_NENC, 9, struct venc_ioctl_msg) + +/*IOCTL params:CMD: InputData - venc_bufferpayload, OutputData - NULL*/ +#define VEN_IOCTL_CMD_ALLOC_OUTPUT_BUFFER \ + _IOW(VEN_IOCTLBASE_NENC, 10, struct venc_ioctl_msg) + + +/*IOCTL params:CMD: InputData - venc_bufferpayload, OutputData - NULL*/ +#define VEN_IOCTL_SET_OUTPUT_BUFFER \ + _IOW(VEN_IOCTLBASE_NENC, 11, struct venc_ioctl_msg) + +/*IOCTL params:CMD: InputData - venc_bufferpayload, OutputData - NULL.*/ +#define VEN_IOCTL_CMD_FREE_OUTPUT_BUFFER \ + _IOW(VEN_IOCTLBASE_NENC, 12, struct venc_ioctl_msg) + + +/* Asynchronous respone message code:* VEN_MSG_START*/ +#define VEN_IOCTL_CMD_START _IO(VEN_IOCTLBASE_NENC, 13) + + +/*IOCTL params:CMD: InputData - venc_buffer, OutputData - NULL + Asynchronous respone message code:VEN_MSG_INPUT_BUFFER_DONE*/ +#define VEN_IOCTL_CMD_ENCODE_FRAME \ + _IOW(VEN_IOCTLBASE_NENC, 14, struct venc_ioctl_msg) + + +/*IOCTL params:CMD: InputData - venc_buffer, OutputData - NULL + Asynchronous response message code:VEN_MSG_OUTPUT_BUFFER_DONE*/ +#define VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER \ + _IOW(VEN_IOCTLBASE_NENC, 15, struct venc_ioctl_msg) + +/*IOCTL params:CMD: InputData - venc_bufferflush, OutputData - NULL + * Asynchronous response message code:VEN_MSG_INPUT_BUFFER_DONE*/ +#define VEN_IOCTL_CMD_FLUSH \ + _IOW(VEN_IOCTLBASE_NENC, 16, struct venc_ioctl_msg) + + +/*Asynchronous respone message code:VEN_MSG_PAUSE*/ +#define VEN_IOCTL_CMD_PAUSE _IO(VEN_IOCTLBASE_NENC, 17) + +/*Asynchronous respone message code:VEN_MSG_RESUME*/ +#define VEN_IOCTL_CMD_RESUME _IO(VEN_IOCTLBASE_NENC, 18) + +/* Asynchronous respone message code:VEN_MSG_STOP*/ +#define VEN_IOCTL_CMD_STOP _IO(VEN_IOCTLBASE_NENC, 19) + +#define VEN_IOCTL_SET_RECON_BUFFER \ + _IOW(VEN_IOCTLBASE_NENC, 20, struct venc_ioctl_msg) + +#define VEN_IOCTL_FREE_RECON_BUFFER \ + _IOW(VEN_IOCTLBASE_NENC, 21, struct venc_ioctl_msg) + +#define VEN_IOCTL_GET_RECON_BUFFER_SIZE \ + _IOW(VEN_IOCTLBASE_NENC, 22, struct venc_ioctl_msg) + + + +/*ENCODER PROPERTY CONFIGURATION & CAPABILITY IOCTLs*/ + +/*IOCTL params:SET: InputData - venc_basecfg, OutputData - NULL + GET: InputData - NULL, OutputData - venc_basecfg*/ +#define VEN_IOCTL_SET_BASE_CFG \ + _IOW(VEN_IOCTLBASE_ENC, 1, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_BASE_CFG \ + _IOR(VEN_IOCTLBASE_ENC, 2, struct venc_ioctl_msg) + +/*IOCTL params:SET: InputData - venc_switch, OutputData - NULL + GET: InputData - NULL, OutputData - venc_switch*/ +#define VEN_IOCTL_SET_LIVE_MODE \ + _IOW(VEN_IOCTLBASE_ENC, 3, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_LIVE_MODE \ + _IOR(VEN_IOCTLBASE_ENC, 4, struct venc_ioctl_msg) + + +/*IOCTL params:SET: InputData - venc_profile, OutputData - NULL + GET: InputData - NULL, OutputData - venc_profile*/ +#define VEN_IOCTL_SET_CODEC_PROFILE \ + _IOW(VEN_IOCTLBASE_ENC, 5, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_CODEC_PROFILE \ + _IOR(VEN_IOCTLBASE_ENC, 6, struct venc_ioctl_msg) + + +/*IOCTL params:SET: InputData - ven_profilelevel, OutputData - NULL + GET: InputData - NULL, OutputData - ven_profilelevel*/ +#define VEN_IOCTL_SET_PROFILE_LEVEL \ + _IOW(VEN_IOCTLBASE_ENC, 7, struct venc_ioctl_msg) + +#define VEN_IOCTL_GET_PROFILE_LEVEL \ + _IOR(VEN_IOCTLBASE_ENC, 8, struct venc_ioctl_msg) + +/*IOCTL params:SET: InputData - venc_switch, OutputData - NULL + GET: InputData - NULL, OutputData - venc_switch*/ +#define VEN_IOCTL_SET_SHORT_HDR \ + _IOW(VEN_IOCTLBASE_ENC, 9, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_SHORT_HDR \ + _IOR(VEN_IOCTLBASE_ENC, 10, struct venc_ioctl_msg) + + +/*IOCTL params: SET: InputData - venc_sessionqp, OutputData - NULL + GET: InputData - NULL, OutputData - venc_sessionqp*/ +#define VEN_IOCTL_SET_SESSION_QP \ + _IOW(VEN_IOCTLBASE_ENC, 11, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_SESSION_QP \ + _IOR(VEN_IOCTLBASE_ENC, 12, struct venc_ioctl_msg) + + +/*IOCTL params:SET: InputData - venc_intraperiod, OutputData - NULL + GET: InputData - NULL, OutputData - venc_intraperiod*/ +#define VEN_IOCTL_SET_INTRA_PERIOD \ + _IOW(VEN_IOCTLBASE_ENC, 13, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_INTRA_PERIOD \ + _IOR(VEN_IOCTLBASE_ENC, 14, struct venc_ioctl_msg) + + +/* Request an Iframe*/ +#define VEN_IOCTL_CMD_REQUEST_IFRAME _IO(VEN_IOCTLBASE_ENC, 15) + +/*IOCTL params:GET: InputData - NULL, OutputData - venc_capability*/ +#define VEN_IOCTL_GET_CAPABILITY \ + _IOR(VEN_IOCTLBASE_ENC, 16, struct venc_ioctl_msg) + + +/*IOCTL params:GET: InputData - NULL, OutputData - venc_seqheader*/ +#define VEN_IOCTL_GET_SEQUENCE_HDR \ + _IOR(VEN_IOCTLBASE_ENC, 17, struct venc_ioctl_msg) + +/*IOCTL params:SET: InputData - venc_entropycfg, OutputData - NULL + GET: InputData - NULL, OutputData - venc_entropycfg*/ +#define VEN_IOCTL_SET_ENTROPY_CFG \ + _IOW(VEN_IOCTLBASE_ENC, 18, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_ENTROPY_CFG \ + _IOR(VEN_IOCTLBASE_ENC, 19, struct venc_ioctl_msg) + +/*IOCTL params:SET: InputData - venc_dbcfg, OutputData - NULL + GET: InputData - NULL, OutputData - venc_dbcfg*/ +#define VEN_IOCTL_SET_DEBLOCKING_CFG \ + _IOW(VEN_IOCTLBASE_ENC, 20, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_DEBLOCKING_CFG \ + _IOR(VEN_IOCTLBASE_ENC, 21, struct venc_ioctl_msg) + + +/*IOCTL params:SET: InputData - venc_intrarefresh, OutputData - NULL + GET: InputData - NULL, OutputData - venc_intrarefresh*/ +#define VEN_IOCTL_SET_INTRA_REFRESH \ + _IOW(VEN_IOCTLBASE_ENC, 22, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_INTRA_REFRESH \ + _IOR(VEN_IOCTLBASE_ENC, 23, struct venc_ioctl_msg) + + +/*IOCTL params:SET: InputData - venc_multiclicecfg, OutputData - NULL + GET: InputData - NULL, OutputData - venc_multiclicecfg*/ +#define VEN_IOCTL_SET_MULTI_SLICE_CFG \ + _IOW(VEN_IOCTLBASE_ENC, 24, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_MULTI_SLICE_CFG \ + _IOR(VEN_IOCTLBASE_ENC, 25, struct venc_ioctl_msg) + +/*IOCTL params:SET: InputData - venc_ratectrlcfg, OutputData - NULL + GET: InputData - NULL, OutputData - venc_ratectrlcfg*/ +#define VEN_IOCTL_SET_RATE_CTRL_CFG \ + _IOW(VEN_IOCTLBASE_ENC, 26, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_RATE_CTRL_CFG \ + _IOR(VEN_IOCTLBASE_ENC, 27, struct venc_ioctl_msg) + + +/*IOCTL params:SET: InputData - venc_voptimingcfg, OutputData - NULL + GET: InputData - NULL, OutputData - venc_voptimingcfg*/ +#define VEN_IOCTL_SET_VOP_TIMING_CFG \ + _IOW(VEN_IOCTLBASE_ENC, 28, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_VOP_TIMING_CFG \ + _IOR(VEN_IOCTLBASE_ENC, 29, struct venc_ioctl_msg) + + +/*IOCTL params:SET: InputData - venc_framerate, OutputData - NULL + GET: InputData - NULL, OutputData - venc_framerate*/ +#define VEN_IOCTL_SET_FRAME_RATE \ + _IOW(VEN_IOCTLBASE_ENC, 30, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_FRAME_RATE \ + _IOR(VEN_IOCTLBASE_ENC, 31, struct venc_ioctl_msg) + + +/*IOCTL params:SET: InputData - venc_targetbitrate, OutputData - NULL + GET: InputData - NULL, OutputData - venc_targetbitrate*/ +#define VEN_IOCTL_SET_TARGET_BITRATE \ + _IOW(VEN_IOCTLBASE_ENC, 32, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_TARGET_BITRATE \ + _IOR(VEN_IOCTLBASE_ENC, 33, struct venc_ioctl_msg) + + +/*IOCTL params:SET: InputData - venc_rotation, OutputData - NULL + GET: InputData - NULL, OutputData - venc_rotation*/ +#define VEN_IOCTL_SET_ROTATION \ + _IOW(VEN_IOCTLBASE_ENC, 34, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_ROTATION \ + _IOR(VEN_IOCTLBASE_ENC, 35, struct venc_ioctl_msg) + + +/*IOCTL params:SET: InputData - venc_headerextension, OutputData - NULL + GET: InputData - NULL, OutputData - venc_headerextension*/ +#define VEN_IOCTL_SET_HEC \ + _IOW(VEN_IOCTLBASE_ENC, 36, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_HEC \ + _IOR(VEN_IOCTLBASE_ENC, 37, struct venc_ioctl_msg) + +/*IOCTL params:SET: InputData - venc_switch, OutputData - NULL + GET: InputData - NULL, OutputData - venc_switch*/ +#define VEN_IOCTL_SET_DATA_PARTITION \ + _IOW(VEN_IOCTLBASE_ENC, 38, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_DATA_PARTITION \ + _IOR(VEN_IOCTLBASE_ENC, 39, struct venc_ioctl_msg) + +/*IOCTL params:SET: InputData - venc_switch, OutputData - NULL + GET: InputData - NULL, OutputData - venc_switch*/ +#define VEN_IOCTL_SET_RVLC \ + _IOW(VEN_IOCTLBASE_ENC, 40, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_RVLC \ + _IOR(VEN_IOCTLBASE_ENC, 41, struct venc_ioctl_msg) + + +/*IOCTL params:SET: InputData - venc_switch, OutputData - NULL + GET: InputData - NULL, OutputData - venc_switch*/ +#define VEN_IOCTL_SET_AC_PREDICTION \ + _IOW(VEN_IOCTLBASE_ENC, 42, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_AC_PREDICTION \ + _IOR(VEN_IOCTLBASE_ENC, 43, struct venc_ioctl_msg) + + +/*IOCTL params:SET: InputData - venc_qprange, OutputData - NULL + GET: InputData - NULL, OutputData - venc_qprange*/ +#define VEN_IOCTL_SET_QP_RANGE \ + _IOW(VEN_IOCTLBASE_ENC, 44, struct venc_ioctl_msg) +#define VEN_IOCTL_GET_QP_RANGE \ + _IOR(VEN_IOCTLBASE_ENC, 45, struct venc_ioctl_msg) + +#define VEN_IOCTL_GET_NUMBER_INSTANCES \ + _IOR(VEN_IOCTLBASE_ENC, 46, struct venc_ioctl_msg) + +#define VEN_IOCTL_SET_METABUFFER_MODE \ + _IOW(VEN_IOCTLBASE_ENC, 47, struct venc_ioctl_msg) + + +/*IOCTL params:SET: InputData - unsigned int, OutputData - NULL.*/ +#define VEN_IOCTL_SET_EXTRADATA \ + _IOW(VEN_IOCTLBASE_ENC, 48, struct venc_ioctl_msg) +/*IOCTL params:GET: InputData - NULL, OutputData - unsigned int.*/ +#define VEN_IOCTL_GET_EXTRADATA \ + _IOR(VEN_IOCTLBASE_ENC, 49, struct venc_ioctl_msg) + +/*IOCTL params:SET: InputData - NULL, OutputData - NULL.*/ +#define VEN_IOCTL_SET_SLICE_DELIVERY_MODE \ + _IO(VEN_IOCTLBASE_ENC, 50) + +struct venc_switch{ + unsigned char status; +}; + +struct venc_allocatorproperty{ + unsigned long mincount; + unsigned long maxcount; + unsigned long actualcount; + unsigned long datasize; + unsigned long suffixsize; + unsigned long alignment; + unsigned long bufpoolid; +}; + +struct venc_bufferpayload{ + unsigned char *pbuffer; + size_t sz; + int fd; + unsigned int offset; + unsigned int maped_size; + unsigned long filled_len; +}; + +struct venc_buffer{ + unsigned char *ptrbuffer; + unsigned long sz; + unsigned long len; + unsigned long offset; + long long timestamp; + unsigned long flags; + void *clientdata; +}; + +struct venc_basecfg{ + unsigned long input_width; + unsigned long input_height; + unsigned long dvs_width; + unsigned long dvs_height; + unsigned long codectype; + unsigned long fps_num; + unsigned long fps_den; + unsigned long targetbitrate; + unsigned long inputformat; +}; + +struct venc_profile{ + unsigned long profile; +}; +struct ven_profilelevel{ + unsigned long level; +}; + +struct venc_sessionqp{ + unsigned long iframeqp; + unsigned long pframqp; +}; + +struct venc_qprange{ + unsigned long maxqp; + unsigned long minqp; +}; +struct venc_intraperiod{ + unsigned long num_pframes; + unsigned long num_bframes; +}; +struct venc_seqheader{ + unsigned char *hdrbufptr; + unsigned long bufsize; + unsigned long hdrlen; +}; + +struct venc_capability{ + unsigned long codec_types; + unsigned long maxframe_width; + unsigned long maxframe_height; + unsigned long maxtarget_bitrate; + unsigned long maxframe_rate; + unsigned long input_formats; + unsigned char dvs; +}; + +struct venc_entropycfg{ + unsigned longentropysel; + unsigned long cabacmodel; +}; + +struct venc_dbcfg{ + unsigned long db_mode; + unsigned long slicealpha_offset; + unsigned long slicebeta_offset; +}; + +struct venc_intrarefresh{ + unsigned long irmode; + unsigned long mbcount; +}; + +struct venc_multiclicecfg{ + unsigned long mslice_mode; + unsigned long mslice_size; +}; + +struct venc_bufferflush{ + unsigned long flush_mode; +}; + +struct venc_ratectrlcfg{ + unsigned long rcmode; +}; + +struct venc_voptimingcfg{ + unsigned long voptime_resolution; +}; +struct venc_framerate{ + unsigned long fps_denominator; + unsigned long fps_numerator; +}; + +struct venc_targetbitrate{ + unsigned long target_bitrate; +}; + + +struct venc_rotation{ + unsigned long rotation; +}; + +struct venc_timeout{ + unsigned long millisec; +}; + +struct venc_headerextension{ + unsigned long header_extension; +}; + +struct venc_msg{ + unsigned long statuscode; + unsigned long msgcode; + struct venc_buffer buf; + unsigned long msgdata_size; +}; + +struct venc_recon_addr{ + unsigned char *pbuffer; + unsigned long buffer_size; + unsigned long pmem_fd; + unsigned long offset; +}; + +struct venc_recon_buff_size{ + int width; + int height; + int size; + int alignment; +}; + +#endif /* _MSM_VIDC_ENC_H_ */ diff --git a/include/media/msm/vcd_api.h b/include/media/msm/vcd_api.h new file mode 100644 index 000000000000..1db6dc59245a --- /dev/null +++ b/include/media/msm/vcd_api.h @@ -0,0 +1,158 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#ifndef _VCD_API_H_ +#define _VCD_API_H_ +#include "vcd_property.h" +#include "vcd_status.h" + +#define VCD_FRAME_FLAG_EOS 0x00000001 +#define VCD_FRAME_FLAG_DECODEONLY 0x00000004 +#define VCD_FRAME_FLAG_DATACORRUPT 0x00000008 +#define VCD_FRAME_FLAG_ENDOFFRAME 0x00000010 +#define VCD_FRAME_FLAG_SYNCFRAME 0x00000020 +#define VCD_FRAME_FLAG_EXTRADATA 0x00000040 +#define VCD_FRAME_FLAG_CODECCONFIG 0x00000080 +#define VCD_FRAME_FLAG_BFRAME 0x00100000 +#define VCD_FRAME_FLAG_EOSEQ 0x00200000 + +#define VCD_FLUSH_INPUT 0x0001 +#define VCD_FLUSH_OUTPUT 0x0002 +#define VCD_FLUSH_ALL 0x0003 + +#define VCD_FRAMETAG_INVALID 0xffffffff + +struct vcd_handle_container { + void *handle; +}; +struct vcd_flush_cmd { + u32 mode; +}; + +enum vcd_frame { + VCD_FRAME_YUV = 1, + VCD_FRAME_I, + VCD_FRAME_P, + VCD_FRAME_B, + VCD_FRAME_NOTCODED, + VCD_FRAME_IDR, + VCD_FRAME_32BIT = 0x7fffffff +}; + +enum vcd_power_state { + VCD_PWR_STATE_ON = 1, + VCD_PWR_STATE_SLEEP, +}; + +struct vcd_aspect_ratio { + u32 aspect_ratio; + u32 extended_par_width; + u32 extended_par_height; +}; + +struct vcd_frame_data { + u8 *virtual; + u8 *physical; + u32 ion_flag; + u32 alloc_len; + u32 data_len; + u32 offset; + s64 time_stamp; /* in usecs*/ + u32 flags; + u32 frm_clnt_data; + struct vcd_property_dec_output_buffer dec_op_prop; + u32 interlaced; + enum vcd_frame frame; + u32 ip_frm_tag; + u32 intrlcd_ip_frm_tag; + u8 *desc_buf; + u32 desc_size; + struct ion_handle *buff_ion_handle; + struct vcd_aspect_ratio aspect_ratio_info; +}; + +struct vcd_sequence_hdr { + u8 *sequence_header; + u32 sequence_header_len; + +}; + +enum vcd_buffer_type { + VCD_BUFFER_INPUT = 0x1, + VCD_BUFFER_OUTPUT = 0x2, + VCD_BUFFER_INVALID = 0x3, + VCD_BUFFER_32BIT = 0x7FFFFFFF +}; + +struct vcd_buffer_requirement { + u32 min_count; + u32 actual_count; + u32 max_count; + size_t sz; + u32 align; + u32 buf_pool_id; +}; + +struct vcd_init_config { + void *device_name; + void *(*map_dev_base_addr) (void *device_name); + void (*un_map_dev_base_addr) (void); + void (*interrupt_clr) (void); + void (*register_isr) (void *device_name); + void (*deregister_isr) (void); + u32 (*timer_create) (void (*timer_handler)(void *), + void *user_data, void **timer_handle); + void (*timer_release) (void *timer_handle); + void (*timer_start) (void *timer_handle, u32 time_out); + void (*timer_stop) (void *timer_handle); +}; + +/*Flags passed to vcd_open*/ +#define VCD_CP_SESSION 0x00000001 + +u32 vcd_init(struct vcd_init_config *config, s32 *driver_handle); +u32 vcd_term(s32 driver_handle); +u32 vcd_open(s32 driver_handle, u32 decoding, + void (*callback) (u32 event, u32 status, void *info, size_t sz, + void *handle, void *const client_data), void *client_data, int flags); +u32 vcd_close(void *handle); +u32 vcd_encode_start(void *handle); +u32 vcd_encode_frame(void *handle, struct vcd_frame_data *input_frame); +u32 vcd_decode_start(void *handle, struct vcd_sequence_hdr *seq_hdr); +u32 vcd_decode_frame(void *handle, struct vcd_frame_data *input_frame); +u32 vcd_pause(void *handle); +u32 vcd_resume(void *handle); +u32 vcd_flush(void *handle, u32 mode); +u32 vcd_stop(void *handle); +u32 vcd_set_property(void *handle, struct vcd_property_hdr *prop_hdr, + void *prop_val); +u32 vcd_get_property(void *handle, struct vcd_property_hdr *prop_hdr, + void *prop_val); +u32 vcd_set_buffer_requirements(void *handle, enum vcd_buffer_type buffer, + struct vcd_buffer_requirement *buffer_req); +u32 vcd_get_buffer_requirements(void *handle, enum vcd_buffer_type buffer, + struct vcd_buffer_requirement *buffer_req); +u32 vcd_set_buffer(void *handle, enum vcd_buffer_type buffer_type, + u8 *buffer, u32 buf_size); +u32 vcd_allocate_buffer(void *handle, enum vcd_buffer_type buffer, + u32 buf_size, u8 **vir_buf_addr, u8 **phy_buf_addr); + +u32 vcd_free_buffer(void *handle, enum vcd_buffer_type buffer_type, u8 *buffer); +u32 vcd_fill_output_buffer(void *handle, struct vcd_frame_data *buffer); +u32 vcd_set_device_power(s32 driver_handle, + enum vcd_power_state pwr_state); +void vcd_read_and_clear_interrupt(void); +void vcd_response_handler(void); +u8 vcd_get_num_of_clients(void); +u32 vcd_get_ion_status(void); +struct ion_client *vcd_get_ion_client(void); +#endif diff --git a/include/media/msm/vcd_property.h b/include/media/msm/vcd_property.h new file mode 100644 index 000000000000..9b09b1d1aa2c --- /dev/null +++ b/include/media/msm/vcd_property.h @@ -0,0 +1,372 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#ifndef _VCD_DRIVER_PROPERTY_H_ +#define _VCD_DRIVER_PROPERTY_H_ + +#define VCD_START_BASE 0x0 +#define VCD_I_LIVE (VCD_START_BASE + 0x1) +#define VCD_I_CODEC (VCD_START_BASE + 0x2) +#define VCD_I_FRAME_SIZE (VCD_START_BASE + 0x3) +#define VCD_I_METADATA_ENABLE (VCD_START_BASE + 0x4) +#define VCD_I_METADATA_HEADER (VCD_START_BASE + 0x5) +#define VCD_I_PROFILE (VCD_START_BASE + 0x6) +#define VCD_I_LEVEL (VCD_START_BASE + 0x7) +#define VCD_I_BUFFER_FORMAT (VCD_START_BASE + 0x8) +#define VCD_I_FRAME_RATE (VCD_START_BASE + 0x9) +#define VCD_I_TARGET_BITRATE (VCD_START_BASE + 0xA) +#define VCD_I_MULTI_SLICE (VCD_START_BASE + 0xB) +#define VCD_I_ENTROPY_CTRL (VCD_START_BASE + 0xC) +#define VCD_I_DEBLOCKING (VCD_START_BASE + 0xD) +#define VCD_I_RATE_CONTROL (VCD_START_BASE + 0xE) +#define VCD_I_QP_RANGE (VCD_START_BASE + 0xF) +#define VCD_I_SESSION_QP (VCD_START_BASE + 0x10) +#define VCD_I_INTRA_PERIOD (VCD_START_BASE + 0x11) +#define VCD_I_VOP_TIMING (VCD_START_BASE + 0x12) +#define VCD_I_SHORT_HEADER (VCD_START_BASE + 0x13) +#define VCD_I_SEQ_HEADER (VCD_START_BASE + 0x14) +#define VCD_I_HEADER_EXTENSION (VCD_START_BASE + 0x15) +#define VCD_I_INTRA_REFRESH (VCD_START_BASE + 0x16) +#define VCD_I_POST_FILTER (VCD_START_BASE + 0x17) +#define VCD_I_PROGRESSIVE_ONLY (VCD_START_BASE + 0x18) +#define VCD_I_OUTPUT_ORDER (VCD_START_BASE + 0x19) +#define VCD_I_RECON_BUFFERS (VCD_START_BASE + 0x1A) +#define VCD_I_FREE_RECON_BUFFERS (VCD_START_BASE + 0x1B) +#define VCD_I_GET_RECON_BUFFER_SIZE (VCD_START_BASE + 0x1C) +#define VCD_I_H264_MV_BUFFER (VCD_START_BASE + 0x1D) +#define VCD_I_FREE_H264_MV_BUFFER (VCD_START_BASE + 0x1E) +#define VCD_I_GET_H264_MV_SIZE (VCD_START_BASE + 0x1F) +#define VCD_I_DEC_PICTYPE (VCD_START_BASE + 0x20) +#define VCD_I_CONT_ON_RECONFIG (VCD_START_BASE + 0x21) +#define VCD_I_META_BUFFER_MODE (VCD_START_BASE + 0x22) +#define VCD_I_DISABLE_DMX (VCD_START_BASE + 0x23) +#define VCD_I_DISABLE_DMX_SUPPORT (VCD_START_BASE + 0x24) +#define VCD_I_ENABLE_SPS_PPS_FOR_IDR (VCD_START_BASE + 0x25) +#define VCD_REQ_PERF_LEVEL (VCD_START_BASE + 0x26) +#define VCD_I_SLICE_DELIVERY_MODE (VCD_START_BASE + 0x27) +#define VCD_I_VOP_TIMING_CONSTANT_DELTA (VCD_START_BASE + 0x28) + +#define VCD_START_REQ (VCD_START_BASE + 0x1000) +#define VCD_I_REQ_IFRAME (VCD_START_REQ + 0x1) + +#define VCD_I_RESERVED_BASE (VCD_START_BASE + 0x10000) + +struct vcd_property_hdr { + u32 prop_id; + size_t sz; +}; + +struct vcd_property_live { + u32 live; +}; + +enum vcd_codec { + VCD_CODEC_H264 = 0x1, + VCD_CODEC_H263 = 0x2, + VCD_CODEC_MPEG1 = 0x3, + VCD_CODEC_MPEG2 = 0x4, + VCD_CODEC_MPEG4 = 0x5, + VCD_CODEC_DIVX_3 = 0x6, + VCD_CODEC_DIVX_4 = 0x7, + VCD_CODEC_DIVX_5 = 0x8, + VCD_CODEC_DIVX_6 = 0x9, + VCD_CODEC_XVID = 0xA, + VCD_CODEC_VC1 = 0xB, + VCD_CODEC_VC1_RCV = 0xC +}; + +struct vcd_property_codec { + enum vcd_codec codec; +}; + +struct vcd_property_frame_size { + u32 width; + u32 height; + u32 stride; + u32 scan_lines; +}; + +enum vcd_perf_level { + VCD_PERF_LEVEL0, + VCD_PERF_LEVEL1, + VCD_PERF_LEVEL2, + VCD_PERF_LEVEL_TURBO, +}; + +#define VCD_METADATA_DATANONE 0x001 +#define VCD_METADATA_QCOMFILLER 0x002 +#define VCD_METADATA_QPARRAY 0x004 +#define VCD_METADATA_CONCEALMB 0x008 +#define VCD_METADATA_SEI 0x010 +#define VCD_METADATA_VUI 0x020 +#define VCD_METADATA_VC1 0x040 +#define VCD_METADATA_PASSTHROUGH 0x080 +#define VCD_METADATA_ENC_SLICE 0x100 + +struct vcd_property_meta_data_enable { + u32 meta_data_enable_flag; +}; + +struct vcd_property_metadata_hdr { + u32 meta_data_id; + u32 version; + u32 port_index; + u32 type; +}; + +struct vcd_property_frame_rate { + u32 fps_denominator; + u32 fps_numerator; +}; + +struct vcd_property_target_bitrate { + u32 target_bitrate; +}; + +struct vcd_property_perf_level { + enum vcd_perf_level level; +}; + +enum vcd_yuv_buffer_format { + VCD_BUFFER_FORMAT_NV12 = 0x1, + VCD_BUFFER_FORMAT_TILE_4x2 = 0x2, + VCD_BUFFER_FORMAT_NV12_16M2KA = 0x3, + VCD_BUFFER_FORMAT_TILE_1x1 = 0x4 +}; + +struct vcd_property_buffer_format { + enum vcd_yuv_buffer_format buffer_format; +}; + +struct vcd_property_post_filter { + u32 post_filter; +}; + +enum vcd_codec_profile { + VCD_PROFILE_UNKNOWN = 0x0, + VCD_PROFILE_MPEG4_SP = 0x1, + VCD_PROFILE_MPEG4_ASP = 0x2, + VCD_PROFILE_H264_BASELINE = 0x3, + VCD_PROFILE_H264_MAIN = 0x4, + VCD_PROFILE_H264_HIGH = 0x5, + VCD_PROFILE_H263_BASELINE = 0x6, + VCD_PROFILE_VC1_SIMPLE = 0x7, + VCD_PROFILE_VC1_MAIN = 0x8, + VCD_PROFILE_VC1_ADVANCE = 0x9, + VCD_PROFILE_MPEG2_MAIN = 0xA, + VCD_PROFILE_MPEG2_SIMPLE = 0xB +}; + +struct vcd_property_profile { + enum vcd_codec_profile profile; +}; + +enum vcd_codec_level { + VCD_LEVEL_UNKNOWN = 0x0, + VCD_LEVEL_MPEG4_0 = 0x1, + VCD_LEVEL_MPEG4_0b = 0x2, + VCD_LEVEL_MPEG4_1 = 0x3, + VCD_LEVEL_MPEG4_2 = 0x4, + VCD_LEVEL_MPEG4_3 = 0x5, + VCD_LEVEL_MPEG4_3b = 0x6, + VCD_LEVEL_MPEG4_4 = 0x7, + VCD_LEVEL_MPEG4_4a = 0x8, + VCD_LEVEL_MPEG4_5 = 0x9, + VCD_LEVEL_MPEG4_6 = 0xA, + VCD_LEVEL_MPEG4_7 = 0xB, + VCD_LEVEL_MPEG4_X = 0xC, + VCD_LEVEL_H264_1 = 0x10, + VCD_LEVEL_H264_1b = 0x11, + VCD_LEVEL_H264_1p1 = 0x12, + VCD_LEVEL_H264_1p2 = 0x13, + VCD_LEVEL_H264_1p3 = 0x14, + VCD_LEVEL_H264_2 = 0x15, + VCD_LEVEL_H264_2p1 = 0x16, + VCD_LEVEL_H264_2p2 = 0x17, + VCD_LEVEL_H264_3 = 0x18, + VCD_LEVEL_H264_3p1 = 0x19, + VCD_LEVEL_H264_3p2 = 0x1A, + VCD_LEVEL_H264_4 = 0x1B, + VCD_LEVEL_H264_4p1 = 0x1C, + VCD_LEVEL_H264_4p2 = 0x1D, + VCD_LEVEL_H264_5 = 0x1E, + VCD_LEVEL_H264_5p1 = 0x1F, + VCD_LEVEL_H263_10 = 0x20, + VCD_LEVEL_H263_20 = 0x21, + VCD_LEVEL_H263_30 = 0x22, + VCD_LEVEL_H263_40 = 0x23, + VCD_LEVEL_H263_45 = 0x24, + VCD_LEVEL_H263_50 = 0x25, + VCD_LEVEL_H263_60 = 0x26, + VCD_LEVEL_H263_70 = 0x27, + VCD_LEVEL_H263_X = 0x28, + VCD_LEVEL_MPEG2_LOW = 0x30, + VCD_LEVEL_MPEG2_MAIN = 0x31, + VCD_LEVEL_MPEG2_HIGH_14 = 0x32, + VCD_LEVEL_MPEG2_HIGH = 0x33, + VCD_LEVEL_MPEG2_X = 0x34, + VCD_LEVEL_VC1_S_LOW = 0x40, + VCD_LEVEL_VC1_S_MEDIUM = 0x41, + VCD_LEVEL_VC1_M_LOW = 0x42, + VCD_LEVEL_VC1_M_MEDIUM = 0x43, + VCD_LEVEL_VC1_M_HIGH = 0x44, + VCD_LEVEL_VC1_A_0 = 0x45, + VCD_LEVEL_VC1_A_1 = 0x46, + VCD_LEVEL_VC1_A_2 = 0x47, + VCD_LEVEL_VC1_A_3 = 0x48, + VCD_LEVEL_VC1_A_4 = 0x49, + VCD_LEVEL_VC1_X = 0x4A +}; + +struct vcd_property_level { + enum vcd_codec_level level; +}; + +enum vcd_m_slice_sel { + VCD_MSLICE_OFF = 0x1, + VCD_MSLICE_BY_MB_COUNT = 0x2, + VCD_MSLICE_BY_BYTE_COUNT = 0x3, + VCD_MSLICE_BY_GOB = 0x4 +}; + +struct vcd_property_multi_slice { + enum vcd_m_slice_sel m_slice_sel; + u32 m_slice_size; +}; + +enum vcd_entropy_sel { + VCD_ENTROPY_SEL_CAVLC = 0x1, + VCD_ENTROPY_SEL_CABAC = 0x2 +}; + +enum vcd_cabac_model { + VCD_CABAC_MODEL_NUMBER_0 = 0x1, + VCD_CABAC_MODEL_NUMBER_1 = 0x2, + VCD_CABAC_MODEL_NUMBER_2 = 0x3 +}; + +struct vcd_property_entropy_control { + enum vcd_entropy_sel entropy_sel; + enum vcd_cabac_model cabac_model; +}; + +enum vcd_db_config { + VCD_DB_ALL_BLOCKING_BOUNDARY = 0x1, + VCD_DB_DISABLE = 0x2, + VCD_DB_SKIP_SLICE_BOUNDARY = 0x3 +}; +struct vcd_property_db_config { + enum vcd_db_config db_config; + u32 slice_alpha_offset; + u32 slice_beta_offset; +}; + +enum vcd_rate_control { + VCD_RATE_CONTROL_OFF = 0x1, + VCD_RATE_CONTROL_VBR_VFR = 0x2, + VCD_RATE_CONTROL_VBR_CFR = 0x3, + VCD_RATE_CONTROL_CBR_VFR = 0x4, + VCD_RATE_CONTROL_CBR_CFR = 0x5 +}; + +struct vcd_property_rate_control { + enum vcd_rate_control rate_control; +}; + +struct vcd_property_qp_range { + u32 max_qp; + u32 min_qp; +}; + +struct vcd_property_session_qp { + u32 i_frame_qp; + u32 p_frame_qp; + u32 b_frame_qp; +}; + +struct vcd_property_i_period { + u32 p_frames; + u32 b_frames; +}; + +struct vcd_property_vop_timing { + u32 vop_time_resolution; +}; + +struct vcd_property_vop_timing_constant_delta { + u32 constant_delta; /*In usecs */ +}; + +struct vcd_property_short_header { + u32 short_header; +}; + +struct vcd_property_intra_refresh_mb_number { + u32 cir_mb_number; +}; + +struct vcd_property_req_i_frame { + u32 req_i_frame; +}; + +struct vcd_frame_rect { + u32 left; + u32 top; + u32 right; + u32 bottom; +}; + +struct vcd_property_dec_output_buffer { + struct vcd_frame_rect disp_frm; + struct vcd_property_frame_size frm_size; +}; + +enum vcd_output_order { + VCD_DEC_ORDER_DISPLAY = 0x0, + VCD_DEC_ORDER_DECODE = 0x1 +}; + +struct vcd_property_enc_recon_buffer { + u8 *user_virtual_addr; + u8 *kernel_virtual_addr; + u8 *physical_addr; + u8 *dev_addr; + u32 buffer_size; + u32 ysize; + int pmem_fd; + u32 offset; + void *client_data; +}; + +struct vcd_property_h264_mv_buffer { + u8 *kernel_virtual_addr; + u8 *physical_addr; + u32 size; + u32 count; + int pmem_fd; + u32 offset; + u8 *dev_addr; + void *client_data; +}; + +struct vcd_property_buffer_size { + int width; + int height; + int size; + int alignment; +}; + +struct vcd_property_sps_pps_for_idr_enable { + u32 sps_pps_for_idr_enable_flag; +}; + +#endif diff --git a/include/media/msm/vcd_status.h b/include/media/msm/vcd_status.h new file mode 100644 index 000000000000..9b67ed0e3465 --- /dev/null +++ b/include/media/msm/vcd_status.h @@ -0,0 +1,61 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#ifndef _VCD_ERR_STATUS_H_ +#define _VCD_ERR_STATUS_H_ + +#define VCD_EVT_RESP_BASE 0x1000 +#define VCD_EVT_RESP_OPEN (VCD_EVT_RESP_BASE + 0x1) +#define VCD_EVT_RESP_START (VCD_EVT_RESP_BASE + 0x2) +#define VCD_EVT_RESP_STOP (VCD_EVT_RESP_BASE + 0x3) +#define VCD_EVT_RESP_PAUSE (VCD_EVT_RESP_BASE + 0x4) +#define VCD_EVT_RESP_FLUSH_INPUT_DONE (VCD_EVT_RESP_BASE + 0x5) +#define VCD_EVT_RESP_FLUSH_OUTPUT_DONE (VCD_EVT_RESP_BASE + 0x6) +#define VCD_EVT_RESP_INPUT_FLUSHED (VCD_EVT_RESP_BASE + 0x7) +#define VCD_EVT_RESP_OUTPUT_FLUSHED (VCD_EVT_RESP_BASE + 0x8) +#define VCD_EVT_RESP_INPUT_DONE (VCD_EVT_RESP_BASE + 0x9) +#define VCD_EVT_RESP_OUTPUT_DONE (VCD_EVT_RESP_BASE + 0xa) + +#define VCD_EVT_IND_BASE 0x2000 +#define VCD_EVT_IND_INPUT_RECONFIG (VCD_EVT_IND_BASE + 0x1) +#define VCD_EVT_IND_OUTPUT_RECONFIG (VCD_EVT_IND_BASE + 0x2) +#define VCD_EVT_IND_HWERRFATAL (VCD_EVT_IND_BASE + 0x3) +#define VCD_EVT_IND_RESOURCES_LOST (VCD_EVT_IND_BASE + 0x4) +#define VCD_EVT_IND_INFO_OUTPUT_RECONFIG (VCD_EVT_IND_BASE + 0x5) +#define VCD_EVT_IND_INFO_FIELD_DROPPED (VCD_EVT_IND_BASE + 0x6) + +#define VCD_S_SUCCESS 0x0 + +#define VCD_S_ERR_BASE 0x80000000 +#define VCD_ERR_FAIL (VCD_S_ERR_BASE + 0x01) +#define VCD_ERR_ALLOC_FAIL (VCD_S_ERR_BASE + 0x02) +#define VCD_ERR_ILLEGAL_OP (VCD_S_ERR_BASE + 0x03) +#define VCD_ERR_ILLEGAL_PARM (VCD_S_ERR_BASE + 0x04) +#define VCD_ERR_BAD_POINTER (VCD_S_ERR_BASE + 0x05) +#define VCD_ERR_BAD_HANDLE (VCD_S_ERR_BASE + 0x06) +#define VCD_ERR_NOT_SUPPORTED (VCD_S_ERR_BASE + 0x07) +#define VCD_ERR_BAD_STATE (VCD_S_ERR_BASE + 0x08) +#define VCD_ERR_BUSY (VCD_S_ERR_BASE + 0x09) +#define VCD_ERR_MAX_CLIENT (VCD_S_ERR_BASE + 0x0a) +#define VCD_ERR_IFRAME_EXPECTED (VCD_S_ERR_BASE + 0x0b) +#define VCD_ERR_INTRLCD_FIELD_DROP (VCD_S_ERR_BASE + 0x0c) +#define VCD_ERR_HW_FATAL (VCD_S_ERR_BASE + 0x0d) +#define VCD_ERR_BITSTREAM_ERR (VCD_S_ERR_BASE + 0x0e) +#define VCD_ERR_QEMPTY (VCD_S_ERR_BASE + 0x0f) +#define VCD_ERR_SEQHDR_PARSE_FAIL (VCD_S_ERR_BASE + 0x10) +#define VCD_ERR_INPUT_NOT_PROCESSED (VCD_S_ERR_BASE + 0x11) +#define VCD_ERR_INDEX_NOMORE (VCD_S_ERR_BASE + 0x12) + +#define VCD_FAILED(rc) ((rc > VCD_S_ERR_BASE) ? true : false) + +#endif diff --git a/include/media/msm/vidc_init.h b/include/media/msm/vidc_init.h new file mode 100644 index 000000000000..48bc9263b4a4 --- /dev/null +++ b/include/media/msm/vidc_init.h @@ -0,0 +1,100 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ + +#ifndef VIDC_INIT_H +#define VIDC_INIT_H +#include +#include +#include + +#define VIDC_MAX_NUM_CLIENTS 4 +#define MAX_VIDEO_NUM_OF_BUFF 100 + +enum buffer_dir { + BUFFER_TYPE_INPUT, + BUFFER_TYPE_OUTPUT +}; + +struct buf_addr_table { + unsigned long user_vaddr; + unsigned long kernel_vaddr; + unsigned long phy_addr; + unsigned long buff_ion_flag; + struct ion_handle *buff_ion_handle; + int pmem_fd; + struct file *file; + unsigned long dev_addr; + void *client_data; +}; + +struct video_client_ctx { + void *vcd_handle; + u32 num_of_input_buffers; + u32 num_of_output_buffers; + struct buf_addr_table input_buf_addr_table[MAX_VIDEO_NUM_OF_BUFF]; + struct buf_addr_table output_buf_addr_table[MAX_VIDEO_NUM_OF_BUFF]; + struct list_head msg_queue; + struct mutex msg_queue_lock; + struct mutex enrty_queue_lock; + wait_queue_head_t msg_wait; + struct completion event; + struct vcd_property_h264_mv_buffer vcd_h264_mv_buffer; + struct vcd_property_enc_recon_buffer recon_buffer[4]; + u32 event_status; + u32 seq_header_set; + u32 stop_msg; + u32 stop_called; + u32 stop_sync_cb; + struct ion_client *user_ion_client; + struct ion_handle *seq_hdr_ion_handle; + struct ion_handle *h264_mv_ion_handle; + struct ion_handle *recon_buffer_ion_handle[4]; + u32 dmx_disable; +}; + +void __iomem *vidc_get_ioaddr(void); +int vidc_load_firmware(void); +void vidc_release_firmware(void); +u32 vidc_get_fd_info(struct video_client_ctx *client_ctx, + enum buffer_dir buffer, int pmem_fd, + unsigned long kvaddr, int index, + struct ion_handle **buff_handle); +u32 vidc_lookup_addr_table(struct video_client_ctx *client_ctx, + enum buffer_dir buffer, u32 search_with_user_vaddr, + unsigned long *user_vaddr, unsigned long *kernel_vaddr, + unsigned long *phy_addr, int *pmem_fd, struct file **file, + s32 *buffer_index); +u32 vidc_insert_addr_table(struct video_client_ctx *client_ctx, + enum buffer_dir buffer, unsigned long user_vaddr, + unsigned long *kernel_vaddr, int pmem_fd, + unsigned long buffer_addr_offset, + unsigned int max_num_buffers, unsigned long length); +u32 vidc_insert_addr_table_kernel(struct video_client_ctx *client_ctx, + enum buffer_dir buffer, unsigned long user_vaddr, + unsigned long kernel_vaddr, unsigned long phys_addr, + unsigned int max_num_buffers, + unsigned long length); +u32 vidc_delete_addr_table(struct video_client_ctx *client_ctx, + enum buffer_dir buffer, unsigned long user_vaddr, + unsigned long *kernel_vaddr); +void vidc_cleanup_addr_table(struct video_client_ctx *client_ctx, + enum buffer_dir buffer); + +u32 vidc_timer_create(void (*timer_handler)(void *), + void *user_data, void **timer_handle); +void vidc_timer_release(void *timer_handle); +void vidc_timer_start(void *timer_handle, u32 time_out); +void vidc_timer_stop(void *timer_handle); + + +#endif diff --git a/include/media/msm/vidc_type.h b/include/media/msm/vidc_type.h new file mode 100644 index 000000000000..04d28b260884 --- /dev/null +++ b/include/media/msm/vidc_type.h @@ -0,0 +1,30 @@ +/* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#ifndef VIDC_TYPE_H +#define VIDC_TYPE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG 0 +#define VIDC_ENABLE_DBGFS + +#define USE_RES_TRACKER +#endif diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h new file mode 100644 index 000000000000..c91bdfc07c20 --- /dev/null +++ b/include/media/msm_camera.h @@ -0,0 +1,19 @@ +/* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#ifndef __LINUX_MSM_CAMERA_H +#define __LINUX_MSM_CAMERA_H + +#include +#include + +#endif /* __LINUX_MSM_CAMERA_H */ diff --git a/include/media/msm_v4l2_overlay.h b/include/media/msm_v4l2_overlay.h new file mode 100644 index 000000000000..c83cfb7b1916 --- /dev/null +++ b/include/media/msm_v4l2_overlay.h @@ -0,0 +1,9 @@ +#ifndef LINUX_MSM_V4L2_OVERLAY +#define LINUX_MSM_V4L2_OVERLAY + +#include + +#define VIDIOC_MSM_USERPTR_QBUF \ +_IOWR('V', BASE_VIDIOC_PRIVATE, struct v4l2_buffer) + +#endif diff --git a/include/uapi/Kbuild b/include/uapi/Kbuild index 81d2106287fe..3098462d692c 100644 --- a/include/uapi/Kbuild +++ b/include/uapi/Kbuild @@ -12,3 +12,4 @@ header-y += video/ header-y += drm/ header-y += xen/ header-y += scsi/ +header-y += media/ diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index 707cc39a47a1..bac2a91cdb2c 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -251,6 +251,7 @@ header-y += mroute.h header-y += mroute6.h header-y += msdos_fs.h header-y += msg.h +header-y += msm_mdp.h header-y += mtio.h header-y += n_r3964.h header-y += nbd.h diff --git a/include/uapi/linux/msm_mdp.h b/include/uapi/linux/msm_mdp.h new file mode 100644 index 000000000000..cab9e7714d34 --- /dev/null +++ b/include/uapi/linux/msm_mdp.h @@ -0,0 +1,480 @@ +#ifndef _UAPI_MSM_MDP_H_ +#define _UAPI_MSM_MDP_H_ + +#include +#include + +#define MSMFB_IOCTL_MAGIC 'm' +#define MSMFB_GRP_DISP _IOW(MSMFB_IOCTL_MAGIC, 1, unsigned int) +#define MSMFB_BLIT _IOW(MSMFB_IOCTL_MAGIC, 2, unsigned int) +#define MSMFB_SUSPEND_SW_REFRESHER _IOW(MSMFB_IOCTL_MAGIC, 128, unsigned int) +#define MSMFB_RESUME_SW_REFRESHER _IOW(MSMFB_IOCTL_MAGIC, 129, unsigned int) +#define MSMFB_CURSOR _IOW(MSMFB_IOCTL_MAGIC, 130, struct fb_cursor) +#define MSMFB_SET_LUT _IOW(MSMFB_IOCTL_MAGIC, 131, struct fb_cmap) +#define MSMFB_HISTOGRAM _IOWR(MSMFB_IOCTL_MAGIC, 132, struct mdp_histogram_data) +/* new ioctls's for set/get ccs matrix */ +#define MSMFB_GET_CCS_MATRIX _IOWR(MSMFB_IOCTL_MAGIC, 133, struct mdp_ccs) +#define MSMFB_SET_CCS_MATRIX _IOW(MSMFB_IOCTL_MAGIC, 134, struct mdp_ccs) +#define MSMFB_OVERLAY_SET _IOWR(MSMFB_IOCTL_MAGIC, 135, \ + struct mdp_overlay) +#define MSMFB_OVERLAY_UNSET _IOW(MSMFB_IOCTL_MAGIC, 136, unsigned int) +#define MSMFB_OVERLAY_PLAY _IOW(MSMFB_IOCTL_MAGIC, 137, \ + struct msmfb_overlay_data) +#define MSMFB_GET_PAGE_PROTECTION _IOR(MSMFB_IOCTL_MAGIC, 138, \ + struct mdp_page_protection) +#define MSMFB_SET_PAGE_PROTECTION _IOW(MSMFB_IOCTL_MAGIC, 139, \ + struct mdp_page_protection) +#define MSMFB_OVERLAY_GET _IOR(MSMFB_IOCTL_MAGIC, 140, \ + struct mdp_overlay) +#define MSMFB_OVERLAY_PLAY_ENABLE _IOW(MSMFB_IOCTL_MAGIC, 141, unsigned int) +#define MSMFB_OVERLAY_BLT _IOWR(MSMFB_IOCTL_MAGIC, 142, \ + struct msmfb_overlay_blt) +#define MSMFB_OVERLAY_BLT_OFFSET _IOW(MSMFB_IOCTL_MAGIC, 143, unsigned int) +#define MSMFB_HISTOGRAM_START _IOR(MSMFB_IOCTL_MAGIC, 144, \ + struct mdp_histogram_start_req) +#define MSMFB_HISTOGRAM_STOP _IOR(MSMFB_IOCTL_MAGIC, 145, unsigned int) +#define MSMFB_NOTIFY_UPDATE _IOW(MSMFB_IOCTL_MAGIC, 146, unsigned int) + +#define MSMFB_OVERLAY_3D _IOWR(MSMFB_IOCTL_MAGIC, 147, \ + struct msmfb_overlay_3d) + +#define MSMFB_MIXER_INFO _IOWR(MSMFB_IOCTL_MAGIC, 148, \ + struct msmfb_mixer_info_req) +#define MSMFB_OVERLAY_PLAY_WAIT _IOWR(MSMFB_IOCTL_MAGIC, 149, \ + struct msmfb_overlay_data) +#define MSMFB_WRITEBACK_INIT _IO(MSMFB_IOCTL_MAGIC, 150) +#define MSMFB_WRITEBACK_START _IO(MSMFB_IOCTL_MAGIC, 151) +#define MSMFB_WRITEBACK_STOP _IO(MSMFB_IOCTL_MAGIC, 152) +#define MSMFB_WRITEBACK_QUEUE_BUFFER _IOW(MSMFB_IOCTL_MAGIC, 153, \ + struct msmfb_data) +#define MSMFB_WRITEBACK_DEQUEUE_BUFFER _IOW(MSMFB_IOCTL_MAGIC, 154, \ + struct msmfb_data) +#define MSMFB_WRITEBACK_TERMINATE _IO(MSMFB_IOCTL_MAGIC, 155) +#define MSMFB_MDP_PP _IOWR(MSMFB_IOCTL_MAGIC, 156, struct msmfb_mdp_pp) + +#define FB_TYPE_3D_PANEL 0x10101010 +#define MDP_IMGTYPE2_START 0x10000 +#define MSMFB_DRIVER_VERSION 0xF9E8D701 + +enum { + NOTIFY_UPDATE_START, + NOTIFY_UPDATE_STOP, +}; + +enum { + MDP_RGB_565, /* RGB 565 planer */ + MDP_XRGB_8888, /* RGB 888 padded */ + MDP_Y_CBCR_H2V2, /* Y and CbCr, pseudo planer w/ Cb is in MSB */ + MDP_Y_CBCR_H2V2_ADRENO, + MDP_ARGB_8888, /* ARGB 888 */ + MDP_RGB_888, /* RGB 888 planer */ + MDP_Y_CRCB_H2V2, /* Y and CrCb, pseudo planer w/ Cr is in MSB */ + MDP_YCRYCB_H2V1, /* YCrYCb interleave */ + MDP_Y_CRCB_H2V1, /* Y and CrCb, pseduo planer w/ Cr is in MSB */ + MDP_Y_CBCR_H2V1, /* Y and CrCb, pseduo planer w/ Cr is in MSB */ + MDP_RGBA_8888, /* ARGB 888 */ + MDP_BGRA_8888, /* ABGR 888 */ + MDP_RGBX_8888, /* RGBX 888 */ + MDP_Y_CRCB_H2V2_TILE, /* Y and CrCb, pseudo planer tile */ + MDP_Y_CBCR_H2V2_TILE, /* Y and CbCr, pseudo planer tile */ + MDP_Y_CR_CB_H2V2, /* Y, Cr and Cb, planar */ + MDP_Y_CR_CB_GH2V2, /* Y, Cr and Cb, planar aligned to Android YV12 */ + MDP_Y_CB_CR_H2V2, /* Y, Cb and Cr, planar */ + MDP_Y_CRCB_H1V1, /* Y and CrCb, pseduo planer w/ Cr is in MSB */ + MDP_Y_CBCR_H1V1, /* Y and CbCr, pseduo planer w/ Cb is in MSB */ + MDP_YCRCB_H1V1, /* YCrCb interleave */ + MDP_YCBCR_H1V1, /* YCbCr interleave */ + MDP_IMGTYPE_LIMIT, + MDP_RGB_BORDERFILL, /* border fill pipe */ + MDP_BGR_565 = MDP_IMGTYPE2_START, /* BGR 565 planer */ + MDP_FB_FORMAT, /* framebuffer format */ + MDP_IMGTYPE_LIMIT2 /* Non valid image type after this enum */ +}; + +enum { + PMEM_IMG, + FB_IMG, +}; + +enum { + HSIC_HUE = 0, + HSIC_SAT, + HSIC_INT, + HSIC_CON, + NUM_HSIC_PARAM, +}; + +/* mdp_blit_req flag values */ +#define MDP_ROT_NOP 0 +#define MDP_FLIP_LR 0x1 +#define MDP_FLIP_UD 0x2 +#define MDP_ROT_90 0x4 +#define MDP_ROT_180 (MDP_FLIP_UD|MDP_FLIP_LR) +#define MDP_ROT_270 (MDP_ROT_90|MDP_FLIP_UD|MDP_FLIP_LR) +#define MDP_DITHER 0x8 +#define MDP_BLUR 0x10 +#define MDP_BLEND_FG_PREMULT 0x20000 +#define MDP_DEINTERLACE 0x80000000 +#define MDP_SHARPENING 0x40000000 +#define MDP_NO_DMA_BARRIER_START 0x20000000 +#define MDP_NO_DMA_BARRIER_END 0x10000000 +#define MDP_NO_BLIT 0x08000000 +#define MDP_BLIT_WITH_DMA_BARRIERS 0x000 +#define MDP_BLIT_WITH_NO_DMA_BARRIERS \ + (MDP_NO_DMA_BARRIER_START | MDP_NO_DMA_BARRIER_END) +#define MDP_BLIT_SRC_GEM 0x04000000 +#define MDP_BLIT_DST_GEM 0x02000000 +#define MDP_BLIT_NON_CACHED 0x01000000 +#define MDP_OV_PIPE_SHARE 0x00800000 +#define MDP_DEINTERLACE_ODD 0x00400000 +#define MDP_OV_PLAY_NOWAIT 0x00200000 +#define MDP_SOURCE_ROTATED_90 0x00100000 +#define MDP_DPP_HSIC 0x00080000 +#define MDP_BACKEND_COMPOSITION 0x00040000 +#define MDP_BORDERFILL_SUPPORTED 0x00010000 +#define MDP_SECURE_OVERLAY_SESSION 0x00008000 +#define MDP_MEMORY_ID_TYPE_FB 0x00001000 + +#define MDP_TRANSP_NOP 0xffffffff +#define MDP_ALPHA_NOP 0xff + +#define MDP_FB_PAGE_PROTECTION_NONCACHED (0) +#define MDP_FB_PAGE_PROTECTION_WRITECOMBINE (1) +#define MDP_FB_PAGE_PROTECTION_WRITETHROUGHCACHE (2) +#define MDP_FB_PAGE_PROTECTION_WRITEBACKCACHE (3) +#define MDP_FB_PAGE_PROTECTION_WRITEBACKWACACHE (4) +/* Sentinel: Don't use! */ +#define MDP_FB_PAGE_PROTECTION_INVALID (5) +/* Count of the number of MDP_FB_PAGE_PROTECTION_... values. */ +#define MDP_NUM_FB_PAGE_PROTECTION_VALUES (5) + +struct mdp_rect { + uint32_t x; + uint32_t y; + uint32_t w; + uint32_t h; +}; + +struct mdp_img { + uint32_t width; + uint32_t height; + uint32_t format; + uint32_t offset; + int memory_id; /* the file descriptor */ + uint32_t priv; +}; + +/* + * {3x3} + {3} ccs matrix + */ + +#define MDP_CCS_RGB2YUV 0 +#define MDP_CCS_YUV2RGB 1 + +#define MDP_CCS_SIZE 9 +#define MDP_BV_SIZE 3 + +struct mdp_ccs { + int direction; /* MDP_CCS_RGB2YUV or YUV2RGB */ + uint16_t ccs[MDP_CCS_SIZE]; /* 3x3 color coefficients */ + uint16_t bv[MDP_BV_SIZE]; /* 1x3 bias vector */ +}; + +struct mdp_csc { + int id; + uint32_t csc_mv[9]; + uint32_t csc_pre_bv[3]; + uint32_t csc_post_bv[3]; + uint32_t csc_pre_lv[6]; + uint32_t csc_post_lv[6]; +}; + +/* The version of the mdp_blit_req structure so that + * user applications can selectively decide which functionality + * to include + */ + +#define MDP_BLIT_REQ_VERSION 2 + +struct mdp_blit_req { + struct mdp_img src; + struct mdp_img dst; + struct mdp_rect src_rect; + struct mdp_rect dst_rect; + uint32_t alpha; + uint32_t transp_mask; + uint32_t flags; + int sharpening_strength; /* -127 <--> 127, default 64 */ +}; + +struct mdp_blit_req_list { + uint32_t count; + struct mdp_blit_req req[]; +}; + +#define MSMFB_DATA_VERSION 2 + +struct msmfb_data { + uint32_t offset; + int memory_id; + int id; + uint32_t flags; + uint32_t priv; + uint32_t iova; +}; + +#define MSMFB_NEW_REQUEST -1 + +struct msmfb_overlay_data { + uint32_t id; + struct msmfb_data data; + uint32_t version_key; + struct msmfb_data plane1_data; + struct msmfb_data plane2_data; +}; + +struct msmfb_img { + uint32_t width; + uint32_t height; + uint32_t format; +}; + +#define MSMFB_WRITEBACK_DEQUEUE_BLOCKING 0x1 +struct msmfb_writeback_data { + struct msmfb_data buf_info; + struct msmfb_img img; +}; + +struct dpp_ctrl { + /* + *'sharp_strength' has inputs = -128 <-> 127 + * Increasingly positive values correlate with increasingly sharper + * picture. Increasingly negative values correlate with increasingly + * smoothed picture. + */ + int8_t sharp_strength; + int8_t hsic_params[NUM_HSIC_PARAM]; +}; + +struct mdp_overlay { + struct msmfb_img src; + struct mdp_rect src_rect; + struct mdp_rect dst_rect; + uint32_t z_order; /* stage number */ + uint32_t is_fg; /* control alpha & transp */ + uint32_t alpha; + uint32_t transp_mask; + uint32_t flags; + uint32_t id; + uint32_t user_data[8]; + struct dpp_ctrl dpp; +}; + +struct msmfb_overlay_3d { + uint32_t is_3d; + uint32_t width; + uint32_t height; +}; + + +struct msmfb_overlay_blt { + uint32_t enable; + uint32_t offset; + uint32_t width; + uint32_t height; + uint32_t bpp; +}; + +struct mdp_histogram { + uint32_t frame_cnt; + uint32_t bin_cnt; + uint32_t *r; + uint32_t *g; + uint32_t *b; +}; + + +/* + + mdp_block_type defines the identifiers for each of pipes in MDP 4.3 + + MDP_BLOCK_RESERVED is provided for backward compatibility and is + deprecated. It corresponds to DMA_P. So MDP_BLOCK_DMA_P should be used + instead. + +*/ + +enum { + MDP_BLOCK_RESERVED = 0, + MDP_BLOCK_OVERLAY_0, + MDP_BLOCK_OVERLAY_1, + MDP_BLOCK_VG_1, + MDP_BLOCK_VG_2, + MDP_BLOCK_RGB_1, + MDP_BLOCK_RGB_2, + MDP_BLOCK_DMA_P, + MDP_BLOCK_DMA_S, + MDP_BLOCK_DMA_E, + MDP_BLOCK_OVERLAY_2, + MDP_BLOCK_MAX, +}; + +/* + * mdp_histogram_start_req is used to provide the parameters for + * histogram start request + */ + +struct mdp_histogram_start_req { + uint32_t block; + uint8_t frame_cnt; + uint8_t bit_mask; + uint8_t num_bins; +}; + +/* + * mdp_histogram_data is used to return the histogram data, once + * the histogram is done/stopped/cance + */ + +struct mdp_histogram_data { + uint32_t block; + uint8_t bin_cnt; + uint32_t *c0; + uint32_t *c1; + uint32_t *c2; + uint32_t *extra_info; +}; + +struct mdp_pcc_coeff { + uint32_t c, r, g, b, rr, gg, bb, rg, gb, rb, rgb_0, rgb_1; +}; + +struct mdp_pcc_cfg_data { + uint32_t block; + uint32_t ops; + struct mdp_pcc_coeff r, g, b; +}; + +#define MDP_CSC_FLAG_ENABLE 0x1 +#define MDP_CSC_FLAG_YUV_IN 0x2 +#define MDP_CSC_FLAG_YUV_OUT 0x4 + +struct mdp_csc_cfg { + /* flags for enable CSC, toggling RGB,YUV input/output */ + uint32_t flags; + uint32_t csc_mv[9]; + uint32_t csc_pre_bv[3]; + uint32_t csc_post_bv[3]; + uint32_t csc_pre_lv[6]; + uint32_t csc_post_lv[6]; +}; + +struct mdp_csc_cfg_data { + uint32_t block; + struct mdp_csc_cfg csc_data; +}; + +enum { + mdp_lut_igc, + mdp_lut_pgc, + mdp_lut_hist, + mdp_lut_max, +}; + + +struct mdp_igc_lut_data { + uint32_t block; + uint32_t len, ops; + uint32_t *c0_c1_data; + uint32_t *c2_data; +}; + +struct mdp_ar_gc_lut_data { + uint32_t x_start; + uint32_t slope; + uint32_t offset; +}; + +struct mdp_pgc_lut_data { + uint32_t block; + uint32_t flags; + uint8_t num_r_stages; + uint8_t num_g_stages; + uint8_t num_b_stages; + struct mdp_ar_gc_lut_data *r_data; + struct mdp_ar_gc_lut_data *g_data; + struct mdp_ar_gc_lut_data *b_data; +}; + + +struct mdp_hist_lut_data { + uint32_t block; + uint32_t ops; + uint32_t len; + uint32_t *data; +}; + + +struct mdp_lut_cfg_data { + uint32_t lut_type; + union { + struct mdp_igc_lut_data igc_lut_data; + struct mdp_pgc_lut_data pgc_lut_data; + struct mdp_hist_lut_data hist_lut_data; + } data; +}; + +struct mdp_qseed_cfg_data { + uint32_t block; + uint32_t table_num; + uint32_t ops; + uint32_t len; + uint32_t *data; +}; + + +enum { + mdp_op_pcc_cfg, + mdp_op_csc_cfg, + mdp_op_lut_cfg, + mdp_op_qseed_cfg, + mdp_op_max, +}; + +struct msmfb_mdp_pp { + uint32_t op; + union { + struct mdp_pcc_cfg_data pcc_cfg_data; + struct mdp_csc_cfg_data csc_cfg_data; + struct mdp_lut_cfg_data lut_cfg_data; + struct mdp_qseed_cfg_data qseed_cfg_data; + } data; +}; + + +struct mdp_page_protection { + uint32_t page_protection; +}; + + +struct mdp_mixer_info { + int pndx; + int pnum; + int ptype; + int mixer_num; + int z_order; +}; + +#define MAX_PIPE_PER_MIXER 4 + +struct msmfb_mixer_info_req { + int mixer_num; + int cnt; + struct mdp_mixer_info info[MAX_PIPE_PER_MIXER]; +}; + +enum { + DISPLAY_SUBSYSTEM_ID, + ROTATOR_SUBSYSTEM_ID, +}; +#endif /*_UAPI_MSM_MDP_H_*/ diff --git a/include/uapi/media/Kbuild b/include/uapi/media/Kbuild new file mode 100644 index 000000000000..75a11b286a61 --- /dev/null +++ b/include/uapi/media/Kbuild @@ -0,0 +1 @@ +header-y += msm_camera.h diff --git a/include/uapi/media/msm_camera.h b/include/uapi/media/msm_camera.h new file mode 100644 index 000000000000..be9e04671897 --- /dev/null +++ b/include/uapi/media/msm_camera.h @@ -0,0 +1,2266 @@ +/* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + * + */ +#ifndef __UAPI_MSM_CAMERA_H +#define __UAPI_MSM_CAMERA_H + +#ifdef MSM_CAMERA_BIONIC +#include +#endif +#include +#include +#include +#ifdef MSM_CAMERA_GCC +#include +#else +#include +#endif + +#include + +#define BIT(nr) (1UL << (nr)) + +#define MSM_CAM_IOCTL_MAGIC 'm' + +#define MAX_SERVER_PAYLOAD_LENGTH 8192 + +#define MSM_CAM_IOCTL_GET_SENSOR_INFO \ + _IOR(MSM_CAM_IOCTL_MAGIC, 1, struct msm_camsensor_info *) + +#define MSM_CAM_IOCTL_REGISTER_PMEM \ + _IOW(MSM_CAM_IOCTL_MAGIC, 2, struct msm_pmem_info *) + +#define MSM_CAM_IOCTL_UNREGISTER_PMEM \ + _IOW(MSM_CAM_IOCTL_MAGIC, 3, unsigned) + +#define MSM_CAM_IOCTL_CTRL_COMMAND \ + _IOW(MSM_CAM_IOCTL_MAGIC, 4, struct msm_ctrl_cmd *) + +#define MSM_CAM_IOCTL_CONFIG_VFE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 5, struct msm_camera_vfe_cfg_cmd *) + +#define MSM_CAM_IOCTL_GET_STATS \ + _IOR(MSM_CAM_IOCTL_MAGIC, 6, struct msm_camera_stats_event_ctrl *) + +#define MSM_CAM_IOCTL_GETFRAME \ + _IOR(MSM_CAM_IOCTL_MAGIC, 7, struct msm_camera_get_frame *) + +#define MSM_CAM_IOCTL_ENABLE_VFE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 8, struct camera_enable_cmd *) + +#define MSM_CAM_IOCTL_CTRL_CMD_DONE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 9, struct camera_cmd *) + +#define MSM_CAM_IOCTL_CONFIG_CMD \ + _IOW(MSM_CAM_IOCTL_MAGIC, 10, struct camera_cmd *) + +#define MSM_CAM_IOCTL_DISABLE_VFE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 11, struct camera_enable_cmd *) + +#define MSM_CAM_IOCTL_PAD_REG_RESET2 \ + _IOW(MSM_CAM_IOCTL_MAGIC, 12, struct camera_enable_cmd *) + +#define MSM_CAM_IOCTL_VFE_APPS_RESET \ + _IOW(MSM_CAM_IOCTL_MAGIC, 13, struct camera_enable_cmd *) + +#define MSM_CAM_IOCTL_RELEASE_FRAME_BUFFER \ + _IOW(MSM_CAM_IOCTL_MAGIC, 14, struct camera_enable_cmd *) + +#define MSM_CAM_IOCTL_RELEASE_STATS_BUFFER \ + _IOW(MSM_CAM_IOCTL_MAGIC, 15, struct msm_stats_buf *) + +#define MSM_CAM_IOCTL_AXI_CONFIG \ + _IOW(MSM_CAM_IOCTL_MAGIC, 16, struct msm_camera_vfe_cfg_cmd *) + +#define MSM_CAM_IOCTL_GET_PICTURE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 17, struct msm_frame *) + +#define MSM_CAM_IOCTL_SET_CROP \ + _IOW(MSM_CAM_IOCTL_MAGIC, 18, struct crop_info *) + +#define MSM_CAM_IOCTL_PICT_PP \ + _IOW(MSM_CAM_IOCTL_MAGIC, 19, uint8_t *) + +#define MSM_CAM_IOCTL_PICT_PP_DONE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 20, struct msm_snapshot_pp_status *) + +#define MSM_CAM_IOCTL_SENSOR_IO_CFG \ + _IOW(MSM_CAM_IOCTL_MAGIC, 21, struct sensor_cfg_data *) + +#define MSM_CAM_IOCTL_FLASH_LED_CFG \ + _IOW(MSM_CAM_IOCTL_MAGIC, 22, unsigned *) + +#define MSM_CAM_IOCTL_UNBLOCK_POLL_FRAME \ + _IO(MSM_CAM_IOCTL_MAGIC, 23) + +#define MSM_CAM_IOCTL_CTRL_COMMAND_2 \ + _IOW(MSM_CAM_IOCTL_MAGIC, 24, struct msm_ctrl_cmd *) + +#define MSM_CAM_IOCTL_AF_CTRL \ + _IOR(MSM_CAM_IOCTL_MAGIC, 25, struct msm_ctrl_cmt_t *) + +#define MSM_CAM_IOCTL_AF_CTRL_DONE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 26, struct msm_ctrl_cmt_t *) + +#define MSM_CAM_IOCTL_CONFIG_VPE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 27, struct msm_camera_vpe_cfg_cmd *) + +#define MSM_CAM_IOCTL_AXI_VPE_CONFIG \ + _IOW(MSM_CAM_IOCTL_MAGIC, 28, struct msm_camera_vpe_cfg_cmd *) + +#define MSM_CAM_IOCTL_STROBE_FLASH_CFG \ + _IOW(MSM_CAM_IOCTL_MAGIC, 29, uint32_t *) + +#define MSM_CAM_IOCTL_STROBE_FLASH_CHARGE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 30, uint32_t *) + +#define MSM_CAM_IOCTL_STROBE_FLASH_RELEASE \ + _IO(MSM_CAM_IOCTL_MAGIC, 31) + +#define MSM_CAM_IOCTL_FLASH_CTRL \ + _IOW(MSM_CAM_IOCTL_MAGIC, 32, struct flash_ctrl_data *) + +#define MSM_CAM_IOCTL_ERROR_CONFIG \ + _IOW(MSM_CAM_IOCTL_MAGIC, 33, uint32_t *) + +#define MSM_CAM_IOCTL_ABORT_CAPTURE \ + _IO(MSM_CAM_IOCTL_MAGIC, 34) + +#define MSM_CAM_IOCTL_SET_FD_ROI \ + _IOW(MSM_CAM_IOCTL_MAGIC, 35, struct fd_roi_info *) + +#define MSM_CAM_IOCTL_GET_CAMERA_INFO \ + _IOR(MSM_CAM_IOCTL_MAGIC, 36, struct msm_camera_info *) + +#define MSM_CAM_IOCTL_UNBLOCK_POLL_PIC_FRAME \ + _IO(MSM_CAM_IOCTL_MAGIC, 37) + +#define MSM_CAM_IOCTL_RELEASE_PIC_BUFFER \ + _IOW(MSM_CAM_IOCTL_MAGIC, 38, struct camera_enable_cmd *) + +#define MSM_CAM_IOCTL_PUT_ST_FRAME \ + _IOW(MSM_CAM_IOCTL_MAGIC, 39, struct msm_camera_st_frame *) + +#define MSM_CAM_IOCTL_V4L2_EVT_NOTIFY \ + _IOW(MSM_CAM_IOCTL_MAGIC, 40, struct v4l2_event_and_payload) + +#define MSM_CAM_IOCTL_SET_MEM_MAP_INFO \ + _IOR(MSM_CAM_IOCTL_MAGIC, 41, struct msm_mem_map_info *) + +#define MSM_CAM_IOCTL_ACTUATOR_IO_CFG \ + _IOW(MSM_CAM_IOCTL_MAGIC, 42, struct msm_actuator_cfg_data *) + +#define MSM_CAM_IOCTL_MCTL_POST_PROC \ + _IOW(MSM_CAM_IOCTL_MAGIC, 43, struct msm_mctl_post_proc_cmd *) + +#define MSM_CAM_IOCTL_RESERVE_FREE_FRAME \ + _IOW(MSM_CAM_IOCTL_MAGIC, 44, struct msm_cam_evt_divert_frame *) + +#define MSM_CAM_IOCTL_RELEASE_FREE_FRAME \ + _IOR(MSM_CAM_IOCTL_MAGIC, 45, struct msm_cam_evt_divert_frame *) + +#define MSM_CAM_IOCTL_PICT_PP_DIVERT_DONE \ + _IOR(MSM_CAM_IOCTL_MAGIC, 46, struct msm_pp_frame *) + +#define MSM_CAM_IOCTL_SENSOR_V4l2_S_CTRL \ + _IOR(MSM_CAM_IOCTL_MAGIC, 47, struct v4l2_control) + +#define MSM_CAM_IOCTL_SENSOR_V4l2_QUERY_CTRL \ + _IOR(MSM_CAM_IOCTL_MAGIC, 48, struct v4l2_queryctrl) + +#define MSM_CAM_IOCTL_GET_KERNEL_SYSTEM_TIME \ + _IOW(MSM_CAM_IOCTL_MAGIC, 49, struct timeval *) + +#define MSM_CAM_IOCTL_SET_VFE_OUTPUT_TYPE \ + _IOW(MSM_CAM_IOCTL_MAGIC, 50, uint32_t *) + +#define MSM_CAM_IOCTL_MCTL_DIVERT_DONE \ + _IOR(MSM_CAM_IOCTL_MAGIC, 51, struct msm_cam_evt_divert_frame *) + +#define MSM_CAM_IOCTL_GET_ACTUATOR_INFO \ + _IOW(MSM_CAM_IOCTL_MAGIC, 52, struct msm_actuator_cfg_data *) + +#define MSM_CAM_IOCTL_EEPROM_IO_CFG \ + _IOW(MSM_CAM_IOCTL_MAGIC, 53, struct msm_eeprom_cfg_data *) + +#define MSM_CAM_IOCTL_ISPIF_IO_CFG \ + _IOR(MSM_CAM_IOCTL_MAGIC, 54, struct ispif_cfg_data *) + +#define MSM_CAM_IOCTL_STATS_REQBUF \ + _IOR(MSM_CAM_IOCTL_MAGIC, 55, struct msm_stats_reqbuf *) + +#define MSM_CAM_IOCTL_STATS_ENQUEUEBUF \ + _IOR(MSM_CAM_IOCTL_MAGIC, 56, struct msm_stats_buf_info *) + +#define MSM_CAM_IOCTL_STATS_FLUSH_BUFQ \ + _IOR(MSM_CAM_IOCTL_MAGIC, 57, struct msm_stats_flush_bufq *) + +#define MSM_CAM_IOCTL_SET_MCTL_SDEV \ + _IOW(MSM_CAM_IOCTL_MAGIC, 58, struct msm_mctl_set_sdev_data *) + +#define MSM_CAM_IOCTL_UNSET_MCTL_SDEV \ + _IOW(MSM_CAM_IOCTL_MAGIC, 59, struct msm_mctl_set_sdev_data *) + +#define MSM_CAM_IOCTL_GET_INST_HANDLE \ + _IOR(MSM_CAM_IOCTL_MAGIC, 60, uint32_t *) + +#define MSM_CAM_IOCTL_STATS_UNREG_BUF \ + _IOR(MSM_CAM_IOCTL_MAGIC, 61, struct msm_stats_flush_bufq *) + +#define MSM_CAM_IOCTL_CSIC_IO_CFG \ + _IOWR(MSM_CAM_IOCTL_MAGIC, 62, struct csic_cfg_data *) + +#define MSM_CAM_IOCTL_CSID_IO_CFG \ + _IOWR(MSM_CAM_IOCTL_MAGIC, 63, struct csid_cfg_data *) + +#define MSM_CAM_IOCTL_CSIPHY_IO_CFG \ + _IOR(MSM_CAM_IOCTL_MAGIC, 64, struct csiphy_cfg_data *) + +#define MSM_CAM_IOCTL_OEM \ + _IOW(MSM_CAM_IOCTL_MAGIC, 65, struct sensor_cfg_data *) + +#define MSM_CAM_IOCTL_AXI_INIT \ + _IOWR(MSM_CAM_IOCTL_MAGIC, 66, uint8_t *) + +#define MSM_CAM_IOCTL_AXI_RELEASE \ + _IO(MSM_CAM_IOCTL_MAGIC, 67) + +struct v4l2_event_and_payload { + struct v4l2_event evt; + uint32_t payload_length; + uint32_t transaction_id; + void *payload; +}; + +struct msm_stats_reqbuf { + int num_buf; /* how many buffers requested */ + int stats_type; /* stats type */ +}; + +struct msm_stats_flush_bufq { + int stats_type; /* enum msm_stats_enum_type */ +}; + +struct msm_mctl_pp_cmd { + int32_t id; + uint16_t length; + void *value; +}; + +struct msm_mctl_post_proc_cmd { + int32_t type; + struct msm_mctl_pp_cmd cmd; +}; + +#define MSM_CAMERA_LED_OFF 0 +#define MSM_CAMERA_LED_LOW 1 +#define MSM_CAMERA_LED_HIGH 2 +#define MSM_CAMERA_LED_INIT 3 +#define MSM_CAMERA_LED_RELEASE 4 + +#define MSM_CAMERA_STROBE_FLASH_NONE 0 +#define MSM_CAMERA_STROBE_FLASH_XENON 1 + +#define MSM_MAX_CAMERA_SENSORS 5 +#define MAX_SENSOR_NAME 32 +#define MAX_CAM_NAME_SIZE 32 +#define MAX_ACT_MOD_NAME_SIZE 32 +#define MAX_ACT_NAME_SIZE 32 +#define NUM_ACTUATOR_DIR 2 +#define MAX_ACTUATOR_SCENARIO 8 +#define MAX_ACTUATOR_REGION 5 +#define MAX_ACTUATOR_INIT_SET 12 +#define MAX_ACTUATOR_TYPE_SIZE 32 +#define MAX_ACTUATOR_REG_TBL_SIZE 8 + + +#define MSM_MAX_CAMERA_CONFIGS 2 + +#define PP_SNAP 0x01 +#define PP_RAW_SNAP ((0x01)<<1) +#define PP_PREV ((0x01)<<2) +#define PP_THUMB ((0x01)<<3) +#define PP_MASK (PP_SNAP|PP_RAW_SNAP|PP_PREV|PP_THUMB) + +#define MSM_CAM_CTRL_CMD_DONE 0 +#define MSM_CAM_SENSOR_VFE_CMD 1 + +/* Should be same as VIDEO_MAX_PLANES in videodev2.h */ +#define MAX_PLANES 8 + +/***************************************************** + * structure + *****************************************************/ + +/* define five type of structures for userspace <==> kernel + * space communication: + * command 1 - 2 are from userspace ==> kernel + * command 3 - 4 are from kernel ==> userspace + * + * 1. control command: control command(from control thread), + * control status (from config thread); + */ +struct msm_ctrl_cmd { + uint16_t type; + uint16_t length; + void *value; + uint16_t status; + uint32_t timeout_ms; + int resp_fd; /* FIXME: to be used by the kernel, pass-through for now */ + int vnode_id; /* video dev id. Can we overload resp_fd? */ + int queue_idx; + uint32_t evt_id; + uint32_t stream_type; /* used to pass value to qcamera server */ + int config_ident; /*used as identifier for config node*/ +}; + +struct msm_cam_evt_msg { + unsigned short type; /* 1 == event (RPC), 0 == message (adsp) */ + unsigned short msg_id; + unsigned int len; /* size in, number of bytes out */ + uint32_t frame_id; + void *data; + struct timespec timestamp; +}; + +struct msm_pp_frame_sp { + /* phy addr of the buffer */ + unsigned long phy_addr; + uint32_t y_off; + uint32_t cbcr_off; + /* buffer length */ + uint32_t length; + int32_t fd; + uint32_t addr_offset; + /* mapped addr */ + unsigned long vaddr; +}; + +struct msm_pp_frame_mp { + /* phy addr of the plane */ + unsigned long phy_addr; + /* offset of plane data */ + uint32_t data_offset; + /* plane length */ + uint32_t length; + int32_t fd; + uint32_t addr_offset; + /* mapped addr */ + unsigned long vaddr; +}; + +struct msm_pp_frame { + uint32_t handle; /* stores vb cookie */ + uint32_t frame_id; + unsigned short buf_idx; + int path; + unsigned short image_type; + unsigned short num_planes; /* 1 for sp */ + struct timeval timestamp; + union { + struct msm_pp_frame_sp sp; + struct msm_pp_frame_mp mp[MAX_PLANES]; + }; + int node_type; + uint32_t inst_handle; +}; + +struct msm_pp_crop { + uint32_t src_x; + uint32_t src_y; + uint32_t src_w; + uint32_t src_h; + uint32_t dst_x; + uint32_t dst_y; + uint32_t dst_w; + uint32_t dst_h; + uint8_t update_flag; +}; + +struct msm_mctl_pp_frame_cmd { + uint32_t cookie; + uint8_t vpe_output_action; + struct msm_pp_frame src_frame; + struct msm_pp_frame dest_frame; + struct msm_pp_crop crop; + int path; +}; + +struct msm_cam_evt_divert_frame { + unsigned short image_mode; + unsigned short op_mode; + unsigned short inst_idx; + unsigned short node_idx; + struct msm_pp_frame frame; + int do_pp; +}; + +struct msm_mctl_pp_cmd_ack_event { + uint32_t cmd; /* VPE_CMD_ZOOM? */ + int status; /* 0 done, < 0 err */ + uint32_t cookie; /* daemon's cookie */ +}; + +struct msm_mctl_pp_event_info { + int32_t event; + union { + struct msm_mctl_pp_cmd_ack_event ack; + }; +}; + +struct msm_isp_event_ctrl { + unsigned short resptype; + union { + struct msm_cam_evt_msg isp_msg; + struct msm_ctrl_cmd ctrl; + struct msm_cam_evt_divert_frame div_frame; + struct msm_mctl_pp_event_info pp_event_info; + } isp_data; +}; + +#define MSM_CAM_RESP_CTRL 0 +#define MSM_CAM_RESP_STAT_EVT_MSG 1 +#define MSM_CAM_RESP_STEREO_OP_1 2 +#define MSM_CAM_RESP_STEREO_OP_2 3 +#define MSM_CAM_RESP_V4L2 4 +#define MSM_CAM_RESP_DIV_FRAME_EVT_MSG 5 +#define MSM_CAM_RESP_DONE_EVENT 6 +#define MSM_CAM_RESP_MCTL_PP_EVENT 7 +#define MSM_CAM_RESP_MAX 8 + +#define MSM_CAM_APP_NOTIFY_EVENT 0 +#define MSM_CAM_APP_NOTIFY_ERROR_EVENT 1 + +/* this one is used to send ctrl/status up to config thread */ + +struct msm_stats_event_ctrl { + /* 0 - ctrl_cmd from control thread, + * 1 - stats/event kernel, + * 2 - V4L control or read request */ + int resptype; + int timeout_ms; + struct msm_ctrl_cmd ctrl_cmd; + /* struct vfe_event_t stats_event; */ + struct msm_cam_evt_msg stats_event; +}; + +/* 2. config command: config command(from config thread); */ +struct msm_camera_cfg_cmd { + /* what to config: + * 1 - sensor config, 2 - vfe config */ + uint16_t cfg_type; + + /* sensor config type */ + uint16_t cmd_type; + uint16_t queue; + uint16_t length; + void *value; +}; + +#define CMD_GENERAL 0 +#define CMD_AXI_CFG_OUT1 1 +#define CMD_AXI_CFG_SNAP_O1_AND_O2 2 +#define CMD_AXI_CFG_OUT2 3 +#define CMD_PICT_T_AXI_CFG 4 +#define CMD_PICT_M_AXI_CFG 5 +#define CMD_RAW_PICT_AXI_CFG 6 + +#define CMD_FRAME_BUF_RELEASE 7 +#define CMD_PREV_BUF_CFG 8 +#define CMD_SNAP_BUF_RELEASE 9 +#define CMD_SNAP_BUF_CFG 10 +#define CMD_STATS_DISABLE 11 +#define CMD_STATS_AEC_AWB_ENABLE 12 +#define CMD_STATS_AF_ENABLE 13 +#define CMD_STATS_AEC_ENABLE 14 +#define CMD_STATS_AWB_ENABLE 15 +#define CMD_STATS_ENABLE 16 + +#define CMD_STATS_AXI_CFG 17 +#define CMD_STATS_AEC_AXI_CFG 18 +#define CMD_STATS_AF_AXI_CFG 19 +#define CMD_STATS_AWB_AXI_CFG 20 +#define CMD_STATS_RS_AXI_CFG 21 +#define CMD_STATS_CS_AXI_CFG 22 +#define CMD_STATS_IHIST_AXI_CFG 23 +#define CMD_STATS_SKIN_AXI_CFG 24 + +#define CMD_STATS_BUF_RELEASE 25 +#define CMD_STATS_AEC_BUF_RELEASE 26 +#define CMD_STATS_AF_BUF_RELEASE 27 +#define CMD_STATS_AWB_BUF_RELEASE 28 +#define CMD_STATS_RS_BUF_RELEASE 29 +#define CMD_STATS_CS_BUF_RELEASE 30 +#define CMD_STATS_IHIST_BUF_RELEASE 31 +#define CMD_STATS_SKIN_BUF_RELEASE 32 + +#define UPDATE_STATS_INVALID 33 +#define CMD_AXI_CFG_SNAP_GEMINI 34 +#define CMD_AXI_CFG_SNAP 35 +#define CMD_AXI_CFG_PREVIEW 36 +#define CMD_AXI_CFG_VIDEO 37 + +#define CMD_STATS_IHIST_ENABLE 38 +#define CMD_STATS_RS_ENABLE 39 +#define CMD_STATS_CS_ENABLE 40 +#define CMD_VPE 41 +#define CMD_AXI_CFG_VPE 42 +#define CMD_AXI_CFG_ZSL 43 +#define CMD_AXI_CFG_SNAP_VPE 44 +#define CMD_AXI_CFG_SNAP_THUMB_VPE 45 + +#define CMD_CONFIG_PING_ADDR 46 +#define CMD_CONFIG_PONG_ADDR 47 +#define CMD_CONFIG_FREE_BUF_ADDR 48 +#define CMD_AXI_CFG_ZSL_ALL_CHNLS 49 +#define CMD_AXI_CFG_VIDEO_ALL_CHNLS 50 +#define CMD_VFE_BUFFER_RELEASE 51 +#define CMD_VFE_PROCESS_IRQ 52 +#define CMD_STATS_BG_ENABLE 53 +#define CMD_STATS_BF_ENABLE 54 +#define CMD_STATS_BHIST_ENABLE 55 +#define CMD_STATS_BG_BUF_RELEASE 56 +#define CMD_STATS_BF_BUF_RELEASE 57 +#define CMD_STATS_BHIST_BUF_RELEASE 58 +#define CMD_VFE_PIX_SOF_COUNT_UPDATE 59 +#define CMD_VFE_COUNT_PIX_SOF_ENABLE 60 +#define CMD_STATS_BE_ENABLE 61 +#define CMD_STATS_BE_BUF_RELEASE 62 + +#define CMD_AXI_CFG_PRIM BIT(8) +#define CMD_AXI_CFG_PRIM_ALL_CHNLS BIT(9) +#define CMD_AXI_CFG_SEC BIT(10) +#define CMD_AXI_CFG_SEC_ALL_CHNLS BIT(11) +#define CMD_AXI_CFG_TERT1 BIT(12) +#define CMD_AXI_CFG_TERT2 BIT(13) + +#define CMD_AXI_START 0xE1 +#define CMD_AXI_STOP 0xE2 +#define CMD_AXI_RESET 0xE3 +#define CMD_AXI_ABORT 0xE4 + + + +#define AXI_CMD_PREVIEW BIT(0) +#define AXI_CMD_CAPTURE BIT(1) +#define AXI_CMD_RECORD BIT(2) +#define AXI_CMD_ZSL BIT(3) +#define AXI_CMD_RAW_CAPTURE BIT(4) +#define AXI_CMD_LIVESHOT BIT(5) + +/* vfe config command: config command(from config thread)*/ +struct msm_vfe_cfg_cmd { + int cmd_type; + uint16_t length; + void *value; +}; + +struct msm_vpe_cfg_cmd { + int cmd_type; + uint16_t length; + void *value; +}; + +#define MAX_CAMERA_ENABLE_NAME_LEN 32 +struct camera_enable_cmd { + char name[MAX_CAMERA_ENABLE_NAME_LEN]; +}; + +#define MSM_PMEM_OUTPUT1 0 +#define MSM_PMEM_OUTPUT2 1 +#define MSM_PMEM_OUTPUT1_OUTPUT2 2 +#define MSM_PMEM_THUMBNAIL 3 +#define MSM_PMEM_MAINIMG 4 +#define MSM_PMEM_RAW_MAINIMG 5 +#define MSM_PMEM_AEC_AWB 6 +#define MSM_PMEM_AF 7 +#define MSM_PMEM_AEC 8 +#define MSM_PMEM_AWB 9 +#define MSM_PMEM_RS 10 +#define MSM_PMEM_CS 11 +#define MSM_PMEM_IHIST 12 +#define MSM_PMEM_SKIN 13 +#define MSM_PMEM_VIDEO 14 +#define MSM_PMEM_PREVIEW 15 +#define MSM_PMEM_VIDEO_VPE 16 +#define MSM_PMEM_C2D 17 +#define MSM_PMEM_MAINIMG_VPE 18 +#define MSM_PMEM_THUMBNAIL_VPE 19 +#define MSM_PMEM_BAYER_GRID 20 +#define MSM_PMEM_BAYER_FOCUS 21 +#define MSM_PMEM_BAYER_HIST 22 +#define MSM_PMEM_BAYER_EXPOSURE 23 +#define MSM_PMEM_MAX 24 + +#define STAT_AEAW 0 +#define STAT_AEC 1 +#define STAT_AF 2 +#define STAT_AWB 3 +#define STAT_RS 4 +#define STAT_CS 5 +#define STAT_IHIST 6 +#define STAT_SKIN 7 +#define STAT_BG 8 +#define STAT_BF 9 +#define STAT_BE 10 +#define STAT_BHIST 11 +#define STAT_MAX 12 + +#define FRAME_PREVIEW_OUTPUT1 0 +#define FRAME_PREVIEW_OUTPUT2 1 +#define FRAME_SNAPSHOT 2 +#define FRAME_THUMBNAIL 3 +#define FRAME_RAW_SNAPSHOT 4 +#define FRAME_MAX 5 + +enum msm_stats_enum_type { + MSM_STATS_TYPE_AEC, /* legacy based AEC */ + MSM_STATS_TYPE_AF, /* legacy based AF */ + MSM_STATS_TYPE_AWB, /* legacy based AWB */ + MSM_STATS_TYPE_RS, /* legacy based RS */ + MSM_STATS_TYPE_CS, /* legacy based CS */ + MSM_STATS_TYPE_IHIST, /* legacy based HIST */ + MSM_STATS_TYPE_SKIN, /* legacy based SKIN */ + MSM_STATS_TYPE_BG, /* Bayer Grids */ + MSM_STATS_TYPE_BF, /* Bayer Focus */ + MSM_STATS_TYPE_BE, /* Bayer Exposure*/ + MSM_STATS_TYPE_BHIST, /* Bayer Hist */ + MSM_STATS_TYPE_AE_AW, /* legacy stats for vfe 2.x*/ + MSM_STATS_TYPE_COMP, /* Composite stats */ + MSM_STATS_TYPE_MAX /* MAX */ +}; + +struct msm_stats_buf_info { + int type; /* msm_stats_enum_type */ + int fd; + void *vaddr; + uint32_t offset; + uint32_t len; + uint32_t y_off; + uint32_t cbcr_off; + uint32_t planar0_off; + uint32_t planar1_off; + uint32_t planar2_off; + uint8_t active; + int buf_idx; +}; + +struct msm_pmem_info { + int type; + int fd; + void *vaddr; + uint32_t offset; + uint32_t len; + uint32_t y_off; + uint32_t cbcr_off; + uint32_t planar0_off; + uint32_t planar1_off; + uint32_t planar2_off; + uint8_t active; +}; + +struct outputCfg { + uint32_t height; + uint32_t width; + + uint32_t window_height_firstline; + uint32_t window_height_lastline; +}; + +#define VIDEO_NODE 0 +#define MCTL_NODE 1 + +#define OUTPUT_1 0 +#define OUTPUT_2 1 +#define OUTPUT_1_AND_2 2 /* snapshot only */ +#define OUTPUT_1_AND_3 3 /* video */ +#define CAMIF_TO_AXI_VIA_OUTPUT_2 4 +#define OUTPUT_1_AND_CAMIF_TO_AXI_VIA_OUTPUT_2 5 +#define OUTPUT_2_AND_CAMIF_TO_AXI_VIA_OUTPUT_1 6 +#define OUTPUT_1_2_AND_3 7 +#define OUTPUT_ALL_CHNLS 8 +#define OUTPUT_VIDEO_ALL_CHNLS 9 +#define OUTPUT_ZSL_ALL_CHNLS 10 +#define LAST_AXI_OUTPUT_MODE_ENUM = OUTPUT_ZSL_ALL_CHNLS + +#define OUTPUT_PRIM BIT(8) +#define OUTPUT_PRIM_ALL_CHNLS BIT(9) +#define OUTPUT_SEC BIT(10) +#define OUTPUT_SEC_ALL_CHNLS BIT(11) +#define OUTPUT_TERT1 BIT(12) +#define OUTPUT_TERT2 BIT(13) + + + +#define MSM_FRAME_PREV_1 0 +#define MSM_FRAME_PREV_2 1 +#define MSM_FRAME_ENC 2 + +#define OUTPUT_TYPE_P BIT(0) +#define OUTPUT_TYPE_T BIT(1) +#define OUTPUT_TYPE_S BIT(2) +#define OUTPUT_TYPE_V BIT(3) +#define OUTPUT_TYPE_L BIT(4) +#define OUTPUT_TYPE_ST_L BIT(5) +#define OUTPUT_TYPE_ST_R BIT(6) +#define OUTPUT_TYPE_ST_D BIT(7) +#define OUTPUT_TYPE_R BIT(8) +#define OUTPUT_TYPE_R1 BIT(9) +#define OUTPUT_TYPE_SAEC BIT(10) +#define OUTPUT_TYPE_SAFC BIT(11) +#define OUTPUT_TYPE_SAWB BIT(12) +#define OUTPUT_TYPE_IHST BIT(13) +#define OUTPUT_TYPE_CSTA BIT(14) + +struct fd_roi_info { + void *info; + int info_len; +}; + +struct msm_mem_map_info { + uint32_t cookie; + uint32_t length; + uint32_t mem_type; +}; + +#define MSM_MEM_MMAP 0 +#define MSM_MEM_USERPTR 1 +#define MSM_PLANE_MAX 8 +#define MSM_PLANE_Y 0 +#define MSM_PLANE_UV 1 + +struct msm_frame { + struct timespec ts; + int path; + int type; + unsigned long buffer; + uint32_t phy_offset; + uint32_t y_off; + uint32_t cbcr_off; + uint32_t planar0_off; + uint32_t planar1_off; + uint32_t planar2_off; + int fd; + + void *cropinfo; + int croplen; + uint32_t error_code; + struct fd_roi_info roi_info; + uint32_t frame_id; + int stcam_quality_ind; + uint32_t stcam_conv_value; + + struct ion_allocation_data ion_alloc; + struct ion_fd_data fd_data; + int ion_dev_fd; +}; + +enum msm_st_frame_packing { + SIDE_BY_SIDE_HALF, + SIDE_BY_SIDE_FULL, + TOP_DOWN_HALF, + TOP_DOWN_FULL, +}; + +struct msm_st_crop { + uint32_t in_w; + uint32_t in_h; + uint32_t out_w; + uint32_t out_h; +}; + +struct msm_st_half { + uint32_t buf_p0_off; + uint32_t buf_p1_off; + uint32_t buf_p0_stride; + uint32_t buf_p1_stride; + uint32_t pix_x_off; + uint32_t pix_y_off; + struct msm_st_crop stCropInfo; +}; + +struct msm_st_frame { + struct msm_frame buf_info; + int type; + enum msm_st_frame_packing packing; + struct msm_st_half L; + struct msm_st_half R; + int frame_id; +}; + +#define MSM_CAMERA_ERR_MASK (0xFFFFFFFF & 1) + +struct stats_buff { + unsigned long buff; + int fd; +}; + +struct msm_stats_buf { + uint8_t awb_ymin; + struct stats_buff aec; + struct stats_buff awb; + struct stats_buff af; + struct stats_buff be; + struct stats_buff ihist; + struct stats_buff rs; + struct stats_buff cs; + struct stats_buff skin; + int type; + uint32_t status_bits; + unsigned long buffer; + int fd; + int length; + struct ion_handle *handle; + uint32_t frame_id; + int buf_idx; +}; +#define MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT 0 +/* video capture mode in VIDIOC_S_PARM */ +#define MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+1) +/* extendedmode for video recording in VIDIOC_S_PARM */ +#define MSM_V4L2_EXT_CAPTURE_MODE_VIDEO \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+2) +/* extendedmode for the full size main image in VIDIOC_S_PARM */ +#define MSM_V4L2_EXT_CAPTURE_MODE_MAIN (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+3) +/* extendedmode for the thumb nail image in VIDIOC_S_PARM */ +#define MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+4) +/* ISP_PIX_OUTPUT1: no pp, directly send output1 buf to user */ +#define MSM_V4L2_EXT_CAPTURE_MODE_ISP_PIX_OUTPUT1 \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+5) +/* ISP_PIX_OUTPUT2: no pp, directly send output2 buf to user */ +#define MSM_V4L2_EXT_CAPTURE_MODE_ISP_PIX_OUTPUT2 \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+6) +/* raw image type */ +#define MSM_V4L2_EXT_CAPTURE_MODE_RAW \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+7) +/* RDI dump */ +#define MSM_V4L2_EXT_CAPTURE_MODE_RDI \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+8) +/* RDI dump 1 */ +#define MSM_V4L2_EXT_CAPTURE_MODE_RDI1 \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+9) +/* RDI dump 2 */ +#define MSM_V4L2_EXT_CAPTURE_MODE_RDI2 \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+10) +#define MSM_V4L2_EXT_CAPTURE_MODE_AEC \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+11) +#define MSM_V4L2_EXT_CAPTURE_MODE_AWB \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+12) +#define MSM_V4L2_EXT_CAPTURE_MODE_AF \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+13) +#define MSM_V4L2_EXT_CAPTURE_MODE_IHIST \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+14) +#define MSM_V4L2_EXT_CAPTURE_MODE_CS \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+15) +#define MSM_V4L2_EXT_CAPTURE_MODE_RS \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+16) +#define MSM_V4L2_EXT_CAPTURE_MODE_CSTA \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+17) +#define MSM_V4L2_EXT_CAPTURE_MODE_V2X_LIVESHOT \ + (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+18) +#define MSM_V4L2_EXT_CAPTURE_MODE_MAX (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+19) + + +#define MSM_V4L2_PID_MOTION_ISO V4L2_CID_PRIVATE_BASE +#define MSM_V4L2_PID_EFFECT (V4L2_CID_PRIVATE_BASE+1) +#define MSM_V4L2_PID_HJR (V4L2_CID_PRIVATE_BASE+2) +#define MSM_V4L2_PID_LED_MODE (V4L2_CID_PRIVATE_BASE+3) +#define MSM_V4L2_PID_PREP_SNAPSHOT (V4L2_CID_PRIVATE_BASE+4) +#define MSM_V4L2_PID_EXP_METERING (V4L2_CID_PRIVATE_BASE+5) +#define MSM_V4L2_PID_ISO (V4L2_CID_PRIVATE_BASE+6) +#define MSM_V4L2_PID_CAM_MODE (V4L2_CID_PRIVATE_BASE+7) +#define MSM_V4L2_PID_LUMA_ADAPTATION (V4L2_CID_PRIVATE_BASE+8) +#define MSM_V4L2_PID_BEST_SHOT (V4L2_CID_PRIVATE_BASE+9) +#define MSM_V4L2_PID_FOCUS_MODE (V4L2_CID_PRIVATE_BASE+10) +#define MSM_V4L2_PID_BL_DETECTION (V4L2_CID_PRIVATE_BASE+11) +#define MSM_V4L2_PID_SNOW_DETECTION (V4L2_CID_PRIVATE_BASE+12) +#define MSM_V4L2_PID_CTRL_CMD (V4L2_CID_PRIVATE_BASE+13) +#define MSM_V4L2_PID_EVT_SUB_INFO (V4L2_CID_PRIVATE_BASE+14) +#define MSM_V4L2_PID_STROBE_FLASH (V4L2_CID_PRIVATE_BASE+15) +#define MSM_V4L2_PID_INST_HANDLE (V4L2_CID_PRIVATE_BASE+16) +#define MSM_V4L2_PID_MMAP_INST (V4L2_CID_PRIVATE_BASE+17) +#define MSM_V4L2_PID_PP_PLANE_INFO (V4L2_CID_PRIVATE_BASE+18) +#define MSM_V4L2_PID_MAX MSM_V4L2_PID_PP_PLANE_INFO + +/* camera operation mode for video recording - two frame output queues */ +#define MSM_V4L2_CAM_OP_DEFAULT 0 +/* camera operation mode for video recording - two frame output queues */ +#define MSM_V4L2_CAM_OP_PREVIEW (MSM_V4L2_CAM_OP_DEFAULT+1) +/* camera operation mode for video recording - two frame output queues */ +#define MSM_V4L2_CAM_OP_VIDEO (MSM_V4L2_CAM_OP_DEFAULT+2) +/* camera operation mode for standard shapshot - two frame output queues */ +#define MSM_V4L2_CAM_OP_CAPTURE (MSM_V4L2_CAM_OP_DEFAULT+3) +/* camera operation mode for zsl shapshot - three output queues */ +#define MSM_V4L2_CAM_OP_ZSL (MSM_V4L2_CAM_OP_DEFAULT+4) +/* camera operation mode for raw snapshot - one frame output queue */ +#define MSM_V4L2_CAM_OP_RAW (MSM_V4L2_CAM_OP_DEFAULT+5) +/* camera operation mode for jpeg snapshot - one frame output queue */ +#define MSM_V4L2_CAM_OP_JPEG_CAPTURE (MSM_V4L2_CAM_OP_DEFAULT+6) + + +#define MSM_V4L2_VID_CAP_TYPE 0 +#define MSM_V4L2_STREAM_ON 1 +#define MSM_V4L2_STREAM_OFF 2 +#define MSM_V4L2_SNAPSHOT 3 +#define MSM_V4L2_QUERY_CTRL 4 +#define MSM_V4L2_GET_CTRL 5 +#define MSM_V4L2_SET_CTRL 6 +#define MSM_V4L2_QUERY 7 +#define MSM_V4L2_GET_CROP 8 +#define MSM_V4L2_SET_CROP 9 +#define MSM_V4L2_OPEN 10 +#define MSM_V4L2_CLOSE 11 +#define MSM_V4L2_SET_CTRL_CMD 12 +#define MSM_V4L2_EVT_SUB_MASK 13 +#define MSM_V4L2_PRIVATE_CMD 14 +#define MSM_V4L2_MAX 15 +#define V4L2_CAMERA_EXIT 43 + +struct crop_info { + void *info; + int len; +}; + +struct msm_postproc { + int ftnum; + struct msm_frame fthumnail; + int fmnum; + struct msm_frame fmain; +}; + +struct msm_snapshot_pp_status { + void *status; +}; + +#define CFG_SET_MODE 0 +#define CFG_SET_EFFECT 1 +#define CFG_START 2 +#define CFG_PWR_UP 3 +#define CFG_PWR_DOWN 4 +#define CFG_WRITE_EXPOSURE_GAIN 5 +#define CFG_SET_DEFAULT_FOCUS 6 +#define CFG_MOVE_FOCUS 7 +#define CFG_REGISTER_TO_REAL_GAIN 8 +#define CFG_REAL_TO_REGISTER_GAIN 9 +#define CFG_SET_FPS 10 +#define CFG_SET_PICT_FPS 11 +#define CFG_SET_BRIGHTNESS 12 +#define CFG_SET_CONTRAST 13 +#define CFG_SET_ZOOM 14 +#define CFG_SET_EXPOSURE_MODE 15 +#define CFG_SET_WB 16 +#define CFG_SET_ANTIBANDING 17 +#define CFG_SET_EXP_GAIN 18 +#define CFG_SET_PICT_EXP_GAIN 19 +#define CFG_SET_LENS_SHADING 20 +#define CFG_GET_PICT_FPS 21 +#define CFG_GET_PREV_L_PF 22 +#define CFG_GET_PREV_P_PL 23 +#define CFG_GET_PICT_L_PF 24 +#define CFG_GET_PICT_P_PL 25 +#define CFG_GET_AF_MAX_STEPS 26 +#define CFG_GET_PICT_MAX_EXP_LC 27 +#define CFG_SEND_WB_INFO 28 +#define CFG_SENSOR_INIT 29 +#define CFG_GET_3D_CALI_DATA 30 +#define CFG_GET_CALIB_DATA 31 +#define CFG_GET_OUTPUT_INFO 32 +#define CFG_GET_EEPROM_INFO 33 +#define CFG_GET_EEPROM_DATA 34 +#define CFG_SET_ACTUATOR_INFO 35 +#define CFG_GET_ACTUATOR_INFO 36 +/* TBD: QRD */ +#define CFG_SET_SATURATION 37 +#define CFG_SET_SHARPNESS 38 +#define CFG_SET_TOUCHAEC 39 +#define CFG_SET_AUTO_FOCUS 40 +#define CFG_SET_AUTOFLASH 41 +#define CFG_SET_EXPOSURE_COMPENSATION 42 +#define CFG_SET_ISO 43 +#define CFG_START_STREAM 44 +#define CFG_STOP_STREAM 45 +#define CFG_GET_CSI_PARAMS 46 +#define CFG_POWER_UP 47 +#define CFG_POWER_DOWN 48 +#define CFG_WRITE_I2C_ARRAY 49 +#define CFG_READ_I2C_ARRAY 50 +#define CFG_PCLK_CHANGE 51 +#define CFG_CONFIG_VREG_ARRAY 52 +#define CFG_CONFIG_CLK_ARRAY 53 +#define CFG_GPIO_OP 54 +#define CFG_MAX 55 + + +#define MOVE_NEAR 0 +#define MOVE_FAR 1 + +#define SENSOR_PREVIEW_MODE 0 +#define SENSOR_SNAPSHOT_MODE 1 +#define SENSOR_RAW_SNAPSHOT_MODE 2 +#define SENSOR_HFR_60FPS_MODE 3 +#define SENSOR_HFR_90FPS_MODE 4 +#define SENSOR_HFR_120FPS_MODE 5 + +#define SENSOR_QTR_SIZE 0 +#define SENSOR_FULL_SIZE 1 +#define SENSOR_QVGA_SIZE 2 +#define SENSOR_INVALID_SIZE 3 + +#define CAMERA_EFFECT_OFF 0 +#define CAMERA_EFFECT_MONO 1 +#define CAMERA_EFFECT_NEGATIVE 2 +#define CAMERA_EFFECT_SOLARIZE 3 +#define CAMERA_EFFECT_SEPIA 4 +#define CAMERA_EFFECT_POSTERIZE 5 +#define CAMERA_EFFECT_WHITEBOARD 6 +#define CAMERA_EFFECT_BLACKBOARD 7 +#define CAMERA_EFFECT_AQUA 8 +#define CAMERA_EFFECT_EMBOSS 9 +#define CAMERA_EFFECT_SKETCH 10 +#define CAMERA_EFFECT_NEON 11 +#define CAMERA_EFFECT_FADED 12 +#define CAMERA_EFFECT_VINTAGECOOL 13 +#define CAMERA_EFFECT_VINTAGEWARM 14 +#define CAMERA_EFFECT_ACCENT_BLUE 15 +#define CAMERA_EFFECT_ACCENT_GREEN 16 +#define CAMERA_EFFECT_ACCENT_ORANGE 17 +#define CAMERA_EFFECT_MAX 18 + +/* QRD */ +#define CAMERA_EFFECT_BW 10 +#define CAMERA_EFFECT_BLUISH 12 +#define CAMERA_EFFECT_REDDISH 13 +#define CAMERA_EFFECT_GREENISH 14 + +/* QRD */ +#define CAMERA_ANTIBANDING_OFF 0 +#define CAMERA_ANTIBANDING_50HZ 2 +#define CAMERA_ANTIBANDING_60HZ 1 +#define CAMERA_ANTIBANDING_AUTO 3 + +#define CAMERA_CONTRAST_LV0 0 +#define CAMERA_CONTRAST_LV1 1 +#define CAMERA_CONTRAST_LV2 2 +#define CAMERA_CONTRAST_LV3 3 +#define CAMERA_CONTRAST_LV4 4 +#define CAMERA_CONTRAST_LV5 5 +#define CAMERA_CONTRAST_LV6 6 +#define CAMERA_CONTRAST_LV7 7 +#define CAMERA_CONTRAST_LV8 8 +#define CAMERA_CONTRAST_LV9 9 + +#define CAMERA_BRIGHTNESS_LV0 0 +#define CAMERA_BRIGHTNESS_LV1 1 +#define CAMERA_BRIGHTNESS_LV2 2 +#define CAMERA_BRIGHTNESS_LV3 3 +#define CAMERA_BRIGHTNESS_LV4 4 +#define CAMERA_BRIGHTNESS_LV5 5 +#define CAMERA_BRIGHTNESS_LV6 6 +#define CAMERA_BRIGHTNESS_LV7 7 +#define CAMERA_BRIGHTNESS_LV8 8 + + +#define CAMERA_SATURATION_LV0 0 +#define CAMERA_SATURATION_LV1 1 +#define CAMERA_SATURATION_LV2 2 +#define CAMERA_SATURATION_LV3 3 +#define CAMERA_SATURATION_LV4 4 +#define CAMERA_SATURATION_LV5 5 +#define CAMERA_SATURATION_LV6 6 +#define CAMERA_SATURATION_LV7 7 +#define CAMERA_SATURATION_LV8 8 + +#define CAMERA_SHARPNESS_LV0 0 +#define CAMERA_SHARPNESS_LV1 3 +#define CAMERA_SHARPNESS_LV2 6 +#define CAMERA_SHARPNESS_LV3 9 +#define CAMERA_SHARPNESS_LV4 12 +#define CAMERA_SHARPNESS_LV5 15 +#define CAMERA_SHARPNESS_LV6 18 +#define CAMERA_SHARPNESS_LV7 21 +#define CAMERA_SHARPNESS_LV8 24 +#define CAMERA_SHARPNESS_LV9 27 +#define CAMERA_SHARPNESS_LV10 30 + +#define CAMERA_SETAE_AVERAGE 0 +#define CAMERA_SETAE_CENWEIGHT 1 + +#define CAMERA_WB_AUTO 1 /* This list must match aeecamera.h */ +#define CAMERA_WB_CUSTOM 2 +#define CAMERA_WB_INCANDESCENT 3 +#define CAMERA_WB_FLUORESCENT 4 +#define CAMERA_WB_DAYLIGHT 5 +#define CAMERA_WB_CLOUDY_DAYLIGHT 6 +#define CAMERA_WB_TWILIGHT 7 +#define CAMERA_WB_SHADE 8 + +#define CAMERA_EXPOSURE_COMPENSATION_LV0 12 +#define CAMERA_EXPOSURE_COMPENSATION_LV1 6 +#define CAMERA_EXPOSURE_COMPENSATION_LV2 0 +#define CAMERA_EXPOSURE_COMPENSATION_LV3 -6 +#define CAMERA_EXPOSURE_COMPENSATION_LV4 -12 + +enum msm_v4l2_saturation_level { + MSM_V4L2_SATURATION_L0, + MSM_V4L2_SATURATION_L1, + MSM_V4L2_SATURATION_L2, + MSM_V4L2_SATURATION_L3, + MSM_V4L2_SATURATION_L4, + MSM_V4L2_SATURATION_L5, + MSM_V4L2_SATURATION_L6, + MSM_V4L2_SATURATION_L7, + MSM_V4L2_SATURATION_L8, + MSM_V4L2_SATURATION_L9, + MSM_V4L2_SATURATION_L10, +}; + +enum msm_v4l2_contrast_level { + MSM_V4L2_CONTRAST_L0, + MSM_V4L2_CONTRAST_L1, + MSM_V4L2_CONTRAST_L2, + MSM_V4L2_CONTRAST_L3, + MSM_V4L2_CONTRAST_L4, + MSM_V4L2_CONTRAST_L5, + MSM_V4L2_CONTRAST_L6, + MSM_V4L2_CONTRAST_L7, + MSM_V4L2_CONTRAST_L8, + MSM_V4L2_CONTRAST_L9, + MSM_V4L2_CONTRAST_L10, +}; + + +enum msm_v4l2_exposure_level { + MSM_V4L2_EXPOSURE_N2, + MSM_V4L2_EXPOSURE_N1, + MSM_V4L2_EXPOSURE_D, + MSM_V4L2_EXPOSURE_P1, + MSM_V4L2_EXPOSURE_P2, +}; + +enum msm_v4l2_sharpness_level { + MSM_V4L2_SHARPNESS_L0, + MSM_V4L2_SHARPNESS_L1, + MSM_V4L2_SHARPNESS_L2, + MSM_V4L2_SHARPNESS_L3, + MSM_V4L2_SHARPNESS_L4, + MSM_V4L2_SHARPNESS_L5, + MSM_V4L2_SHARPNESS_L6, +}; + +enum msm_v4l2_expo_metering_mode { + MSM_V4L2_EXP_FRAME_AVERAGE, + MSM_V4L2_EXP_CENTER_WEIGHTED, + MSM_V4L2_EXP_SPOT_METERING, +}; + +enum msm_v4l2_iso_mode { + MSM_V4L2_ISO_AUTO = 0, + MSM_V4L2_ISO_DEBLUR, + MSM_V4L2_ISO_100, + MSM_V4L2_ISO_200, + MSM_V4L2_ISO_400, + MSM_V4L2_ISO_800, + MSM_V4L2_ISO_1600, +}; + +enum msm_v4l2_wb_mode { + MSM_V4L2_WB_OFF, + MSM_V4L2_WB_AUTO , + MSM_V4L2_WB_CUSTOM, + MSM_V4L2_WB_INCANDESCENT, + MSM_V4L2_WB_FLUORESCENT, + MSM_V4L2_WB_DAYLIGHT, + MSM_V4L2_WB_CLOUDY_DAYLIGHT, +}; + +enum msm_v4l2_special_effect { + MSM_V4L2_EFFECT_OFF, + MSM_V4L2_EFFECT_MONO, + MSM_V4L2_EFFECT_NEGATIVE, + MSM_V4L2_EFFECT_SOLARIZE, + MSM_V4L2_EFFECT_SEPIA, + MSM_V4L2_EFFECT_POSTERAIZE, + MSM_V4L2_EFFECT_WHITEBOARD, + MSM_V4L2_EFFECT_BLACKBOARD, + MSM_V4L2_EFFECT_AQUA, + MSM_V4L2_EFFECT_EMBOSS, + MSM_V4L2_EFFECT_SKETCH, + MSM_V4L2_EFFECT_NEON, + MSM_V4L2_EFFECT_MAX, +}; + +enum msm_v4l2_power_line_frequency { + MSM_V4L2_POWER_LINE_OFF, + MSM_V4L2_POWER_LINE_60HZ, + MSM_V4L2_POWER_LINE_50HZ, + MSM_V4L2_POWER_LINE_AUTO, +}; + +#define CAMERA_ISO_TYPE_AUTO 0 +#define CAMEAR_ISO_TYPE_HJR 1 +#define CAMEAR_ISO_TYPE_100 2 +#define CAMERA_ISO_TYPE_200 3 +#define CAMERA_ISO_TYPE_400 4 +#define CAMEAR_ISO_TYPE_800 5 +#define CAMERA_ISO_TYPE_1600 6 + +struct sensor_pict_fps { + uint16_t prevfps; + uint16_t pictfps; +}; + +struct exp_gain_cfg { + uint16_t gain; + uint32_t line; +}; + +struct focus_cfg { + int32_t steps; + int dir; +}; + +struct fps_cfg { + uint16_t f_mult; + uint16_t fps_div; + uint32_t pict_fps_div; +}; +struct wb_info_cfg { + uint16_t red_gain; + uint16_t green_gain; + uint16_t blue_gain; +}; +struct sensor_3d_exp_cfg { + uint16_t gain; + uint32_t line; + uint16_t r_gain; + uint16_t b_gain; + uint16_t gr_gain; + uint16_t gb_gain; + uint16_t gain_adjust; +}; +struct sensor_3d_cali_data_t{ + unsigned char left_p_matrix[3][4][8]; + unsigned char right_p_matrix[3][4][8]; + unsigned char square_len[8]; + unsigned char focal_len[8]; + unsigned char pixel_pitch[8]; + uint16_t left_r; + uint16_t left_b; + uint16_t left_gb; + uint16_t left_af_far; + uint16_t left_af_mid; + uint16_t left_af_short; + uint16_t left_af_5um; + uint16_t left_af_50up; + uint16_t left_af_50down; + uint16_t right_r; + uint16_t right_b; + uint16_t right_gb; + uint16_t right_af_far; + uint16_t right_af_mid; + uint16_t right_af_short; + uint16_t right_af_5um; + uint16_t right_af_50up; + uint16_t right_af_50down; +}; +struct sensor_init_cfg { + uint8_t prev_res; + uint8_t pict_res; +}; + +struct sensor_calib_data { + /* Color Related Measurements */ + uint16_t r_over_g; + uint16_t b_over_g; + uint16_t gr_over_gb; + + /* Lens Related Measurements */ + uint16_t macro_2_inf; + uint16_t inf_2_macro; + uint16_t stroke_amt; + uint16_t af_pos_1m; + uint16_t af_pos_inf; +}; + +enum msm_sensor_resolution_t { + MSM_SENSOR_RES_FULL, + MSM_SENSOR_RES_QTR, + MSM_SENSOR_RES_2, + MSM_SENSOR_RES_3, + MSM_SENSOR_RES_4, + MSM_SENSOR_RES_5, + MSM_SENSOR_RES_6, + MSM_SENSOR_RES_7, + MSM_SENSOR_INVALID_RES, +}; + +struct msm_sensor_output_info_t { + uint16_t x_output; + uint16_t y_output; + uint16_t line_length_pclk; + uint16_t frame_length_lines; + uint32_t vt_pixel_clk; + uint32_t op_pixel_clk; + uint16_t binning_factor; +}; + +struct sensor_output_info_t { + struct msm_sensor_output_info_t *output_info; + uint16_t num_info; +}; + +struct msm_sensor_exp_gain_info_t { + uint16_t coarse_int_time_addr; + uint16_t global_gain_addr; + uint16_t vert_offset; +}; + +struct msm_sensor_output_reg_addr_t { + uint16_t x_output; + uint16_t y_output; + uint16_t line_length_pclk; + uint16_t frame_length_lines; +}; + +struct sensor_driver_params_type { + struct msm_camera_i2c_reg_setting *init_settings; + uint16_t init_settings_size; + struct msm_camera_i2c_reg_setting *mode_settings; + uint16_t mode_settings_size; + struct msm_sensor_output_reg_addr_t *sensor_output_reg_addr; + struct msm_camera_i2c_reg_setting *start_settings; + struct msm_camera_i2c_reg_setting *stop_settings; + struct msm_camera_i2c_reg_setting *groupon_settings; + struct msm_camera_i2c_reg_setting *groupoff_settings; + struct msm_sensor_exp_gain_info_t *sensor_exp_gain_info; + struct msm_sensor_output_info_t *output_info; +}; + +struct mirror_flip { + int32_t x_mirror; + int32_t y_flip; +}; + +struct cord { + uint32_t x; + uint32_t y; +}; + +struct msm_eeprom_data_t { + void *eeprom_data; + uint16_t index; +}; + +struct msm_camera_csid_vc_cfg { + uint8_t cid; + uint8_t dt; + uint8_t decode_format; +}; + +struct csi_lane_params_t { + uint16_t csi_lane_assign; + uint8_t csi_lane_mask; + uint8_t csi_if; + uint8_t csid_core[2]; + uint8_t csi_phy_sel; +}; + +struct msm_camera_csid_lut_params { + uint8_t num_cid; + struct msm_camera_csid_vc_cfg *vc_cfg; +}; + +struct msm_camera_csid_params { + uint8_t lane_cnt; + uint16_t lane_assign; + uint8_t phy_sel; + struct msm_camera_csid_lut_params lut_params; +}; + +struct msm_camera_csiphy_params { + uint8_t lane_cnt; + uint8_t settle_cnt; + uint16_t lane_mask; + uint8_t combo_mode; +}; + +struct msm_camera_csi2_params { + struct msm_camera_csid_params csid_params; + struct msm_camera_csiphy_params csiphy_params; +}; + +enum msm_camera_csi_data_format { + CSI_8BIT, + CSI_10BIT, + CSI_12BIT, +}; + +struct msm_camera_csi_params { + enum msm_camera_csi_data_format data_format; + uint8_t lane_cnt; + uint8_t lane_assign; + uint8_t settle_cnt; + uint8_t dpcm_scheme; +}; + +enum csic_cfg_type_t { + CSIC_INIT, + CSIC_CFG, +}; + +struct csic_cfg_data { + enum csic_cfg_type_t cfgtype; + struct msm_camera_csi_params *csic_params; +}; + +enum csid_cfg_type_t { + CSID_INIT, + CSID_CFG, +}; + +struct csid_cfg_data { + enum csid_cfg_type_t cfgtype; + union { + uint32_t csid_version; + struct msm_camera_csid_params *csid_params; + } cfg; +}; + +enum csiphy_cfg_type_t { + CSIPHY_INIT, + CSIPHY_CFG, +}; + +struct csiphy_cfg_data { + enum csiphy_cfg_type_t cfgtype; + struct msm_camera_csiphy_params *csiphy_params; +}; + +#define CSI_EMBED_DATA 0x12 +#define CSI_RESERVED_DATA_0 0x13 +#define CSI_YUV422_8 0x1E +#define CSI_RAW8 0x2A +#define CSI_RAW10 0x2B +#define CSI_RAW12 0x2C + +#define CSI_DECODE_6BIT 0 +#define CSI_DECODE_8BIT 1 +#define CSI_DECODE_10BIT 2 +#define CSI_DECODE_DPCM_10_8_10 5 + +#define ISPIF_STREAM(intf, action, vfe) (((intf)<> 24) : 0xFF) + +#define CLR_IMG_MODE(handle) (handle &= 0xFF00FFFF) +#define SET_IMG_MODE(handle, data) \ + (handle |= ((0x1 << 23) | ((data & 0x7F) << 16))) +#define GET_IMG_MODE(handle) \ + ((handle & 0x800000) ? ((handle & 0x7F0000) >> 16) : 0xFF) + +#define CLR_MCTLPP_INST_IDX(handle) (handle &= 0xFFFF00FF) +#define SET_MCTLPP_INST_IDX(handle, data) \ + (handle |= ((0x1 << 15) | ((data & 0x7F) << 8))) +#define GET_MCTLPP_INST_IDX(handle) \ + ((handle & 0x8000) ? ((handle & 0x7F00) >> 8) : 0xFF) + +#define CLR_VIDEO_INST_IDX(handle) (handle &= 0xFFFFFF00) +#define GET_VIDEO_INST_IDX(handle) \ + ((handle & 0x80) ? (handle & 0x7F) : 0xFF) +#define SET_VIDEO_INST_IDX(handle, data) \ + (handle |= (0x1 << 7) | (data & 0x7F)) + +#endif /* __UAPI_MSM_CAMERA_H */ -- GitLab